-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
This commit is contained in:
Mergul 2020-03-06 10:12:52 +01:00
parent 87e9a31d7f
commit 5399b584dd
3 changed files with 44 additions and 10 deletions

View file

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

View file

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

View file

@ -515,6 +515,14 @@ struct ExternalUpdateCallTest
}
}
version(unittest)
{
void main()
{
}
}
else:
extern(C) int main()
{