-BlockAllocator is no longer template

-Multithreaded IDManager.getNewID()
 *use implementation with free IDs stack (instead of classic pool)
-support for multiple UpdatePasses. Passes are added by name, and must be called between begin() end() functions.
-removed mutex from addEntity()
-commit() function added. Used to commit all changes made while update() call. Called automatically by begin() end() functions.
This commit is contained in:
Mergul 2018-10-25 11:46:08 +02:00
parent 430ce8074c
commit d3f7593afc
6 changed files with 406 additions and 189 deletions

View file

@ -5,8 +5,11 @@ import ecs.manager;
import std.experimental.allocator;
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)
{
private uint block_size;
private uint blocks_in_allocation;
void* next_block = null;
void* getBlock()

View file

@ -17,10 +17,10 @@ mixin template EventManagerCode()
//@disable this();
this(EntityManager m)
/*this(EntityManager m)
{
manager = m;
}
}*/
void sendSelfEvent(Ev)(EntityID id, Ev event)
{
@ -120,6 +120,6 @@ mixin template EventManagerCode()
EventList current_events;
EventList process_events;
BlockAllocator!(events_block_size, events_blocks_in_allocation) allocator;
BlockAllocator/*!(events_block_size, events_blocks_in_allocation)*/ allocator;
EntityManager manager;
}

View file

@ -1,8 +1,15 @@
module ecs.id_manager;
import std.experimental.allocator;
import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator;
import ecs.entity;
import ecs.vector;
import core.atomic;
import core.stdc.string : memcpy;
import core.sync.mutex;
/************************************************************************************************************************
*IDManager is responsible for assignment and removing IDs. IDs are unique throughtout a whole duration of the program.
*/
@ -11,17 +18,62 @@ struct IDManager
/************************************************************************************************************************
*Get new ID.
*/
EntityID getNewID()
pragma(inline, false) EntityID getNewID()
{
if (m_next_id >= m_ids_array.length)
m_ids_array.add(Data());
//uint current = m_next_id;
//uint next;// = m_ids_array[m_next_id].next_id;
begin:
//if (current == uint.max)//> m_last_id)
int current = m_stack_top.atomicOp!"-="(1) + 1;
if(current < 0)
{
uint add_id = m_last_id.atomicOp!"+="(1) - 1;
if (add_id >= m_ids_array.length)
{
uint local_id = add_id - cast(uint) m_ids_array.length;
uint block_id = local_id >> 16;
if (block_id >= m_blocks_count)
{
add_mutex.lock();
if(block_id >= m_blocks_count)
{
m_blocks[m_blocks_count].alloc();
m_blocks_count++;
}
add_mutex.unlock();
}
}
EntityID id;
id.id = add_id;
id.counter = 0;
return id;
}
//current += 1;
uint index = m_free_stack[current];
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;
id.id = index;
id.counter = m_ids_array[index].counter;
//current = m_ids_array[index].next_id;
return id;
/*next = m_ids_array[current].next_id;
if(cas(&m_next_id,current,next))
{
EntityID id;
id.id = current;
id.counter = m_ids_array[current].counter;
m_next_id = m_ids_array[current].next_id;
return id;
}
else
{
current = next;
goto begin;
}*/
}
/************************************************************************************************************************
@ -33,9 +85,12 @@ struct IDManager
if (data.counter != id.counter)
return;
data.counter++;
data.next_id = m_next_id;
//data.next_id = m_next_id;
data.entity = null;
m_next_id = id.id;
///m_next_id = id.id;
m_stack_top.atomicOp!"+="(1);
m_free_stack[m_stack_top] = id.id;
}
/************************************************************************************************************************
@ -43,7 +98,15 @@ struct IDManager
*/
void update(ref Entity entity)
{
if(entity.id.counter == m_ids_array[entity.id.id].counter)m_ids_array[entity.id.id].entity = &entity;
if (entity.id.id >= cast(uint) m_ids_array.length)
{
uint local_id = entity.id.id - cast(uint) m_ids_array.length;
uint block_id = local_id >> 16;
local_id -= block_id << 16;
m_blocks[block_id].data[local_id].entity = &entity;
}
else //if (entity.id.counter == m_ids_array[entity.id.id].counter)
m_ids_array[entity.id.id].entity = &entity;
}
/************************************************************************************************************************
@ -51,6 +114,19 @@ struct IDManager
*/
export Entity* getEntityPointer(EntityID id)
{
if (id.id >= m_ids_array.length)
{
uint local_id = id.id - cast(uint) m_ids_array.length;
uint block_id = local_id >> 16;
assert(block_id < m_blocks_count);
if (block_id >= m_blocks_count)
return null;
local_id -= block_id << 16;
if (m_blocks[block_id].data[local_id].counter != id.counter)
return null;
return m_blocks[block_id].data[local_id].entity;
}
Data* data = &m_ids_array[id.id];
if (data.counter != id.counter)
return null;
@ -67,16 +143,81 @@ struct IDManager
return data.counter == id.counter;
}
void initialize()
{
m_ids_array = Mallocator.instance.makeArray!Data(65536);
m_free_stack = Mallocator.instance.makeArray!uint(65536);
m_blocks = Mallocator.instance.makeArray!Block(64);
m_blocks_count = 1;
m_blocks[0].alloc();
add_mutex = Mallocator.instance.make!Mutex();
}
void optimize()
{
if(m_stack_top < -1)m_stack_top = -1;
if(m_last_id > m_ids_array.length)
{
uint begin = cast(uint)m_ids_array.length;
Data[] new_array = Mallocator.instance.makeArray!Data(begin + (m_blocks_count << 16));
memcpy(new_array.ptr, m_ids_array.ptr, m_ids_array.length * Data.sizeof);
Mallocator.instance.dispose(m_ids_array);
m_ids_array = new_array;
uint[] new_stack = Mallocator.instance.makeArray!uint(m_ids_array.length);
memcpy(new_stack.ptr,m_free_stack.ptr,m_free_stack.length * uint.sizeof);
Mallocator.instance.dispose(m_free_stack);
m_free_stack = new_stack;
foreach(block;m_blocks[0..m_blocks_count-1])
{
memcpy(cast(void*)m_ids_array.ptr + begin * Data.sizeof, block.data.ptr, 65536 * Data.sizeof);
begin += 65536;
}
memcpy(cast(void*)m_ids_array.ptr + begin * Data.sizeof, m_blocks[m_blocks_count-1].data.ptr, (m_last_id - begin) * Data.sizeof);
foreach(block;m_blocks[1..m_blocks_count])block.free();
m_blocks_count = 1;
}
}
private static struct Block
{
void alloc()
{
assert(data is null);
data = Mallocator.instance.makeArray!Data(65536);
}
void free()
{
assert(data !is null);
Mallocator.instance.dispose(data);
}
Data[] data; //65536
}
private static struct Data
{
uint counter = 0;
uint next_id = uint.max;
//uint next_id = uint.max;
Entity* entity = null;
}
private:
uint m_next_id;
Vector!Data m_ids_array;
Mutex add_mutex;
//shared uint m_next_id = 0;
//shared uint m_last_id = 0;
Data[] m_ids_array = null;
uint m_blocks_count = 0;
Block[] m_blocks;
//shared int m_stack_top = -1;
uint[] m_free_stack = null;
align(64) shared uint m_last_id = 0;
align(64) shared int m_stack_top = -1;
}
unittest

