-IDManager

-times counting for tests
This commit is contained in:
Mergul 2018-09-12 14:01:35 +02:00
parent 86e4e57f74
commit 17551b08a5
4 changed files with 118 additions and 10 deletions

View file

@ -5,12 +5,17 @@ import ecs.manager;
struct EntityID struct EntityID
{ {
uint id; uint id;
uint id_count; uint counter;
} }
struct Entity struct Entity
{ {
EntityID id; EntityID id;
void updateID()
{
EntityManager.instance.id_manager.update(this);
}
} }
struct EntityTemplate struct EntityTemplate

65
source/ecs/id_manager.d Normal file
View file

@ -0,0 +1,65 @@
module ecs.id_manager;
import ecs.entity;
import ecs.vector;
struct IDManager
{
EntityID getNewID()
{
while(m_next_id >= m_ids_array.length)m_ids_array.add(Data());
EntityID id;
id.id = m_next_id;
id.counter = m_ids_array[m_next_id].counter++;
m_next_id = m_ids_array[m_next_id].next_id;
if(m_next_id == uint.max)m_next_id = cast(uint)m_ids_array.length;
return id;
}
void releaseID(EntityID id)
{
Data* data = &m_ids_array[id.id];
if(data.counter != id.counter)return;
data.next_id = m_next_id;
data.entity = null;
m_next_id = id.id;
}
void update(ref Entity entity)
{
m_ids_array[entity.id.id].entity = &entity;
}
struct Data
{
uint counter = 0;
uint next_id = uint.max;
Entity* entity = null;
}
private uint m_next_id = 0;
Vector!Data m_ids_array;
}
unittest
{
IDManager manager;
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));
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));
}

View file

@ -12,6 +12,7 @@ import ecs.system;
import ecs.entity; import ecs.entity;
import ecs.vector; import ecs.vector;
import ecs.hash_map; import ecs.hash_map;
import ecs.id_manager;
alias gEM = EntityManager.instance; alias gEM = EntityManager.instance;
@ -23,6 +24,12 @@ class EntityManager
instance = Mallocator.instance.make!EntityManager; instance = Mallocator.instance.make!EntityManager;
} }
static void destory()
{
Mallocator.instance.dispose(instance);
instance = null;
}
void registerSystem(Sys)(int priority) void registerSystem(Sys)(int priority)
{ {
alias types = Parameters!(Sys.update); alias types = Parameters!(Sys.update);
@ -197,7 +204,7 @@ class EntityManager
{ {
if (block is null) if (block is null)
{ {
block = cast(EntitiesBlock*) AlignedMallocator.instance.alignedAllocate(4096, 4096); block = cast(EntitiesBlock*) AlignedMallocator.instance.alignedAllocate(page_size, page_size);
*block = EntitiesBlock(tmpl.info); *block = EntitiesBlock(tmpl.info);
if (previous_block is null) if (previous_block is null)
{ {
@ -211,7 +218,7 @@ class EntityManager
break; // new block certainly has free space break; // new block certainly has free space
} }
// check if there is enought space // check if there is enought space
if (block.dataDelta() + (block.entities_count + 1) * tmpl.info.size > 4096) if (block.dataDelta() + (block.entities_count + 1) * tmpl.info.size > page_size)
{ {
previous_block = block; previous_block = block;
block = block.next_block; block = block.next_block;
@ -224,6 +231,9 @@ class EntityManager
void* start = block.dataBegin() + block.entities_count * tmpl.info.size; void* start = block.dataBegin() + block.entities_count * tmpl.info.size;
memcpy(start, tmpl.entity_data.ptr, tmpl.info.size); memcpy(start, tmpl.entity_data.ptr, tmpl.info.size);
Entity* entity = cast(Entity*)start;
entity.id = id_manager.getNewID();
entity.updateID();
block.entities_count++; block.entities_count++;
} }
@ -273,8 +283,13 @@ class EntityManager
///there is a loooot of data (4kB, pure magic) ///there is a loooot of data (4kB, pure magic)
} }
enum page_size = 4096;
enum pages_in_block = 128;
alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity); alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity);
IDManager id_manager;
HashMap!(ushort[], EntityInfo*) entities_infos; HashMap!(ushort[], EntityInfo*) entities_infos;
HashMap!(string, uint) components_map; HashMap!(string, uint) components_map;
System[] systems; System[] systems;

View file

@ -5,14 +5,11 @@ import ecs.events;
import ecs.system; import ecs.system;
import ecs.entity; import ecs.entity;
import core.time;
import std.stdio;
int main() int main()
{ {
return 0;
}
unittest
{
alias SerializeVector = ubyte[]; alias SerializeVector = ubyte[];
struct TestComp struct TestComp
@ -99,24 +96,50 @@ unittest
EntityManager.initialize(); EntityManager.initialize();
assert(gEM !is null); assert(gEM !is null);
MonoTime time = MonoTime.currTime;
gEM.registerComponent!TestComp2; gEM.registerComponent!TestComp2;
gEM.registerComponent!TestComp; gEM.registerComponent!TestComp;
ulong dur = (MonoTime.currTime - time).total!"usecs";
writeln("Components register time: ",dur," usecs");
time = MonoTime.currTime;
gEM.registerSystem!TestSystem(0); gEM.registerSystem!TestSystem(0);
gEM.registerSystem!TestSystem2(0); gEM.registerSystem!TestSystem2(0);
dur = (MonoTime.currTime - time).total!"usecs";
writeln("System register time: ",dur," usecs");
time = MonoTime.currTime;
ushort[2] ids = [0,1]; ushort[2] ids = [0,1];
EntityTemplate* tmpl = gEM.allocateTemplate(ids); EntityTemplate* tmpl = gEM.allocateTemplate(ids);
*cast(EntityID*)tmpl.entity_data.ptr = EntityID(1,1); *cast(EntityID*)tmpl.entity_data.ptr = EntityID(1,1);
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Template allocating time: ",dur," usecs");
time = MonoTime.currTime;
foreach(i; 0..1_000_000)gEM.addEntity(tmpl); foreach(i; 0..1_000_000)gEM.addEntity(tmpl);
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Entities adding: ",dur," usecs");
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1)); //assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1));
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1)); //assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1));
time = MonoTime.currTime;
gEM.update(); gEM.update();
gEM.update();
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Update time: ",dur," usecs");
import std.stdio; import std.stdio;
writeln((cast(uint*)tmpl.info.first_block)[0..48]); writeln((cast(uint*)tmpl.info.first_block)[0..48]);
gEM.freeTemplate(tmpl); gEM.freeTemplate(tmpl);
return 0;
} }