Skip to content

Commit

Permalink
v2.0.0 (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
vanifatovvlad authored Sep 18, 2023
1 parent 7da381a commit db27cf7
Show file tree
Hide file tree
Showing 10 changed files with 344 additions and 104 deletions.
18 changes: 4 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public class HealthBarSystem : UpdateSystem {
.ToSystemStateProcessor(CreateHealthBarForHero, RemoveHealthBarForHero);
}

public override void Dispose() {
heroProcessor.Dispose();
}

public override void OnUpdate(float deltaTime) {
heroProcessor.Process();
}
Expand All @@ -49,20 +53,6 @@ public class HealthBarSystem : UpdateSystem {
public GameObject healthBar;
}
}

public class DestroySystem : UpdateSystem {
private Filter toDestroyFilter;

public override void OnAwake() { }

public override void OnUpdate(float deltaTime) {
foreach (var entity in toDestroyFilter) {
// MigrateSystemStateComponents must be called before each RemoveEntity
World.MigrateSystemStateComponents(entity);
World.RemoveEntity(entity);
}
}
}
```

## License
Expand Down
8 changes: 4 additions & 4 deletions Scellecs.Morpeh/SystemStateFilterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ public static class SystemStateFilterExtensions
{
[PublicAPI]
public static SystemStateProcessor<TSystemStateComponent> ToSystemStateProcessor<TSystemStateComponent>(
this Filter filter,
SystemStateProcessor<TSystemStateComponent>.CreateDelegate onAdd,
SystemStateProcessor<TSystemStateComponent>.RemoveDelegate onRemove = null)
this FilterBuilder filter,
SystemStateProcessor<TSystemStateComponent>.SetupDelegate setup,
SystemStateProcessor<TSystemStateComponent>.DisposeDelegate dispose = null)
where TSystemStateComponent : struct, ISystemStateComponent
{
return new(filter, onAdd, onRemove);
return new SystemStateProcessor<TSystemStateComponent>(filter, setup, dispose);
}
}
}
127 changes: 87 additions & 40 deletions Scellecs.Morpeh/SystemStateProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,86 +1,133 @@
#if UNITY_EDITOR
#define MORPEH_DEBUG
#endif

using System;
using JetBrains.Annotations;

namespace Scellecs.Morpeh
{
using System;
using JetBrains.Annotations;
using UnityEngine;

public readonly struct SystemStateProcessor<TSystemStateComponent>
public struct SystemStateProcessor<TSystemStateComponent>
where TSystemStateComponent : struct, ISystemStateComponent
{
private readonly CreateDelegate _onAdd;
private readonly RemoveDelegate _onRemove;
internal readonly SetupDelegate setupDelegate;
internal readonly DisposeDelegate disposeDelegate;
internal readonly World world;

internal readonly Filter entitiesWithoutStateFilter;
internal readonly Filter stateOnlyFilterFilter;

private readonly Filter _entitiesWithoutStateFilter;
private readonly Filter _stateOnlyFilterFilter;
internal readonly Stash<TSystemStateComponent> stateStash;
internal readonly Stash<Info> infoStash;

private readonly Stash<TSystemStateComponent> _stateStash;
private readonly Stash<Info<TSystemStateComponent>> _infoStash;
internal int frame;

public Filter Entities { get; }
public readonly Filter Entities;

internal SystemStateProcessor(
Filter filter,
CreateDelegate onAdd,
RemoveDelegate onRemove = null)
internal SystemStateProcessor(FilterBuilder filter, SetupDelegate setup, DisposeDelegate dispose)
{
Entities = filter;
Entities = filter.Build();

_onAdd = onAdd;
_onRemove = onRemove ?? delegate { };
setupDelegate = setup;
disposeDelegate = dispose;
world = filter.world;

_entitiesWithoutStateFilter = Entities.Without<TSystemStateComponent>();
_stateOnlyFilterFilter = Entities.world.Filter.With<TSystemStateComponent>();
entitiesWithoutStateFilter = filter.Without<TSystemStateComponent>().Build();
stateOnlyFilterFilter = world.Filter.With<TSystemStateComponent>().Build();

_stateStash = Entities.world.GetStash<TSystemStateComponent>();
_infoStash = Entities.world.GetStash<Info<TSystemStateComponent>>();
stateStash = world.GetStash<TSystemStateComponent>();
infoStash = world.GetStash<Info>();

frame = 0;

if (disposeDelegate != null)
{
#if MORPEH_DEBUG
if (typeof(IDisposable).IsAssignableFrom(typeof(TSystemStateComponent)))
{
var tName = typeof(TSystemStateComponent).Name;
throw new Exception($"{tName} cannot be IDisposable");
}

if (stateStash.componentDispose != null)
{
var tName = typeof(TSystemStateComponent).Name;
throw new Exception(
$"Only one instance of DisposableSystemStateProcessor<{tName}> can be created per world");
}
#endif

stateStash.componentDispose = (ref TSystemStateComponent component) => dispose.Invoke(ref component);
}
}

public void Dispose()
{
DestroyAllStates();

if (disposeDelegate != null)
{
stateStash.componentDispose = null;
}
}

[PublicAPI]
public void Process()
{
var currentFrame = Time.frameCount;
var currentFrame = ++frame;

foreach (var entity in Entities)
{
_infoStash.Set(entity, new Info<TSystemStateComponent>
infoStash.Set(entity, new Info
{
frame = currentFrame,
frame = currentFrame
});
}

foreach (var entity in _entitiesWithoutStateFilter)
foreach (var entity in entitiesWithoutStateFilter)
{
_stateStash.Set(entity, _onAdd.Invoke(entity));
stateStash.Set(entity, setupDelegate.Invoke(entity));
}

foreach (var entity in _stateOnlyFilterFilter)
foreach (var entity in stateOnlyFilterFilter)
{
var lastFrame = _infoStash.Get(entity, out var exists).frame;
var lastFrame = infoStash.Get(entity, out var exists).frame;

if (exists && lastFrame == currentFrame)
{
continue;
}

ref var state = ref _stateStash.Get(entity);
infoStash.Remove(entity);
stateStash.Remove(entity);
}

world.Commit();
}

_onRemove.Invoke(ref state);
[PublicAPI]
public void DestroyAllStates()
{
if (stateOnlyFilterFilter.IsEmpty())
{
return;
}

_stateStash.Remove(entity);
_infoStash.Remove(entity);
foreach (var entity in stateOnlyFilterFilter)
{
infoStash.Remove(entity);
stateStash.Remove(entity);
}

Entities.world.Commit();
world.Commit();
}

public delegate TSystemStateComponent CreateDelegate(Entity entity);

public delegate void RemoveDelegate(ref TSystemStateComponent data);
public delegate TSystemStateComponent SetupDelegate(Entity entity);

public delegate void DisposeDelegate(ref TSystemStateComponent data);

[Serializable]
internal struct Info<TSystemState> : IComponent
where TSystemState : struct, ISystemStateComponent
internal struct Info : IComponent
{
public int frame;
}
Expand Down
43 changes: 0 additions & 43 deletions Scellecs.Morpeh/SystemStateWorldExtensions.cs

This file was deleted.

3 changes: 0 additions & 3 deletions Scellecs.Morpeh/SystemStateWorldExtensions.cs.meta

This file was deleted.

8 changes: 8 additions & 0 deletions Tests.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions Tests/Morpeh.SystemStateProcessor.Tests.asmdef
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "Morpeh.SystemStateProcessor.Tests",
"rootNamespace": "",
"references": [
"Scellecs.Morpeh",
"UnityEngine.TestRunner",
"UnityEditor.TestRunner"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"nunit.framework.dll"
],
"autoReferenced": false,
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"versionDefines": [],
"noEngineReferences": false
}
7 changes: 7 additions & 0 deletions Tests/Morpeh.SystemStateProcessor.Tests.asmdef.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit db27cf7

Please sign in to comment.