-LinearLayout implemntation:

*Entity.getComponent works
 *adding/removing objects work
 *update work
This commit is contained in:
Mergul 2018-09-26 09:02:16 +02:00
parent 535071ebb9
commit cb9bac5dde
5 changed files with 411 additions and 120 deletions

View file

@ -10,6 +10,9 @@
"versions": [ "versions": [
"LinearLayout" "LinearLayout"
], ],
"dflags-posix-ldc": [
"-defaultlib=phobos2-ldc,druntime-ldc"
],
"configurations" : [ "configurations" : [
{ {
"name" : "library", "name" : "library",

View file

@ -7,7 +7,7 @@ import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator;
struct BlockAllocator(uint block_size, uint blocks_in_allocation) struct BlockAllocator(uint block_size, uint blocks_in_allocation)
{ {
void* next_block; void* next_block = null;
void* getBlock() void* getBlock()
{ {

View file

@ -20,9 +20,21 @@ struct Entity
T* getComponent(T)() T* getComponent(T)()
{ {
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
EntityManager.EntityInfo* info = block.type_data; EntityManager.EntityInfo* info = block.type_info;
if(T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)return null; if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
return cast(T*)(cast(void*)&this + info.deltas[T.component_id]); return null;
version (LinearLayout)
{
static if (EntityID.sizeof == 8)
uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) >> 3);
else
uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) / EntityID.sizeof());
return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof);
}
else
{
return cast(T*)(cast(void*)&this + info.deltas[T.component_id]);
}
} }
} }

View file

@ -72,12 +72,75 @@ class EntityManager
alias storages = ParameterStorageClassTuple!(Sys.update); alias storages = ParameterStorageClassTuple!(Sys.update);
static string genCall()() static string genCall()()
{ {
string ret = "s.update(*cast(Entity*)data_pointer,"; string ret;
version (LinearLayout)
{
{
uint i = 0;
uint opt = 0;
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{
i++;
if (isPointer!param)
{
ret ~= "if(opt_ptr" ~ opt.to!string ~ " !is null)opt_ptr"
~ opt.to!string ~ " = &opt_array" ~ opt.to!string ~ "[i];";
opt++;
}
}
}
}
/*foreach (i; 1 .. (Parameters!(Sys.update)).length) /*foreach (i; 1 .. (Parameters!(Sys.update)).length)
{ {
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1) ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1)
.to!string ~ "]),"; .to!string ~ "]),";
}*/ }*/
uint i = 0;
uint req = 0;
uint opt = 0;
version (LinearLayout)
{
ret ~= "s.update(id_array[i],";
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{
i++;
if (isPointer!param)
{
ret ~= "opt_ptr" ~ (opt++).to!string ~ ",";
}
else
{
ret ~= "array" ~ (req++).to!string ~ "[i],";
}
}
}
else
{
ret ~= "s.update(*cast(Entity*)data_pointer,";
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{
i++;
if (isPointer!param)
{
ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ (opt++)
.to!string ~ "]),";
}
else
{
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (req++)
.to!string ~ "]),";
}
}
}
ret ~= ");";
return ret;
}
static string genArrays()()
{
string ret;
uint i = 0; uint i = 0;
uint req = 0; uint req = 0;
uint opt = 0; uint opt = 0;
@ -86,16 +149,17 @@ class EntityManager
i++; i++;
if (isPointer!param) if (isPointer!param)
{ {
ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ (opt++) ret ~= "PointerTarget!(types[" ~ i.to!string
.to!string ~ "]),"; ~ "])[] opt_array" ~ opt.to!string ~ ";";
ret ~= "types[" ~ i.to!string ~ "] opt_ptr" ~ opt.to!string ~ ";";
opt++;
} }
else else
{ {
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (req++) ret ~= "types[" ~ i.to!string ~ "][] array" ~ req.to!string ~ " = (cast(types[" ~ i.to!string ~ "]*)(cast(void*)block + info.deltas[types[" ~ i.to!string ~ "].component_id]))[0..block.entities_count];";
.to!string ~ "]),"; req++;
} }
} }
ret ~= ");";
return ret; return ret;
} }
@ -154,29 +218,62 @@ class EntityManager
EntitiesBlock* block = data.info.first_block; EntitiesBlock* block = data.info.first_block;
while (block !is null) while (block !is null)
{ {
uint size = block.type_data.size; version (LinearLayout)
void* data_pointer = block.dataBegin();
foreach (i, ref pointer; pointers)
{ {
pointer = data_pointer + data.deltas[i]; //uint size = block.type_info.size;
} /*void* data_pointer = block.dataBegin();
foreach (i, ref pointer; optional_pointers) foreach (i, ref pointer; pointers)
{ {
uint ind = cast(uint)(i + pointers.length); pointer = cast(void*) block + data.deltas[i];
if (data.deltas[ind] != uint.max) }
pointer = data_pointer + data.deltas[ind]; foreach (i, ref pointer; optional_pointers)
else {
pointer = null; uint ind = cast(uint)(i + pointers.length);
} if (data.deltas[ind] != uint.max)
foreach (i; 0 .. block.entities_count) pointer = cast(void*) block + data.deltas[ind];
{ else
mixin(genCall()); pointer = null;
data_pointer += size; //data.info.size; }*/
foreach (ref pointer; pointers) EntityInfo* info = block.type_info;
pointer += size; Entity[] id_array = (cast(Entity*)block.dataBegin())[0..block.entities_count];
foreach (ref pointer; optional_pointers) mixin(genArrays());
if (pointer != null) foreach (i; 0 .. block.entities_count)
{
mixin(genCall());
//data_pointer += EntityID.sizeof; //data.info.size;
/*foreach (ref pointer; pointers)
pointer += size; pointer += size;
foreach (ref pointer; optional_pointers)
if (pointer != null)
pointer += size;*/
}
}
else
{
uint size = block.type_info.size;
void* data_pointer = block.dataBegin();
foreach (i, ref pointer; pointers)
{
pointer = data_pointer + data.deltas[i];
}
foreach (i, ref pointer; optional_pointers)
{
uint ind = cast(uint)(i + pointers.length);
if (data.deltas[ind] != uint.max)
pointer = data_pointer + data.deltas[ind];
else
pointer = null;
}
foreach (i; 0 .. block.entities_count)
{
mixin(genCall());
data_pointer += size; //data.info.size;
foreach (ref pointer; pointers)
pointer += size;
foreach (ref pointer; optional_pointers)
if (pointer != null)
pointer += size;
}
} }
block = block.next_block; block = block.next_block;
} }
@ -393,10 +490,21 @@ class EntityManager
temp.info = info; temp.info = info;
//fill components with default data //fill components with default data
foreach (comp; info.components) version (LinearLayout)
{ {
temp.entity_data[info.deltas[comp] .. info.deltas[comp] + components[comp].size] foreach (comp; info.components)
= components[comp].init_data; {
temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size]
= components[comp].init_data;
}
}
else
{
foreach (comp; info.components)
{
temp.entity_data[info.deltas[comp] .. info.deltas[comp] + components[comp].size]
= components[comp].init_data;
}
} }
return temp; return temp;
@ -412,6 +520,23 @@ class EntityManager
info.components = Mallocator.instance.makeArray(ids); info.components = Mallocator.instance.makeArray(ids);
info.deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1); info.deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1);
version (LinearLayout)
{
info.tmpl_deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1);
uint block_memory = page_size - EntitiesBlock.sizeof;
uint entity_comps_size = EntityID.sizeof;
uint mem_begin = EntitiesBlock.sizeof;
foreach (id; ids)
{
entity_comps_size += components[id].size;
}
uint entites_in_block = block_memory / entity_comps_size;
info.max_entities = cast(ushort) entites_in_block;
uint current_delta = cast(uint)(mem_begin + entites_in_block * EntityID.sizeof);
}
info.size = EntityID.sizeof; info.size = EntityID.sizeof;
info.alignment = EntityID.alignof; info.alignment = EntityID.alignof;
@ -419,11 +544,29 @@ class EntityManager
{ {
info.alignment = max(info.alignment, components[id].alignment); info.alignment = max(info.alignment, components[id].alignment);
alignNum(info.size, components[id].alignment); alignNum(info.size, components[id].alignment);
info.deltas[id] = info.size;
version (LinearLayout)
{
info.tmpl_deltas[id] = info.size;
info.deltas[id] = cast(ushort) current_delta;
current_delta += entites_in_block * components[id].size;
}
else
{
info.deltas[id] = info.size;
}
info.size += components[id].size; info.size += components[id].size;
} }
alignNum(info.size, info.alignment); alignNum(info.size, info.alignment);
version (LinearLayout)
{
}
else
info.max_entities = (page_size - EntitiesBlock.sizeof) / info.size;
foreach (uint i, ref system; systems) foreach (uint i, ref system; systems)
{ {
if (system.m_update is null) if (system.m_update is null)
@ -497,7 +640,6 @@ class EntityManager
delta_id++; delta_id++;
} }
call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.m_components.length); call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.m_components.length);
uint index = 0; uint index = 0;
@ -527,9 +669,10 @@ class EntityManager
private void __removeComponents(EntityID entity_id, ushort[] del_ids) private void __removeComponents(EntityID entity_id, ushort[] del_ids)
{ {
Entity* entity = id_manager.getEntityPointer(entity_id); Entity* entity = id_manager.getEntityPointer(entity_id);
if(!entity)return; if (!entity)
return;
EntitiesBlock* block = getMetaData(entity); EntitiesBlock* block = getMetaData(entity);
EntityInfo* info = block.type_data; EntityInfo* info = block.type_info;
qsort(del_ids.ptr, del_ids.length, ushort.sizeof, &compareUShorts); qsort(del_ids.ptr, del_ids.length, ushort.sizeof, &compareUShorts);
@ -598,9 +741,10 @@ class EntityManager
{ {
uint num = cast(uint) new_ids.length; uint num = cast(uint) new_ids.length;
Entity* entity = id_manager.getEntityPointer(entity_id); Entity* entity = id_manager.getEntityPointer(entity_id);
if(!entity)return; if (!entity)
return;
EntitiesBlock* block = getMetaData(entity); EntitiesBlock* block = getMetaData(entity);
EntityInfo* info = block.type_data; EntityInfo* info = block.type_info;
ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0
.. info.components.length + num]; .. info.components.length + num];
/*ushort[num] new_ids; /*ushort[num] new_ids;
@ -717,7 +861,7 @@ class EntityManager
const uint num = Components.length; const uint num = Components.length;
Entity* entity = id_manager.getEntityPointer(entity_id); Entity* entity = id_manager.getEntityPointer(entity_id);
EntitiesBlock* block = getMetaData(entity); EntitiesBlock* block = getMetaData(entity);
EntityInfo* info = block.type_data; EntityInfo* info = block.type_info;
ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0
.. info.components.length + num]; .. info.components.length + num];
ushort[num] new_ids; ushort[num] new_ids;
@ -755,10 +899,25 @@ class EntityManager
export ref Entity addEntity(EntityTemplate* tmpl) export ref Entity addEntity(EntityTemplate* tmpl)
{ {
EntitiesBlock* block = findBlockWithFreeSpace(tmpl.info); EntitiesBlock* block = findBlockWithFreeSpace(tmpl.info);
uint id = (block.entities_count + block.added_count);
EntityInfo* info = tmpl.info;
void* start = block.dataBegin() + (block.entities_count + block.added_count) version (LinearLayout)
* tmpl.info.size; {
memcpy(start, tmpl.entity_data.ptr, tmpl.info.size); void* data_begin = block.dataBegin();
void* start = data_begin + EntityID.sizeof * id;
//memcpy(data_begin + EntityID.sizeof * id, tmpl.entity_data.ptr, EntityID.sizeof);
foreach (i, comp; info.components)
{
memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id,
tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size);
}
}
else
{
void* start = block.dataBegin() + id * info.size;
memcpy(start, tmpl.entity_data.ptr, info.size);
}
if (!block.added_count) if (!block.added_count)
blocks_to_update.add(block); blocks_to_update.add(block);
@ -791,14 +950,15 @@ class EntityManager
{ {
previous_block.next_block = block; previous_block.next_block = block;
block.prev_block = previous_block; block.prev_block = previous_block;
block.id = previous_block.id + 1; block.id = cast(ushort)(previous_block.id + 1);
} }
info.first_with_free_space = block; info.first_with_free_space = block;
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() + ( /*if (block.dataDelta() + (
block.entities_count + block.added_count + 1) * info.size > page_size) block.entities_count + block.added_count + 1) * info.size > page_size)*/
if (block.entities_count + block.added_count >= block.type_info.max_entities)
{ {
previous_block = block; previous_block = block;
block = block.next_block; block = block.next_block;
@ -834,41 +994,66 @@ class EntityManager
{ {
//pos is Entity number in block //pos is Entity number in block
void* data_begin = block.dataBegin(); void* data_begin = block.dataBegin();
uint pos = cast(int)(cast(void*) entity - data_begin) / block.type_data.size; EntityInfo* info = block.type_info;
block.entities_count--; block.entities_count--;
//set "first_with_free_space" if should it be //set "first_with_free_space" if should it be
if (block.type_data.first_with_free_space.id > block.id) if (info.first_with_free_space.id > block.id)
block.type_data.first_with_free_space = block; info.first_with_free_space = block;
if (call_destructors) version (LinearLayout)
{ {
void* data = data_begin + pos * block.type_data.size; static if (EntityID.sizeof == 8)
foreach (comp; block.type_data.components) uint pos = cast(uint)((cast(void*) entity - data_begin) >> 3);
else
uint pos = cast(uint)((cast(void*) entity - data_begin) / EntityID.sizeof());
if (call_destructors)
{ {
if (components[comp].destroy_callback) //void* data = data_begin + pos * info.size;
foreach (comp; info.components)
{ {
components[comp].destroy_callback(data + block.type_data.deltas[comp]); if (components[comp].destroy_callback)
{
//components[comp].destroy_callback(data + info.deltas[comp]);
components[comp].destroy_callback(cast(
void*) block + info.deltas[comp] + pos * components[comp].size);
}
}
}
}
else
{
uint pos = cast(int)(cast(void*) entity - data_begin) / info.size;
if (call_destructors)
{
void* data = data_begin + pos * info.size;
foreach (comp; info.components)
{
if (components[comp].destroy_callback)
{
components[comp].destroy_callback(data + info.deltas[comp]);
}
} }
} }
} }
if (block.entities_count == 0) if (block.entities_count == 0)
{ {
if (block.type_data.first_block is block) if (info.first_block is block)
{ {
block.type_data.first_block = block.next_block; info.first_block = block.next_block;
} }
if (block.type_data.first_with_free_space is block) if (info.first_with_free_space is block)
{ {
block.type_data.first_with_free_space = block.next_block;//block.type_data.first_block; info.first_with_free_space = block.next_block; //info.first_block;
} }
if (block.prev_block) if (block.prev_block)
{ {
block.prev_block.next_block = block.next_block; block.prev_block.next_block = block.next_block;
} }
if(block.next_block) if (block.next_block)
{ {
block.next_block.prev_block = block.prev_block; block.next_block.prev_block = block.prev_block;
} }
@ -879,14 +1064,27 @@ class EntityManager
if (pos == block.entities_count) if (pos == block.entities_count)
return; return;
//copy memory of last entity to position of removed entity version (LinearLayout)
void* src = data_begin + block.entities_count * block.type_data.size; {
void* dst = data_begin + pos * block.type_data.size; foreach (comp; info.components)
{
void* ptr = cast(void*) block + info.deltas[comp];
uint size = components[comp].size;
memcpy(ptr + pos * size, ptr + block.entities_count * size, size);
}
memcpy(dst, src, block.type_data.size); entity.id = *cast(EntityID*)(data_begin + block.entities_count * EntityID.sizeof);
}
else
{
//copy memory of last entity to position of removed entity
void* src = data_begin + block.entities_count * info.size;
void* dst = data_begin + pos * info.size;
memcpy(dst, src, info.size);
}
//update pointer for moved entity ID //update pointer for moved entity ID
entity = cast(Entity*) dst; //entity = cast(Entity*) dst;
entity.updateID(); entity.updateID();
} }
@ -981,7 +1179,7 @@ class EntityManager
removeEntities(); removeEntities();
changeEntites(); changeEntites();
clearEvents(); //clearEvents();
} }
struct ComponentInfo struct ComponentInfo
@ -1006,12 +1204,27 @@ class EntityManager
{ {
///entity components ///entity components
ushort[] components; ushort[] components;
///deltas in memory for components
ushort[] deltas; version (LinearLayout)
{
///deltas in memory for components in EntitiesBlock
ushort[] deltas;
///deltas in memory for components in EntityTemplate
ushort[] tmpl_deltas;
}
else
{
///deltas in memory for components
ushort[] deltas;
}
///alignment of whole entity ///alignment of whole entity
ushort alignment; ushort alignment; //unused in linear-layout
///size of entity (with alignment respect) ///size of entity (with alignment respect)
ushort size; ushort size;
///max number of entities in block
ushort max_entities;
///pointer to first block/page ///pointer to first block/page
EntitiesBlock* first_block; EntitiesBlock* first_block;
///a hint for allocations ///a hint for allocations
@ -1029,7 +1242,7 @@ class EntityManager
uint dataDelta() uint dataDelta()
{ {
ushort dif = EntitiesBlock.sizeof; ushort dif = EntitiesBlock.sizeof;
alignNum(dif, type_data.alignment); alignNum(dif, type_info.alignment);
return dif; return dif;
} }
@ -1037,23 +1250,29 @@ class EntityManager
export void* dataBegin() export void* dataBegin()
{ {
ushort dif = EntitiesBlock.sizeof; ushort dif = EntitiesBlock.sizeof;
alignNum(dif, type_data.alignment); version (LinearLayout)
{
}
else
alignNum(dif, type_info.alignment);
return cast(void*)&this + dif; return cast(void*)&this + dif;
} }
///pointer to Entity type info ///pointer to Entity type info
EntityInfo* type_data = null; EntityInfo* type_info = null;
///number of entities in block ///number of entities in block
ushort entities_count = 0; ushort entities_count = 0;
///number of new entities in block ///number of new entities in block
ushort added_count = 0; ushort added_count = 0;
///block id ///block id
uint id = 0; ushort id = 0;
///maximum number of entities in block
//ushort max_entities = 0;
///pointer to next block/page ///pointer to next block/page
EntitiesBlock* next_block = null; EntitiesBlock* next_block = null;
///pointer to next block/page ///pointer to next block/page
EntitiesBlock* prev_block = null; EntitiesBlock* prev_block = null;
//there is a loooot of data (4kB, pure magic) //there is a loooot of data (some kB of memory, pure magic)
} }
/************************************************************************************************************************ /************************************************************************************************************************
@ -1068,7 +1287,7 @@ class EntityManager
///poiner to Entity type info ///poiner to Entity type info
EntityManager.EntityInfo* info; EntityManager.EntityInfo* info;
///deltas for components ///deltas for components
ushort[] deltas; ushort[] deltas; //unused in linear-layout
} }
alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity); alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity);
@ -1078,7 +1297,7 @@ class EntityManager
//alias event_manager this; //alias event_manager this;
///Single page size. Must be power of two. ///Single page size. Must be power of two.
enum page_size = 4096; enum page_size = 32768; //4096;
///Number of pages in block. ///Number of pages in block.
enum pages_in_block = 128; enum pages_in_block = 128;

View file

@ -23,11 +23,11 @@ int main()
float a; float a;
} }
struct TestComp static struct TestComp
{ {
__gshared ushort component_id; __gshared ushort component_id;
int a; int a = 1;
ulong b; ulong b = 2;
static void serializeComponent(SerializeVector output) static void serializeComponent(SerializeVector output)
{ {
@ -40,11 +40,11 @@ int main()
} }
} }
struct TestComp2 static struct TestComp2
{ {
__gshared ushort component_id; __gshared ushort component_id;
int b; int b = 3;
int a; int a = 4;
static void serializeComponent(ref TestComp comp, SerializeVector output) static void serializeComponent(ref TestComp comp, SerializeVector output)
{ {
@ -57,11 +57,11 @@ int main()
} }
} }
struct TestComp3 static struct TestComp3
{ {
__gshared ushort component_id; __gshared ushort component_id;
uint gg; //good game uint gg = 5; //good game
uint bg; //bad game uint bg = 6; //bad game
void serializeComponent(SerializeVector output) void serializeComponent(SerializeVector output)
{ {
@ -74,11 +74,15 @@ int main()
} }
} }
struct TestComp4 static struct TestComp4
{ {
__gshared ushort component_id; __gshared ushort component_id;
uint gg; //good game uint gg = 7; //good game
uint bg; //bad game uint bg = 8; //bad game
ulong a;
ulong b;
ulong c;
ulong g;
static void serializeComponent(ref TestComp comp, SerializeVector output) static void serializeComponent(ref TestComp comp, SerializeVector output)
{ {
@ -107,12 +111,12 @@ int main()
void onBegin() void onBegin()
{ {
writeln("On Test System begin."); //writeln("On Test System begin.");
} }
void onEnd() void onEnd()
{ {
writeln("On Test System end."); //writeln("On Test System end.");
} }
void initialize(ref Entity entity, ref TestComp comp) void initialize(ref Entity entity, ref TestComp comp)
@ -127,7 +131,7 @@ int main()
@("optional") TestComp3* test3; @("optional") TestComp3* test3;
} }
void update(ref Entity entity, ref TestComp test, ref TestComp2 test2, TestComp3* test3) //ref TestComp comp) void update(ref Entity entity, ref TestComp test, ref TestComp2 test2)//, TestComp3* test3) //ref TestComp comp)
{ {
assert(cast(size_t)&test % TestComp.alignof == 0); assert(cast(size_t)&test % TestComp.alignof == 0);
assert(cast(size_t)&test2 % TestComp2.alignof == 0); assert(cast(size_t)&test2 % TestComp2.alignof == 0);
@ -141,8 +145,12 @@ int main()
test2.a = 8; test2.a = 8;
//writeln("Jakis tekst! ",test2.b); //writeln("Jakis tekst! ",test2.b);
//writeln("Low priority tekst! "); //writeln("Low priority tekst! ");
if (test3) /*if (test3)
{
test3.gg = 200; test3.gg = 200;
test3.bg += 1;
}*/
} }
void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3) void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3)
@ -209,6 +217,21 @@ int main()
}*/ }*/
} }
void writeEntityComponents(Entity* entity)
{
write(entity.id);
TestComp* test_comp = entity.getComponent!TestComp;
if(test_comp)write(*test_comp);
TestComp2* test_comp2 = entity.getComponent!TestComp2;
if(test_comp2)write(*test_comp2);
TestComp3* test_comp3 = entity.getComponent!TestComp3;
if(test_comp3)write(*test_comp3);
TestComp4* test_comp4 = entity.getComponent!TestComp4;
if(test_comp4)write(*test_comp4);
writeln();
//writeln((cast(uint*) pp)[0 .. 14], " ", pp);
}
EntityManager.initialize(); EntityManager.initialize();
assert(gEM !is null); assert(gEM !is null);
@ -237,14 +260,24 @@ int main()
time = MonoTime.currTime; time = MonoTime.currTime;
ushort[2] ids = [TestComp2.component_id, TestComp.component_id]; ushort[3] ids = [TestComp2.component_id, TestComp.component_id, TestComp4.component_id];
EntityTemplate* tmpl = gEM.allocateTemplate(ids); EntityTemplate* tmpl = gEM.allocateTemplate(ids);
ushort[3] ids2 = [TestComp3.component_id, TestComp.component_id, TestComp4.component_id];
EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2);
//writeln(tmpl.info.components[]); //writeln(tmpl.info.components[]);
*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1); //*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1);
dur = (MonoTime.currTime - time).total!"usecs"; dur = (MonoTime.currTime - time).total!"usecs";
writeln("Template allocating: ", dur, " usecs"); writeln("Template allocating: ", dur, " usecs");
Entity entity;
{
entity = gEM.addEntity(tmpl);
writeEntityComponents(gEM.getEntity(entity.id));
}
time = MonoTime.currTime; time = MonoTime.currTime;
//foreach(i; 0..1_000_000)gEM.addEntity(tmpl); //foreach(i; 0..1_000_000)gEM.addEntity(tmpl);
@ -253,13 +286,18 @@ int main()
EntityID[1000] idss; EntityID[1000] idss;
foreach (i; 0 .. 1_000) /*foreach (i; 0 .. 1_000)
{ {
gEM.begin();
foreach (j; 0 .. 1_000) foreach (j; 0 .. 1_000)
idss[j] = gEM.addEntity(tmpl).id; idss[j] = gEM.addEntity(tmpl).id;
foreach (j; 0 .. 1_000) foreach (j; 0 .. 1_000)
gEM.removeEntity(idss[j]); gEM.removeEntity(idss[j]);
} gEM.end();
}*/
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Entities adding: ", dur, " usecs");
uint blocks = 0; uint blocks = 0;
foreach (info; &gEM.entities_infos.byValue) foreach (info; &gEM.entities_infos.byValue)
@ -273,13 +311,6 @@ int main()
} }
writeln("Entities blocks: ", blocks); writeln("Entities blocks: ", blocks);
/*Entity entity = gEM.addEntity(tmpl);
gEM.removeEntity(entity.id);
gEM.addEntity(tmpl);*/
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Entities adding: ", dur, " usecs");
//foreach(j; 0..1_000)gEM.addEntity(tmpl); //foreach(j; 0..1_000)gEM.addEntity(tmpl);
gEM.registerSystem!TestSystem2(0); gEM.registerSystem!TestSystem2(0);
@ -287,43 +318,69 @@ int main()
//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));
foreach (i; 0 .. 500_000)
{
gEM.addEntity(tmpl);
gEM.addEntity(tmpl2);
}
time = MonoTime.currTime; time = MonoTime.currTime;
//gEM.update();
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Update: ", dur, " usecs");
Entity entity = gEM.addEntity(tmpl);
gEM.begin(); gEM.begin();
gEM.update(); gEM.update();
gEM.end(); gEM.end();
Entity* pp = gEM.getEntity(entity.id); dur = (MonoTime.currTime - time).total!"usecs";
writeln((cast(uint*) pp)[0 .. 14], " ", pp); writeln("Update: ", dur, " usecs");
time = MonoTime.currTime;
gEM.begin();
gEM.update();
gEM.end();
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Update: ", dur, " usecs");
time = MonoTime.currTime;
gEM.begin();
gEM.update();
gEM.end();
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Update: ", dur, " usecs");
writeEntityComponents(gEM.getEntity(entity.id));
entity = gEM.addEntity(tmpl);
gEM.begin();
gEM.update();
gEM.end();
//Entity* pp;// = gEM.getEntity(entity.id);
//writeln((cast(uint*) pp)[0 .. 14], " ", pp);
writeEntityComponents(gEM.getEntity(entity.id));
gEM.addEntity(tmpl); gEM.addEntity(tmpl);
gEM.addComponents(entity.id, TestComp4());
gEM.addComponents(entity.id, TestComp3()); gEM.addComponents(entity.id, TestComp3());
gEM.begin(); gEM.begin();
gEM.update(); gEM.update();
gEM.end(); gEM.end();
pp = gEM.getEntity(entity.id); writeEntityComponents(gEM.getEntity(entity.id));
writeln((cast(uint*) pp)[0 .. 14], " ", pp); gEM.removeComponents!(TestComp)(entity.id);
//gEM.removeComponents!(TestComp)(entity.id);
gEM.begin(); gEM.begin();
gEM.update(); gEM.update();
gEM.end(); gEM.end();
pp = gEM.getEntity(entity.id); writeEntityComponents(gEM.getEntity(entity.id));
writeln((cast(uint*) pp)[0 .. 14], " ", pp);
//import std.stdio; //import std.stdio;
//writeln((cast(uint*)tmpl.info.first_block)[0..48]); //writeln((cast(uint*)tmpl.info.first_block)[0..48]);