-add ecsID template function (get Component/System/Event ID, passes tests)

-removed some ECS mixins code
This commit is contained in:
Mergul 2020-09-29 18:41:31 +02:00
parent 13c82acad4
commit a926b79223
9 changed files with 138 additions and 123 deletions

View file

@ -53,6 +53,7 @@ module bubel.ecs.core;
public import bubel.ecs.manager;
public import bubel.ecs.entity;
public import bubel.ecs.traits : ecsID;
/************************************************************************************************************************
Main struct used as namespace for templates.
@ -60,12 +61,12 @@ Main struct used as namespace for templates.
static struct ECS
{
/************************************************************************************************************************
Mark structure as System. Should be added on top of structure (before any data).
Set default system parameters (number of parallel jobs)
*/
mixin template System(uint jobs_count = 32)
{
__gshared ushort system_id = ushort.max;
uint __ecs_jobs_count = jobs_count;
// __gshared ushort system_id = ushort.max;
__gshared uint __ecs_jobs_count = jobs_count;
}
/************************************************************************************************************************
@ -73,21 +74,21 @@ static struct ECS
*/
mixin template Component()
{
__gshared ushort component_id = ushort.max;
//__gshared ushort component_id = ushort.max;
ComponentRef ref_() @nogc nothrow return
{
return ComponentRef(&this, component_id);
return ComponentRef(&this, ecsID!(typeof(this)));
}
}
/************************************************************************************************************************
Mark structure as Event. Should be added on top of structure (before any data).
*/
mixin template Event()
{
__gshared ushort event_id = ushort.max;
}
// mixin template Event()
// {
// __gshared ushort event_id = ushort.max;
// }
/************************************************************************************************************************
Make list of excluded components. This template get structure types as argument. Should be added inside System structure.

View file

@ -8,6 +8,7 @@ module bubel.ecs.entity;
import bubel.ecs.system;
import bubel.ecs.manager;
import bubel.ecs.traits : ecsID;
/************************************************************************************************************************
Entity ID structure. Used as reference to Entity. Pointer to entity should be ever used to store entity reference!
@ -40,7 +41,7 @@ struct Entity
return null;
return cast(T*)(cast(void*)block + info.deltas[T.component_id] + block.entityIndex(&this) * T.sizeof);*/
return cast(T*)getComponent(T.component_id);
return cast(T*)getComponent(ecsID!T);
}
void* getComponent(ushort component_id) const
@ -81,7 +82,7 @@ struct EntityMeta
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
return null;
return cast(T*)(cast(void*)block + info.deltas[T.component_id] + index * T.sizeof);*/
return cast(T*)getComponent(T.component_id);
return cast(T*)getComponent(ecsID!T);
}
void* getComponent(ushort component_id) const
@ -125,8 +126,8 @@ export struct EntityTemplate
*/
T* getComponent(T)() nothrow @nogc
{
if(T.component_id >= info.tmpl_deltas.length || info.tmpl_deltas[T.component_id] == ushort.max)return null;
return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]);
if(ecsID!T >= info.tmpl_deltas.length || info.tmpl_deltas[ecsID!T] == ushort.max)return null;
return cast(T*)(entity_data.ptr + info.tmpl_deltas[ecsID!T]);
}
}

View file

@ -4,6 +4,7 @@ import bubel.ecs.block_allocator;
import bubel.ecs.entity;
import bubel.ecs.manager;
import bubel.ecs.std;
import bubel.ecs.traits : ecsID;
import std.algorithm.comparison : max;
@ -32,7 +33,7 @@ package struct EventManager
{
uint block_id = current_index + thread_id;
EventData* data = &events[Ev.event_id];
EventData* data = &events[ecsID!Ev];
EventBlock* block = data.blocks[block_id];
//EntityManager.EventInfo* info = &manager.events[Ev.event_id];
//event.entity_id = id;

View file

@ -367,10 +367,10 @@ export struct EntityManager
System system;
system.m_pass = pass;
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, "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")))
{
@ -408,7 +408,7 @@ export struct EntityManager
~ "\" due to non existing event \"" ~ EventName ~ "\".");
callers[i].callback = cast(void*)&callEventHandler!(EventParamType);
callers[i].id = EventParamType.event_id;
callers[i].id = ecsID!EventParamType;
i++;
}
}
@ -1125,8 +1125,8 @@ export struct EntityManager
system.m_priority = priority;
//(cast(Sys*) system.m_system_pointer).__ecsInitialize();
//system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs;
system.jobs = Mallocator.makeArray!(Job)((cast(Sys*) system.m_system_pointer)
.__ecs_jobs_count);
static if(__traits(hasMember, Sys ,"__ecs_jobs_count"))system.jobs = Mallocator.makeArray!(Job)(Sys.__ecs_jobs_count);
else system.jobs = Mallocator.makeArray!(Job)(32);
static if (OnUpdateOverloadNum != -1)
{
@ -1194,7 +1194,7 @@ export struct EntityManager
systems[$ - 1].enable();
}
Sys.system_id = system.id;
ecsID!Sys = system.id;
}
/************************************************************************************************************************
@ -1212,9 +1212,9 @@ export struct EntityManager
*/
Sys* getSystem(Sys)() nothrow @nogc
{
if (Sys.system_id >= systems.length)
if (ecsID!Sys >= systems.length)
return null;
return cast(Sys*) systems[Sys.system_id].m_system_pointer;
return cast(Sys*) systems[ecsID!Sys].m_system_pointer;
}
export ushort registerPass(const(char)[] name)
@ -1244,10 +1244,10 @@ export struct EntityManager
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, "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)
&& is(ReturnType!(Comp.onDestroy) == void)
@ -1283,7 +1283,7 @@ export struct EntityManager
ushort comp_id = components_map.get(cast(char[]) ComponentName, ushort.max);
if (comp_id < components.length)
{
Comp.component_id = comp_id;
ecsID!Comp = comp_id;
if (components[comp_id].init_data)
Mallocator.dispose(components[comp_id].init_data);
components[comp_id] = info;
@ -1291,7 +1291,7 @@ export struct EntityManager
else
{
components.add(info);
Comp.component_id = cast(ushort)(components.length - 1);
ecsID!Comp = cast(ushort)(components.length - 1);
char[] name = Mallocator.makeArray(cast(char[]) ComponentName);
components_map.add(name, cast(ushort)(components.length - 1));
}
@ -1301,10 +1301,10 @@ export struct EntityManager
{
EventInfo info;
static if (!(hasMember!(Ev, "event_id")) || !is(typeof(Ev.event_id) == ushort))
{
static assert(0, "Add \"mixin ECS.Event;\" in top of event structure;");
}
// static if (!(hasMember!(Ev, "event_id")) || !is(typeof(Ev.event_id) == ushort))
// {
// static assert(0, "Add \"mixin ECS.Event;\" in top of event structure;");
// }
static if (hasMember!(Ev, "onDestroy") && isFunction!(Ev.onDestroy)
&& is(ReturnType!(Ev.onDestroy) == void) && Parameters!(Ev.onDestroy).length == 0)
@ -1324,12 +1324,12 @@ export struct EntityManager
ushort event_id = events_map.get(fullName!Ev, ushort.max);
if (event_id < events.length)
{
Ev.event_id = event_id;
ecsID!Ev = event_id;
}
else
{
events.add(info);
Ev.event_id = cast(ushort)(events.length - 1);
ecsID!Ev = cast(ushort)(events.length - 1);
// events_map.add(Ev.stringof, cast(ushort)(events.length - 1));
events_map.add(fullName!Ev, cast(ushort)(events.length - 1));
}
@ -1348,9 +1348,9 @@ export struct EntityManager
// static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate),
// functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)),
// "Function must match system update function."); FIXME: It's lead to crash on android build
static assert(__traits(hasMember, Sys, "system_id"), "Sys must be system type.");
// static assert(__traits(hasMember, Sys, "system_id"), "Sys must be system type.");
System* system = getSystem(Sys.system_id);
System* system = getSystem(ecsID!Sys);
assert(system != null,
"System must be registered in EntityManager before any funcion can be called.");
if (!system.m_any_system_caller)
@ -2256,7 +2256,7 @@ export struct EntityManager
ushort[num] del_ids;
static foreach (i, comp; Components)
{
del_ids[i] = comp.component_id;
del_ids[i] = ecsID!comp;
}
removeComponents(entity_id, del_ids);

View file

@ -2,6 +2,18 @@ module bubel.ecs.traits;
import std.traits;
ref ushort ecsID(T)()
{
__gshared ushort id = ushort.max;
return id;
}
ref ushort ecsID(T)(T obj)
{
static if(isPointer!T)return ecsID!(PointerTarget!T);
else return ecsID!T;
}
bool isForeachDelegateWithTypes(DG, Types...)()
{
return is(DG == delegate) && is(ReturnType!DG == int) && is(Parameters!DG == Types);