-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)
|
foreach (info; &entities_infos.byValue)
|
||||||
{
|
{
|
||||||
addEntityCaller(*info, systems[$ - 1]);
|
addEntityCaller(*info, cast(uint)systems.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateEntityCallers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerComponent(Comp)()
|
void registerComponent(Comp)()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
ComponentInfo info;
|
||||||
|
|
||||||
static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort))
|
static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort))
|
||||||
{
|
{
|
||||||
static assert(0, "Component should have \"__gshared ushort component_id");
|
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.size = Comp.sizeof;
|
||||||
info.aligment = Comp.alignof; //8;
|
info.aligment = Comp.alignof; //8;
|
||||||
info.init_data = Mallocator.instance.makeArray!ubyte(Comp.sizeof);
|
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);
|
components.add(info);
|
||||||
Comp.component_id = cast(ushort)(components.length - 1);
|
Comp.component_id = cast(ushort)(components.length - 1);
|
||||||
|
|
@ -203,9 +219,10 @@ class EntityManager
|
||||||
temp.info = info;
|
temp.info = info;
|
||||||
|
|
||||||
//fill components with default data
|
//fill components with default data
|
||||||
foreach(comp;info.components)
|
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;
|
return temp;
|
||||||
|
|
@ -233,21 +250,35 @@ class EntityManager
|
||||||
}
|
}
|
||||||
alignNum(info.size, info.alignment);
|
alignNum(info.size, info.alignment);
|
||||||
|
|
||||||
foreach (ref system; systems)
|
foreach (uint i, ref system; systems)
|
||||||
{
|
{
|
||||||
if (system.m_update is null)
|
if (system.m_update is null)
|
||||||
continue;
|
continue;
|
||||||
addEntityCaller(*info, system);
|
addEntityCaller(*info, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateEntityCallers();
|
||||||
|
|
||||||
entities_infos.add(info.components, info);
|
entities_infos.add(info.components, info);
|
||||||
}
|
}
|
||||||
return 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
|
ushort[] deltas = (cast(ushort*) alloca(system.m_components.length * ushort.sizeof))[0
|
||||||
.. system.m_components.length];
|
.. system.m_components.length];
|
||||||
foreach (i, id; system.m_components)
|
foreach (i, id; system.m_components)
|
||||||
|
|
@ -443,10 +474,12 @@ class EntityManager
|
||||||
EntitiesBlock* block = getMetaData(entity);
|
EntitiesBlock* block = getMetaData(entity);
|
||||||
id_manager.releaseID(id); //release id from manager
|
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
|
//pos is Entity number in block
|
||||||
void* data_begin = block.dataBegin();
|
void* data_begin = block.dataBegin();
|
||||||
|
|
@ -458,6 +491,18 @@ class EntityManager
|
||||||
if (block.type_data.first_with_free_space.id > block.id)
|
if (block.type_data.first_with_free_space.id > block.id)
|
||||||
block.type_data.first_with_free_space = block;
|
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)
|
if (pos == block.entities_count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -488,6 +533,7 @@ class EntityManager
|
||||||
ushort size;
|
ushort size;
|
||||||
ushort aligment;
|
ushort aligment;
|
||||||
ubyte[] init_data;
|
ubyte[] init_data;
|
||||||
|
void function(void* pointer) destroy_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
|
|
@ -548,6 +594,8 @@ class EntityManager
|
||||||
*/
|
*/
|
||||||
struct CallData
|
struct CallData
|
||||||
{
|
{
|
||||||
|
///system ID. Used to update system pointer after system reload.
|
||||||
|
uint system_id;
|
||||||
///pointer to used system
|
///pointer to used system
|
||||||
System* system;
|
System* system;
|
||||||
///poiner to Entity type info
|
///poiner to Entity type info
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue