-move code from templates to ECS side:

*sendEvent - using EventRef (alias to ComponentRef)
 *ListenerCallData now contain entities count and pointer to EntityInfo
 *Remove system_pointer from SystemCallData (use context instead)
 *Register event
-Now all BECS functinality can be used without templates
-clean code
This commit is contained in:
Mergul 2021-03-24 18:35:03 +01:00
parent 0d08b8532a
commit 70a5388820
5 changed files with 126 additions and 261 deletions

View file

@ -1,4 +1,4 @@
project('decs', 'd', version : '0.5.0') project('decs', 'd', version : '0.1.0')
# Options # Options
betterC_opt = get_option('betterC') betterC_opt = get_option('betterC')
@ -78,6 +78,24 @@ decs_dep = declare_dependency(
# Tests # Tests
if BuildTests_opt if BuildTests_opt
subdir('tests') subdir('tests')
executable('d-api-tests',
['tests/tests.d'],
include_directories : [inc],
d_args : args,
link_args : link_args,
dependencies : decs_dep,
)
if C_API_opt
add_languages('c')
executable('c-api-tests',
['c-api/test.c'],
include_directories : [inc],
dependencies : decs_dep,
)
endif
endif endif
# Demos # Demos

View file

@ -8,6 +8,8 @@ import bubel.ecs.traits : becsID;
import std.algorithm.comparison : max; import std.algorithm.comparison : max;
alias EventRef = ComponentRef;
package struct EventManager package struct EventManager
{ {
@ -30,12 +32,17 @@ package struct EventManager
} }
export void sendEvent(Ev)(EntityID id, Ev event, uint thread_id = 0) nothrow @nogc export void sendEvent(Ev)(EntityID id, Ev event, uint thread_id = 0) nothrow @nogc
{
sendEvent(id, EventRef(&event, becsID!Ev), thread_id);
}
export void sendEvent(EntityID id, EventRef event, uint thread_id = 0) nothrow @nogc
{ {
uint block_id = current_index + thread_id; uint block_id = current_index + thread_id;
EventData* data = &events[becsID!Ev]; EventData* data = &events[event.component_id];
EventBlock* block = data.blocks[block_id]; EventBlock* block = data.blocks[block_id];
//EntityManager.EventInfo* info = &manager.events[Ev.event_id]; EntityManager.EventInfo* info = &manager.events[event.component_id];
//event.entity_id = id; //event.entity_id = id;
if (block is null) if (block is null)
@ -61,10 +68,11 @@ package struct EventManager
data.blocks[block_id] = block; data.blocks[block_id] = block;
} }
uint size = Ev.sizeof + EntityID.sizeof; uint size = info.size + EntityID.sizeof;
void* ptr = cast(void*) block + data.data_offset + block.count * size; void* ptr = cast(void*) block + data.data_offset + block.count * size;
*cast(EntityID*)ptr = id; *cast(EntityID*)ptr = id;
*cast(Ev*)(ptr + EntityID.sizeof) = event; memcpy(ptr + EntityID.sizeof, event.ptr, info.size);
//*cast(Ev*)(ptr + EntityID.sizeof) = event;
//Ev* event_array = cast(Ev*)(cast(void*) block + data.data_offset); //Ev* event_array = cast(Ev*)(cast(void*) block + data.data_offset);
//event_array[block.count] = event; //event_array[block.count] = event;
block.count++; block.count++;

View file

@ -105,8 +105,6 @@ export struct EntityManager
foreach (EntityInfo* info; &entities_infos.byValue) foreach (EntityInfo* info; &entities_infos.byValue)
{ {
//if(info.components)Mallocator.dispose(info.components);
Mallocator.dispose(info); Mallocator.dispose(info);
} }
@ -364,20 +362,13 @@ export struct EntityManager
else else
assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist."); assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist.");
// enum SystemName = fullyQualifiedName!Sys;
enum SystemName = fullName!Sys; enum SystemName = fullName!Sys;
//enum SystemName = Sys.stringof;
System system; System system;
system.m_pass = pass; system.m_pass = pass;
alias SystemData = SystemEntityData!Sys; alias SystemData = SystemEntityData!Sys;
// static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort))
// {
// static assert(0, "Add \"mixin ECS.System;\" in top of system structure;");
// }
static if (!(hasMember!(Sys, "EntitiesData"))) static if (!(hasMember!(Sys, "EntitiesData")))
{ {
static assert(0, "System should gave \"EntitiesData\" struct for input components"); static assert(0, "System should gave \"EntitiesData\" struct for input components");
@ -407,7 +398,6 @@ export struct EntityManager
{ {
alias EventParamType = Params[1]; alias EventParamType = Params[1];
enum EventName = fullName!(Unqual!(EventParamType)); enum EventName = fullName!(Unqual!(EventParamType));
// enum EventName = fullyQualifiedName!(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, assert(evt != ushort.max,
"Can't register system \"" ~ SystemName "Can't register system \"" ~ SystemName
@ -556,50 +546,6 @@ export struct EntityManager
} }
} }
struct InputData
{
uint length;
uint thread_id;
uint job_id;
//this struct containt multiple data pointers in linear memory (e.g. data_pointer+1 may be valid)
void* data_pointer;
}
static void fillInputData_dyn(ref InputData input_data, EntityInfo* info,
EntitiesBlock* block, uint offset, uint entities_count, System* system)
{
input_data.length = entities_count;
// input_data.thread_id = 0;
foreach(size_t i, ushort component; system.m_components)
{
*(&input_data.data_pointer + i) = cast(void*) block + info.deltas[component] + offset * gEntityManager.components[component].size;
}
foreach(size_t i, ushort component; system.m_optional_components)
{
if(component < info.deltas.length && info.deltas[component] != 0)*(&input_data.data_pointer + i + system.m_components.length) = cast(void*) block + info.deltas[component] + offset * gEntityManager.components[component].size;
}
}
static void fillEntitiesData(ref Sys.EntitiesData entities_data, ref InputData input_data)
{
}
/*bool checkOnUpdateParams()
{
bool ret = false;
foreach (func; __traits(getOverloads, Sys, "onUpdate"))
{
if ((Parameters!(func)).length == 1 && is(Parameters!(func)[0] == Sys.EntitiesData))
{
ret = true;
break;
}
}
return ret;
}*/
int getOnUpdateOverload()() int getOnUpdateOverload()()
{ {
int ret = -1; int ret = -1;
@ -627,77 +573,11 @@ export struct EntityManager
static if (OnUpdateOverloadNum != -1) static if (OnUpdateOverloadNum != -1)
{ {
//static if (!IsEmpty)
//{
/*static void callUpdate(ref CallData data)
{
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 (blocks == 1)
{
if (data.end)
entities_count = data.end;
else
entities_count = block.entities_count;
}
else
entities_count = block.entities_count;
if (entities_count > 0)
{
assert(entities_count <= block.entities_count
&& offset < block.entities_count);
assert(entities_count > offset);
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;
}
static if (hasMember!(Sys.EntitiesData, "job_id"))
{
input_data.job_id = cast(typeof(input_data.job_id)) data.job_id;
}
if(data.context) (*cast(void delegate(Sys.EntitiesData)*)data.context)(input_data);
else s.onUpdate(input_data);
}
block = block.next_block;
offset = 0;
blocks--;
}
}*/
static void callUpdate(SystemCallData* data) static void callUpdate(SystemCallData* data)
{ {
Sys* s = cast(Sys*) data.system_pointer; Sys* s = cast(Sys*) data.context;
Sys.EntitiesData input_data; Sys.EntitiesData input_data;
// EntityInfo* info = data.block.type_info; //block.type_info;
//System* system = data.system;
static if (!IsEmpty)SystemData.fillInputData(input_data, data.info, data.block, data.begin, data.count);//, system); static if (!IsEmpty)SystemData.fillInputData(input_data, data.info, data.block, data.begin, data.count);//, system);
@ -714,46 +594,6 @@ export struct EntityManager
s.onUpdate(input_data); s.onUpdate(input_data);
} }
/*}
else
{*/
/*static void callUpdate(SystemCallData data)
{
Sys* s = cast(Sys*) data.system_pointer;
Sys.EntitiesData input_data;
static if (hasMember!(Sys.EntitiesData, "thread_id"))
{
input_data.thread_id = cast(typeof(input_data.thread_id)) data.thread_id;
}
static if (hasMember!(Sys.EntitiesData, "job_id"))
{
input_data.job_id = cast(typeof(input_data.job_id)) data.job_id;
}
s.onUpdate(input_data);
}*/
/*static void callUpdate(ref CallData data)
{
Sys* s = cast(Sys*) data.system.m_system_pointer;
Sys.EntitiesData input_data;
static if (hasMember!(Sys.EntitiesData, "thread_id"))
{
input_data.thread_id = cast(typeof(input_data.thread_id)) data.thread_id;
}
static if (hasMember!(Sys.EntitiesData, "job_id"))
{
input_data.job_id = cast(typeof(input_data.job_id)) data.job_id;
}
s.onUpdate(input_data);
}*/
// }
system.m_update = &callUpdate; system.m_update = &callUpdate;
} }
@ -797,7 +637,7 @@ export struct EntityManager
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;
SystemData.fillInputData(input_data, data.block.type_info, SystemData.fillInputData(input_data, data.block.type_info,
data.block, data.begin, data.end);//, data.system); data.block, data.begin, data.count);//, data.system);
static if (is(RetTyp == void)) static if (is(RetTyp == void))
mixin("s." ~ func_name ~ "(input_data)"); mixin("s." ~ func_name ~ "(input_data)");
else else
@ -852,18 +692,10 @@ export struct EntityManager
system.m_system_pointer = cast(void*) Mallocator.make!Sys; system.m_system_pointer = cast(void*) Mallocator.make!Sys;
system.m_priority = priority; system.m_priority = priority;
//(cast(Sys*) system.m_system_pointer).__ecsInitialize();
//system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs;
static if(__traits(hasMember, Sys ,"__becs_jobs_count"))system.jobs = Mallocator.makeArray!(Job)(Sys.__becs_jobs_count); static if(__traits(hasMember, Sys ,"__becs_jobs_count"))system.jobs = Mallocator.makeArray!(Job)(Sys.__becs_jobs_count);
else system.jobs = Mallocator.makeArray!(Job)(32); else system.jobs = Mallocator.makeArray!(Job)(32);
/*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);
foreach (iii, comp_info; components_info.readonlyDeps) foreach (iii, comp_info; components_info.readonlyDeps)
@ -985,8 +817,6 @@ export struct EntityManager
{ {
UpdatePass* pass = Mallocator.make!UpdatePass; UpdatePass* pass = Mallocator.make!UpdatePass;
pass.name = Mallocator.makeArray(cast(char[]) name); pass.name = Mallocator.makeArray(cast(char[]) name);
/*pass.name = Mallocator.makeArray!char(name.length);
pass.name[0..$] = name[0..$];*/
passes.add(pass); passes.add(pass);
passes_map.add(name, cast(ushort)(passes.length - 1)); passes_map.add(name, cast(ushort)(passes.length - 1));
return cast(ushort)(passes.length - 1); return cast(ushort)(passes.length - 1);
@ -1004,14 +834,7 @@ export struct EntityManager
{ {
ComponentInfo info; ComponentInfo info;
// enum ComponentName = fullyQualifiedName!Comp;
enum ComponentName = fullName!Comp; enum ComponentName = fullName!Comp;
// enum ComponentName = Comp.stringof;
// static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort))
// {
// static assert(0, "Add \"mixin ECS.Component;\" in top of component structure;");
// }
static if (hasMember!(Comp, "onDestroy") && isFunction!(Comp.onDestroy) static if (hasMember!(Comp, "onDestroy") && isFunction!(Comp.onDestroy)
&& is(ReturnType!(Comp.onDestroy) == void) && is(ReturnType!(Comp.onDestroy) == void)
@ -1044,21 +867,6 @@ export struct EntityManager
info.init_data = Mallocator.makeArray!ubyte(Comp.sizeof); info.init_data = Mallocator.makeArray!ubyte(Comp.sizeof);
*cast(Comp*) info.init_data.ptr = Comp.init; // = Comp(); *cast(Comp*) info.init_data.ptr = Comp.init; // = Comp();
/*ushort comp_id = components_map.get(cast(char[]) ComponentName, ushort.max);
if (comp_id < components.length)
{
becsID!Comp = comp_id;
if (components[comp_id].init_data)
Mallocator.dispose(components[comp_id].init_data);
components[comp_id] = info;
}
else
{
components.add(info);
becsID!Comp = cast(ushort)(components.length - 1);
char[] name = Mallocator.makeArray(cast(char[]) ComponentName);
components_map.add(name, cast(ushort)(components.length - 1));
}*/
becsID!Comp = registerComponent(ComponentName, info); becsID!Comp = registerComponent(ComponentName, info);
} }
@ -1121,6 +929,22 @@ export struct EntityManager
} }
} }
export ushort registerEvent(const (char)[] name, EventRegisterInfo refister_info)
{
EventInfo info;
info.size = refister_info.size;
info.alignment = refister_info.alignment;
ushort event_id = events_map.get(name, ushort.max);
if (event_id >= events.length)
{
events.add(info);
event_id = cast(ushort)(events.length - 1);
events_map.add(name, cast(ushort)(events.length - 1));
}
return event_id;
}
export void callEntitiesFunction(Sys, T)(T func) export void callEntitiesFunction(Sys, T)(T func)
{ {
//TODO: check if onUpdate function is good //TODO: check if onUpdate function is good
@ -1210,14 +1034,14 @@ export struct EntityManager
{ {
if (sys.m_empty) if (sys.m_empty)
{ {
CallData data = CallData(caller.system_id, sys, null, null, sys.m_update); CallData data = CallData(caller.system_id, sys, null, sys.m_system_pointer, sys.m_update);
data.update(); data.update();
} }
else else
foreach (info; caller.infos) foreach (info; caller.infos)
{ {
CallData data = CallData(caller.system_id, sys, info, CallData data = CallData(caller.system_id, sys, info,
null, sys.m_update); sys.m_system_pointer, sys.m_update);
data.update(); data.update();
} }
} }
@ -1263,7 +1087,7 @@ export struct EntityManager
if (sys.m_empty) if (sys.m_empty)
{ {
tmp_datas.add(CallData(caller.system_id, sys, null, null, sys.m_update)); tmp_datas.add(CallData(caller.system_id, sys, null, sys.m_system_pointer, sys.m_update));
nextJob(); nextJob();
caller.job_group.jobs = sys.jobs[0 .. 1]; caller.job_group.jobs = sys.jobs[0 .. 1];
(cast(void delegate(JobGroup) nothrow @nogc) m_dispatch_jobs)(caller.job_group); (cast(void delegate(JobGroup) nothrow @nogc) m_dispatch_jobs)(caller.job_group);
@ -1328,7 +1152,7 @@ export struct EntityManager
assert(entities_per_job == full_blocks_count * info.max_entities + entities_count + ( assert(entities_per_job == full_blocks_count * info.max_entities + entities_count + (
first_block.entities_count - first_elem)); first_block.entities_count - first_elem));
CallData data = CallData(caller.system_id, sys, CallData data = CallData(caller.system_id, sys,
info, null, sys.m_update, first_block, info, sys.m_system_pointer, sys.m_update, 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);
@ -1344,7 +1168,7 @@ export struct EntityManager
assert(last_elem > 0); assert(last_elem > 0);
assert(last_elem <= block.entities_count); assert(last_elem <= block.entities_count);
CallData data = CallData(caller.system_id, sys, CallData data = CallData(caller.system_id, sys,
info, null, sys.m_update, first_block, info, sys.m_system_pointer, sys.m_update, first_block,
cast(ushort)(full_blocks_count + 2), 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);
@ -1363,7 +1187,7 @@ export struct EntityManager
uint last_elem = entities_per_job - entities_count; uint last_elem = entities_per_job - entities_count;
assert(last_elem > 0); assert(last_elem > 0);
CallData data = CallData(caller.system_id, sys, CallData data = CallData(caller.system_id, sys,
info, null, sys.m_update, first_block, 1, info, sys.m_system_pointer, sys.m_update, 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;
@ -1383,7 +1207,7 @@ export struct EntityManager
else else
{ {
//take whole info blocks //take whole info blocks
CallData data = CallData(caller.system_id, sys, info, null, sys.m_update, CallData data = CallData(caller.system_id, sys, info, sys.m_system_pointer, sys.m_update,
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
@ -1997,7 +1821,7 @@ export struct EntityManager
{ {
if (!new_info.systems[listener]) if (!new_info.systems[listener])
{ {
callRemoveEntityListener(&systems[listener], info, block, ind, ind + 1); callRemoveEntityListener(&systems[listener], info, block, ind, 1);
} }
} }
} }
@ -2022,7 +1846,7 @@ export struct EntityManager
if (!info.systems[listener]) if (!info.systems[listener])
{ {
callAddEntityListener(&systems[listener], new_info, new_block, callAddEntityListener(&systems[listener], new_info, new_block,
new_block.entities_count - 1, new_block.entities_count); new_block.entities_count - 1, 1);
} }
} }
} }
@ -2034,7 +1858,7 @@ export struct EntityManager
if (info.systems[listener]) if (info.systems[listener])
{ {
callChangeEntityListener(&systems[listener], new_info, new_block, callChangeEntityListener(&systems[listener], new_info, new_block,
new_block.entities_count - 1, new_block.entities_count, del_ids); new_block.entities_count - 1, 1, del_ids);
} }
} }
} }
@ -2140,7 +1964,7 @@ export struct EntityManager
{ {
if (!new_info.systems[listener]) if (!new_info.systems[listener])
{ {
callRemoveEntityListener(&systems[listener], info, block, ind, ind + 1); callRemoveEntityListener(&systems[listener], info, block, ind, 1);
} }
} }
} }
@ -2185,7 +2009,7 @@ export struct EntityManager
if (!info.systems[listener]) if (!info.systems[listener])
{ {
callAddEntityListener(&systems[listener], new_info, new_block, callAddEntityListener(&systems[listener], new_info, new_block,
new_block.entities_count - 1, new_block.entities_count); new_block.entities_count - 1, 1);
} }
} }
} }
@ -2197,7 +2021,7 @@ export struct EntityManager
if (info.systems[listener]) if (info.systems[listener])
{ {
callChangeEntityListener(&systems[listener], new_info, new_block, callChangeEntityListener(&systems[listener], new_info, new_block,
new_block.entities_count - 1, new_block.entities_count, new_ids); new_block.entities_count - 1, 1, new_ids);
} }
} }
} }
@ -2523,7 +2347,7 @@ export struct EntityManager
{ {
uint pos = block.entityIndex(entity); uint pos = block.entityIndex(entity);
callRemoveEntityListeners(info, block, pos, pos + 1); callRemoveEntityListeners(info, block, pos, 1);
} }
id_manager.releaseID(id); //release id from manager id_manager.releaseID(id); //release id from manager
@ -2654,49 +2478,51 @@ export struct EntityManager
return has_work; return has_work;
} }
private void callAddEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow private void callAddEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin, int count) @nogc nothrow
{ {
foreach (listener; info.add_listeners) foreach (listener; info.add_listeners)
{ {
System* system = &systems[listener]; System* system = &systems[listener];
callAddEntityListener(system, info, block, begin, end); callAddEntityListener(system, info, block, begin, count);
} }
} }
private static void callAddEntityListener(System* system, EntityInfo* info, private static void callAddEntityListener(System* system, EntityInfo* info,
EntitiesBlock* block, int begin, int end) @nogc nothrow EntitiesBlock* block, int begin, int count) @nogc nothrow
{ {
ListenerCallData data; ListenerCallData data;
data.system = system; data.system = system;
data.block = block; data.block = block;
data.begin = begin; data.begin = begin;
data.end = end; data.count = count;
data.info = block.type_info;
(cast(void function(ref ListenerCallData) nothrow @nogc) system.m_add_entity)(data); (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_add_entity)(data);
} }
private void callRemoveEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin, private void callRemoveEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin,
int end) @nogc nothrow int count) @nogc nothrow
{ {
foreach (listener; info.remove_listeners) foreach (listener; info.remove_listeners)
{ {
System* system = &systems[listener]; System* system = &systems[listener];
callRemoveEntityListener(system, info, block, begin, end); callRemoveEntityListener(system, info, block, begin, count);
} }
} }
private static void callRemoveEntityListener(System* system, private static void callRemoveEntityListener(System* system,
EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow EntityInfo* info, EntitiesBlock* block, int begin, int count) @nogc nothrow
{ {
ListenerCallData data; ListenerCallData data;
data.system = system; data.system = system;
data.block = block; data.block = block;
data.begin = begin; data.begin = begin;
data.end = end; data.count = count;
data.info = block.type_info;
(cast(void function(ref ListenerCallData) nothrow @nogc) system.m_remove_entity)(data); (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_remove_entity)(data);
} }
private void callChangeEntityListener(System* system, EntityInfo* info, private void callChangeEntityListener(System* system, EntityInfo* info,
EntitiesBlock* block, int begin, int end, ushort[] ch_ids) @nogc nothrow EntitiesBlock* block, int begin, int count, ushort[] ch_ids) @nogc nothrow
{ {
int i = 0; int i = 0;
int j = 0; int j = 0;
@ -2728,7 +2554,8 @@ export struct EntityManager
data.system = system; data.system = system;
data.block = block; data.block = block;
data.begin = begin; data.begin = begin;
data.end = end; data.count = count;
data.info = block.type_info;
(cast(void function(ref ListenerCallData) nothrow @nogc) system.m_change_entity)(data); (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_change_entity)(data);
} }
@ -2771,7 +2598,7 @@ export struct EntityManager
if (info.add_listeners) if (info.add_listeners)
{ {
callAddEntityListeners(info, block, entities_count, block.entities_count); callAddEntityListeners(info, block, entities_count, block.entities_count - entities_count);
} }
} }
@ -2947,6 +2774,11 @@ export struct EntityManager
event_manager.sendEvent(id, event, threadID); event_manager.sendEvent(id, event, threadID);
} }
void sendEvent(EntityID id, EventRef event) nothrow @nogc
{
event_manager.sendEvent(id, event, threadID);
}
private void generateDependencies() nothrow @nogc private void generateDependencies() nothrow @nogc
{ {
foreach (pass_id, pass; passes) foreach (pass_id, pass; passes)
@ -3147,19 +2979,25 @@ export struct EntityManager
struct EventCallData struct EventCallData
{ {
EntitiesBlock* block;
void* system_pointer;
void* event;
Entity* entity; Entity* entity;
void* event;
void* system_pointer;
ushort id; ushort id;
EntitiesBlock* block;
} }
struct EventInfo struct EventInfo
{ {
ushort size; ushort size;
ushort alignment; ushort alignment;
EventCaller[] callers;
void function(void* pointer) nothrow @nogc destroy_callback; void function(void* pointer) nothrow @nogc destroy_callback;
EventCaller[] callers;
}
struct EventRegisterInfo
{
ushort size;
ushort alignment;
} }
/************************************************************************************************************************ /************************************************************************************************************************
@ -3418,7 +3256,7 @@ export struct EntityManager
else else
blocks = uint.max; blocks = uint.max;
SystemCallData call_data = SystemCallData(0, thread_id, job_id, system.m_system_pointer, context, info); SystemCallData call_data = SystemCallData(0, thread_id, job_id, context, info);
while (block !is null && blocks > 0) while (block !is null && blocks > 0)
{ {
@ -3451,7 +3289,7 @@ export struct EntityManager
} }
else else
{ {
SystemCallData call_data = SystemCallData(0, thread_id, job_id, system.m_system_pointer, context, info); SystemCallData call_data = SystemCallData(0, thread_id, job_id, context, info);
(cast(void function(SystemCallData*) @nogc nothrow) update_func)(&call_data); (cast(void function(SystemCallData*) @nogc nothrow) update_func)(&call_data);
} }
} }
@ -3492,7 +3330,6 @@ export struct EntityManager
uint count; uint count;
uint thread_id; uint thread_id;
uint job_id; uint job_id;
void* system_pointer;
void* context; void* context;
EntityInfo* info; EntityInfo* info;
EntitiesBlock* block; EntitiesBlock* block;
@ -3501,10 +3338,11 @@ export struct EntityManager
struct ListenerCallData struct ListenerCallData
{ {
uint count;
System* system; System* system;
EntityInfo* info;
EntitiesBlock* block; EntitiesBlock* block;
uint begin; uint begin;
uint end;
} }
struct Job struct Job
@ -3814,7 +3652,6 @@ struct SystemEntityData(Sys)
string name; string name;
static if (isArray!MemberType) static if (isArray!MemberType)
{ // Workaround. This code is never called with: not an array type, but compiler prints an error { // Workaround. This code is never called with: not an array type, but compiler prints an error
// name = fullyQualifiedName!(Unqual!(ForeachType!MemberType));//.stringof;
name = fullName!(Unqual!(ForeachType!MemberType)); name = fullName!(Unqual!(ForeachType!MemberType));
} }
@ -4014,9 +3851,7 @@ struct SystemEntityData(Sys)
string name; string name;
static if (isArray!MemberType) static if (isArray!MemberType)
{ // Workaround. This code is never called with: not an array type, but compiler prints an error { // Workaround. This code is never called with: not an array type, but compiler prints an error
// name = fullyQualifiedName!(Unqual!(ForeachType!MemberType));
name = fullName!(Unqual!(ForeachType!MemberType)); name = fullName!(Unqual!(ForeachType!MemberType));
//name = Unqual!(ForeachType!MemberType).stringof;
} }
bool is_optional; bool is_optional;

View file

@ -648,6 +648,8 @@ unittest
void onAddEntity(EntitiesData data) void onAddEntity(EntitiesData data)
{ {
foreach(i; 0..data.length)
data.long_[i] += 1;
add++; add++;
assert(add_order == 1); assert(add_order == 1);
add_order++; add_order++;

View file

@ -283,13 +283,13 @@ struct ChangeTestSystem
bool onBegin() bool onBegin()
{ {
////writeln("On Test System begin."); // writeln("On Test System begin.");
return true; return true;
} }
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)
@ -307,10 +307,10 @@ struct ChangeTestSystem
void onUpdate(EntitiesData data) void onUpdate(EntitiesData data)
{ {
foreach (i; 0 .. data.length) /*foreach (i; 0 .. data.length)
{ {
} }*/
} }
} }
@ -318,6 +318,8 @@ struct TestSystem
{ {
mixin ECS.System!16; //__gshared ushort system_id; mixin ECS.System!16; //__gshared ushort system_id;
uint print = 1;
void onCreate() void onCreate()
{ {
//writeln("On Test System create."); //writeln("On Test System create.");
@ -343,13 +345,14 @@ struct TestSystem
bool onBegin() bool onBegin()
{ {
////writeln("On Test System begin."); if(print)printf("On Test System begin.\n");
return true; return true;
} }
void onEnd() void onEnd()
{ {
////writeln("On Test System end."); if(print)printf("On Test System end.\n");
print = 0;
} }
void initialize(ref Entity entity, ref TestComp comp) void initialize(ref Entity entity, ref TestComp comp)
@ -406,7 +409,7 @@ struct TestSystemWithHighPriority
void initialize(ref Entity entity, ref TestComp comp) void initialize(ref Entity entity, ref TestComp comp)
{ {
int o = 1;
} }
void onUpdate(EntitiesData data) void onUpdate(EntitiesData data)
@ -844,6 +847,7 @@ else:
//dur = (MonoTime.currTime - time).total!"usecs"; //dur = (MonoTime.currTime - time).total!"usecs";
//writeln("Entities adding: ", dur, " usecs"); //writeln("Entities adding: ", dur, " usecs");
printf("Entities adding: %f usecs\n", cast(float)(Time.getUSecTime() - time)); printf("Entities adding: %f usecs\n", cast(float)(Time.getUSecTime() - time));
Mallocator.dispose(idss);
time = Time.getUSecTime(); time = Time.getUSecTime();
uint blocks = 0; uint blocks = 0;
@ -1021,8 +1025,6 @@ else:
gEntityManager.freeTemplate(copy_default_tempalte); gEntityManager.freeTemplate(copy_default_tempalte);
EntityManager.destroy(); EntityManager.destroy();
Mallocator.dispose(idss);
printf("end\n"); //*/ printf("end\n"); //*/
return 0; return 0;