-added EmptySystem supprort (called once per frame, sholud be once per jobs)
-EntitiesData can contain "thread_id" which is filled with ID of current thread
This commit is contained in:
parent
5399b584dd
commit
d6b53425dd
3 changed files with 237 additions and 156 deletions
|
|
@ -164,6 +164,11 @@ export struct EntityManager
|
|||
|
||||
foreach (ref system; systems)
|
||||
{
|
||||
if (system.m_empty == true)
|
||||
{
|
||||
addSystemCaller(system.id);
|
||||
continue;
|
||||
}
|
||||
if (system.m_update is null)
|
||||
{
|
||||
if (system.m_add_entity || system.m_remove_entity || system.m_change_entity)
|
||||
|
|
@ -357,46 +362,8 @@ export struct EntityManager
|
|||
{
|
||||
static void callEventHandler(Type)(ref EventCallData data)
|
||||
{
|
||||
//Sys.EventInput input;
|
||||
Sys* data_system = cast(Sys*) data.system_pointer;
|
||||
/*EntityInfo* info = data.block.type_info;
|
||||
|
||||
alias EventFields = Fields!(Sys.EventInput);
|
||||
foreach (ref event_field; input.tupleof)
|
||||
{
|
||||
alias EventFieldType = Unqual!(typeof(*event_field));
|
||||
enum bool is_entity = is(EventFieldType == ecs.entity.Entity);
|
||||
|
||||
static if (is_entity)
|
||||
{
|
||||
event_field = cast(Entity*) data.block.dataBegin() + data.id;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum long index_in_entities_data = getIndexOfTypeInEntitiesData!(Sys.EntitiesData,
|
||||
EventFieldType);
|
||||
static assert(index_in_entities_data != -1,
|
||||
"Component present in EventInput has to be present in EntitiesData!"); // Type present in EventInput has to be present in EntitiesData
|
||||
|
||||
enum bool is_optional = hasUDA!(Sys.EntitiesData.tupleof[index_in_entities_data],
|
||||
"optional");
|
||||
static if (is_optional)
|
||||
{
|
||||
if(info.deltas[EventFieldType.component_id] != 0)event_field = cast(EventFieldType*)(cast(void*) data.block
|
||||
+ info.deltas[EventFieldType.component_id]
|
||||
+ data.id * EventFieldType.sizeof);
|
||||
else event_field = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
event_field = cast(EventFieldType*)(cast(void*) data.block
|
||||
+ info.deltas[EventFieldType.component_id]
|
||||
+ data.id * EventFieldType.sizeof);
|
||||
}
|
||||
}
|
||||
|
||||
}//*/
|
||||
Type* event = cast(Type*) data.event;
|
||||
data_system.handleEvent(gEM.getEntity(event.entity_id), *event);
|
||||
}
|
||||
|
|
@ -542,8 +509,8 @@ export struct EntityManager
|
|||
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
||||
{
|
||||
alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member));
|
||||
if (member == "length" || member == "thread_id" || is(MemberType == Entity[])
|
||||
|| is(MemberType == const(Entity)[]))
|
||||
if (member == "length" || member == "thread_id"
|
||||
|| is(MemberType == Entity[]) || is(MemberType == const(Entity)[]))
|
||||
{
|
||||
if (is(MemberType == Entity[]) || is(MemberType == const(Entity)[]))
|
||||
components_info.entites_array = member;
|
||||
|
|
@ -648,7 +615,7 @@ export struct EntityManager
|
|||
static assert(MemberType.sizeof > 1,
|
||||
"EntitiesData 'length' member can't be byte or ubyte.");
|
||||
}
|
||||
else static if(member == "thread_id")
|
||||
else static if (member == "thread_id")
|
||||
{
|
||||
static assert(isIntegral!(MemberType),
|
||||
"EntitiesData 'thread_id' member must be integral type.");
|
||||
|
|
@ -710,11 +677,11 @@ export struct EntityManager
|
|||
{
|
||||
input_data.length = cast(typeof(input_data.length))(entities_count - offset);
|
||||
}
|
||||
|
||||
static if (hasMember!(Sys.EntitiesData, "thread_id"))
|
||||
|
||||
/*static if (hasMember!(Sys.EntitiesData, "thread_id"))
|
||||
{
|
||||
input_data.thread_id = cast(typeof(input_data.thread_id))threadID();
|
||||
}
|
||||
}//*/
|
||||
|
||||
static foreach (iii, comp_info; components_info.req)
|
||||
{
|
||||
|
|
@ -774,52 +741,86 @@ export struct EntityManager
|
|||
|
||||
static if (OnUpdateOverloadNum != -1)
|
||||
{
|
||||
static void callUpdate(ref CallData data)
|
||||
static if (components_info.req.length != 0 || components_info.optional.length != 0)
|
||||
{
|
||||
Sys* s = cast(Sys*) data.system.m_system_pointer;
|
||||
|
||||
Sys.EntitiesData input_data;
|
||||
EntityInfo* info = data.info; //block.type_info;
|
||||
System* system = data.system;
|
||||
|
||||
EntitiesBlock* block;
|
||||
if (data.first_block)
|
||||
block = data.first_block;
|
||||
else
|
||||
block = info.first_block;
|
||||
|
||||
uint offset = data.begin;
|
||||
uint entities_count;
|
||||
uint blocks;
|
||||
if (data.blocks)
|
||||
blocks = data.blocks;
|
||||
else
|
||||
blocks = uint.max;
|
||||
|
||||
while (block !is null && blocks > 0)
|
||||
static void callUpdate(ref CallData data)
|
||||
{
|
||||
if (blocks == 1)
|
||||
Sys* s = cast(Sys*) data.system.m_system_pointer;
|
||||
|
||||
Sys.EntitiesData input_data;
|
||||
EntityInfo* info = data.info; //block.type_info;
|
||||
System* system = data.system;
|
||||
|
||||
EntitiesBlock* block;
|
||||
if (data.first_block)
|
||||
block = data.first_block;
|
||||
else
|
||||
block = info.first_block;
|
||||
|
||||
uint offset = data.begin;
|
||||
uint entities_count;
|
||||
uint blocks;
|
||||
if (data.blocks)
|
||||
blocks = data.blocks;
|
||||
else
|
||||
blocks = uint.max;
|
||||
|
||||
while (block !is null && blocks > 0)
|
||||
{
|
||||
if (data.end)
|
||||
entities_count = data.end;
|
||||
if (blocks == 1)
|
||||
{
|
||||
if (data.end)
|
||||
entities_count = data.end;
|
||||
else
|
||||
entities_count = block.entities_count;
|
||||
}
|
||||
else
|
||||
entities_count = block.entities_count;
|
||||
|
||||
assert(entities_count <= block.entities_count
|
||||
&& offset <= block.entities_count);
|
||||
|
||||
fillInputData(input_data, info, block, offset, entities_count, system);
|
||||
|
||||
static if (hasMember!(Sys.EntitiesData, "thread_id"))
|
||||
{
|
||||
input_data.thread_id = cast(typeof(input_data.thread_id)) data
|
||||
.thread_id;
|
||||
}
|
||||
|
||||
//s.onUpdate(input_data);
|
||||
(cast(typeof(&__traits(getOverloads, s,
|
||||
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data);
|
||||
|
||||
block = block.next_block;
|
||||
offset = 0;
|
||||
blocks--;
|
||||
}
|
||||
else
|
||||
entities_count = block.entities_count;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static void callUpdate(ref CallData data)
|
||||
{
|
||||
Sys* s = cast(Sys*) data.system.m_system_pointer;
|
||||
|
||||
assert(entities_count <= block.entities_count && offset <= block.entities_count);
|
||||
Sys.EntitiesData input_data;
|
||||
|
||||
fillInputData(input_data, info, block, offset, entities_count, system);
|
||||
/*static if (hasMember!(Sys.EntitiesData, "length"))
|
||||
{
|
||||
input_data.length = 0;
|
||||
}//*/
|
||||
|
||||
static if (hasMember!(Sys.EntitiesData, "thread_id"))
|
||||
{
|
||||
input_data.thread_id = cast(typeof(input_data.thread_id)) data.thread_id;
|
||||
}
|
||||
|
||||
//s.onUpdate(input_data);
|
||||
(cast(typeof(&__traits(getOverloads, s,
|
||||
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data);
|
||||
|
||||
block = block.next_block;
|
||||
offset = 0;
|
||||
blocks--;
|
||||
}
|
||||
|
||||
system.m_empty = true;
|
||||
}
|
||||
|
||||
system.m_update = &callUpdate;
|
||||
|
|
@ -1097,11 +1098,18 @@ export struct EntityManager
|
|||
System* sys = &systems[caller.system_id];
|
||||
if (sys.enabled && sys.execute)
|
||||
{
|
||||
foreach (info; caller.infos)
|
||||
if (sys.m_empty)
|
||||
{
|
||||
CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate);
|
||||
CallData data = CallData(caller.system_id, sys, null, sys.m_update_delegate);
|
||||
data.update();
|
||||
}
|
||||
else
|
||||
foreach (info; caller.infos)
|
||||
{
|
||||
CallData data = CallData(caller.system_id, sys, info,
|
||||
sys.m_update_delegate);
|
||||
data.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1130,6 +1138,26 @@ export struct EntityManager
|
|||
System* sys = &systems[caller.system_id];
|
||||
if (sys.enabled && sys.execute)
|
||||
{
|
||||
uint job_id = 0;
|
||||
void nextJob()
|
||||
{
|
||||
CallData[] callers = m_call_data_allocator.getCallData(
|
||||
cast(uint) tmp_datas.length);
|
||||
//callers[0 .. $] = tmp_datas[0 .. $];
|
||||
memcpy(callers.ptr, &tmp_datas[0], CallData.sizeof * tmp_datas.length);
|
||||
tmp_datas.clear();
|
||||
sys.jobs[job_id].callers = callers;
|
||||
job_id++;
|
||||
}
|
||||
|
||||
if (sys.m_empty)
|
||||
{
|
||||
tmp_datas.add(CallData(caller.system_id, sys, null, sys.m_update_delegate));
|
||||
nextJob();
|
||||
caller.job_group.jobs = sys.jobs[0 .. 1];
|
||||
(cast(void delegate(JobGroup) nothrow @nogc) m_dispatch_jobs)(caller.job_group);
|
||||
continue;
|
||||
}
|
||||
uint entities_count = 0;
|
||||
foreach (info; caller.infos)
|
||||
{
|
||||
|
|
@ -1155,20 +1183,8 @@ export struct EntityManager
|
|||
entities_per_job = entities_count / jobs_count + 1;
|
||||
}
|
||||
|
||||
uint job_id = 0;
|
||||
entities_count = 0;
|
||||
|
||||
void nextJob()
|
||||
{
|
||||
CallData[] callers = m_call_data_allocator.getCallData(
|
||||
cast(uint) tmp_datas.length);
|
||||
//callers[0 .. $] = tmp_datas[0 .. $];
|
||||
memcpy(callers.ptr, &tmp_datas[0], CallData.sizeof * tmp_datas.length);
|
||||
tmp_datas.clear();
|
||||
sys.jobs[job_id].callers = callers;
|
||||
job_id++;
|
||||
}
|
||||
|
||||
foreach (info; caller.infos)
|
||||
{
|
||||
uint blocks_count = info.nonEmptyBlocksCount();
|
||||
|
|
@ -1596,6 +1612,41 @@ export struct EntityManager
|
|||
entity.systems[system_id] = true;
|
||||
}
|
||||
|
||||
export void addSystemCaller(uint system_id) nothrow @nogc
|
||||
{
|
||||
System* system = &systems[system_id];
|
||||
|
||||
uint index = 0;
|
||||
for (; index < passes[system.m_pass].system_callers.length; index++)
|
||||
{
|
||||
if (passes[system.m_pass].system_callers[index].system_id == system_id)
|
||||
return;
|
||||
}
|
||||
|
||||
bool added = false;
|
||||
foreach (i, caller; passes[system.m_pass].system_callers)
|
||||
{
|
||||
if (systems[caller.system_id].priority > system.priority)
|
||||
{
|
||||
SystemCaller* sys_caller = Mallocator.make!SystemCaller;
|
||||
sys_caller.system_id = system.id;
|
||||
sys_caller.job_group.caller = sys_caller;
|
||||
system.m_any_system_caller = sys_caller;
|
||||
passes[system.m_pass].system_callers.add(sys_caller, i);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!added)
|
||||
{
|
||||
SystemCaller* sys_caller = Mallocator.make!SystemCaller;
|
||||
sys_caller.system_id = system.id;
|
||||
sys_caller.job_group.caller = sys_caller;
|
||||
system.m_any_system_caller = sys_caller;
|
||||
passes[system.m_pass].system_callers.add(sys_caller);
|
||||
}
|
||||
}
|
||||
|
||||
export void addSystemCaller(ref EntityInfo info, uint system_id) nothrow @nogc
|
||||
{
|
||||
System* system = &systems[system_id];
|
||||
|
|
@ -2402,7 +2453,10 @@ export struct EntityManager
|
|||
|
||||
foreach (caller; events[i].callers)
|
||||
{
|
||||
if(call_data.block.type_info.systems[caller.system.m_id] == false)continue;
|
||||
if (
|
||||
call_data.block.type_info.systems[caller.system.m_id]
|
||||
== false)
|
||||
continue;
|
||||
call_data.system_pointer = caller.system.m_system_pointer;
|
||||
(cast(void function(
|
||||
ref EventCallData) nothrow @nogc) caller.callback)(
|
||||
|
|
@ -2887,6 +2941,8 @@ export struct EntityManager
|
|||
ushort begin;
|
||||
///index of last element in last block
|
||||
ushort end;
|
||||
///current thread index
|
||||
uint thread_id;
|
||||
}
|
||||
|
||||
struct ListenerCallData
|
||||
|
|
@ -2906,6 +2962,7 @@ export struct EntityManager
|
|||
//EntityManager.instance.getThreadID();
|
||||
foreach (ref caller; callers)
|
||||
{
|
||||
caller.thread_id = EntityManager.instance.threadID();
|
||||
caller.update();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue