From 6217aec6be06ddd5c2c83254b2fa1756b5348661 Mon Sep 17 00:00:00 2001 From: DanielMz25 Date: Fri, 7 Sep 2018 20:54:29 +0200 Subject: [PATCH] -changed README -license changed to BSD (maybe temporary) -added configurations to dub.json -initial ECS implementation (WIP): -Manager, System, Entity, Component -registering components -registering systems -calling update --- .gitignore | 5 +- README.md | 2 + dub.json | 18 +++++- source/ecs/ecs.d | 10 ++- source/ecs/entity.d | 18 ++++++ source/ecs/entity_allocator.d | 15 +++-- source/ecs/events.d | 11 ++++ source/ecs/manager.d | 112 ++++++++++++++++++++++++++++++++++ source/ecs/system.d | 16 +++++ tests/tests.d | 69 +++++++++++++++++++++ 10 files changed, 265 insertions(+), 11 deletions(-) create mode 100644 source/ecs/entity.d create mode 100644 source/ecs/events.d create mode 100644 source/ecs/manager.d create mode 100644 source/ecs/system.d create mode 100644 tests/tests.d diff --git a/.gitignore b/.gitignore index 413e5fb..7cfa996 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,7 @@ perf.data perf.data.old *.o *.a -*.obj \ No newline at end of file +*.obj +*.exe +*.lib +*.so \ No newline at end of file diff --git a/README.md b/README.md index 50c3dfc..08cab68 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # Dynamic Entity Component System + +Entity-Component-System implementation in D language. \ No newline at end of file diff --git a/dub.json b/dub.json index 547b6be..1106532 100755 --- a/dub.json +++ b/dub.json @@ -1,9 +1,21 @@ { - "name": "dlps", + "name": "ecs", "authors": [ "Michał Masiukiewicz", "Dawid Masiukiewicz" ], "description": "Dynamic Entity Component System", - "copyright": "Copyright © 2017-2018, Michał Masiukiewicz", - "license": "MIT" + "copyright": "Copyright © 2017-2018, Michał Masiukiewicz, Dawid Masiukiewicz", + "license": "BSD", + "sourcePaths" : ["source\/"], + "configurations" : [ + { + "name" : "library", + "targetType" : "library" + }, + { + "name" : "tests", + "sourcePaths" : ["source\/","tests\/"], + "targetType" : "executable" + } + ] } \ No newline at end of file diff --git a/source/ecs/ecs.d b/source/ecs/ecs.d index e009bf8..60d0f6a 100644 --- a/source/ecs/ecs.d +++ b/source/ecs/ecs.d @@ -1,5 +1,9 @@ +module ecs.ecs; + import std.stdio; +version(Design): + alias SytemFuncType = void function(ref SystemCallData data, void* componentsStart); struct HasComponentsStore @@ -191,7 +195,7 @@ struct Manager { continue; } - entTypeData.systems ~= sys + entTypeData.systems ~= sys; } return typeData; @@ -215,7 +219,7 @@ struct Manager void systemCaller(ref SystemCallData data, void * componentsStart) { Func(cast(FUnc.par1Type)(componentsStart + data.componentsDt[0]), - cast(FUnc.par1Type)(componentsStart + data.componentsDt[1])...); + cast(FUnc.par1Type)(componentsStart + data.componentsDt[1])/*...*/); } System* system = new System(&systemCaller, entTypeData); systems ~= system; @@ -267,7 +271,7 @@ class System alias SerializeVector = ubyte[]; -__ghsared EntityManager gEntityManager; +__gshared EntityManager gEntityManager; unittest { diff --git a/source/ecs/entity.d b/source/ecs/entity.d new file mode 100644 index 0000000..0639b78 --- /dev/null +++ b/source/ecs/entity.d @@ -0,0 +1,18 @@ +module ecs.entity; + +struct EntityID +{ + uint id; + uint id_count; +} + +struct Entity +{ + EntityID id; +} + +struct EntityTemplate +{ + uint[] components; + Entity* entity; +} \ No newline at end of file diff --git a/source/ecs/entity_allocator.d b/source/ecs/entity_allocator.d index bf0b560..50192c2 100644 --- a/source/ecs/entity_allocator.d +++ b/source/ecs/entity_allocator.d @@ -23,19 +23,26 @@ struct EntityAllocator BucketArray[] arrays; Bucket* lastEmptyBucket; - void initBucketArray(ref BucketArray bArr) + Bucket* initBucketArray(ref BucketArray bArr) { - + return null; } void allocateBucketArray() { - auto bucketArray = new BucketArray(); - assert(bucketArray.buckets[0].ptr % bucketSize == 0) arrays ~= bucketArray; + //auto bucketArray = new BucketArray(); + BucketArray bucketArray; + assert(cast(uint)bucketArray.buckets[0].memory.ptr % bucketSize == 0); + arrays ~= bucketArray; Bucket* lasBucket = initBucketArray(bucketArray); lastEmptyBucket = lasBucket; } + void allocateBucket() + { + + } + ubyte[] getMemory() { if (lastEmptyBucket is null) diff --git a/source/ecs/events.d b/source/ecs/events.d new file mode 100644 index 0000000..aa2fc66 --- /dev/null +++ b/source/ecs/events.d @@ -0,0 +1,11 @@ +module ecs.events; + +struct Event +{ + uint type; +} + +class EventManager +{ + +} \ No newline at end of file diff --git a/source/ecs/manager.d b/source/ecs/manager.d new file mode 100644 index 0000000..332f524 --- /dev/null +++ b/source/ecs/manager.d @@ -0,0 +1,112 @@ +module ecs.manager; + +import std.experimental.allocator.mallocator : Mallocator; +import std.experimental.allocator; +import std.traits; + +import ecs.system; +import ecs.entity; + +alias gEM = EntityManager.instance; + +class EntityManager +{ + + static void initialize() + { + instance = Mallocator.instance.make!EntityManager; + } + + void registerSystem(Sys)(int priority) + { + static void callUpdate(ref CallData data, void* entity) + { + static if(hasMember!(Sys,"update")) + { + Sys* s = cast(Sys*)data.system.system_pointer; + s.update(); + } + } + + System system; + static if(hasMember!(Sys,"update")) + { + system.update = &callUpdate; + } + system.system_pointer = cast(void*)Mallocator.instance.make!Sys; + + if(systems is null) + { + systems = Mallocator.instance.makeArray!System(1); + systems[0] = system; + } + else + { + Mallocator.instance.expandArray(systems,1); + systems[$-1] = system; + } + } + + void registerComponent(Comp)() + { + uint size = Comp.sizeof; + ComponentInfo info; + info.size = size; + info.aligment = 8; + + if(components is null) + { + components = Mallocator.instance.makeArray!ComponentInfo(1); + components[0] = info; + } + else + { + Mallocator.instance.expandArray(components,1); + components[$-1] = info; + } + } + + void update() + { + foreach(ref system;systems) + { + if(system.update is null)continue; + CallData call_data = CallData(&system,null); + system.update(call_data,null); + } + } + + EntityTemplate* allocateTemplate(uint[] components_ids) + { + uint size = 0; + foreach(id;components_ids) + { + size += components[id].size; + } + + size += EntityID.sizeof; + + ubyte[] entity_data = Mallocator.instance.makeArray!ubyte(size); + EntityTemplate* temp = Mallocator.instance.make!EntityTemplate; + temp.components = components_ids; + temp.entity = cast(Entity*)entity_data.ptr; + return temp; + } + + struct CallData + { + System* system; + uint[] deltas; + } + + struct ComponentInfo + { + int size; + int aligment; + } + + System[] systems; + ComponentInfo[] components; + __gshared EntityManager instance; + +} \ No newline at end of file diff --git a/source/ecs/system.d b/source/ecs/system.d new file mode 100644 index 0000000..57a33cf --- /dev/null +++ b/source/ecs/system.d @@ -0,0 +1,16 @@ +module ecs.system; + +import ecs.entity; +import ecs.manager; + +struct System +{ + ///should system update and catch events? + bool enabled = true; + ///system priority + int prority; + ///pointer to system implementation + void* system_pointer; + + void function(ref EntityManager.CallData data, void* entity) update; +} \ No newline at end of file diff --git a/tests/tests.d b/tests/tests.d new file mode 100644 index 0000000..4168e5c --- /dev/null +++ b/tests/tests.d @@ -0,0 +1,69 @@ +module tests.tests; + +import ecs.manager; +import ecs.events; +import ecs.system; +import ecs.entity; + +int main() +{ + return 0; +} + +unittest +{ + + alias SerializeVector = ubyte[]; + + struct TestComp + { + __gshared static int component_id; + int a; + ulong b; + + static void serializeComponent(ref TestComp comp, SerializeVector output) + { + + } + + static void deserializeComponent(ref TestComp comp, ubyte[] data) + { + + } + } + + struct TestSystem + { + + void initialize(ref TestComp comp) + { + + } + + void update()//ref TestComp comp) + { + //comp.a+=1000; + //comp.b+=2000; + import std.stdio; + writeln("Jakis tekst!"); + } + + void handleEvent(Event event, ref TestComp comp) + { + + } + } + + EntityManager.initialize(); + assert(gEM !is null); + + + gEM.registerComponent!TestComp; + + uint[1] ids = [0]; + EntityTemplate* tmpl = gEM.allocateTemplate(ids); + + gEM.registerSystem!TestSystem(0); + + gEM.update(); +} \ No newline at end of file