Theater-ECS/src/Internal/Managers/SystemsManager.bf
Booklordofthedings 1f507c254b Version 0.8 Release (#6)
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
2024-11-23 10:20:20 +01:00

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;
});
}
}