From 5399b584dd0f47efa3f5ac151257fb3e1cd737da Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 6 Mar 2020 10:12:52 +0100 Subject: [PATCH] -IDManager reserve EntityID(0) as empty -fixed bug with events called on destroyed entities (crash) -don't call event on system for unsupported entity -added "entity_id" property to EntitiesData --- source/ecs/id_manager.d | 27 ++++++++++++++++++++------- source/ecs/manager.d | 19 ++++++++++++++++--- tests/tests.d | 8 ++++++++ 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/source/ecs/id_manager.d b/source/ecs/id_manager.d index ebd7679..04cc360 100644 --- a/source/ecs/id_manager.d +++ b/source/ecs/id_manager.d @@ -136,7 +136,9 @@ begin: */ export bool isExist(EntityID id) nothrow @nogc { + if(id.id >= m_ids_array.length)return false; Data* data = &m_ids_array[id.id]; + if(data.entity is null)return false; return data.counter == id.counter; } @@ -151,6 +153,9 @@ begin: add_mutex = Mallocator.make!Mutex(); add_mutex.initialize(); + + getNewID(); + optimize(); } void deinitialize() @trusted @nogc nothrow @@ -243,23 +248,31 @@ private: unittest { IDManager manager; + manager.initialize(); EntityID id1 = manager.getNewID(); EntityID id2 = manager.getNewID(); EntityID id3 = manager.getNewID(); - assert(id1 == EntityID(0, 1)); - assert(id2 == EntityID(1, 1)); - assert(id3 == EntityID(2, 1)); + assert(id1 == EntityID(1, 0)); + assert(id2 == EntityID(2, 0)); + assert(id3 == EntityID(3, 0)); + manager.optimize(); manager.releaseID(id2); manager.releaseID(id1); id2 = manager.getNewID(); id1 = manager.getNewID(); - assert(id1 == EntityID(1, 2)); - assert(id2 == EntityID(0, 2)); - assert(id3 == EntityID(2, 1)); + Entity e; + e.id = id3; + manager.update(e); + + assert(id1 == EntityID(2, 1)); + assert(id2 == EntityID(1, 1)); + assert(id3 == EntityID(3, 0)); assert(manager.isExist(id3)); - assert(!manager.isExist(EntityID(0, 1))); + assert(!manager.isExist(EntityID(1, 0))); + assert(!manager.isExist(EntityID(0, 0))); + manager.deinitialize(); } diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 7c89b71..27eaa40 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -542,7 +542,7 @@ export struct EntityManager foreach (member; __traits(allMembers, Sys.EntitiesData)) { alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member)); - if (member == "length" || is(MemberType == Entity[]) + if (member == "length" || member == "thread_id" || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) { if (is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) @@ -648,6 +648,13 @@ export struct EntityManager static assert(MemberType.sizeof > 1, "EntitiesData 'length' member can't be byte or ubyte."); } + else static if(member == "thread_id") + { + static assert(isIntegral!(MemberType), + "EntitiesData 'thread_id' member must be integral type."); + static assert(MemberType.sizeof > 1, + "EntitiesData 'thread_id' member can't be byte or ubyte."); + } else static if (!(isArray!(MemberType))) static assert(0, "EntitiesData members should be arrays of elements!"); } @@ -703,6 +710,11 @@ export struct EntityManager { input_data.length = cast(typeof(input_data.length))(entities_count - offset); } + + static if (hasMember!(Sys.EntitiesData, "thread_id")) + { + input_data.thread_id = cast(typeof(input_data.thread_id))threadID(); + } static foreach (iii, comp_info; components_info.req) { @@ -2378,9 +2390,9 @@ export struct EntityManager { EventCallData call_data; void* event_pointer = cast(void*) block + event.data_offset; - call_data.event = event_pointer; foreach (j; 0 .. block.count) { + call_data.event = event_pointer; EntityID entity_id = *cast(EntityID*) event_pointer; Entity* entity = id_manager.getEntityPointer(entity_id); if (entity) @@ -2390,6 +2402,7 @@ export struct EntityManager foreach (caller; events[i].callers) { + if(call_data.block.type_info.systems[caller.system.m_id] == false)continue; call_data.system_pointer = caller.system.m_system_pointer; (cast(void function( ref EventCallData) nothrow @nogc) caller.callback)( @@ -2412,9 +2425,9 @@ export struct EntityManager { id_manager.optimize(); updateBlocks(); - removeEntities(); changeEntities(); updateEvents(); + removeEntities(); event_manager.clearEvents(); } diff --git a/tests/tests.d b/tests/tests.d index 9f432fa..3ff9d00 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -515,6 +515,14 @@ struct ExternalUpdateCallTest } } +version(unittest) +{ + void main() + { + + } +} +else: extern(C) int main() {