View file

@ -59,10 +59,30 @@ class EntityManager
threads_count = 0;
threads = Mallocator.instance.makeArray!ThreadData(threads_count);
add_mutex = Mallocator.instance.make!Mutex;
id_manager.initialize();
allocator = BlockAllocator(page_size,pages_in_block);
//add_mutex = Mallocator.instance.make!Mutex;
entity_block_alloc_mutex = Mallocator.instance.make!Mutex;
//event_manager = EventManager(this);
//event_manager.manager = this;
UpdatePass* pass = Mallocator.instance.make!UpdatePass;
pass.name = Mallocator.instance.makeArray("update");
passes.add(pass);
passes_map.add(cast(string)pass.name, cast(ushort)(passes.length - 1));
}
/************************************************************************************************************************
*Same as "void registerSystem(Sys)(int priority, int pass = 0)" but use pass name instead of id.
*/
void registerSystem(Sys)(int priority, const (char)[] pass_name)
{
ushort pass = passes_map.get(pass_name, ushort.max);
assert(pass != ushort.max);
registerSystem!(Sys)(priority, pass);
}
/************************************************************************************************************************
@ -73,11 +93,14 @@ class EntityManager
*params:
*priority = system priority. Priority determines order of execution of systems updates.
*/
void registerSystem(Sys)(int priority)
void registerSystem(Sys)(int priority, ushort pass = 0)
{
alias STC = ParameterStorageClass;
assert(pass < passes.length);
System system;
system.m_pass = pass;
static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort))
{
@ -450,10 +473,6 @@ class EntityManager
mixin(genCompList());
/*if(system.m_components)qsort(system.m_components.ptr, system.m_components.length, ushort.sizeof, &compareUShorts);
if(system.m_optional_components)qsort(system.m_optional_components.ptr, system.m_optional_components.length, ushort.sizeof, &compareUShorts);
if(system.m_absent_components)qsort(system.m_absent_components.ptr, system.m_absent_components.length, ushort.sizeof, &compareUShorts);*/
ushort sys_id = systems_map.get(Sys.stringof, ushort.max);
if (sys_id < systems.length)
{
@ -492,13 +511,13 @@ class EntityManager
version (UpdateBySystems)
{
bool added = false;
foreach (i, ref caller; system_callers)
foreach (i, ref caller; passes[pass].system_callers)
{
if (systems[caller.system_id].priority > priority)
{
SystemCaller* sys_caller = Mallocator.instance.make!SystemCaller;
sys_caller.system_id = Sys.system_id;
system_callers.add(sys_caller, i);
passes[pass].system_callers.add(sys_caller, i);
added = true;
break;
}
@ -507,7 +526,7 @@ class EntityManager
{
SystemCaller* sys_caller = Mallocator.instance.make!SystemCaller;
sys_caller.system_id = Sys.system_id;
system_callers.add(sys_caller);
passes[pass].system_callers.add(sys_caller);
}
}
}
@ -525,6 +544,15 @@ class EntityManager
return cast(Sys*) systems[Sys.system_id].m_system_pointer;
}
ushort registerPass(const (char)[] name)
{
UpdatePass* pass = Mallocator.instance.make!UpdatePass;
pass.name = Mallocator.instance.makeArray(name);
passes.add(pass);
passes_map.add(name,cast(ushort)(passes.length - 1));
return cast(ushort)(passes.length - 1);
}
/************************************************************************************************************************
*Register component into EntityManager.
*/
@ -564,7 +592,7 @@ class EntityManager
{
components.add(info);
Comp.component_id = cast(ushort)(components.length - 1);
string name = Mallocator.instance.makeArray(Comp.stringof);
const (char)[] name = Mallocator.instance.makeArray(Comp.stringof);
components_map.add(name, cast(ushort)(components.length - 1));
}
}
@ -605,14 +633,25 @@ class EntityManager
}
}
/************************************************************************************************************************
*Same as "void update(int pass = 0)" but use pass name instead of id.
*/
void update(const (char)[] pass_name)
{
ushort pass = passes_map.get(pass_name, ushort.max);
assert(pass != ushort.max);
update(pass);
}
/************************************************************************************************************************
*Update systems. Should be called only between begin() and end().
*/
export void update()
export void update(ushort pass = 0)
{
assert(pass < passes.length);
version (UpdateBySystems)
{
foreach (caller; system_callers)
foreach (caller; passes[pass].system_callers)
{
System* sys = &systems[caller.system_id];
if (sys.enabled)
@ -644,14 +683,25 @@ class EntityManager
}
}
void updateMT()
/************************************************************************************************************************
*Same as "void updateMT(int pass = 0)" but use pass name instead of id.
*/
void updateMT(const (char)[] pass_name)
{
ushort pass = passes_map.get(pass_name, ushort.max);
assert(pass != ushort.max);
updateMT(pass);
}
void updateMT(ushort pass = 0)
{
assert(pass < passes.length);
assert(m_dispatch_jobs,
"Can't update with multithreading without JobDispatch function. Please use setJobDispatchFunc().");
Vector!CallData tmp_datas;
tmp_datas.reserve(8);
foreach (caller; system_callers)
foreach (caller; passes[pass].system_callers)
{
System* sys = &systems[caller.system_id];
if (sys.enabled)
@ -766,7 +816,7 @@ class EntityManager
nextJob();
caller.job_group.jobs = sys.jobs[0 .. job_id];
m_dispatch_jobs(caller.job_group);//sys.jobs[0 .. job_id]);
m_dispatch_jobs(caller.job_group); //sys.jobs[0 .. job_id]);
}
}
}
@ -978,14 +1028,14 @@ class EntityManager
}
uint index = 0;
for (; index < system_callers.length; index++)
for (; index < passes[system.m_pass].system_callers.length; index++)
{
if (system_callers[index].system_id == system_id)
if (passes[system.m_pass].system_callers[index].system_id == system_id)
break;
}
if (index < system_callers.length)
system_callers[index].infos.add(&entity);
if (index < passes[system.m_pass].system_callers.length)
passes[system.m_pass].system_callers[index].infos.add(&entity);
/*for (; index < entity.callers.length; index++)
{
CallData* caller = &entity.callers[index];
@ -1137,10 +1187,6 @@ class EntityManager
del_ids[i] = comp.component_id;
}
/*change_entities_list.add(0);
change_entities_list.add((cast(ubyte*)&entity_id)[0..8]);
change_entities_list.add((cast(ubyte*)&num)[0..4]);
change_entities_list.add(cast(ubyte[])del_ids);*/
removeComponents(entity_id, del_ids);
}
@ -1361,9 +1407,9 @@ class EntityManager
threads[thread_id].blocks_to_update.add(block);
Entity* entity = cast(Entity*) start;
add_mutex.lock_nothrow();
//add_mutex.lock_nothrow();
entity.id = id_manager.getNewID();
add_mutex.unlock_nothrow();
//add_mutex.unlock_nothrow();
entity.updateID();
return *entity;
@ -1605,28 +1651,28 @@ class EntityManager
}
}
export void commit()
{
id_manager.optimize();
updateBlocks();
removeEntities();
changeEntities();
}
/************************************************************************************************************************
*Begin of update process. Should be called before any update is called.
*/
export void begin()
{
updateBlocks();
removeEntities();
changeEntities();
commit();
m_call_data_allocator.clear();
/*version (UpdateBySystems)
{
}
else
{*/
foreach (ref system; instance.systems)
{
if (system.m_begin)
(cast(void function(void*)) system.m_begin)(system.m_system_pointer);
}
//}
}
/************************************************************************************************************************
@ -1634,22 +1680,14 @@ class EntityManager
*/
export void end()
{
/*version (UpdateBySystems)
{
}
else
{*/
foreach (ref system; instance.systems)
{
if (system.m_end)
(cast(void function(void*)) system.m_end)(system.m_system_pointer);
}
//}
updateBlocks();
removeEntities();
changeEntities();
commit();
//clearEvents();
}
@ -1665,140 +1703,149 @@ class EntityManager
/*private */
void generateDependencies()
{
foreach (caller; system_callers)
foreach(pass_id,pass;passes)
{
caller.system = &systems[caller.system_id];
if(caller.exclusion)Mallocator.instance.dispose(caller.exclusion);
if(caller.dependencies)Mallocator.instance.dispose(caller.dependencies);
}
uint index = 0;
SystemCaller*[] exclusion;
exclusion = (cast(SystemCaller**) alloca((SystemCaller*).sizeof * system_callers.length))[0
.. system_callers.length];
foreach (caller; system_callers)
{
index = 0;
out_for: foreach (caller2; system_callers)
foreach (caller; pass.system_callers)
{
if (/*caller.system.priority != caller2.system.priority ||*/ caller is caller2)
continue;
foreach (cmp; caller.system.m_read_only_components)
{
foreach (cmp2; caller2.system.m_modified_components)
{
if (cmp == cmp2)
{
exclusion[index++] = caller2;
continue out_for;
}
}
}
foreach (cmp; caller.system.m_modified_components)
{
foreach (cmp2; caller2.system.m_read_only_components)
{
if (cmp == cmp2)
{
exclusion[index++] = caller2;
continue out_for;
}
}
foreach (cmp2; caller2.system.m_modified_components)
{
if (cmp == cmp2)
{
exclusion[index++] = caller2;
continue out_for;
}
}
}
caller.system = &systems[caller.system_id];
if (caller.exclusion)
Mallocator.instance.dispose(caller.exclusion);
if (caller.dependencies)
Mallocator.instance.dispose(caller.dependencies);
}
if(index > 0)caller.exclusion = Mallocator.instance.makeArray(exclusion[0..index]);
else caller.exclusion = null;
/*import std.stdio;
write("Exclusive systems for system ", caller.system.name, ": ");
foreach (ex; exclusion[0 .. index])
write(ex.system.name, " ");
writeln();*/
}
extern (C) static int compareSystems(const void* a, const void* b)
{
SystemCaller* _a = *cast(SystemCaller**) a;
SystemCaller* _b = *cast(SystemCaller**) b;
if (_a.system.priority < _b.system.priority)
return -1;
else if (_a.system.priority == _b.system.priority)
uint index = 0;
SystemCaller*[] exclusion;
exclusion = (cast(SystemCaller**) alloca((SystemCaller*).sizeof * pass.system_callers.length))[0
.. pass.system_callers.length];
foreach (caller; pass.system_callers)
{
if (_a.exclusion.length < _b.exclusion.length)
index = 0;
out_for: foreach (caller2; pass.system_callers)
{
if ( /*caller.system.priority != caller2.system.priority ||*/ caller is caller2)
continue;
foreach (cmp; caller.system.m_read_only_components)
{
foreach (cmp2; caller2.system.m_modified_components)
{
if (cmp == cmp2)
{
exclusion[index++] = caller2;
continue out_for;
}
}
}
foreach (cmp; caller.system.m_modified_components)
{
foreach (cmp2; caller2.system.m_read_only_components)
{
if (cmp == cmp2)
{
exclusion[index++] = caller2;
continue out_for;
}
}
foreach (cmp2; caller2.system.m_modified_components)
{
if (cmp == cmp2)
{
exclusion[index++] = caller2;
continue out_for;
}
}
}
}
if (index > 0)
caller.exclusion = Mallocator.instance.makeArray(exclusion[0 .. index]);
else
caller.exclusion = null;
/*import std.stdio;
write("Exclusive systems for system ", caller.system.name, ": ");
foreach (ex; exclusion[0 .. index])
write(ex.system.name, " ");
writeln();*/
}
extern (C) static int compareSystems(const void* a, const void* b)
{
SystemCaller* _a = *cast(SystemCaller**) a;
SystemCaller* _b = *cast(SystemCaller**) b;
if (_a.system.priority < _b.system.priority)
return -1;
else if (_a.exclusion.length == _b.exclusion.length)
return 0;
else if (_a.system.priority == _b.system.priority)
{
if (_a.exclusion.length < _b.exclusion.length)
return -1;
else if (_a.exclusion.length == _b.exclusion.length)
return 0;
else
return 1;
}
else
return 1;
}
else
return 1;
}
qsort(system_callers.array.ptr, system_callers.length, (SystemCaller*)
.sizeof, &compareSystems);
qsort(pass.system_callers.array.ptr, pass.system_callers.length, (SystemCaller*)
.sizeof, &compareSystems);
/*static struct CallerData
{
uint id;
//bool
}*/
/*caller_data = (cast(SystemCaller**) alloca((SystemCaller*).sizeof * system_callers.length))[0
.. system_callers.length];*/
foreach(uint i,caller;system_callers)caller.job_group.id = i;
int priority = int.min;
uint beg = 0;
index = 0;
foreach(uint i,caller;system_callers)
{
/*
if(priority == int.min)priority = caller.system.priority;
if(priority != caller.system.priority)
/*static struct CallerData
{
foreach(caller2;system_callers[beg..i])
{
}
priority = caller.system.priority;
beg = i;
uint id;
//bool
}*/
/*caller_data = (cast(SystemCaller**) alloca((SystemCaller*).sizeof * pass.system_callers.length))[0
.. pass.system_callers.length];*/
foreach (uint i, caller; pass.system_callers)
caller.job_group.id = i;
int priority = int.min;
uint beg = 0;
index = 0;
foreach(ex;caller.exclusion)
foreach (uint i, caller; pass.system_callers)
{
if(ex.job_group.id > caller.job_group.id)continue;
exclusion[index++] = ex;
}
if(index > 0)
{
caller.dependencies = Mallocator.instance.makeArray(exclusion[0..index]);
caller.job_group.dependencies = Mallocator.instance.makeArray!(JobGroup*)(index);
foreach(j,dep;caller.dependencies)
/*
if(priority == int.min)priority = caller.system.priority;
if(priority != caller.system.priority)
{
caller.job_group.dependencies[j] = &dep.job_group;
}
}
else caller.dependencies = null;
foreach(caller2;pass.system_callers[beg..i])
{
}
priority = caller.system.priority;
beg = i;
}*/
index = 0;
foreach (ex; caller.exclusion)
{
if (ex.job_group.id > caller.job_group.id)
continue;
/*import std.stdio;
write("Dependencies for system ", caller.system.name, ": ");
foreach (ex; caller.dependencies)
write(ex.system.name, " ");
writeln();*/
exclusion[index++] = ex;
}
if (index > 0)
{
caller.dependencies = Mallocator.instance.makeArray(exclusion[0 .. index]);
caller.job_group.dependencies = Mallocator.instance.makeArray!(JobGroup*)(index);
foreach (j, dep; caller.dependencies)
{
caller.job_group.dependencies[j] = &dep.job_group;
}
}
else
caller.dependencies = null;
/*import std.stdio;
write("Dependencies for system ", caller.system.name, ": ");
foreach (ex; caller.dependencies)
write(ex.system.name, " ");
writeln();*/
}
}
}
@ -1963,11 +2010,24 @@ class EntityManager
Vector!(EntitiesBlock*) blocks_to_update;
}
struct UpdatePass
{
~this()
{
assert(name);
if(name)Mallocator.instance.dispose(name);
}
char[] name;
Vector!(SystemCaller*) system_callers;
}
static uint thread_id;
ThreadData[] threads;
Vector!(SystemCaller*) system_callers;
Vector!(UpdatePass*) passes;
//Vector!(SystemCaller*) system_callers;
alias SytemFuncType = void function(ref EntityManager.CallData data);
@ -1981,7 +2041,7 @@ class EntityManager
enum pages_in_block = 128;
IDManager id_manager;
BlockAllocator!(page_size, pages_in_block) allocator;
BlockAllocator/*!(page_size, pages_in_block)*/ allocator;
//EventManager event_manager;
mixin EventManagerCode;
@ -1995,13 +2055,14 @@ class EntityManager
HashMap!(ushort[], EntityInfo*) entities_infos;
HashMap!(const(char)[], ushort) systems_map;
HashMap!(string, ushort) components_map;
HashMap!(string, ushort) events_map;
HashMap!(const(char)[], ushort) components_map;
HashMap!(const(char)[], ushort) events_map;
HashMap!(const(char)[], ushort) passes_map;
Vector!System systems;
Vector!ComponentInfo components;
Vector!EventInfo events;
Mutex add_mutex;
//Mutex add_mutex;
Mutex entity_block_alloc_mutex;
CallDataAllocator m_call_data_allocator;

