-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
This commit is contained in:
DanielMz25 2018-09-07 20:54:29 +02:00
parent 8285bde71d
commit 6217aec6be
10 changed files with 265 additions and 11 deletions

5
.gitignore vendored
View file

@ -6,4 +6,7 @@ perf.data
perf.data.old perf.data.old
*.o *.o
*.a *.a
*.obj *.obj
*.exe
*.lib
*.so

View file

@ -1 +1,3 @@
# Dynamic Entity Component System # Dynamic Entity Component System
Entity-Component-System implementation in D language.

View file

@ -1,9 +1,21 @@
{ {
"name": "dlps", "name": "ecs",
"authors": [ "authors": [
"Michał Masiukiewicz", "Dawid Masiukiewicz" "Michał Masiukiewicz", "Dawid Masiukiewicz"
], ],
"description": "Dynamic Entity Component System", "description": "Dynamic Entity Component System",
"copyright": "Copyright © 2017-2018, Michał Masiukiewicz", "copyright": "Copyright © 2017-2018, Michał Masiukiewicz, Dawid Masiukiewicz",
"license": "MIT" "license": "BSD",
"sourcePaths" : ["source\/"],
"configurations" : [
{
"name" : "library",
"targetType" : "library"
},
{
"name" : "tests",
"sourcePaths" : ["source\/","tests\/"],
"targetType" : "executable"
}
]
} }

View file

@ -1,5 +1,9 @@
module ecs.ecs;
import std.stdio; import std.stdio;
version(Design):
alias SytemFuncType = void function(ref SystemCallData data, void* componentsStart); alias SytemFuncType = void function(ref SystemCallData data, void* componentsStart);
struct HasComponentsStore struct HasComponentsStore
@ -191,7 +195,7 @@ struct Manager
{ {
continue; continue;
} }
entTypeData.systems ~= sys entTypeData.systems ~= sys;
} }
return typeData; return typeData;
@ -215,7 +219,7 @@ struct Manager
void systemCaller(ref SystemCallData data, void * componentsStart) void systemCaller(ref SystemCallData data, void * componentsStart)
{ {
Func(cast(FUnc.par1Type)(componentsStart + data.componentsDt[0]), 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); System* system = new System(&systemCaller, entTypeData);
systems ~= system; systems ~= system;
@ -267,7 +271,7 @@ class System
alias SerializeVector = ubyte[]; alias SerializeVector = ubyte[];
__ghsared EntityManager gEntityManager; __gshared EntityManager gEntityManager;
unittest unittest
{ {

18
source/ecs/entity.d Normal file
View file

@ -0,0 +1,18 @@
module ecs.entity;
struct EntityID
{
uint id;
uint id_count;
}
struct Entity
{
EntityID id;
}
struct EntityTemplate
{
uint[] components;
Entity* entity;
}

View file

@ -23,19 +23,26 @@ struct EntityAllocator
BucketArray[] arrays; BucketArray[] arrays;
Bucket* lastEmptyBucket; Bucket* lastEmptyBucket;
void initBucketArray(ref BucketArray bArr) Bucket* initBucketArray(ref BucketArray bArr)
{ {
return null;
} }
void allocateBucketArray() void allocateBucketArray()
{ {
auto bucketArray = new BucketArray(); //auto bucketArray = new BucketArray();
assert(bucketArray.buckets[0].ptr % bucketSize == 0) arrays ~= bucketArray; BucketArray bucketArray;
assert(cast(uint)bucketArray.buckets[0].memory.ptr % bucketSize == 0);
arrays ~= bucketArray;
Bucket* lasBucket = initBucketArray(bucketArray); Bucket* lasBucket = initBucketArray(bucketArray);
lastEmptyBucket = lasBucket; lastEmptyBucket = lasBucket;
} }
void allocateBucket()
{
}
ubyte[] getMemory() ubyte[] getMemory()
{ {
if (lastEmptyBucket is null) if (lastEmptyBucket is null)

11
source/ecs/events.d Normal file
View file

@ -0,0 +1,11 @@
module ecs.events;
struct Event
{
uint type;
}
class EventManager
{
}

112
source/ecs/manager.d Normal file
View file

@ -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;
}

16
source/ecs/system.d Normal file
View file

@ -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;
}

69
tests/tests.d Normal file
View file

@ -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();
}