Added section ordering for systems runtime

This commit is contained in:
Booklordofthedings 2024-11-19 16:27:52 +01:00
parent 34b929c4e7
commit 6cd249dc5b
4 changed files with 117 additions and 8 deletions

View file

@ -11,6 +11,8 @@ class PagedSparseSet
private List<Entity> _packed = new .() ~ delete _;
private UList _packedEntities ~ delete _;
private function void(void* data) _deallocationFunction = null;
public this(int_cosize size)
{
_packedEntities = new .(size);
@ -29,12 +31,15 @@ class PagedSparseSet
_sparse[e.Index/PageSize][e.Index % PageSize] = (.)_packed.Count-1;
}
public bool Remove(Entity e)
public bool Remove(Entity e, bool cleanup = false)
{
EnsurePage(e.Index/PageSize);
if(_sparse[e.Index/PageSize] == null)
return false;
if(_deallocationFunction != null && !cleanup)
_deallocationFunction(_packedEntities[(.)(_sparse[e.Index/PageSize][e.Index % PageSize].Index)]);
let toRm = _packed[_sparse[e.Index/PageSize][e.Index % PageSize].Index];
let b = _packed.Back;
_packed[_sparse[e.Index/PageSize][e.Index % PageSize].Index] = b;

View file

@ -38,6 +38,9 @@ class ComponentManager
return (.)(Components.Count-1);
}
///Sets a function that should be called, when an object gets removed
public void SetDeallocationFunction(Component c, function void(void*) func) => Components[c].[Friend]_deallocationFunction = func;
[Inline]
public void* GetData(Entity e, Component c) => Components[c].[Unchecked]Get(e);
@ -52,7 +55,7 @@ class ComponentManager
public void AddToEntity(Entity e, Component c, void* data) => Components[c].Add(e, data);
///Remove a component from the given entity
public bool RemoveFromEntity(Entity e, Component c) => Components[c].Remove(e);
public bool RemoveFromEntity(Entity e, Component c) => Components[c].Remove(e, true);
///Remove a component from the given entity and return it
public Result<void*> GetAndRemoveFromEntity(Entity e, Component c)

View file

@ -7,6 +7,11 @@ class SystemsManager : IEnumerable<(String key, System value)>
{
private ECS _owner;
private Dictionary<String, System> _registeredSystems = new .() ~ delete _;
private Dictionary<String, (function void(ECS), float, SystemSection)> _registeredLooseSystems = new .() ~ DeleteDictionaryAndKeys!(_);
private bool _dirty = false;
private List<System> _sortedSystems = new .() ~ delete _;
private List<(function void(ECS), float, SystemSection)> _sortedLooseSystems = new .() ~ delete _;
public this(ECS ecs)
{
@ -16,34 +21,103 @@ class SystemsManager : IEnumerable<(String key, System value)>
///Registers a system and returns false if its already contained
public bool RegisterSystem(System sys, StringView id)
{
if (_registeredSystems.ContainsKeyAlt<StringView>(id))
if (_registeredSystems.ContainsKeyAlt<StringView>(id) || _registeredLooseSystems.ContainsKeyAlt<StringView>(id))
return false;
_dirty = true;
_registeredSystems.Add(new .(id), sys);
sys.RegisterSystem(_owner);
return true;
}
///Register a system without an actual system object
public bool RegisterLooseSystem(StringView id, function void(ECS) func, float runtimeDelay = 0, SystemSection section = .TECS_Update)
{
if (_registeredSystems.ContainsKeyAlt<StringView>(id) || _registeredLooseSystems.ContainsKeyAlt<StringView>(id))
return false;
_dirty = true;
_registeredLooseSystems.Add(new .(id), (func, runtimeDelay, section));
return true;
}
///Deregister a single system
public Result<System> DeregisterSystem(StringView id)
{
if (!_registeredSystems.ContainsKeyAlt<StringView>(id))
_dirty = true;
if (!(_registeredSystems.ContainsKeyAlt<StringView>(id) || _registeredLooseSystems.ContainsKeyAlt<StringView>(id)))
return .Err;
if (_registeredSystems.ContainsKeyAlt<StringView>(id))
return .Ok(_registeredSystems.GetAndRemoveAlt<StringView>(id).Value.value);
else
{
_registeredLooseSystems.Remove(scope .(id));
return .Ok(null);
}
}
///Remove all systems from use and return the amount of systems cleared
public int ClearAllSystems()
{
_dirty = true;
var c = _registeredSystems.Count;
_registeredSystems.Clear();
return c;
}
///Runs all systems once
public void RunAllSystems(ECS ecs)
public void RunAllSystems(ECS ecs, float delta = 0)
{
for (var i in _registeredSystems)
i.value.RunSystem(ecs);
if (_dirty)
{
SortSystemPriorites();
_dirty = false;
}
int counter = 0;
int counterLoose = 0;
for (uint8 section <= 255)
{
if (_sortedSystems.Count > counter)
while (_sortedSystems[counter].Section == (.)section)
{
_sortedSystems[counter].RunSystem(ecs);
counter++;
}
if (_sortedLooseSystems.Count > counterLoose)
while (_sortedLooseSystems[counterLoose].2 == (.)section)
{
_sortedLooseSystems[counterLoose].0(ecs);
counter++;
}
}
}
///Run all systems with a specific section
public void RunSystemsBySection(ECS ecs, SystemSection section, float delta = 0)
{
if (_dirty)
{
SortSystemPriorites();
_dirty = false;
}
int counter = 0;
int counterLoose = 0;
if (_sortedSystems.Count > counter)
while (_sortedSystems[counter].Section == (.)section)
{
_sortedSystems[counter].RunSystem(ecs);
counter++;
}
if (_sortedLooseSystems.Count > counterLoose)
while (_sortedLooseSystems[counterLoose].2 == (.)section)
{
_sortedLooseSystems[counterLoose].0(ecs);
counter++;
}
}
///Run a single system
@ -67,4 +141,29 @@ class SystemsManager : IEnumerable<(String key, System value)>
public int Count => _registeredSystems.Count;
public Dictionary<String, System>.Enumerator GetEnumerator() => _registeredSystems.GetEnumerator();
public Dictionary<String, (function void(ECS), float, SystemSection)>.Enumerator GetLooseEnumerator() => _registeredLooseSystems.GetEnumerator();
private void SortSystemPriorites()
{
_sortedSystems.Clear();
_sortedLooseSystems.Clear();
for (var i in _registeredSystems)
_sortedSystems.Add(i.value);
_sortedSystems.Sort(scope (a, b) =>
{
return a.Section - b.Section;
});
for (var i in _registeredLooseSystems)
_sortedLooseSystems.Add(i.value);
_sortedLooseSystems.Sort(scope (a, b) =>
{
return a.2 - b.2;
});
}
}

View file

@ -1,4 +1,5 @@
namespace Theater_ECS;
using Theater_ECS.Internal;
using Theater_ECS.Internal.Containers;
using System;
@ -8,6 +9,7 @@ abstract class System
{
public bool Paused = false; //Wether or not this service should be run
public float RuntimeDelay = 0; //How many seconds should we wait after running this system
public SystemSection Section = .TECS_Update;
private List<Component> _Components = new .(10) ~ delete _;