View file

@ -53,6 +53,8 @@ package:
int m_priority;
///pointer to system implementation
void* m_system_pointer;
///system pass index
int m_pass;
///system name
const (char)[] name;
@ -66,7 +68,7 @@ package:
EntityManager.Job[] jobs;
System*[] m_dependencies;
//System*[] m_dependencies;
ushort[] m_read_only_components;
ushort[] m_modified_components;

View file

@ -175,7 +175,7 @@ int main()
void initialize(ref Entity entity, ref TestComp comp)
{
int o = 1;
}
void update(EntitiesData data)
@ -284,6 +284,8 @@ import std.meta;
gEM.setJobDispachFunc(&dispatch);
assert(gEM !is null);
gEM.registerPass("fixed");
MonoTime time = MonoTime.currTime;
gEM.registerComponent!TestComp2;
@ -299,7 +301,7 @@ import std.meta;
time = MonoTime.currTime;
gEM.registerSystem!TestSystemWithHighPriority(100);
gEM.registerSystem!TestSystemWithHighPriority(100,"fixed");
gEM.registerSystem!TestSystem(0);
//gEM.registerSystem!TestSystemWithHighPriority(100);
//gEM.registerSystem!TestSystem2(0);
@ -346,6 +348,7 @@ import std.meta;
gEM.removeEntity(idss[j]);
gEM.end();
}
gEM.commit();
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Entities adding: ", dur, " usecs");
@ -373,12 +376,18 @@ import std.meta;
Entity entity2;
time = MonoTime.currTime;
foreach (i; 0 .. 500_000)
{
entity2 = gEM.addEntity(tmpl);
gEM.addEntity(tmpl2);
}
gEM.commit();
dur = (MonoTime.currTime - time).total!"usecs";
writeln("Entities adding2: ", dur, " usecs");
time = MonoTime.currTime;
gEM.begin();
@ -441,6 +450,7 @@ import std.meta;
gEM.begin();
gEM.update();
gEM.update("fixed");
gEM.end();
writeEntityComponents(gEM.getEntity(entity.id));