Fix crash in commit() when all components were removed from entity
Fix crash from issue #2 and add unittest case for it. Also implements general "empty" entity support
This commit is contained in:
parent
beb1837c43
commit
8ac9fa5dbd
3 changed files with 185 additions and 42 deletions
|
|
@ -1856,6 +1856,7 @@ export struct EntityManager
|
|||
*/
|
||||
export EntityTemplate* allocateTemplate(EntityTemplate* copy_tmpl)
|
||||
{
|
||||
assert(copy_tmpl, "copy_tmpl can't be null");
|
||||
EntityTemplate* tmpl = Mallocator.make!EntityTemplate;
|
||||
tmpl.info = copy_tmpl.info;
|
||||
tmpl.entity_data = Mallocator.makeArray(copy_tmpl.entity_data);
|
||||
|
|
@ -1870,46 +1871,66 @@ export struct EntityManager
|
|||
*/
|
||||
export EntityInfo* getEntityInfo(ushort[] ids)
|
||||
{
|
||||
if(ids.length == 0)ids = null;
|
||||
EntityInfo* info = entities_infos.get(ids, null);
|
||||
if (info is null)
|
||||
{
|
||||
info = Mallocator.make!EntityInfo;
|
||||
|
||||
info.components = Mallocator.makeArray(ids);
|
||||
info.deltas = Mallocator.makeArray!ushort(ids[$ - 1] + 1);
|
||||
|
||||
info.size = EntityID.sizeof;
|
||||
info.alignment = EntityID.alignof;
|
||||
|
||||
info.tmpl_deltas = Mallocator.makeArray!ushort(ids[$ - 1] + 1, ushort.max);
|
||||
uint components_size = EntityID.sizeof;
|
||||
|
||||
foreach (i, id; ids)
|
||||
if(ids is null)
|
||||
{
|
||||
info.alignment = max(info.alignment, components[id].alignment);
|
||||
alignNum(info.size, components[id].alignment);
|
||||
info.tmpl_deltas[id] = info.size;
|
||||
info.size += components[id].size;
|
||||
components_size += components[id].size;
|
||||
uint block_memory = cast(uint)(
|
||||
m_page_size - EntitiesBlock.sizeof - info.size);
|
||||
uint entites_in_block = block_memory / info.size;
|
||||
info.max_entities = cast(ushort) entites_in_block;
|
||||
}
|
||||
alignNum(info.size, info.alignment);
|
||||
|
||||
uint block_memory = cast(uint)(
|
||||
m_page_size - EntitiesBlock.sizeof - (info.size - components_size));
|
||||
//uint entity_comps_size = EntityID.sizeof;
|
||||
uint mem_begin = EntitiesBlock.sizeof;
|
||||
|
||||
uint entites_in_block = block_memory / info.size; //entity_comps_size;
|
||||
info.max_entities = cast(ushort) entites_in_block;
|
||||
ushort current_delta = cast(ushort)(mem_begin + entites_in_block * EntityID.sizeof);
|
||||
|
||||
foreach (i, id; ids)
|
||||
else
|
||||
{
|
||||
if (current_delta == 0)
|
||||
current_delta = ushort.max;
|
||||
alignNum(current_delta, components[id].alignment);
|
||||
info.deltas[id] = cast(ushort) current_delta;
|
||||
current_delta += entites_in_block * components[id].size;
|
||||
uint components_size = EntityID.sizeof;
|
||||
|
||||
info.components = Mallocator.makeArray(ids);
|
||||
info.deltas = Mallocator.makeArray!ushort(ids[$ - 1] + 1);
|
||||
info.tmpl_deltas = Mallocator.makeArray!ushort(ids[$ - 1] + 1, ushort.max);
|
||||
|
||||
foreach (i, id; ids)
|
||||
{
|
||||
info.alignment = max(info.alignment, components[id].alignment);
|
||||
alignNum(info.size, components[id].alignment);
|
||||
info.tmpl_deltas[id] = info.size;
|
||||
info.size += components[id].size;
|
||||
components_size += components[id].size;
|
||||
}
|
||||
alignNum(info.size, info.alignment);
|
||||
|
||||
uint block_memory = cast(uint)(
|
||||
m_page_size - EntitiesBlock.sizeof - (info.size - components_size));
|
||||
//uint entity_comps_size = EntityID.sizeof;
|
||||
uint mem_begin = EntitiesBlock.sizeof;
|
||||
|
||||
uint entites_in_block = block_memory / info.size; //entity_comps_size;
|
||||
info.max_entities = cast(ushort) entites_in_block;
|
||||
ushort current_delta = cast(ushort)(mem_begin + entites_in_block * EntityID.sizeof);
|
||||
|
||||
foreach (i, id; ids)
|
||||
{
|
||||
if (current_delta == 0)
|
||||
current_delta = ushort.max;
|
||||
alignNum(current_delta, components[id].alignment);
|
||||
info.deltas[id] = cast(ushort) current_delta;
|
||||
current_delta += entites_in_block * components[id].size;
|
||||
}
|
||||
|
||||
info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length);
|
||||
info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length);
|
||||
|
||||
foreach (comp; info.components)
|
||||
{
|
||||
info.comp_add_info[comp] = info;
|
||||
info.comp_rem_info[comp] = null;
|
||||
}
|
||||
}
|
||||
|
||||
info.systems = Mallocator.makeArray!bool(systems.length);
|
||||
|
|
@ -1930,15 +1951,6 @@ export struct EntityManager
|
|||
addSystemCaller(*info, cast(uint) i);
|
||||
}
|
||||
|
||||
info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length);
|
||||
info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length);
|
||||
|
||||
foreach (comp; info.components)
|
||||
{
|
||||
info.comp_add_info[comp] = info;
|
||||
info.comp_rem_info[comp] = null;
|
||||
}
|
||||
|
||||
entities_infos.add(info.components, info);
|
||||
|
||||
generateListeners(info);
|
||||
|
|
@ -2552,7 +2564,7 @@ export struct EntityManager
|
|||
use you should save ID instead of pointer.
|
||||
|
||||
Params:
|
||||
tmpl = pointer entity template allocated by EntityManager.
|
||||
tmpl = pointer entity template allocated by EntityManager. Can be null in which case empty entity would be added (entity without components)
|
||||
*/
|
||||
export Entity* addEntity(EntityTemplate* tmpl)
|
||||
{
|
||||
|
|
@ -2564,12 +2576,14 @@ export struct EntityManager
|
|||
use you should save ID instead of pointer.
|
||||
|
||||
Params:
|
||||
tmpl = pointer entity template allocated by EntityManager.
|
||||
tmpl = pointer entity template allocated by EntityManager. Can be null in which case empty entity would be added (entity without components)
|
||||
replacement = list of components references to used. Memory form list replace data from template inside new entity. Should be used only for data which vary between most entities (like 3D position etc.)
|
||||
*/
|
||||
export Entity* addEntity(EntityTemplate* tmpl, ComponentRef[] replacement)
|
||||
{
|
||||
EntityInfo* info = tmpl.info;
|
||||
EntityInfo* info = void;
|
||||
if(tmpl)info = tmpl.info;
|
||||
else info = getEntityInfo(null);
|
||||
|
||||
ushort index = 0;
|
||||
EntitiesBlock* block;
|
||||
|
|
@ -3446,7 +3460,7 @@ export struct EntityManager
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (id > components[$ - 1])
|
||||
if (components.length == 0 || id > components[$ - 1])
|
||||
ids[len++] = id;
|
||||
|
||||
assert(len == components.length + 1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue