-add systemCaller to entity only if their components matches
-System onEnable() and onDisable() callbacks
This commit is contained in:
parent
22fdd2f4e4
commit
ae53e13d42
4 changed files with 152 additions and 78 deletions
|
|
@ -7,6 +7,7 @@ import std.algorithm : max;
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
|
|
||||||
import core.stdc.string;
|
import core.stdc.string;
|
||||||
|
import core.stdc.stdlib;
|
||||||
|
|
||||||
import ecs.system;
|
import ecs.system;
|
||||||
import ecs.entity;
|
import ecs.entity;
|
||||||
|
|
@ -34,6 +35,8 @@ class EntityManager
|
||||||
{
|
{
|
||||||
alias types = Parameters!(Sys.update);
|
alias types = Parameters!(Sys.update);
|
||||||
|
|
||||||
|
System system;
|
||||||
|
|
||||||
static string genCall()()
|
static string genCall()()
|
||||||
{
|
{
|
||||||
string ret = "s.update(";
|
string ret = "s.update(";
|
||||||
|
|
@ -57,6 +60,8 @@ class EntityManager
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static if (hasMember!(Sys, "update"))
|
||||||
|
{
|
||||||
static void callUpdate(ref CallData data, void* entity)
|
static void callUpdate(ref CallData data, void* entity)
|
||||||
{
|
{
|
||||||
static if (hasMember!(Sys, "update"))
|
static if (hasMember!(Sys, "update"))
|
||||||
|
|
@ -78,25 +83,44 @@ class EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System system;
|
|
||||||
static if (hasMember!(Sys, "update"))
|
|
||||||
{
|
|
||||||
system.update = &callUpdate;
|
system.update = &callUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static if (hasMember!(Sys, "onEnable"))
|
||||||
|
{
|
||||||
|
static void callEnable(void* system_pointer)
|
||||||
|
{
|
||||||
|
|
||||||
|
Sys* s = cast(Sys*) system_pointer;
|
||||||
|
s.onEnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
system.m_enable = &callEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static if (hasMember!(Sys, "onDisable"))
|
||||||
|
{
|
||||||
|
static void callDisable(void* system_pointer)
|
||||||
|
{
|
||||||
|
|
||||||
|
Sys* s = cast(Sys*) system_pointer;
|
||||||
|
s.onDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
system.m_disable = &callDisable;
|
||||||
|
}
|
||||||
|
|
||||||
system.system_pointer = cast(void*) Mallocator.instance.make!Sys;
|
system.system_pointer = cast(void*) Mallocator.instance.make!Sys;
|
||||||
|
|
||||||
system.components = Mallocator.instance.makeArray!uint(types.length);
|
system.components = Mallocator.instance.makeArray!uint(types.length);
|
||||||
mixin(genCompList());
|
mixin(genCompList());
|
||||||
|
|
||||||
if (systems is null)
|
systems.add(system);
|
||||||
|
systems[$ - 1].enable();
|
||||||
|
|
||||||
|
foreach (info; &entities_infos.byValue)
|
||||||
{
|
{
|
||||||
systems = Mallocator.instance.makeArray!System(1);
|
addEntityCaller(*info, systems[$ - 1]);
|
||||||
systems[0] = system;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Mallocator.instance.expandArray(systems, 1);
|
|
||||||
systems[$ - 1] = system;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,17 +131,7 @@ class EntityManager
|
||||||
info.size = size;
|
info.size = size;
|
||||||
info.aligment = Comp.alignof; //8;
|
info.aligment = Comp.alignof; //8;
|
||||||
|
|
||||||
if (components is null)
|
components.add(info);
|
||||||
{
|
|
||||||
components = Mallocator.instance.makeArray!ComponentInfo(1);
|
|
||||||
components[0] = info;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Mallocator.instance.expandArray(components, 1);
|
|
||||||
components[$ - 1] = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
components_map.add(Comp.stringof, cast(uint)(components.length - 1));
|
components_map.add(Comp.stringof, cast(uint)(components.length - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,7 +141,8 @@ class EntityManager
|
||||||
{
|
{
|
||||||
foreach (data; info.callers)
|
foreach (data; info.callers)
|
||||||
{
|
{
|
||||||
data.system.update(data, null); //caller(call_data,null);
|
if (data.system.enabled)
|
||||||
|
(cast(SytemFuncType) data.system.update)(data, null); //caller(call_data,null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -163,20 +178,7 @@ class EntityManager
|
||||||
{
|
{
|
||||||
if (system.update is null)
|
if (system.update is null)
|
||||||
continue;
|
continue;
|
||||||
CallData call_data = CallData(&system, info, null);
|
addEntityCaller(*info, system);
|
||||||
call_data.deltas = Mallocator.instance.makeArray!ushort(system.components.length);
|
|
||||||
foreach (i, id; system.components)
|
|
||||||
{
|
|
||||||
foreach (i2, id2; info.components)
|
|
||||||
{
|
|
||||||
if (id2 == id)
|
|
||||||
{
|
|
||||||
call_data.deltas[i] = info.deltas[i2];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
info.callers.add(call_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entities_infos.add(info.components, info);
|
entities_infos.add(info.components, info);
|
||||||
|
|
@ -188,6 +190,35 @@ class EntityManager
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addEntityCaller(ref EntityInfo entity, ref System system)
|
||||||
|
{
|
||||||
|
CallData call_data = CallData(&system, &entity, null);
|
||||||
|
ushort[] deltas = (cast(ushort*) alloca(system.components.length * ushort.sizeof))[0
|
||||||
|
.. system.components.length];
|
||||||
|
foreach (i, id; system.components)
|
||||||
|
{
|
||||||
|
deltas[i] = ushort.max;
|
||||||
|
foreach (i2, id2; entity.components)
|
||||||
|
{
|
||||||
|
if (id2 == id)
|
||||||
|
{
|
||||||
|
deltas[i] = entity.deltas[i2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (deltas[i] == ushort.max)
|
||||||
|
{
|
||||||
|
deltas = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (deltas)
|
||||||
|
{
|
||||||
|
call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.components.length);
|
||||||
|
entity.callers.add(call_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void freeTemplate(EntityTemplate* template_)
|
void freeTemplate(EntityTemplate* template_)
|
||||||
{
|
{
|
||||||
Mallocator.instance.dispose(template_.entity_data);
|
Mallocator.instance.dispose(template_.entity_data);
|
||||||
|
|
@ -204,7 +235,8 @@ class EntityManager
|
||||||
{
|
{
|
||||||
if (block is null)
|
if (block is null)
|
||||||
{
|
{
|
||||||
block = cast(EntitiesBlock*) AlignedMallocator.instance.alignedAllocate(page_size, page_size);
|
block = cast(EntitiesBlock*) AlignedMallocator.instance.alignedAllocate(page_size,
|
||||||
|
page_size);
|
||||||
*block = EntitiesBlock(tmpl.info);
|
*block = EntitiesBlock(tmpl.info);
|
||||||
if (previous_block is null)
|
if (previous_block is null)
|
||||||
{
|
{
|
||||||
|
|
@ -237,13 +269,6 @@ class EntityManager
|
||||||
block.entities_count++;
|
block.entities_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CallData
|
|
||||||
{
|
|
||||||
System* system;
|
|
||||||
EntityInfo* info;
|
|
||||||
ushort[] deltas;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ComponentInfo
|
struct ComponentInfo
|
||||||
{
|
{
|
||||||
ushort size;
|
ushort size;
|
||||||
|
|
@ -283,17 +308,24 @@ class EntityManager
|
||||||
///there is a loooot of data (4kB, pure magic)
|
///there is a loooot of data (4kB, pure magic)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum page_size = 4096;
|
struct CallData
|
||||||
enum pages_in_block = 128;
|
{
|
||||||
|
System* system;
|
||||||
|
EntityManager.EntityInfo* info;
|
||||||
|
ushort[] deltas;
|
||||||
|
}
|
||||||
|
|
||||||
alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity);
|
alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity);
|
||||||
|
|
||||||
|
enum page_size = 4096;
|
||||||
|
enum pages_in_block = 128;
|
||||||
|
|
||||||
IDManager id_manager;
|
IDManager id_manager;
|
||||||
|
|
||||||
HashMap!(ushort[], EntityInfo*) entities_infos;
|
HashMap!(ushort[], EntityInfo*) entities_infos;
|
||||||
HashMap!(string, uint) components_map;
|
HashMap!(string, uint) components_map;
|
||||||
System[] systems;
|
Vector!System systems;
|
||||||
ComponentInfo[] components;
|
Vector!ComponentInfo components;
|
||||||
__gshared EntityManager instance;
|
__gshared EntityManager instance;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
source/ecs/package.d
Normal file
7
source/ecs/package.d
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
module ecs;
|
||||||
|
|
||||||
|
public import ecs.manager;
|
||||||
|
public import ecs.entity;
|
||||||
|
public import ecs.system;
|
||||||
|
import ecs.id_manager;
|
||||||
|
import ecs.events;
|
||||||
|
|
@ -6,7 +6,7 @@ import ecs.manager;
|
||||||
struct System
|
struct System
|
||||||
{
|
{
|
||||||
///should system update and catch events?
|
///should system update and catch events?
|
||||||
bool enabled = true;
|
bool m_enabled = false;
|
||||||
///system priority
|
///system priority
|
||||||
int prority;
|
int prority;
|
||||||
///pointer to system implementation
|
///pointer to system implementation
|
||||||
|
|
@ -14,5 +14,26 @@ struct System
|
||||||
|
|
||||||
uint[] components;
|
uint[] components;
|
||||||
|
|
||||||
void function(ref EntityManager.CallData data, void* entity) update;
|
bool enabled()
|
||||||
|
{
|
||||||
|
return m_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enable()
|
||||||
|
{
|
||||||
|
if(!m_enabled && m_enable)m_enable(system_pointer);
|
||||||
|
m_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disable()
|
||||||
|
{
|
||||||
|
if(m_enabled && m_disable)m_disable(system_pointer);
|
||||||
|
m_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//void function(ref EntityManager.CallData data, void* entity) update;
|
||||||
|
void* update; ///workaroud for DMD bug with upper line
|
||||||
|
|
||||||
|
void function(void* system_pointer) m_enable;
|
||||||
|
void function(void* system_pointer) m_disable;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,18 @@ int main()
|
||||||
struct TestSystem2
|
struct TestSystem2
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void onEnable()
|
||||||
|
{
|
||||||
|
import std.stdio;
|
||||||
|
writeln("TestSystem2 enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDisable()
|
||||||
|
{
|
||||||
|
import std.stdio;
|
||||||
|
writeln("TestSystem2 disabled");
|
||||||
|
}
|
||||||
|
|
||||||
void initialize(ref TestComp comp)
|
void initialize(ref TestComp comp)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -102,15 +114,15 @@ int main()
|
||||||
gEM.registerComponent!TestComp;
|
gEM.registerComponent!TestComp;
|
||||||
|
|
||||||
ulong dur = (MonoTime.currTime - time).total!"usecs";
|
ulong dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
writeln("Components register time: ",dur," usecs");
|
writeln("Components register: ",dur," usecs");
|
||||||
|
|
||||||
time = MonoTime.currTime;
|
time = MonoTime.currTime;
|
||||||
|
|
||||||
gEM.registerSystem!TestSystem(0);
|
gEM.registerSystem!TestSystem(0);
|
||||||
gEM.registerSystem!TestSystem2(0);
|
//gEM.registerSystem!TestSystem2(0);
|
||||||
|
|
||||||
dur = (MonoTime.currTime - time).total!"usecs";
|
dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
writeln("System register time: ",dur," usecs");
|
writeln("Systems register: ",dur," usecs");
|
||||||
|
|
||||||
time = MonoTime.currTime;
|
time = MonoTime.currTime;
|
||||||
|
|
||||||
|
|
@ -119,7 +131,7 @@ int main()
|
||||||
*cast(EntityID*)tmpl.entity_data.ptr = EntityID(1,1);
|
*cast(EntityID*)tmpl.entity_data.ptr = EntityID(1,1);
|
||||||
|
|
||||||
dur = (MonoTime.currTime - time).total!"usecs";
|
dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
writeln("Template allocating time: ",dur," usecs");
|
writeln("Template allocating: ",dur," usecs");
|
||||||
|
|
||||||
time = MonoTime.currTime;
|
time = MonoTime.currTime;
|
||||||
|
|
||||||
|
|
@ -128,6 +140,8 @@ int main()
|
||||||
dur = (MonoTime.currTime - time).total!"usecs";
|
dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
writeln("Entities adding: ",dur," usecs");
|
writeln("Entities adding: ",dur," usecs");
|
||||||
|
|
||||||
|
gEM.registerSystem!TestSystem2(0);
|
||||||
|
|
||||||
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1));
|
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1));
|
||||||
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1));
|
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1));
|
||||||
|
|
||||||
|
|
@ -136,10 +150,10 @@ int main()
|
||||||
gEM.update();
|
gEM.update();
|
||||||
|
|
||||||
dur = (MonoTime.currTime - time).total!"usecs";
|
dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
writeln("Update time: ",dur," usecs");
|
writeln("Update: ",dur," usecs");
|
||||||
|
|
||||||
import std.stdio;
|
//import std.stdio;
|
||||||
writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
//writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
||||||
gEM.freeTemplate(tmpl);
|
gEM.freeTemplate(tmpl);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue