-Components onDestroy() support (called when component is destoryed)
-EntityCallers pointers to systems now are updated after adding new system (or in future system reloading) -fixed compilation issue referenced to filling components with default values
This commit is contained in:
parent
624c899c8c
commit
0eaff0adad
1 changed files with 59 additions and 11 deletions
|
|
@ -124,22 +124,38 @@ class EntityManager
|
|||
|
||||
foreach (info; &entities_infos.byValue)
|
||||
{
|
||||
addEntityCaller(*info, systems[$ - 1]);
|
||||
addEntityCaller(*info, cast(uint)systems.length - 1);
|
||||
}
|
||||
|
||||
updateEntityCallers();
|
||||
}
|
||||
|
||||
void registerComponent(Comp)()
|
||||
{
|
||||
|
||||
ComponentInfo info;
|
||||
|
||||
static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort))
|
||||
{
|
||||
static assert(0, "Component should have \"__gshared ushort component_id");
|
||||
}
|
||||
|
||||
ComponentInfo info;
|
||||
static if (hasMember!(Comp, "onDestroy") && isFunction!(Comp.onDestroy)
|
||||
&& is(ReturnType!(Comp.onDestroy) == void)
|
||||
&& Parameters!(Comp.onDestroy).length == 0)
|
||||
{
|
||||
static void callDestroy(void* pointer)
|
||||
{
|
||||
(cast(Comp*) pointer).onDestroy();
|
||||
}
|
||||
|
||||
info.destroy_callback = &callDestroy;
|
||||
}
|
||||
|
||||
info.size = Comp.sizeof;
|
||||
info.aligment = Comp.alignof; //8;
|
||||
info.init_data = Mallocator.instance.makeArray!ubyte(Comp.sizeof);
|
||||
*cast(Comp*)info.init_data.ptr = Comp();
|
||||
*cast(Comp*) info.init_data.ptr = Comp.init; // = Comp();
|
||||
|
||||
components.add(info);
|
||||
Comp.component_id = cast(ushort)(components.length - 1);
|
||||
|
|
@ -205,7 +221,8 @@ class EntityManager
|
|||
//fill components with default data
|
||||
foreach (comp; info.components)
|
||||
{
|
||||
temp.entity_data[info.deltas[comp]..info.deltas[comp]+components[comp].size] = components[comp].init_data;
|
||||
temp.entity_data[info.deltas[comp] .. info.deltas[comp] + components[comp].size]
|
||||
= components[comp].init_data;
|
||||
}
|
||||
|
||||
return temp;
|
||||
|
|
@ -233,21 +250,35 @@ class EntityManager
|
|||
}
|
||||
alignNum(info.size, info.alignment);
|
||||
|
||||
foreach (ref system; systems)
|
||||
foreach (uint i, ref system; systems)
|
||||
{
|
||||
if (system.m_update is null)
|
||||
continue;
|
||||
addEntityCaller(*info, system);
|
||||
addEntityCaller(*info, i);
|
||||
}
|
||||
|
||||
updateEntityCallers();
|
||||
|
||||
entities_infos.add(info.components, info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
void addEntityCaller(ref EntityInfo entity, ref System system)
|
||||
void updateEntityCallers()
|
||||
{
|
||||
CallData call_data = CallData(&system, &entity, null);
|
||||
foreach(entity;&entities_infos.byValue)
|
||||
{
|
||||
foreach(caller;entity.callers)
|
||||
{
|
||||
caller.system = &systems[caller.system_id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addEntityCaller(ref EntityInfo entity, uint system_id)
|
||||
{
|
||||
System* system = &systems[system_id];
|
||||
CallData call_data = CallData(system_id, system, &entity, null);
|
||||
ushort[] deltas = (cast(ushort*) alloca(system.m_components.length * ushort.sizeof))[0
|
||||
.. system.m_components.length];
|
||||
foreach (i, id; system.m_components)
|
||||
|
|
@ -443,10 +474,12 @@ class EntityManager
|
|||
EntitiesBlock* block = getMetaData(entity);
|
||||
id_manager.releaseID(id); //release id from manager
|
||||
|
||||
removeEntityNoID(entity, block);
|
||||
removeEntityNoID(entity, block, true);
|
||||
|
||||
}
|
||||
|
||||
private void removeEntityNoID(Entity* entity, EntitiesBlock* block)
|
||||
private void removeEntityNoID(Entity* entity, EntitiesBlock* block,
|
||||
bool call_destructors = false)
|
||||
{
|
||||
//pos is Entity number in block
|
||||
void* data_begin = block.dataBegin();
|
||||
|
|
@ -458,6 +491,18 @@ class EntityManager
|
|||
if (block.type_data.first_with_free_space.id > block.id)
|
||||
block.type_data.first_with_free_space = block;
|
||||
|
||||
if(call_destructors)
|
||||
{
|
||||
void* data = data_begin + pos * block.type_data.size;
|
||||
foreach(comp;block.type_data.components)
|
||||
{
|
||||
if(components[comp].destroy_callback)
|
||||
{
|
||||
components[comp].destroy_callback(data + block.type_data.deltas[comp]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == block.entities_count)
|
||||
return;
|
||||
|
||||
|
|
@ -488,6 +533,7 @@ class EntityManager
|
|||
ushort size;
|
||||
ushort aligment;
|
||||
ubyte[] init_data;
|
||||
void function(void* pointer) destroy_callback;
|
||||
}
|
||||
|
||||
/************************************************************************************************************************
|
||||
|
|
@ -548,6 +594,8 @@ class EntityManager
|
|||
*/
|
||||
struct CallData
|
||||
{
|
||||
///system ID. Used to update system pointer after system reload.
|
||||
uint system_id;
|
||||
///pointer to used system
|
||||
System* system;
|
||||
///poiner to Entity type info
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue