-some usefull functions for IDManager
-added EntityManager.removeEntity(EntityID) -EntitiesBlock now has ID usefull for updating first_free_block in EntityInfo
This commit is contained in:
parent
ae53e13d42
commit
d3222eefbb
4 changed files with 109 additions and 25 deletions
|
|
@ -30,6 +30,19 @@ struct IDManager
|
|||
m_ids_array[entity.id.id].entity = &entity;
|
||||
}
|
||||
|
||||
Entity* getEntityPointer(EntityID id)
|
||||
{
|
||||
Data* data = &m_ids_array[id.id];
|
||||
if(data.counter != id.counter)return null;
|
||||
else return data.entity;
|
||||
}
|
||||
|
||||
bool isExist(EntityID id)
|
||||
{
|
||||
Data* data = &m_ids_array[id.id];
|
||||
return data.counter == id.counter;
|
||||
}
|
||||
|
||||
struct Data
|
||||
{
|
||||
uint counter = 0;
|
||||
|
|
@ -61,5 +74,7 @@ unittest
|
|||
assert(id1 == EntityID(1,2));
|
||||
assert(id2 == EntityID(0,2));
|
||||
assert(id3 == EntityID(2,1));
|
||||
assert(manager.isExist(id3));
|
||||
assert(!manager.isExist(EntityID(0,1)));
|
||||
|
||||
}
|
||||
|
|
@ -54,7 +54,7 @@ class EntityManager
|
|||
string ret;
|
||||
foreach (i, param; Parameters!(Sys.update))
|
||||
{
|
||||
ret ~= "system.components[" ~ i.to!string
|
||||
ret ~= "system.m_components[" ~ i.to!string
|
||||
~ "] = components_map.get(types[" ~ i.to!string ~ "].stringof);\n";
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -66,7 +66,7 @@ class EntityManager
|
|||
{
|
||||
static if (hasMember!(Sys, "update"))
|
||||
{
|
||||
Sys* s = cast(Sys*) data.system.system_pointer;
|
||||
Sys* s = cast(Sys*) data.system.m_system_pointer;
|
||||
|
||||
EntitiesBlock* block = data.info.first_block;
|
||||
while (block !is null)
|
||||
|
|
@ -83,7 +83,7 @@ class EntityManager
|
|||
}
|
||||
}
|
||||
|
||||
system.update = &callUpdate;
|
||||
system.m_update = &callUpdate;
|
||||
}
|
||||
|
||||
static if (hasMember!(Sys, "onEnable"))
|
||||
|
|
@ -110,9 +110,9 @@ class EntityManager
|
|||
system.m_disable = &callDisable;
|
||||
}
|
||||
|
||||
system.system_pointer = cast(void*) Mallocator.instance.make!Sys;
|
||||
system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys;
|
||||
|
||||
system.components = Mallocator.instance.makeArray!uint(types.length);
|
||||
system.m_components = Mallocator.instance.makeArray!uint(types.length);
|
||||
mixin(genCompList());
|
||||
|
||||
systems.add(system);
|
||||
|
|
@ -142,7 +142,7 @@ class EntityManager
|
|||
foreach (data; info.callers)
|
||||
{
|
||||
if (data.system.enabled)
|
||||
(cast(SytemFuncType) data.system.update)(data, null); //caller(call_data,null);
|
||||
(cast(SytemFuncType) data.system.m_update)(data, null); //caller(call_data,null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -176,7 +176,7 @@ class EntityManager
|
|||
|
||||
foreach (ref system; systems)
|
||||
{
|
||||
if (system.update is null)
|
||||
if (system.m_update is null)
|
||||
continue;
|
||||
addEntityCaller(*info, system);
|
||||
}
|
||||
|
|
@ -193,9 +193,9 @@ class EntityManager
|
|||
void addEntityCaller(ref EntityInfo entity, ref System system)
|
||||
{
|
||||
CallData call_data = CallData(&system, &entity, null);
|
||||
ushort[] deltas = (cast(ushort*) alloca(system.components.length * ushort.sizeof))[0
|
||||
.. system.components.length];
|
||||
foreach (i, id; system.components)
|
||||
ushort[] deltas = (cast(ushort*) alloca(system.m_components.length * ushort.sizeof))[0
|
||||
.. system.m_components.length];
|
||||
foreach (i, id; system.m_components)
|
||||
{
|
||||
deltas[i] = ushort.max;
|
||||
foreach (i2, id2; entity.components)
|
||||
|
|
@ -214,7 +214,7 @@ class EntityManager
|
|||
}
|
||||
if (deltas)
|
||||
{
|
||||
call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.components.length);
|
||||
call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.m_components.length);
|
||||
entity.callers.add(call_data);
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +225,7 @@ class EntityManager
|
|||
Mallocator.instance.dispose(template_);
|
||||
}
|
||||
|
||||
void addEntity(EntityTemplate* tmpl)
|
||||
ref Entity addEntity(EntityTemplate* tmpl)
|
||||
{
|
||||
EntitiesBlock* previous_block;
|
||||
EntitiesBlock* block = tmpl.info.first_with_free_space; //tmpl.info.first_block;
|
||||
|
|
@ -241,10 +241,12 @@ class EntityManager
|
|||
if (previous_block is null)
|
||||
{
|
||||
tmpl.info.first_block = block;
|
||||
block.id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
previous_block.next_block = block;
|
||||
block.id = previous_block.id + 1;
|
||||
}
|
||||
tmpl.info.first_with_free_space = block;
|
||||
break; // new block certainly has free space
|
||||
|
|
@ -267,6 +269,37 @@ class EntityManager
|
|||
entity.id = id_manager.getNewID();
|
||||
entity.updateID();
|
||||
block.entities_count++;
|
||||
return *entity;
|
||||
}
|
||||
|
||||
void removeEntity(EntityID id)
|
||||
{
|
||||
Entity* entity = id_manager.getEntityPointer(id);
|
||||
if(entity is null)return;
|
||||
EntitiesBlock* block = getMetaData(entity);
|
||||
id_manager.releaseID(id);
|
||||
|
||||
void* data_begin = block.dataBegin();
|
||||
uint pos = cast(int)(cast(void*)entity - data_begin) / block.type_data.size;
|
||||
|
||||
block.entities_count--;
|
||||
|
||||
if(block.type_data.first_with_free_space.id > block.id)block.type_data.first_with_free_space = block;
|
||||
|
||||
if(pos == block.entities_count)return;
|
||||
|
||||
void* src = data_begin + block.entities_count * block.type_data.size;
|
||||
void* dst = data_begin + pos * block.type_data.size;
|
||||
|
||||
memcpy(dst,src,block.type_data.size);
|
||||
|
||||
entity = cast(Entity*) dst;
|
||||
entity.updateID();
|
||||
}
|
||||
|
||||
EntitiesBlock* getMetaData(void* pointer)
|
||||
{
|
||||
return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(page_size - 1)));
|
||||
}
|
||||
|
||||
struct ComponentInfo
|
||||
|
|
@ -304,6 +337,7 @@ class EntityManager
|
|||
|
||||
EntityInfo* type_data;
|
||||
uint entities_count;
|
||||
uint id;
|
||||
EntitiesBlock* next_block;
|
||||
///there is a loooot of data (4kB, pure magic)
|
||||
}
|
||||
|
|
@ -317,7 +351,9 @@ class EntityManager
|
|||
|
||||
alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity);
|
||||
|
||||
///Single page size. Must be power of two.
|
||||
enum page_size = 4096;
|
||||
///Number of pages in block.
|
||||
enum pages_in_block = 128;
|
||||
|
||||
IDManager id_manager;
|
||||
|
|
|
|||
|
|
@ -5,15 +5,6 @@ import ecs.manager;
|
|||
|
||||
struct System
|
||||
{
|
||||
///should system update and catch events?
|
||||
bool m_enabled = false;
|
||||
///system priority
|
||||
int prority;
|
||||
///pointer to system implementation
|
||||
void* system_pointer;
|
||||
|
||||
uint[] components;
|
||||
|
||||
bool enabled()
|
||||
{
|
||||
return m_enabled;
|
||||
|
|
@ -21,18 +12,34 @@ struct System
|
|||
|
||||
void enable()
|
||||
{
|
||||
if(!m_enabled && m_enable)m_enable(system_pointer);
|
||||
if(!m_enabled && m_enable)m_enable(m_system_pointer);
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
if(m_enabled && m_disable)m_disable(system_pointer);
|
||||
if(m_enabled && m_disable)m_disable(m_system_pointer);
|
||||
m_enabled = false;
|
||||
}
|
||||
|
||||
int priority()
|
||||
{
|
||||
return m_priority;
|
||||
}
|
||||
|
||||
package:
|
||||
|
||||
///should system update and catch events?
|
||||
bool m_enabled = false;
|
||||
///system priority
|
||||
int m_priority;
|
||||
///pointer to system implementation
|
||||
void* m_system_pointer;
|
||||
|
||||
uint[] m_components;
|
||||
|
||||
//void function(ref EntityManager.CallData data, void* entity) update;
|
||||
void* update; ///workaroud for DMD bug with upper line
|
||||
void* m_update; ///workaroud for DMD bug with upper line
|
||||
|
||||
void function(void* system_pointer) m_enable;
|
||||
void function(void* system_pointer) m_disable;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue