-IDManager
-times counting for tests
This commit is contained in:
parent
86e4e57f74
commit
17551b08a5
4 changed files with 118 additions and 10 deletions
|
|
@ -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
65
source/ecs/id_manager.d
Normal 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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue