Entity: - ID - Version - Creation - Deletion - Alive Components: - Creation - Deletion - Adding/removing from entity - Store them packed - UList Systems: - Iterate - Register - Automatically getting filled with component data Reviewed-on: #6
199 lines
No EOL
5 KiB
Beef
199 lines
No EOL
5 KiB
Beef
namespace Theater_ECS.Internal.Managers;
|
|
|
|
using System;
|
|
using System.Collections;
|
|
|
|
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)
|
|
{
|
|
_owner = ecs;
|
|
}
|
|
|
|
///Registers a system and returns false if its already contained
|
|
public bool RegisterSystem(System sys, 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)
|
|
{
|
|
_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, float delta = 0)
|
|
{
|
|
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 that fall inbetween two Sections
|
|
public void RunSystemsBetween(ECS ecs, SystemSection sectionStart, SystemSection sectionEnd, float delta = 0)
|
|
{
|
|
if (_dirty)
|
|
{
|
|
SortSystemPriorites();
|
|
_dirty = false;
|
|
}
|
|
|
|
int counter = 0;
|
|
int counterLoose = 0;
|
|
|
|
for (uint8 section = (.)sectionStart; section <= (uint8)sectionEnd; section++)
|
|
{
|
|
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
|
|
public Result<void> RunSystem(StringView id, ECS ecs)
|
|
{
|
|
if (!_registeredSystems.ContainsKeyAlt<StringView>(id))
|
|
return .Err;
|
|
|
|
_registeredSystems[scope .(id)].RunSystem(ecs);
|
|
|
|
return .Ok;
|
|
}
|
|
|
|
///Runs a function over all systems
|
|
public void EnumerateSystems(delegate void(System) func)
|
|
{
|
|
for (var i in _registeredSystems)
|
|
func.Invoke(i.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;
|
|
});
|
|
}
|
|
|
|
} |