Merge branch 'master' of https://gitlab.com/Mergul/bubel-ecs.git into Demos
This commit is contained in:
commit
1acd0df0ef
17 changed files with 332 additions and 293 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/************************************************************************************************************************
|
||||
This module contain main templates for user.
|
||||
There are three structure templates (mixins) which should be added on top of structure:
|
||||
This module contain main helper templates for user.
|
||||
There are three structure templates (mixins) which can be added on top of structure:
|
||||
$(LIST
|
||||
* System: make system structure
|
||||
* Component: make component structure
|
||||
|
|
@ -46,6 +46,26 @@ Struct System1
|
|||
}
|
||||
---
|
||||
|
||||
Templates ReadOnlyDependencies nad WritableDependencies are used to create list of dependencies for System.
|
||||
Writable dependencies are bloking parallel execution of system which has same dependency (as writable or readonly).
|
||||
This dependencies works same as Component dependencies but can be used for creating external dependencies (e.g. dependency on spatial partitioning tree access).
|
||||
|
||||
---
|
||||
enum ExternalDependency1 = "ExternalDependency1";
|
||||
|
||||
Struct System1
|
||||
{
|
||||
mixin!ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
... //used components
|
||||
}
|
||||
|
||||
ReadOnlyDependencies!(ExternalDependency1);
|
||||
}
|
||||
---
|
||||
|
||||
Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz
|
||||
License: BSD 3-clause, see LICENSE file in project root folder.
|
||||
*/
|
||||
|
|
@ -53,6 +73,7 @@ module bubel.ecs.core;
|
|||
|
||||
public import bubel.ecs.manager;
|
||||
public import bubel.ecs.entity;
|
||||
public import bubel.ecs.traits : becsID;
|
||||
|
||||
/************************************************************************************************************************
|
||||
Main struct used as namespace for templates.
|
||||
|
|
@ -60,33 +81,30 @@ 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 uint __becs_jobs_count = jobs_count;
|
||||
}
|
||||
|
||||
/************************************************************************************************************************
|
||||
Mark structure as Component. Should be added on top of structure (before any data).
|
||||
Mark structure as Component
|
||||
*/
|
||||
mixin template Component()
|
||||
{
|
||||
__gshared ushort component_id = ushort.max;
|
||||
|
||||
ComponentRef ref_() @nogc nothrow return
|
||||
{
|
||||
return ComponentRef(&this, component_id);
|
||||
return ComponentRef(&this, becsID!(typeof(this)));
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************************************************
|
||||
Mark structure as Event. Should be added on top of structure (before any data).
|
||||
Mark structure as Event
|
||||
*/
|
||||
mixin template Event()
|
||||
{
|
||||
__gshared ushort event_id = ushort.max;
|
||||
|
||||
}
|
||||
|
||||
/************************************************************************************************************************
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ module bubel.ecs.entity;
|
|||
|
||||
import bubel.ecs.system;
|
||||
import bubel.ecs.manager;
|
||||
public import bubel.ecs.traits : becsID;
|
||||
|
||||
/************************************************************************************************************************
|
||||
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(becsID!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(becsID!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(becsID!T >= info.tmpl_deltas.length || info.tmpl_deltas[becsID!T] == ushort.max)return null;
|
||||
return cast(T*)(entity_data.ptr + info.tmpl_deltas[becsID!T]);
|
||||
}
|
||||
|
||||
/************************************************************************************************************************
|
||||
|
|
|
|||
|
|
@ -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 : becsID;
|
||||
|
||||
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[becsID!Ev];
|
||||
EventBlock* block = data.blocks[block_id];
|
||||
//EntityManager.EventInfo* info = &manager.events[Ev.event_id];
|
||||
//event.entity_id = id;
|
||||
|
|
|
|||
|
|
@ -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 = becsID!EventParamType;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1153,8 +1153,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 ,"__becs_jobs_count"))system.jobs = Mallocator.makeArray!(Job)(Sys.__becs_jobs_count);
|
||||
else system.jobs = Mallocator.makeArray!(Job)(32);
|
||||
|
||||
static if (OnUpdateOverloadNum != -1)
|
||||
{
|
||||
|
|
@ -1222,7 +1222,7 @@ export struct EntityManager
|
|||
|
||||
systems[$ - 1].enable();
|
||||
}
|
||||
Sys.system_id = system.id;
|
||||
becsID!Sys = system.id;
|
||||
}
|
||||
|
||||
/************************************************************************************************************************
|
||||
|
|
@ -1240,9 +1240,9 @@ export struct EntityManager
|
|||
*/
|
||||
Sys* getSystem(Sys)() nothrow @nogc
|
||||
{
|
||||
if (Sys.system_id >= systems.length)
|
||||
if (becsID!Sys >= systems.length)
|
||||
return null;
|
||||
return cast(Sys*) systems[Sys.system_id].m_system_pointer;
|
||||
return cast(Sys*) systems[becsID!Sys].m_system_pointer;
|
||||
}
|
||||
|
||||
export ushort registerPass(const(char)[] name)
|
||||
|
|
@ -1272,10 +1272,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)
|
||||
|
|
@ -1311,7 +1311,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;
|
||||
becsID!Comp = comp_id;
|
||||
if (components[comp_id].init_data)
|
||||
Mallocator.dispose(components[comp_id].init_data);
|
||||
components[comp_id] = info;
|
||||
|
|
@ -1319,7 +1319,7 @@ export struct EntityManager
|
|||
else
|
||||
{
|
||||
components.add(info);
|
||||
Comp.component_id = cast(ushort)(components.length - 1);
|
||||
becsID!Comp = cast(ushort)(components.length - 1);
|
||||
char[] name = Mallocator.makeArray(cast(char[]) ComponentName);
|
||||
components_map.add(name, cast(ushort)(components.length - 1));
|
||||
}
|
||||
|
|
@ -1329,10 +1329,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)
|
||||
|
|
@ -1352,12 +1352,12 @@ export struct EntityManager
|
|||
ushort event_id = events_map.get(fullName!Ev, ushort.max);
|
||||
if (event_id < events.length)
|
||||
{
|
||||
Ev.event_id = event_id;
|
||||
becsID!Ev = event_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
events.add(info);
|
||||
Ev.event_id = cast(ushort)(events.length - 1);
|
||||
becsID!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));
|
||||
}
|
||||
|
|
@ -1376,9 +1376,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(becsID!Sys);
|
||||
assert(system != null,
|
||||
"System must be registered in EntityManager before any funcion can be called.");
|
||||
if (!system.m_any_system_caller)
|
||||
|
|
@ -2265,7 +2265,7 @@ export struct EntityManager
|
|||
ushort[num] del_ids;
|
||||
static foreach (i, comp; Components)
|
||||
{
|
||||
del_ids[i] = comp.component_id;
|
||||
del_ids[i] = becsID!comp;
|
||||
}
|
||||
|
||||
removeComponents(entity_id, del_ids);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,24 @@ module bubel.ecs.traits;
|
|||
|
||||
import std.traits;
|
||||
|
||||
/************************************************************************************************************************
|
||||
Return Component/System/Event unique ID
|
||||
*/
|
||||
ref ushort becsID(T)()
|
||||
{
|
||||
__gshared ushort id = ushort.max;
|
||||
return id;
|
||||
}
|
||||
|
||||
/************************************************************************************************************************
|
||||
Return Component/System/Event unique ID
|
||||
*/
|
||||
ref ushort becsID(T)(T obj)
|
||||
{
|
||||
static if(isPointer!T)return becsID!(PointerTarget!T);
|
||||
else return becsID!T;
|
||||
}
|
||||
|
||||
bool isForeachDelegateWithTypes(DG, Types...)()
|
||||
{
|
||||
return is(DG == delegate) && is(ReturnType!DG == int) && is(Parameters!DG == Types);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue