-PageSize and PagesInBlock values can be adjust in runtime (at initialization time)
-added support for calling custon delegate function for all entities supported by selected system
This commit is contained in:
parent
1f78f2506c
commit
87e9a31d7f
3 changed files with 335 additions and 171 deletions
|
|
@ -33,12 +33,16 @@ alias SerializeVector = ecs.vector.Vector!ubyte;
|
||||||
*/
|
*/
|
||||||
export struct EntityManager
|
export struct EntityManager
|
||||||
{
|
{
|
||||||
export static void initialize(uint threads_count)
|
/************************************************************************************************************************
|
||||||
|
*Initialize ECS.
|
||||||
|
*/
|
||||||
|
export static void initialize(uint threads_count, uint page_size = 32768,
|
||||||
|
uint block_pages_count = 128)
|
||||||
{
|
{
|
||||||
if (instance is null)
|
if (instance is null)
|
||||||
{
|
{
|
||||||
//instance = Mallocator.make!EntityManager(threads_count);
|
//instance = Mallocator.make!EntityManager(threads_count);
|
||||||
instance = Mallocator.make!EntityManager(threads_count);
|
instance = Mallocator.make!EntityManager(threads_count, page_size, block_pages_count);
|
||||||
|
|
||||||
with (instance)
|
with (instance)
|
||||||
{
|
{
|
||||||
|
|
@ -52,6 +56,9 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************
|
||||||
|
*Deinitialize and destroy ECS. This function release whole memory.
|
||||||
|
*/
|
||||||
export static void destroy()
|
export static void destroy()
|
||||||
{
|
{
|
||||||
if (instance is null)
|
if (instance is null)
|
||||||
|
|
@ -65,16 +72,25 @@ export struct EntityManager
|
||||||
if (system.m_destroy)
|
if (system.m_destroy)
|
||||||
(cast(void function(void*)) system.m_destroy)(system.m_system_pointer);
|
(cast(void function(void*)) system.m_destroy)(system.m_system_pointer);
|
||||||
|
|
||||||
if(system.jobs)Mallocator.dispose(system.jobs);
|
if (system.jobs)
|
||||||
if(system.m_read_only_components)Mallocator.dispose(system.m_read_only_components);
|
Mallocator.dispose(system.jobs);
|
||||||
if(system.m_modified_components)Mallocator.dispose(system.m_modified_components);
|
if (system.m_read_only_components)
|
||||||
if(system.m_components)Mallocator.dispose(system.m_components);
|
Mallocator.dispose(system.m_read_only_components);
|
||||||
if(system.m_excluded_components)Mallocator.dispose(system.m_excluded_components);
|
if (system.m_modified_components)
|
||||||
if(system.m_optional_components)Mallocator.dispose(system.m_optional_components);
|
Mallocator.dispose(system.m_modified_components);
|
||||||
if(system.m_name)Mallocator.dispose(system.m_name);
|
if (system.m_components)
|
||||||
if(system.m_event_callers)Mallocator.dispose(system.m_event_callers);
|
Mallocator.dispose(system.m_components);
|
||||||
|
if (system.m_excluded_components)
|
||||||
|
Mallocator.dispose(system.m_excluded_components);
|
||||||
|
if (system.m_optional_components)
|
||||||
|
Mallocator.dispose(system.m_optional_components);
|
||||||
|
if (system.m_name)
|
||||||
|
Mallocator.dispose(system.m_name);
|
||||||
|
if (system.m_event_callers)
|
||||||
|
Mallocator.dispose(system.m_event_callers);
|
||||||
|
|
||||||
if(system.m_system_pointer)Mallocator.dispose(system.m_system_pointer);
|
if (system.m_system_pointer)
|
||||||
|
Mallocator.dispose(system.m_system_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (EntityInfo* info; &entities_infos.byValue)
|
foreach (EntityInfo* info; &entities_infos.byValue)
|
||||||
|
|
@ -92,17 +108,20 @@ export struct EntityManager
|
||||||
|
|
||||||
foreach (ComponentInfo info; components)
|
foreach (ComponentInfo info; components)
|
||||||
{
|
{
|
||||||
if(info.init_data)Mallocator.dispose(info.init_data);
|
if (info.init_data)
|
||||||
|
Mallocator.dispose(info.init_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (EventInfo info; events)
|
foreach (EventInfo info; events)
|
||||||
{
|
{
|
||||||
if(info.callers)Mallocator.dispose(info.callers);
|
if (info.callers)
|
||||||
|
Mallocator.dispose(info.callers);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (name; &components_map.byKey)
|
foreach (name; &components_map.byKey)
|
||||||
{
|
{
|
||||||
if(name)Mallocator.dispose(name);
|
if (name)
|
||||||
|
Mallocator.dispose(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,6 +184,7 @@ export struct EntityManager
|
||||||
SystemCaller* sys_caller = Mallocator.make!SystemCaller;
|
SystemCaller* sys_caller = Mallocator.make!SystemCaller;
|
||||||
sys_caller.system_id = system.id;
|
sys_caller.system_id = system.id;
|
||||||
sys_caller.job_group.caller = sys_caller;
|
sys_caller.job_group.caller = sys_caller;
|
||||||
|
system.m_any_system_caller = sys_caller;
|
||||||
passes[system.m_pass].system_callers.add(sys_caller, i);
|
passes[system.m_pass].system_callers.add(sys_caller, i);
|
||||||
added = true;
|
added = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -175,6 +195,7 @@ export struct EntityManager
|
||||||
SystemCaller* sys_caller = Mallocator.make!SystemCaller;
|
SystemCaller* sys_caller = Mallocator.make!SystemCaller;
|
||||||
sys_caller.system_id = system.id;
|
sys_caller.system_id = system.id;
|
||||||
sys_caller.job_group.caller = sys_caller;
|
sys_caller.job_group.caller = sys_caller;
|
||||||
|
system.m_any_system_caller = sys_caller;
|
||||||
passes[system.m_pass].system_callers.add(sys_caller);
|
passes[system.m_pass].system_callers.add(sys_caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,7 +258,8 @@ export struct EntityManager
|
||||||
|
|
||||||
foreach (ref event; events)
|
foreach (ref event; events)
|
||||||
{
|
{
|
||||||
qsort(event.callers.ptr, event.callers.length, EventCaller.sizeof, &comapreEventCaller);
|
qsort(event.callers.ptr, event.callers.length,
|
||||||
|
EventCaller.sizeof, &comapreEventCaller);
|
||||||
}
|
}
|
||||||
//qsort(event_callers.ptr, event_callers.length, EventInfo.sizeof, &compareUShorts);
|
//qsort(event_callers.ptr, event_callers.length, EventInfo.sizeof, &compareUShorts);
|
||||||
|
|
||||||
|
|
@ -252,17 +274,20 @@ export struct EntityManager
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
*Default constructor.
|
*Default constructor.
|
||||||
*/
|
*/
|
||||||
export this(uint threads_count) nothrow @nogc
|
export this(uint threads_count, uint page_size, uint block_pages_count) nothrow @nogc
|
||||||
{
|
{
|
||||||
if (threads_count == 0)
|
if (threads_count == 0)
|
||||||
threads_count = 1;
|
threads_count = 1;
|
||||||
threads = Mallocator.makeArray!ThreadData(threads_count);
|
threads = Mallocator.makeArray!ThreadData(threads_count);
|
||||||
//foreach(ref thread;threads)thread = ThreadData().init;
|
//foreach(ref thread;threads)thread = ThreadData().init;
|
||||||
|
|
||||||
|
m_page_size = page_size;
|
||||||
|
m_pages_in_block = block_pages_count;
|
||||||
|
|
||||||
id_manager.initialize();
|
id_manager.initialize();
|
||||||
event_manager.initialize(&this);
|
event_manager.initialize(&this);
|
||||||
|
|
||||||
allocator = BlockAllocator(page_size, pages_in_block);
|
allocator = BlockAllocator(m_page_size, m_pages_in_block);
|
||||||
|
|
||||||
//add_mutex = Mallocator.make!Mutex;
|
//add_mutex = Mallocator.make!Mutex;
|
||||||
entity_block_alloc_mutex = Mallocator.make!Mutex;
|
entity_block_alloc_mutex = Mallocator.make!Mutex;
|
||||||
|
|
@ -276,7 +301,8 @@ export struct EntityManager
|
||||||
id_manager.deinitialize();
|
id_manager.deinitialize();
|
||||||
event_manager.destroy();
|
event_manager.destroy();
|
||||||
|
|
||||||
if(threads)Mallocator.dispose(threads);
|
if (threads)
|
||||||
|
Mallocator.dispose(threads);
|
||||||
if (entity_block_alloc_mutex)
|
if (entity_block_alloc_mutex)
|
||||||
{
|
{
|
||||||
entity_block_alloc_mutex.destroy();
|
entity_block_alloc_mutex.destroy();
|
||||||
|
|
@ -378,22 +404,22 @@ export struct EntityManager
|
||||||
void setEventCallers(Sys)(ref System system)
|
void setEventCallers(Sys)(ref System system)
|
||||||
{
|
{
|
||||||
enum event_handlers_num = __traits(getOverloads, Sys, "handleEvent").length;
|
enum event_handlers_num = __traits(getOverloads, Sys, "handleEvent").length;
|
||||||
System.EventCaller[] callers = (cast(System.EventCaller*)alloca(event_handlers_num * System.EventCaller.sizeof))[0..event_handlers_num];
|
System.EventCaller[] callers = (cast(System.EventCaller*) alloca(
|
||||||
|
event_handlers_num * System.EventCaller.sizeof))[0 .. event_handlers_num];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
foreach (j, func; __traits(getOverloads, Sys, "handleEvent"))
|
foreach (j, func; __traits(getOverloads, Sys, "handleEvent"))
|
||||||
{
|
{
|
||||||
alias Params = Parameters!(__traits(getOverloads,
|
alias Params = Parameters!(__traits(getOverloads, Sys, "handleEvent")[j]);
|
||||||
Sys, "handleEvent")[j]);
|
|
||||||
static if (Params.length == 2 && is(Params[0] == Entity*))
|
static if (Params.length == 2 && is(Params[0] == Entity*))
|
||||||
{
|
{
|
||||||
alias EventParamType = Params[1];
|
alias EventParamType = Params[1];
|
||||||
enum EventName = Unqual!(EventParamType).stringof;
|
enum EventName = Unqual!(EventParamType).stringof;
|
||||||
ushort evt = events_map.get(cast(char[]) EventName, ushort.max);
|
ushort evt = events_map.get(cast(char[]) EventName, ushort.max);
|
||||||
assert(evt != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing event \""~EventName~"\".");
|
assert(evt != ushort.max, "Can't register system \"" ~ Sys.stringof
|
||||||
|
~ "\" due to non existing event \"" ~ EventName ~ "\".");
|
||||||
|
|
||||||
callers[i].callback = cast(
|
callers[i].callback = cast(void*)&callEventHandler!(EventParamType);
|
||||||
void*)&callEventHandler!(EventParamType);
|
|
||||||
callers[i].id = EventParamType.event_id;
|
callers[i].id = EventParamType.event_id;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
@ -516,9 +542,11 @@ export struct EntityManager
|
||||||
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
||||||
{
|
{
|
||||||
alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member));
|
alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member));
|
||||||
if (member == "length" || is(MemberType == Entity[]) || is(MemberType == const(Entity)[]))
|
if (member == "length" || is(MemberType == Entity[])
|
||||||
|
|| is(MemberType == const(Entity)[]))
|
||||||
{
|
{
|
||||||
if(is(MemberType == Entity[]) || is(MemberType == const(Entity)[]))components_info.entites_array = member;
|
if (is(MemberType == Entity[]) || is(MemberType == const(Entity)[]))
|
||||||
|
components_info.entites_array = member;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -536,7 +564,8 @@ export struct EntityManager
|
||||||
is_read_only = true;
|
is_read_only = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (att; __traits(getAttributes, __traits(getMember, Sys.EntitiesData, member)))
|
foreach (att; __traits(getAttributes, __traits(getMember,
|
||||||
|
Sys.EntitiesData, member)))
|
||||||
{
|
{
|
||||||
if (att == "optional")
|
if (att == "optional")
|
||||||
{
|
{
|
||||||
|
|
@ -614,8 +643,10 @@ export struct EntityManager
|
||||||
static assert(0, "EntitiesData can't have any function!");
|
static assert(0, "EntitiesData can't have any function!");
|
||||||
else static if (member == "length")
|
else static if (member == "length")
|
||||||
{
|
{
|
||||||
static assert(isIntegral!(MemberType), "EntitiesData 'length' member must be integral type.");
|
static assert(isIntegral!(MemberType),
|
||||||
static assert(MemberType.sizeof > 1, "EntitiesData 'length' member can't be byte or ubyte.");
|
"EntitiesData 'length' member must be integral type.");
|
||||||
|
static assert(MemberType.sizeof > 1,
|
||||||
|
"EntitiesData 'length' member can't be byte or ubyte.");
|
||||||
}
|
}
|
||||||
else static if (!(isArray!(MemberType)))
|
else static if (!(isArray!(MemberType)))
|
||||||
static assert(0, "EntitiesData members should be arrays of elements!");
|
static assert(0, "EntitiesData members should be arrays of elements!");
|
||||||
|
|
@ -664,7 +695,8 @@ export struct EntityManager
|
||||||
|
|
||||||
static if (components_info.entites_array)
|
static if (components_info.entites_array)
|
||||||
{
|
{
|
||||||
__traits(getMember, input_data, components_info.entites_array) = (cast(Entity*) block.dataBegin())[offset .. entities_count];
|
__traits(getMember, input_data, components_info.entites_array) = (
|
||||||
|
cast(Entity*) block.dataBegin())[offset .. entities_count];
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (hasMember!(Sys.EntitiesData, "length"))
|
static if (hasMember!(Sys.EntitiesData, "length"))
|
||||||
|
|
@ -674,24 +706,27 @@ export struct EntityManager
|
||||||
|
|
||||||
static foreach (iii, comp_info; components_info.req)
|
static foreach (iii, comp_info; components_info.req)
|
||||||
{
|
{
|
||||||
__traits(getMember, input_data, comp_info.name) =
|
__traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember,
|
||||||
(cast(ForeachType!(typeof(__traits(getMember,
|
Sys.EntitiesData, comp_info.name)))*)(
|
||||||
Sys.EntitiesData, comp_info.name)))*)(cast(void*) block + info.deltas[ system.m_components[iii]]))[offset .. entities_count];
|
cast(void*) block + info.deltas[system.m_components[iii]]))[offset
|
||||||
|
.. entities_count];
|
||||||
}
|
}
|
||||||
|
|
||||||
static foreach (iii, comp_info; components_info.optional)
|
static foreach (iii, comp_info; components_info.optional)
|
||||||
{
|
{
|
||||||
if(system.m_optional_components[iii] < info.deltas.length && info.deltas[system.m_optional_components[iii]] != 0)
|
if (system.m_optional_components[iii] < info.deltas.length
|
||||||
|
&& info.deltas[system.m_optional_components[iii]] != 0)
|
||||||
{
|
{
|
||||||
__traits(getMember, input_data, comp_info.name) =
|
__traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember,
|
||||||
(cast(ForeachType!(typeof(__traits(getMember,
|
Sys.EntitiesData, comp_info.name)))*)(cast(
|
||||||
Sys.EntitiesData, comp_info.name)))*)(cast(void*) block + info.deltas[ system.m_optional_components[iii]]))[offset .. entities_count];
|
void*) block + info.deltas[system.m_optional_components[iii]]))[offset
|
||||||
|
.. entities_count];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkOnUpdateParams()()
|
/*bool checkOnUpdateParams()()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
foreach (func; __traits(getOverloads, Sys, "onUpdate"))
|
foreach (func; __traits(getOverloads, Sys, "onUpdate"))
|
||||||
|
|
@ -703,9 +738,29 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
int getOnUpdateOverload()()
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
foreach (i, func; __traits(getOverloads, Sys, "onUpdate"))
|
||||||
|
{
|
||||||
|
if ((Parameters!(func)).length == 1 && is(Parameters!(func)[0] == Sys.EntitiesData))
|
||||||
|
{
|
||||||
|
ret = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (hasMember!(Sys, "onUpdate") && checkOnUpdateParams())
|
static if (hasMember!(Sys, "onUpdate"))
|
||||||
|
enum OnUpdateOverloadNum = getOnUpdateOverload();
|
||||||
|
else
|
||||||
|
enum OnUpdateOverloadNum = -1;
|
||||||
|
//enum HasOnUpdate = (hasMember!(Sys, "onUpdate") && checkOnUpdateParams());
|
||||||
|
|
||||||
|
static if (OnUpdateOverloadNum != -1)
|
||||||
{
|
{
|
||||||
static void callUpdate(ref CallData data)
|
static void callUpdate(ref CallData data)
|
||||||
{
|
{
|
||||||
|
|
@ -745,7 +800,9 @@ export struct EntityManager
|
||||||
|
|
||||||
fillInputData(input_data, info, block, offset, entities_count, system);
|
fillInputData(input_data, info, block, offset, entities_count, system);
|
||||||
|
|
||||||
s.onUpdate(input_data);
|
//s.onUpdate(input_data);
|
||||||
|
(cast(typeof(&__traits(getOverloads, s,
|
||||||
|
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data);
|
||||||
|
|
||||||
block = block.next_block;
|
block = block.next_block;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
@ -767,9 +824,12 @@ export struct EntityManager
|
||||||
static RetType callFunc(void* system_pointer)
|
static RetType callFunc(void* system_pointer)
|
||||||
{
|
{
|
||||||
Sys* s = cast(Sys*) system_pointer;
|
Sys* s = cast(Sys*) system_pointer;
|
||||||
static if(is(RetTyp == void))mixin("s."~func_name~"()");
|
static if (is(RetTyp == void))
|
||||||
else return mixin("s."~func_name~"()");
|
mixin("s." ~ func_name ~ "()");
|
||||||
|
else
|
||||||
|
return mixin("s." ~ func_name ~ "()");
|
||||||
}
|
}
|
||||||
|
|
||||||
*member = cast(void*)&callFunc;
|
*member = cast(void*)&callFunc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -783,16 +843,22 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
foreach (func; __traits(getOverloads, Sys, func_name))
|
foreach (func; __traits(getOverloads, Sys, func_name))
|
||||||
{
|
{
|
||||||
static if ((Parameters!(func)).length == 1 && is(Parameters!(func)[0] == Sys.EntitiesData) && is(ReturnType!(func) == RetType))
|
static if ((Parameters!(func)).length == 1
|
||||||
|
&& is(Parameters!(func)[0] == Sys.EntitiesData)
|
||||||
|
&& is(ReturnType!(func) == RetType))
|
||||||
{
|
{
|
||||||
static RetType callFunc(ref ListenerCallData data)
|
static RetType callFunc(ref ListenerCallData data)
|
||||||
{
|
{
|
||||||
Sys* s = cast(Sys*) data.system.m_system_pointer;
|
Sys* s = cast(Sys*) data.system.m_system_pointer;
|
||||||
Sys.EntitiesData input_data;
|
Sys.EntitiesData input_data;
|
||||||
fillInputData(input_data, data.block.type_info, data.block, data.begin, data.end, data.system);
|
fillInputData(input_data, data.block.type_info,
|
||||||
static if(is(RetTyp == void))mixin("s."~func_name~"(input_data)");
|
data.block, data.begin, data.end, data.system);
|
||||||
else return mixin("s."~func_name~"(input_data)");
|
static if (is(RetTyp == void))
|
||||||
|
mixin("s." ~ func_name ~ "(input_data)");
|
||||||
|
else
|
||||||
|
return mixin("s." ~ func_name ~ "(input_data)");
|
||||||
}
|
}
|
||||||
|
|
||||||
*member = cast(void*)&callFunc;
|
*member = cast(void*)&callFunc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -815,7 +881,15 @@ export struct EntityManager
|
||||||
system.m_priority = priority;
|
system.m_priority = priority;
|
||||||
//(cast(Sys*) system.m_system_pointer).__ecsInitialize();
|
//(cast(Sys*) system.m_system_pointer).__ecsInitialize();
|
||||||
//system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs;
|
//system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs;
|
||||||
system.jobs = Mallocator.makeArray!(Job)((cast(Sys*) system.m_system_pointer).__ecs_jobs_count);
|
system.jobs = Mallocator.makeArray!(Job)((cast(Sys*) system.m_system_pointer)
|
||||||
|
.__ecs_jobs_count);
|
||||||
|
|
||||||
|
static if (OnUpdateOverloadNum != -1)
|
||||||
|
{
|
||||||
|
Sys* s = cast(Sys*) system.m_system_pointer;
|
||||||
|
system.m_update_delegate = cast(void delegate())&__traits(getOverloads,
|
||||||
|
s, "onUpdate")[OnUpdateOverloadNum];
|
||||||
|
}
|
||||||
|
|
||||||
genCompList(system, components_map);
|
genCompList(system, components_map);
|
||||||
|
|
||||||
|
|
@ -967,6 +1041,28 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export void callEntitiesFunction(Sys, T)(T func)
|
||||||
|
{
|
||||||
|
Sys* s;
|
||||||
|
static assert(isDelegate!func, "Function must be delegate.");
|
||||||
|
static assert(__traits(hasMember, Sys, "EntitiesData"),
|
||||||
|
"Can't call function with system which hasn't EntitesData structure.");
|
||||||
|
static assert(__traits(hasMember, Sys, "onUpdate"),
|
||||||
|
"Can't call function with system which hasn't onUpdate function callback.");
|
||||||
|
static assert(is(T == typeof(&s.onUpdate)), "Function must match system update function.");
|
||||||
|
static assert(__traits(hasMember, Sys, "system_id"), "Sys must be system type.");
|
||||||
|
|
||||||
|
System* system = getSystem(Sys.system_id);
|
||||||
|
assert(system != null,
|
||||||
|
"System must be registered in EntityManager before any funcion can be called.");
|
||||||
|
|
||||||
|
foreach (info; system.m_any_system_caller.infos)
|
||||||
|
{
|
||||||
|
CallData data = CallData(system.id, system, info, cast(void delegate()) func);
|
||||||
|
data.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
*Same as "void update(int pass = 0)" but use pass name instead of id.
|
*Same as "void update(int pass = 0)" but use pass name instead of id.
|
||||||
*/
|
*/
|
||||||
|
|
@ -991,7 +1087,7 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
foreach (info; caller.infos)
|
foreach (info; caller.infos)
|
||||||
{
|
{
|
||||||
CallData data = CallData(caller.system_id, sys, info);
|
CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate);
|
||||||
data.update();
|
data.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1085,7 +1181,8 @@ export struct EntityManager
|
||||||
if (full_blocks_count * info.max_entities + entities_count + (
|
if (full_blocks_count * info.max_entities + entities_count + (
|
||||||
first_block.entities_count - first_elem) >= entities_per_job)
|
first_block.entities_count - first_elem) >= entities_per_job)
|
||||||
{
|
{
|
||||||
CallData data = CallData(caller.system_id, sys, info, first_block,
|
CallData data = CallData(caller.system_id, sys,
|
||||||
|
info, sys.m_update_delegate, first_block,
|
||||||
cast(ushort)(full_blocks_count + 1),
|
cast(ushort)(full_blocks_count + 1),
|
||||||
cast(ushort) first_elem, 0);
|
cast(ushort) first_elem, 0);
|
||||||
tmp_datas.add(data);
|
tmp_datas.add(data);
|
||||||
|
|
@ -1098,8 +1195,9 @@ export struct EntityManager
|
||||||
entities_count += full_blocks_count * info.max_entities + (
|
entities_count += full_blocks_count * info.max_entities + (
|
||||||
first_block.entities_count - first_elem); // - first_elem;
|
first_block.entities_count - first_elem); // - first_elem;
|
||||||
uint last_elem = entities_per_job - entities_count; // + first_elem - 1;
|
uint last_elem = entities_per_job - entities_count; // + first_elem - 1;
|
||||||
CallData data = CallData(caller.system_id, sys, info,
|
CallData data = CallData(caller.system_id, sys,
|
||||||
first_block, cast(ushort)(full_blocks_count + 2),
|
info, sys.m_update_delegate, first_block,
|
||||||
|
cast(ushort)(full_blocks_count + 2),
|
||||||
cast(ushort) first_elem, cast(ushort) last_elem);
|
cast(ushort) first_elem, cast(ushort) last_elem);
|
||||||
tmp_datas.add(data);
|
tmp_datas.add(data);
|
||||||
first_elem = last_elem;
|
first_elem = last_elem;
|
||||||
|
|
@ -1111,7 +1209,8 @@ export struct EntityManager
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint last_elem = entities_per_job - entities_count;
|
uint last_elem = entities_per_job - entities_count;
|
||||||
CallData data = CallData(caller.system_id, sys, info, first_block, 1,
|
CallData data = CallData(caller.system_id, sys,
|
||||||
|
info, sys.m_update_delegate, first_block, 1,
|
||||||
cast(ushort) first_elem, cast(ushort)(first_elem + last_elem));
|
cast(ushort) first_elem, cast(ushort)(first_elem + last_elem));
|
||||||
tmp_datas.add(data);
|
tmp_datas.add(data);
|
||||||
first_elem += last_elem;
|
first_elem += last_elem;
|
||||||
|
|
@ -1123,7 +1222,7 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CallData data = CallData(caller.system_id, sys, info,
|
CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate,
|
||||||
first_block, cast(ushort) blocks_count, cast(ushort) first_elem);
|
first_block, cast(ushort) blocks_count, cast(ushort) first_elem);
|
||||||
tmp_datas.add(data);
|
tmp_datas.add(data);
|
||||||
entities_count += (blocks_count - 1) * info.max_entities
|
entities_count += (blocks_count - 1) * info.max_entities
|
||||||
|
|
@ -1138,7 +1237,8 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export void setMultithreadingCallbacks(void delegate(JobGroup) dispatch_callback, uint delegate() get_id_callback)
|
export void setMultithreadingCallbacks(void delegate(JobGroup) dispatch_callback,
|
||||||
|
uint delegate() get_id_callback)
|
||||||
{
|
{
|
||||||
m_dispatch_jobs = cast(void delegate(JobGroup jobs) nothrow @nogc) dispatch_callback;
|
m_dispatch_jobs = cast(void delegate(JobGroup jobs) nothrow @nogc) dispatch_callback;
|
||||||
m_thread_id_func = cast(uint delegate() nothrow @nogc) get_id_callback;
|
m_thread_id_func = cast(uint delegate() nothrow @nogc) get_id_callback;
|
||||||
|
|
@ -1149,6 +1249,23 @@ export struct EntityManager
|
||||||
m_dispatch_jobs = func;
|
m_dispatch_jobs = func;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
/************************************************************************************************************************
|
||||||
|
*Return size of single page (block). Every entity data block has size of page.
|
||||||
|
*/
|
||||||
|
uint pageSize()
|
||||||
|
{
|
||||||
|
return m_page_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************
|
||||||
|
*Return number of pages in single block allocation. Library allocate defined number of pages at once and assign it's
|
||||||
|
*for entities.
|
||||||
|
*/
|
||||||
|
uint pagesInBlock()
|
||||||
|
{
|
||||||
|
return m_pages_in_block;
|
||||||
|
}
|
||||||
|
|
||||||
static void alignNum(ref ushort num, ushort alignment) nothrow @nogc pure
|
static void alignNum(ref ushort num, ushort alignment) nothrow @nogc pure
|
||||||
{
|
{
|
||||||
num = cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); //num += alignment - (num & (alignment - 1));
|
num = cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); //num += alignment - (num & (alignment - 1));
|
||||||
|
|
@ -1188,7 +1305,8 @@ export struct EntityManager
|
||||||
//fill components with default data
|
//fill components with default data
|
||||||
foreach (comp; info.components)
|
foreach (comp; info.components)
|
||||||
{
|
{
|
||||||
memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], components[comp].init_data.ptr, components[comp].size);
|
memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp],
|
||||||
|
components[comp].init_data.ptr, components[comp].size);
|
||||||
/*temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size]
|
/*temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size]
|
||||||
= components[comp].init_data;*/
|
= components[comp].init_data;*/
|
||||||
}
|
}
|
||||||
|
|
@ -1199,7 +1317,8 @@ export struct EntityManager
|
||||||
foreach (comp; info.components)
|
foreach (comp; info.components)
|
||||||
{
|
{
|
||||||
memcpy(cast(void*) temp.entity_data + info.tmpl_deltas[comp],
|
memcpy(cast(void*) temp.entity_data + info.tmpl_deltas[comp],
|
||||||
cast(void*) block + info.deltas[comp] + components[comp].size * index, components[comp].size);
|
cast(void*) block + info.deltas[comp] + components[comp].size * index,
|
||||||
|
components[comp].size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1244,7 +1363,8 @@ export struct EntityManager
|
||||||
//fill components with default data
|
//fill components with default data
|
||||||
foreach (comp; info.components)
|
foreach (comp; info.components)
|
||||||
{
|
{
|
||||||
memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], components[comp].init_data.ptr, components[comp].size);
|
memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp],
|
||||||
|
components[comp].init_data.ptr, components[comp].size);
|
||||||
/*temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size]
|
/*temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size]
|
||||||
= components[comp].init_data;*/
|
= components[comp].init_data;*/
|
||||||
}
|
}
|
||||||
|
|
@ -1287,7 +1407,7 @@ export struct EntityManager
|
||||||
alignNum(info.size, info.alignment);
|
alignNum(info.size, info.alignment);
|
||||||
|
|
||||||
uint block_memory = cast(uint)(
|
uint block_memory = cast(uint)(
|
||||||
page_size - EntitiesBlock.sizeof - (info.size - components_size));
|
m_page_size - EntitiesBlock.sizeof - (info.size - components_size));
|
||||||
//uint entity_comps_size = EntityID.sizeof;
|
//uint entity_comps_size = EntityID.sizeof;
|
||||||
uint mem_begin = EntitiesBlock.sizeof;
|
uint mem_begin = EntitiesBlock.sizeof;
|
||||||
|
|
||||||
|
|
@ -1555,7 +1675,8 @@ export struct EntityManager
|
||||||
new_info = new_info.getNewInfoRemove(id);
|
new_info = new_info.getNewInfoRemove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new_info == info)return;
|
if (new_info == info)
|
||||||
|
return;
|
||||||
|
|
||||||
//EntityInfo* new_info = getEntityInfo(ids[0 .. j]);
|
//EntityInfo* new_info = getEntityInfo(ids[0 .. j]);
|
||||||
|
|
||||||
|
|
@ -1674,7 +1795,8 @@ export struct EntityManager
|
||||||
new_info = new_info.getNewInfoAdd(id);
|
new_info = new_info.getNewInfoAdd(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new_info == info)return;
|
if (new_info == info)
|
||||||
|
return;
|
||||||
|
|
||||||
//EntityInfo* new_info = getEntityInfo(ids[0 .. len]);
|
//EntityInfo* new_info = getEntityInfo(ids[0 .. len]);
|
||||||
|
|
||||||
|
|
@ -1835,12 +1957,13 @@ export struct EntityManager
|
||||||
foreach (i, comp; info.components)
|
foreach (i, comp; info.components)
|
||||||
{
|
{
|
||||||
memcpy(cast(void*) new_block + info.deltas[comp] + components[comp].size * new_id,
|
memcpy(cast(void*) new_block + info.deltas[comp] + components[comp].size * new_id,
|
||||||
cast(void*) block + info.deltas[comp] + components[comp].size * index, components[comp].size);
|
cast(void*) block + info.deltas[comp] + components[comp].size * index,
|
||||||
|
components[comp].size);
|
||||||
|
|
||||||
if (components[comp].create_callback)
|
if (components[comp].create_callback)
|
||||||
{
|
{
|
||||||
components[comp].create_callback(
|
components[comp].create_callback(cast(
|
||||||
cast(void*) block + info.deltas[comp] + new_id * components[comp].size);
|
void*) block + info.deltas[comp] + new_id * components[comp].size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2072,7 +2195,7 @@ export struct EntityManager
|
||||||
*/
|
*/
|
||||||
export EntitiesBlock* getMetaData(const void* pointer) nothrow @nogc
|
export EntitiesBlock* getMetaData(const void* pointer) nothrow @nogc
|
||||||
{
|
{
|
||||||
return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(page_size - 1)));
|
return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(m_page_size - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeEntities()
|
private void changeEntities()
|
||||||
|
|
@ -2268,8 +2391,9 @@ export struct EntityManager
|
||||||
foreach (caller; events[i].callers)
|
foreach (caller; events[i].callers)
|
||||||
{
|
{
|
||||||
call_data.system_pointer = caller.system.m_system_pointer;
|
call_data.system_pointer = caller.system.m_system_pointer;
|
||||||
(cast(void function(ref EventCallData) nothrow @nogc) caller
|
(cast(void function(
|
||||||
.callback)(call_data);
|
ref EventCallData) nothrow @nogc) caller.callback)(
|
||||||
|
call_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event_pointer += events[i].size;
|
event_pointer += events[i].size;
|
||||||
|
|
@ -2448,8 +2572,7 @@ export struct EntityManager
|
||||||
caller.dependencies = Mallocator.makeArray(exclusion[0 .. index]);
|
caller.dependencies = Mallocator.makeArray(exclusion[0 .. index]);
|
||||||
/*caller.dependencies = Mallocator.makeArray!(SystemCaller*)(index);
|
/*caller.dependencies = Mallocator.makeArray!(SystemCaller*)(index);
|
||||||
caller.dependencies[0..$] = exclusion[0 .. index];*/
|
caller.dependencies[0..$] = exclusion[0 .. index];*/
|
||||||
caller.job_group.dependencies = Mallocator.makeArray!(
|
caller.job_group.dependencies = Mallocator.makeArray!(JobGroup*)(index);
|
||||||
JobGroup*)(index);
|
|
||||||
|
|
||||||
foreach (j, dep; caller.dependencies)
|
foreach (j, dep; caller.dependencies)
|
||||||
{
|
{
|
||||||
|
|
@ -2467,7 +2590,9 @@ export struct EntityManager
|
||||||
*/
|
*/
|
||||||
struct ComponentInfo
|
struct ComponentInfo
|
||||||
{
|
{
|
||||||
export ~this() nothrow @nogc {}
|
export ~this() nothrow @nogc
|
||||||
|
{
|
||||||
|
}
|
||||||
///Component size
|
///Component size
|
||||||
ushort size;
|
ushort size;
|
||||||
///Component data alignment
|
///Component data alignment
|
||||||
|
|
@ -2537,16 +2662,19 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
if (comp_add_info.length < id)
|
if (comp_add_info.length < id)
|
||||||
{
|
{
|
||||||
EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(instance.components.length);
|
EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(
|
||||||
|
instance.components.length);
|
||||||
if (comp_add_info !is null)
|
if (comp_add_info !is null)
|
||||||
{
|
{
|
||||||
//new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $];
|
//new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $];
|
||||||
memcpy(new_infos.ptr, comp_add_info.ptr, (EntityInfo*).sizeof * comp_add_info.length);
|
memcpy(new_infos.ptr, comp_add_info.ptr, (EntityInfo*)
|
||||||
|
.sizeof * comp_add_info.length);
|
||||||
Mallocator.dispose(comp_add_info);
|
Mallocator.dispose(comp_add_info);
|
||||||
}
|
}
|
||||||
comp_add_info = new_infos;
|
comp_add_info = new_infos;
|
||||||
}
|
}
|
||||||
if(comp_add_info[id])return comp_add_info[id];
|
if (comp_add_info[id])
|
||||||
|
return comp_add_info[id];
|
||||||
|
|
||||||
ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (components.length + 1)))[0
|
ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (components.length + 1)))[0
|
||||||
.. components.length + 1];
|
.. components.length + 1];
|
||||||
|
|
@ -2558,14 +2686,16 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
ids[len++] = comp;
|
ids[len++] = comp;
|
||||||
}
|
}
|
||||||
else if(id == comp)return &this;
|
else if (id == comp)
|
||||||
|
return &this;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ids[len++] = id;
|
ids[len++] = id;
|
||||||
ids[len++] = comp;
|
ids[len++] = comp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(id > components[$ - 1])ids[len++] = id;
|
if (id > components[$ - 1])
|
||||||
|
ids[len++] = id;
|
||||||
|
|
||||||
assert(len == components.length + 1);
|
assert(len == components.length + 1);
|
||||||
|
|
||||||
|
|
@ -2579,16 +2709,19 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
if (comp_rem_info.length < id)
|
if (comp_rem_info.length < id)
|
||||||
{
|
{
|
||||||
EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(instance.components.length);
|
EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(
|
||||||
|
instance.components.length);
|
||||||
if (comp_rem_info !is null)
|
if (comp_rem_info !is null)
|
||||||
{
|
{
|
||||||
//new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $];
|
//new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $];
|
||||||
memcpy(new_infos.ptr, comp_rem_info.ptr, (EntityInfo*).sizeof * comp_rem_info.length);
|
memcpy(new_infos.ptr, comp_rem_info.ptr, (EntityInfo*)
|
||||||
|
.sizeof * comp_rem_info.length);
|
||||||
Mallocator.dispose(comp_rem_info);
|
Mallocator.dispose(comp_rem_info);
|
||||||
}
|
}
|
||||||
comp_rem_info = new_infos;
|
comp_rem_info = new_infos;
|
||||||
}
|
}
|
||||||
if(comp_rem_info[id])return comp_rem_info[id];
|
if (comp_rem_info[id])
|
||||||
|
return comp_rem_info[id];
|
||||||
|
|
||||||
ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (components.length - 1)))[0
|
ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (components.length - 1)))[0
|
||||||
.. components.length - 1];
|
.. components.length - 1];
|
||||||
|
|
@ -2601,7 +2734,8 @@ export struct EntityManager
|
||||||
ids[len++] = comp;
|
ids[len++] = comp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(len == components.length)return &this;
|
if (len == components.length)
|
||||||
|
return &this;
|
||||||
|
|
||||||
assert(len == components.length - 1);
|
assert(len == components.length - 1);
|
||||||
|
|
||||||
|
|
@ -2613,13 +2747,20 @@ export struct EntityManager
|
||||||
|
|
||||||
export ~this() @nogc nothrow
|
export ~this() @nogc nothrow
|
||||||
{
|
{
|
||||||
if(components)Mallocator.dispose(components);
|
if (components)
|
||||||
if(deltas)Mallocator.dispose(deltas);
|
Mallocator.dispose(components);
|
||||||
if(tmpl_deltas)Mallocator.dispose(tmpl_deltas);
|
if (deltas)
|
||||||
if(systems)Mallocator.dispose(systems);
|
Mallocator.dispose(deltas);
|
||||||
if(add_listeners)Mallocator.dispose(add_listeners);
|
if (tmpl_deltas)
|
||||||
if(remove_listeners)Mallocator.dispose(remove_listeners);
|
Mallocator.dispose(tmpl_deltas);
|
||||||
if(change_listeners)Mallocator.dispose(change_listeners);
|
if (systems)
|
||||||
|
Mallocator.dispose(systems);
|
||||||
|
if (add_listeners)
|
||||||
|
Mallocator.dispose(add_listeners);
|
||||||
|
if (remove_listeners)
|
||||||
|
Mallocator.dispose(remove_listeners);
|
||||||
|
if (change_listeners)
|
||||||
|
Mallocator.dispose(change_listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
///entity components
|
///entity components
|
||||||
|
|
@ -2722,6 +2863,8 @@ export struct EntityManager
|
||||||
System* system;
|
System* system;
|
||||||
///poiner to Entity type info
|
///poiner to Entity type info
|
||||||
EntityManager.EntityInfo* info;
|
EntityManager.EntityInfo* info;
|
||||||
|
///delegate function to call (by default it's delegate to onUpdate call)
|
||||||
|
void delegate() update_delegate;
|
||||||
|
|
||||||
///pointer to first block into process (if 0 then first block will be used)
|
///pointer to first block into process (if 0 then first block will be used)
|
||||||
EntitiesBlock* first_block;
|
EntitiesBlock* first_block;
|
||||||
|
|
@ -2845,9 +2988,9 @@ export struct EntityManager
|
||||||
alias SytemFuncType = void function(ref EntityManager.CallData data) nothrow @nogc;
|
alias SytemFuncType = void function(ref EntityManager.CallData data) nothrow @nogc;
|
||||||
|
|
||||||
///Single page size. Must be power of two.
|
///Single page size. Must be power of two.
|
||||||
enum page_size = 32768; //4096;
|
int m_page_size = 32768; //32768; //4096;
|
||||||
///Number of pages in block.
|
///Number of pages in block.
|
||||||
enum pages_in_block = 128;
|
int m_pages_in_block = 128;
|
||||||
|
|
||||||
IDManager id_manager;
|
IDManager id_manager;
|
||||||
BlockAllocator allocator;
|
BlockAllocator allocator;
|
||||||
|
|
|
||||||
|
|
@ -120,10 +120,13 @@ package:
|
||||||
ushort[] m_read_only_components;
|
ushort[] m_read_only_components;
|
||||||
ushort[] m_modified_components;
|
ushort[] m_modified_components;
|
||||||
|
|
||||||
|
EntityManager.SystemCaller* m_any_system_caller;
|
||||||
|
|
||||||
EventCaller[] m_event_callers;
|
EventCaller[] m_event_callers;
|
||||||
|
|
||||||
//void function(ref EntityManager.CallData data) m_update;
|
//void function(ref EntityManager.CallData data) m_update;
|
||||||
void* m_update; ///workaroud for DMD bug with upper line
|
void* m_update; ///workaroud for DMD bug with upper line
|
||||||
|
void delegate() m_update_delegate;
|
||||||
|
|
||||||
//void function(void* system_pointer) m_enable;
|
//void function(void* system_pointer) m_enable;
|
||||||
//void function(void* system_pointer) m_disable;
|
//void function(void* system_pointer) m_disable;
|
||||||
|
|
|
||||||
|
|
@ -501,6 +501,20 @@ struct TestSystem2
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ExternalUpdateCallTest
|
||||||
|
{
|
||||||
|
int print_count = 3;
|
||||||
|
|
||||||
|
void update(TestSystem2.EntitiesData data)
|
||||||
|
{
|
||||||
|
if(print_count > 0)
|
||||||
|
{
|
||||||
|
print_count--;
|
||||||
|
printf("ExternalUpdateCallTest %u %u\n", data.test[0].gg, cast(uint)data.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern(C) int main()
|
extern(C) int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -660,8 +674,6 @@ extern(C) int main()
|
||||||
gEM.registerSystem!TestSystem2(0);
|
gEM.registerSystem!TestSystem2(0);
|
||||||
gEM.endRegister();
|
gEM.endRegister();
|
||||||
|
|
||||||
System* sys = EntityManager.instance.getSystem(TestSystem2.system_id);
|
|
||||||
|
|
||||||
//gEM.generateDependencies();
|
//gEM.generateDependencies();
|
||||||
|
|
||||||
//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));
|
||||||
|
|
@ -799,6 +811,12 @@ extern(C) int main()
|
||||||
|
|
||||||
gEM.commit();
|
gEM.commit();
|
||||||
|
|
||||||
|
System* sys = EntityManager.instance.getSystem(TestSystem2.system_id);
|
||||||
|
|
||||||
|
ExternalUpdateCallTest external_update_test;
|
||||||
|
|
||||||
|
EntityManager.instance.callEntitiesFunction!TestSystem2(&external_update_test.update);
|
||||||
|
|
||||||
printf("pre end\n");
|
printf("pre end\n");
|
||||||
|
|
||||||
writeEntityComponents(gEM.getEntity(entity));
|
writeEntityComponents(gEM.getEntity(entity));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue