-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 core.stdc.string;
|
||||
import core.stdc.stdlib;
|
||||
|
||||
import ecs.system;
|
||||
import ecs.entity;
|
||||
|
|
@ -34,6 +35,8 @@ class EntityManager
|
|||
{
|
||||
alias types = Parameters!(Sys.update);
|
||||
|
||||
System system;
|
||||
|
||||
static string genCall()()
|
||||
{
|
||||
string ret = "s.update(";
|
||||
|
|
@ -57,46 +60,67 @@ class EntityManager
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void callUpdate(ref CallData data, void* entity)
|
||||
{
|
||||
static if (hasMember!(Sys, "update"))
|
||||
{
|
||||
Sys* s = cast(Sys*) data.system.system_pointer;
|
||||
|
||||
EntitiesBlock* block = data.info.first_block;
|
||||
while (block !is null)
|
||||
{
|
||||
void* data_pointer = block.dataBegin();
|
||||
foreach (i; 0 .. block.entities_count)
|
||||
{
|
||||
mixin(genCall());
|
||||
data_pointer += data.info.size;
|
||||
}
|
||||
block = block.next_block;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
System system;
|
||||
static if (hasMember!(Sys, "update"))
|
||||
{
|
||||
static void callUpdate(ref CallData data, void* entity)
|
||||
{
|
||||
static if (hasMember!(Sys, "update"))
|
||||
{
|
||||
Sys* s = cast(Sys*) data.system.system_pointer;
|
||||
|
||||
EntitiesBlock* block = data.info.first_block;
|
||||
while (block !is null)
|
||||
{
|
||||
void* data_pointer = block.dataBegin();
|
||||
foreach (i; 0 .. block.entities_count)
|
||||
{
|
||||
mixin(genCall());
|
||||
data_pointer += data.info.size;
|
||||
}
|
||||
block = block.next_block;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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.components = Mallocator.instance.makeArray!uint(types.length);
|
||||
mixin(genCompList());
|
||||
|
||||
if (systems is null)
|
||||
systems.add(system);
|
||||
systems[$ - 1].enable();
|
||||
|
||||
foreach (info; &entities_infos.byValue)
|
||||
{
|
||||
systems = Mallocator.instance.makeArray!System(1);
|
||||
systems[0] = system;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mallocator.instance.expandArray(systems, 1);
|
||||
systems[$ - 1] = system;
|
||||
addEntityCaller(*info, systems[$ - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,17 +131,7 @@ class EntityManager
|
|||
info.size = size;
|
||||
info.aligment = Comp.alignof; //8;
|
||||
|
||||
if (components is null)
|
||||
{
|
||||
components = Mallocator.instance.makeArray!ComponentInfo(1);
|
||||
components[0] = info;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mallocator.instance.expandArray(components, 1);
|
||||
components[$ - 1] = info;
|
||||
}
|
||||
|
||||
components.add(info);
|
||||
components_map.add(Comp.stringof, cast(uint)(components.length - 1));
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +141,8 @@ class EntityManager
|
|||
{
|
||||
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)
|
||||
continue;
|
||||
CallData call_data = CallData(&system, info, null);
|
||||
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);
|
||||
addEntityCaller(*info, system);
|
||||
}
|
||||
|
||||
entities_infos.add(info.components, info);
|
||||
|
|
@ -188,6 +190,35 @@ class EntityManager
|
|||
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_)
|
||||
{
|
||||
Mallocator.instance.dispose(template_.entity_data);
|
||||
|
|
@ -204,7 +235,8 @@ class EntityManager
|
|||
{
|
||||
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);
|
||||
if (previous_block is null)
|
||||
{
|
||||
|
|
@ -231,19 +263,12 @@ class EntityManager
|
|||
|
||||
void* start = block.dataBegin() + block.entities_count * tmpl.info.size;
|
||||
memcpy(start, tmpl.entity_data.ptr, tmpl.info.size);
|
||||
Entity* entity = cast(Entity*)start;
|
||||
Entity* entity = cast(Entity*) start;
|
||||
entity.id = id_manager.getNewID();
|
||||
entity.updateID();
|
||||
block.entities_count++;
|
||||
}
|
||||
|
||||
struct CallData
|
||||
{
|
||||
System* system;
|
||||
EntityInfo* info;
|
||||
ushort[] deltas;
|
||||
}
|
||||
|
||||
struct ComponentInfo
|
||||
{
|
||||
ushort size;
|
||||
|
|
@ -283,17 +308,24 @@ class EntityManager
|
|||
///there is a loooot of data (4kB, pure magic)
|
||||
}
|
||||
|
||||
enum page_size = 4096;
|
||||
enum pages_in_block = 128;
|
||||
struct CallData
|
||||
{
|
||||
System* system;
|
||||
EntityManager.EntityInfo* info;
|
||||
ushort[] deltas;
|
||||
}
|
||||
|
||||
alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity);
|
||||
|
||||
enum page_size = 4096;
|
||||
enum pages_in_block = 128;
|
||||
|
||||
IDManager id_manager;
|
||||
|
||||
HashMap!(ushort[], EntityInfo*) entities_infos;
|
||||
HashMap!(string, uint) components_map;
|
||||
System[] systems;
|
||||
ComponentInfo[] components;
|
||||
Vector!System systems;
|
||||
Vector!ComponentInfo components;
|
||||
__gshared EntityManager instance;
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue