diff --git a/BeefProj.toml b/BeefProj.toml new file mode 100644 index 0000000..af69b29 --- /dev/null +++ b/BeefProj.toml @@ -0,0 +1,6 @@ +FileVersion = 1 + +[Project] +Name = "Theater-ECS" +TargetType = "BeefLib" +StartupObject = "Theater_ECS.Program" diff --git a/README.md b/README.md index 6205cc6..3a06ac5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,25 @@ -# Theater-ECS +### **Theater-ECS** -An ecs to be used in the TE enviroment \ No newline at end of file +is a library which implements the *entity, component, system* pattern. +It is intended to be used for game development in the "Theater Engine" ecosystem, +however it may also be used for other things. + +### Design goals +- Dynamic + *Lots of ECS libraries use compile time code generation for performance benefits. + Theater-ECS is intended to be fully dynamic so that components and system could be created and registered at runtime* +- Fast + *Theater-ECS should be fast enough for most game projects, while handling a high amount of entities and components* +- Use what you need + *The amount of memory used by Theater-ECS is minimized so that it mostly only uses which memory you are actually using and doesnt + allocate any large unused buffers.* + +### Installation + +No dependencies are required, so you can simply clone this library and add it as a dependency to your +Beef project. +BeefProj.toml: `Dependencies = {Theater-ECS = "*"}` + +### Further information +- [Wiki](https://code.booklordofthe.dev/Theater/Theater-ECS/wiki) +- [Example Project](https://code.booklordofthe.dev/Theater/Theater-ECS-Example) \ No newline at end of file diff --git a/src/Archetype.bf b/src/Archetype.bf new file mode 100644 index 0000000..e634c53 --- /dev/null +++ b/src/Archetype.bf @@ -0,0 +1,9 @@ +namespace Theater_ECS; + +using System; +using System.Collections; + +interface IArchetypeable +{ + public void Instantiate(ECS ecs, Entity e); +} \ No newline at end of file diff --git a/src/Component.bf b/src/Component.bf new file mode 100644 index 0000000..fe76930 --- /dev/null +++ b/src/Component.bf @@ -0,0 +1,5 @@ +namespace Theater_ECS; + +using System; + +typealias Component = int_cosize; \ No newline at end of file diff --git a/src/DeleteECSAndItems.bf b/src/DeleteECSAndItems.bf new file mode 100644 index 0000000..805217b --- /dev/null +++ b/src/DeleteECSAndItems.bf @@ -0,0 +1,16 @@ +namespace Theater_ECS; + +static +{ + /* + This exists for ownership reasons + If this mixin isnt called the ecs will not delete any allocated data passed into it + from the outside. + */ + public static mixin DeleteECSAndItems(ECS e) + { + DeleteDictionaryAndKeysAndValues!(e.Systems); + e.Systems = null; + delete e; + } +} \ No newline at end of file diff --git a/src/ECS.bf b/src/ECS.bf new file mode 100644 index 0000000..91dbc5a --- /dev/null +++ b/src/ECS.bf @@ -0,0 +1,9 @@ +namespace Theater_ECS; +using Theater_ECS.Internal.Managers; + +class ECS +{ + public SystemsManager Systems = new .(this) ~ delete _; + public ComponentManager Components = new .() ~ delete _; + public EntityManager Entities = new .(this) ~ delete _; +} diff --git a/src/Entity.bf b/src/Entity.bf new file mode 100644 index 0000000..98f4de1 --- /dev/null +++ b/src/Entity.bf @@ -0,0 +1,31 @@ +namespace Theater_ECS; + +using System; + +public struct Entity : uint32 +{ + public static readonly Entity Null => 0x000FFFFF; + public static readonly Entity VersionMask => (.)0xFFF00000; + public static readonly uint32 IndexMask => 0x000FFFFF; + public static readonly uint8 VersionOffset => 20; + + public uint32 Index => (.)this & IndexMask; + public uint32 Version => (.)(this & VersionMask) >> VersionOffset + public Entity Next => .(Index, Version + 1); + + public this() + { + this = Entity.Null; + }; + + public this(uint32 index, uint32 version) + { + this = (index & IndexMask) | ((version << VersionOffset) & VersionMask); + + } + + public override void ToString(String strBuffer) + { + strBuffer.Append(scope $"{Index}:{Version}"); + } +} \ No newline at end of file diff --git a/src/Internal/Containers/CommandBuffer.bf b/src/Internal/Containers/CommandBuffer.bf new file mode 100644 index 0000000..a691029 --- /dev/null +++ b/src/Internal/Containers/CommandBuffer.bf @@ -0,0 +1,14 @@ +namespace Theater_ECS.Internal.Containers; + +/* + Not all actions can be done during the run of a system, + this class provides a buffer where actions are stored until a system is done running, + at which points these actions will be applied to the data store. +*/ +class CommandBuffer +{ + public void DeleteEntity(Entity e) {} + public void CreateEntity(IArchetypeable a) {} + public void AddComponentToEntity(Entity e, Component c, void* data) {} + public void RemoveComponentFromEntity(Entity e, Component c) {} +} \ No newline at end of file diff --git a/src/Internal/Containers/PagedSparseSet.bf b/src/Internal/Containers/PagedSparseSet.bf new file mode 100644 index 0000000..826ce2d --- /dev/null +++ b/src/Internal/Containers/PagedSparseSet.bf @@ -0,0 +1,87 @@ +namespace Theater_ECS.Internal.Containers; + +using System; +using System.Collections; + +class PagedSparseSet +{ + public const uint32 PageSize = 4096; + + private List> _sparse = new .()~ DeleteContainerAndItems!(_); + private List _packed = new .() ~ delete _; + private UList _packedEntities ~ delete _; + + private function void(void* data) _deallocationFunction = null; + + public this(int_cosize size) + { + _packedEntities = new .(size); + } + + public bool Contains(Entity e) + { + return _sparse[e.Index/PageSize][e.Index % PageSize] != Entity.Null; + } + + public void Add(Entity e, void* toAdd) + { + EnsureLoadedPage(e.Index/PageSize); + _packed.Add(e); + _packedEntities.Add(toAdd); + _sparse[e.Index/PageSize][e.Index % PageSize] = (.)_packed.Count-1; + } + + 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; + _packed.Back = toRm; + + _sparse[b.Index/PageSize][b.Index % PageSize] = Entity(e.Index, b.Version); + _sparse[e.Index/PageSize][e.Index % PageSize] = Entity.Null; + + _packed.PopBack(); + return true; + } + + [Inline, Unchecked] + public void* Get(Entity e) + { + return _packedEntities[(.)(_sparse[e.Index/PageSize][e.Index % PageSize].Index)]; + } + + public Span GetAll() + { + return _packed; + } + + public int_cosize Count() => (.)_packed.Count; + + ///Ensure that a page exist and is loaded + public void EnsureLoadedPage(uint32 page) + { + EnsurePage(page); + if(_sparse[page] == null) + { + _sparse[page] = new List(PageSize); + _sparse[page].[Friend]Count = 4096; + _sparse[page].SetAll(Entity.Null); + + } + } + + ///Ensure that a page exists, it might be null though + private void EnsurePage(uint32 page) + { + while(_sparse.Count < page+1) + _sparse.Add(null); + } +} \ No newline at end of file diff --git a/src/Internal/Containers/UList.bf b/src/Internal/Containers/UList.bf new file mode 100644 index 0000000..44917c0 --- /dev/null +++ b/src/Internal/Containers/UList.bf @@ -0,0 +1,154 @@ +namespace Theater_ECS.Internal.Containers; + +using System; +using System.Collections; +using System.Threading; +using System.Diagnostics; +using System.Reflection; + +//A variant of list, which has no type associated with it +class UList +{ + private const int_cosize _defaultCapacity = 4; + private const int_cosize _max = int_cosize.MaxValue; + + private void* _items; //The raw data contained by this object + private readonly int_cosize _sizeof; //The size of a single object + private int_cosize _size; //How much data is actually used + private int_cosize _alloc; //How much data is actually allocated + + /// Adds an item to the back of the list. + public void Add(T* toAdd) + { + if (_size + strideof(T) > _alloc) + Realloc(_alloc * 2); + Internal.MemCpy(&((uint8*)_items)[_size], toAdd, sizeof(T)); + _size += _sizeof; + } + + /// Adds an item to the back of the list. + public void Add(void* toAdd) + { + if (_size + _sizeof > _alloc) + Realloc(_alloc * 2); + Internal.MemCpy(&((uint8*)_items)[_size], toAdd, _sizeof); + _size += _sizeof; + } + + public int_cosize Capacity + { + [Inline] + get => (_alloc / _sizeof); + set + { + if (value != _alloc / _sizeof) + Realloc(value * _sizeof); + } + } + + public int_cosize Count + { + [Inline] + get => (_size / _sizeof); + } + + [Unchecked] + public void* this[int_cosize index] + { + [Checked] + get + { + Runtime.Assert(index < (_size/_sizeof)); + return (uint8*)_items + index * _sizeof; + } + + [Unchecked, Inline] + get + { + return (uint8*)_items + index * _sizeof; + } + + [Checked] + set + { + Runtime.Assert(index < (_size/_sizeof)); + Internal.MemCpy((uint8*)_items + index * _sizeof, value, _sizeof); + } + + [Unchecked, Inline] + set + { + Internal.MemCpy((uint8*)_items + index * _sizeof, value, _sizeof); + } + } + +#region Initializers + public this(int_cosize size) + { + _sizeof = size; + Realloc(size * _defaultCapacity); + _alloc = size * _defaultCapacity; + } + + + + public this(int_cosize size, int_cosize capacity) + { + _sizeof = size; + Debug.Assert((uint)capacity <= (uint)_max); + Realloc(size * capacity); + _alloc = size * capacity; + } + + + public ~this() + { + var items = _items; + +#if BF_ENABLE_REALTIME_LEAK_CHECK + // To avoid scanning items being deleted + _items = null; + Interlocked.Fence(); +#endif + + Free(items); + } + +#endregion + +#region MemoryAllocation + private void Realloc(int_cosize newSize) + { + void* oldAlloc = null; + if (newSize > 0) + { + void* newItems = Alloc(newSize); + + if (_size > 0) + Internal.MemCpy(newItems, _items, _size); + oldAlloc = _items; + _items = (.)newItems; + _alloc = newSize; + } + else + { + oldAlloc = _items; + _items = null; + _alloc = 0; + } + + Free(oldAlloc); + return; + } + + private void* Alloc(int_cosize size) + { + return Internal.AllocRawArrayUnmarked(size); + } + + private void Free(void* val) + { + delete val; + } +#endregion +} diff --git a/src/Internal/Managers/ComponentManager.bf b/src/Internal/Managers/ComponentManager.bf new file mode 100644 index 0000000..e62c226 --- /dev/null +++ b/src/Internal/Managers/ComponentManager.bf @@ -0,0 +1,69 @@ +namespace Theater_ECS.Internal.Managers; +using Theater_ECS.Internal.Containers; + +using System; +using System.Collections; + +class ComponentManager +{ + private Dictionary _componentLookup = new .() ~ DeleteDictionaryAndKeys!(_); + public List Components = new .() ~ DeleteContainerAndItems!(_); + + + ///Registers a component based on a name and a size of that component + public Result RegisterComponent(StringView name, int_cosize size) + { + ///Return the existing component if it matches + if(_componentLookup.ContainsKeyAlt(name) + && Components[_componentLookup[scope .(name)]].[Friend]_packedEntities.[Friend]_sizeof == size) + return _componentLookup[scope .(name)]; + else if(_componentLookup.ContainsKeyAlt(name)) + { + return .Err; //There already is a component of the same name but with a different size + } + + //Attempt to find a nulled out entry + //This could be made faster but thats unlikely to ever matter + for(var i in ref Components) + if(i == null) + { + i = new .(size); + _componentLookup.Add(new .(name), (.)@i.Index); + return (Component)@i.Index; + } + + //Make a new one and return it + Components.Add(new .(size)); + _componentLookup.Add(new .(name), (.)(Components.Count-1)); + 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); + + ///Retrieves the id of a component + public Result GetId(StringView name) + { + if(!_componentLookup.ContainsKeyAlt(name)) + return .Err; + return _componentLookup[scope .(name)]; + } + + 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, true); + + ///Remove a component from the given entity and return it + public Result GetAndRemoveFromEntity(Entity e, Component c) + { + if(!Components[c].Contains(e)) + return .Err; + var data = [Unchecked]Components[c].Get(e); + Components[c].Remove(e); + return .Ok(data); + } +} \ No newline at end of file diff --git a/src/Internal/Managers/EntityManager.bf b/src/Internal/Managers/EntityManager.bf new file mode 100644 index 0000000..d36894d --- /dev/null +++ b/src/Internal/Managers/EntityManager.bf @@ -0,0 +1,58 @@ +namespace Theater_ECS.Internal.Managers; + +using System; +using System.Collections; + +class EntityManager +{ + private ECS _owner; + + private List _entities = new .() ~ delete _; + private int32 _available = 0; + private Entity _next = .Null; + + public this(ECS ecs) + { + _owner = ecs; + } + + public Entity Create() + { + if(_available == 0) + { +#if DEBUG + if(_entities.Count + 1 > Entity.IndexMask) + return .Null; //It would be beneficial if we could avoid this check +#endif + _entities.Add(Entity((.)_entities.Count,0)); + return _entities.Back; + } + else + { + _available--; + + let temp = _next.Index; + _next = (.)_entities[_next.Index].Index; + _entities[temp] = (.)(temp | (_entities[temp].Version << Entity.VersionOffset)); + + return _entities[temp]; + } + } + + public Entity Create(IArchetypeable archetype) + { + var e = this.Create(); + archetype.Instantiate(_owner, e); + return e; + } + + public void Remove(Entity e) + { + let temp = _next; + _next = .(e.Index, 255); + _entities[e.Index] = .(temp.Index, _entities[e.Index].Version+1); + _available++; + } + + public bool IsAlive(Entity e) => e == _entities[e.Index]; +} \ No newline at end of file diff --git a/src/Internal/Managers/SystemsManager.bf b/src/Internal/Managers/SystemsManager.bf new file mode 100644 index 0000000..a4fed45 --- /dev/null +++ b/src/Internal/Managers/SystemsManager.bf @@ -0,0 +1,199 @@ +namespace Theater_ECS.Internal.Managers; + +using System; +using System.Collections; + +class SystemsManager : IEnumerable<(String key, System value)> +{ + private ECS _owner; + private Dictionary _registeredSystems = new .() ~ delete _; + private Dictionary _registeredLooseSystems = new .() ~ DeleteDictionaryAndKeys!(_); + + private bool _dirty = false; + private List _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(id) || _registeredLooseSystems.ContainsKeyAlt(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(id) || _registeredLooseSystems.ContainsKeyAlt(id)) + return false; + _dirty = true; + _registeredLooseSystems.Add(new .(id), (func, runtimeDelay, section)); + return true; + } + + ///Deregister a single system + public Result DeregisterSystem(StringView id) + { + _dirty = true; + if (!(_registeredSystems.ContainsKeyAlt(id) || _registeredLooseSystems.ContainsKeyAlt(id))) + return .Err; + if (_registeredSystems.ContainsKeyAlt(id)) + return .Ok(_registeredSystems.GetAndRemoveAlt(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 RunSystem(StringView id, ECS ecs) + { + if (!_registeredSystems.ContainsKeyAlt(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.Enumerator GetEnumerator() => _registeredSystems.GetEnumerator(); + public Dictionary.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; + }); + } + +} \ No newline at end of file diff --git a/src/Internal/SystemSection.bf b/src/Internal/SystemSection.bf new file mode 100644 index 0000000..126b5ee --- /dev/null +++ b/src/Internal/SystemSection.bf @@ -0,0 +1,24 @@ +namespace Theater_ECS.Internal; + +using System; + +//Indicates when systems should be run in relation to each other +//Higher = Later +//Can be extended with own types +//Not all types have to be used +struct SystemSection : uint8 +{ + public const SystemSection TECS_Input = 0; + + public const SystemSection TECS_EarlyUpdate = 5; + public const SystemSection TECS_Update = 10; + public const SystemSection TECS_LateUpdate = 15; + + public const SystemSection TECS_EarlyRendering = 20; + public const SystemSection TECS_Rendering = 25; + public const SystemSection TECS_LateRendering = 30; + + public const SystemSection TECS_Last = 40; + + private this() {} +} \ No newline at end of file diff --git a/src/System.bf b/src/System.bf new file mode 100644 index 0000000..876e8b6 --- /dev/null +++ b/src/System.bf @@ -0,0 +1,199 @@ +namespace Theater_ECS; +using Theater_ECS.Internal; +using Theater_ECS.Internal.Containers; + +using System; +using System.Collections; + +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 _Components = new .(10) ~ delete _; + + ///Get the compoent id and cache it inside of this system + public void RegisterComponent(ECS ecs) where T : struct => _Components.Add(ecs.Components.RegisterComponent(typeof(T).GetFullName(.. scope .()), strideof(T))); + + public abstract void RegisterSystem(ECS ecs); + + ///Yes surely this is a good idea + public function void(void* p1) Run_1;; + public function void(void* p1, void* p2) Run_2; + public function void(void* p1, void* p2, void* p3) Run_3; + public function void(void* p1, void* p2, void* p3, void* p4) Run_4; + public function void(void* p1, void* p2, void* p3, void* p4, void* p5) Run_5; + public function void(void* p1, void* p2, void* p3, void* p4, void* p5, void* p6) Run_6; + public function void(void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void* p7) Run_7; + public function void(void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void* p7, void* p8) Run_8; + public function void(void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void* p7, void* p8, void* p9) Run_9; + + public void RunSystem(ECS ecs) + { + int_cosize count = int_cosize.MaxValue; + Component comp = _Components[0]; + + for (var c in _Components) + if (ecs.Components.Components[c].Count() < count) + { + count = ecs.Components.Components[c].Count(); + comp = c; + } + + //We now have the list of entities to loop through + Span entities = ecs.Components.Components[comp].GetAll(); + UList main = ecs.Components.Components[comp].[Friend]_packedEntities; + var cun = entities.Length; + +#region DumbStatement + switch (_Components.Count) + { + case 1: + for (int ii < cun) + this.Run_1(main[(.)entities[ii].Index]); + case 2: + if (comp == _Components[0]) + for (int ii < cun) + this.Run_2(main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[1])); + else + for (int ii < cun) + this.Run_2(ecs.Components.GetData(entities[ii], _Components[0]), main[(.)entities[ii].Index]); + case 3: + if (comp == _Components[0]) + for (int ii < cun) + this.Run_3(main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2])); + else if (comp == _Components[1]) + for (int ii < cun) + this.Run_3(ecs.Components.GetData(entities[ii], _Components[0]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2])); + else + for (int ii < cun) + this.Run_3(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), main[(.)entities[ii].Index]); + case 4: + if (comp == _Components[0]) + for (int ii < cun) + this.Run_4(main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3])); + else if (comp == _Components[1]) + for (int ii < cun) + this.Run_4(ecs.Components.GetData(entities[ii], _Components[0]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[2])); + else if (comp == _Components[2]) + for (int ii < cun) + this.Run_4(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2])); + else + for (int ii < cun) + this.Run_4(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), main[(.)entities[ii].Index]); + case 5: + if (comp == _Components[0]) + for (int ii < cun) + this.Run_5(main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4])); + else if (comp == _Components[1]) + for (int ii < cun) + this.Run_5(ecs.Components.GetData(entities[ii], _Components[0]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4])); + else if (comp == _Components[2]) + for (int ii < cun) + this.Run_5(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4])); + else if (comp == _Components[3]) + for (int ii < cun) + this.Run_5(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[4])); + else + for (int ii < cun) + this.Run_5(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), main[(.)entities[ii].Index]); + case 6: + if (comp == _Components[0]) + for (int ii < cun) + this.Run_6(main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5])); + else if (comp == _Components[1]) + for (int ii < cun) + this.Run_6(ecs.Components.GetData(entities[ii], _Components[0]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5])); + else if (comp == _Components[2]) + for (int ii < cun) + this.Run_6(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5])); + else if (comp == _Components[3]) + for (int ii < cun) + this.Run_6(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5])); + else if (comp == _Components[4]) + for (int ii < cun) + this.Run_6(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[5])); + else + for (int ii < cun) + this.Run_6(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), main[(.)entities[ii].Index]); + case 7: + if (comp == _Components[0]) + for (int ii < cun) + this.Run_7(main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6])); + else if (comp == _Components[1]) + for (int ii < cun) + this.Run_7(ecs.Components.GetData(entities[ii], _Components[0]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6])); + else if (comp == _Components[2]) + for (int ii < cun) + this.Run_7(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6])); + else if (comp == _Components[3]) + for (int ii < cun) + this.Run_7(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6])); + else if (comp == _Components[4]) + for (int ii < cun) + this.Run_7(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6])); + else if (comp == _Components[5]) + for (int ii < cun) + this.Run_7(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[6])); + else + for (int ii < cun) + this.Run_7(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), main[(.)entities[ii].Index]); + case 8: + if (comp == _Components[0]) + for (int ii < cun) + this.Run_8(main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7])); + else if (comp == _Components[1]) + for (int ii < cun) + this.Run_8(ecs.Components.GetData(entities[ii], _Components[0]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7])); + else if (comp == _Components[2]) + for (int ii < cun) + this.Run_8(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7])); + else if (comp == _Components[3]) + for (int ii < cun) + this.Run_8(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7])); + else if (comp == _Components[4]) + for (int ii < cun) + this.Run_8(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7])); + else if (comp == _Components[5]) + for (int ii < cun) + this.Run_8(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[7])); + else if (comp == _Components[6]) + for (int ii < cun) + this.Run_8(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[7])); + else + for (int ii < cun) + this.Run_8(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), main[(.)entities[ii].Index]); + case 9: + if (comp == _Components[0]) + for (int ii < cun) + this.Run_9(main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7]), ecs.Components.GetData(entities[ii], _Components[8])); + else if (comp == _Components[1]) + for (int ii < cun) + this.Run_9(ecs.Components.GetData(entities[ii], _Components[0]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7]), ecs.Components.GetData(entities[ii], _Components[8])); + else if (comp == _Components[2]) + for (int ii < cun) + this.Run_9(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7]), ecs.Components.GetData(entities[ii], _Components[8])); + else if (comp == _Components[3]) + for (int ii < cun) + this.Run_9(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7]), ecs.Components.GetData(entities[ii], _Components[8])); + else if (comp == _Components[4]) + for (int ii < cun) + this.Run_9(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[7]), ecs.Components.GetData(entities[ii], _Components[8])); + else if (comp == _Components[5]) + for (int ii < cun) + this.Run_9(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[7]), ecs.Components.GetData(entities[ii], _Components[8])); + else if (comp == _Components[6]) + for (int ii < cun) + this.Run_9(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[7]), ecs.Components.GetData(entities[ii], _Components[8])); + else if (comp == _Components[7]) + for (int ii < cun) + this.Run_9(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), main[(.)entities[ii].Index], ecs.Components.GetData(entities[ii], _Components[8])); + else + for (int ii < cun) + this.Run_9(ecs.Components.GetData(entities[ii], _Components[0]), ecs.Components.GetData(entities[ii], _Components[1]), ecs.Components.GetData(entities[ii], _Components[2]), ecs.Components.GetData(entities[ii], _Components[3]), ecs.Components.GetData(entities[ii], _Components[4]), ecs.Components.GetData(entities[ii], _Components[5]), ecs.Components.GetData(entities[ii], _Components[6]), ecs.Components.GetData(entities[ii], _Components[8]), main[(.)entities[ii].Index]); + } + } +#endregion +}