diff --git a/source/ecs/ecs.d b/source/ecs/ecs.d index d82add2..e009bf8 100644 --- a/source/ecs/ecs.d +++ b/source/ecs/ecs.d @@ -1,36 +1,38 @@ -module ecs.ecs; - import std.stdio; - - alias SytemFuncType = void function(ref SystemCallData data, void* componentsStart); -struct HasComponentsStore { +struct HasComponentsStore +{ ulong[4] bits; //256 components - bool has(HasComponentsStore components) { + bool has(HasComponentsStore components) + { return true; } - bool notIn(HasComponentsStore components) { + bool notIn(HasComponentsStore components) + { return true; } - int length() { + int length() + { assert(0); } } // Informacje o kompnencie -struct ComponentInfo { +struct ComponentInfo +{ int size; int aligment; SerializeJSON funsSerJ; SerializeBiN funcSerB; } -struct System { +struct System +{ HasComponentsStore requiredComponents; HasComponentsStore absenComponents; HasComponentsStore maybeComponents; @@ -39,13 +41,15 @@ struct System { SytemFuncType func; } // Informacje o systemie dla konkretnego entitiesa -struct SystemCallData { +struct SystemCallData +{ System* system; int[] componentsDt; } // Informacje o entitiesie danego typu -struct EntityTypeData { +struct EntityTypeData +{ HasComponentsStore components; int[] deltas; int totalSize; @@ -53,21 +57,25 @@ struct EntityTypeData { SystemCallData[] systems; } -struct EntitiesBlock { +struct EntitiesBlock +{ EntityTypeData* typeData; Entity* freeEntitySlot; EntitiesBlock* nextBlock; } -struct EntityID { +struct EntityID +{ ulong id = ulong.max; static immutable notUsedValue = EntityID(ulong.max); } // Dane konkretnego Entitiesa -struct Entity { +struct Entity +{ EntityID entityID = EntityID.notUsedValue; - union { + union + { string name; Entity* nextFreeSlot; } @@ -78,12 +86,14 @@ struct Entity { //ubyte[XX] thereIsComponentsMemory; } -struct Template { +struct Template +{ HasComponentsStore hasComp; Entity* entity; } -struct Manager { +struct Manager +{ EntityAllocator entityArrayAllcoator; ComponentInfo[] components; @@ -92,19 +102,24 @@ struct Manager { HashMapTwoWays!(string, Entity*) nameMap; HashMapTwoWays!(EntityID, Entity*) idMap; - EntitiesBlock* getEntitiesBlock(HasComponentsStore hasComponents) { + EntitiesBlock* getEntitiesBlock(HasComponentsStore hasComponents) + { EntitiesBlock* block = entitiesDatas.get(hasComponents, null); - if (block is null) { + if (block is null) + { // If such component combination was never present, add it block = addNewBlock(hasComponents, block); return block; } // Iterate over list of components until free slot is found or lists ends - do { - if (block.freeEntitySlot !is null) { + do + { + if (block.freeEntitySlot !is null) + { return block; } - if (block.nextBlock is null) { + if (block.nextBlock is null) + { block = addNewBlock(hasComponents); return block; } @@ -114,11 +129,14 @@ struct Manager { } - EntitiesBlock* addNewBlock(HasComponentsStore hasComponents, EntitiesBlock* firstBlock) { + EntitiesBlock* addNewBlock(HasComponentsStore hasComponents, EntitiesBlock* firstBlock) + { // Get last block so order of blocks is preserved, and first blocks are filled first EntitiesBlock* lastBlock = firstBlock; - if (lastBlock !is null) { - while (lastBlock.nextBlock !is null) { + if (lastBlock !is null) + { + while (lastBlock.nextBlock !is null) + { lastBlock = lastBlock.nextBlock; } } @@ -126,32 +144,39 @@ struct Manager { ubyte[] memory = new ubyte[](4096); EntitiesBlock* block = cast(EntitiesBlock*) memory.ptr; - if (lastBlock is null) { + if (lastBlock is null) + { EntityTypeData* entityTypeData = newEntityTypeData(hasComponents); block.typeData = entityTypeData; block.nextBlock = null; entitiesDatas.add(hasComponents, block); - } else { + } + else + { lastBlock.nextBlock = block; block.typeData = lastBlock.typeData; block.nextBlock = null; } } - void alignNum(ref int num, int aligment) { + void alignNum(ref int num, int aligment) + { int reminder = num % aligment; - if (reminder != 0) { + if (reminder != 0) + { num += aligment - reminder; } } - EntityTypeData* newEntityTypeData(HasComponentsStore hasComponents) { + EntityTypeData* newEntityTypeData(HasComponentsStore hasComponents) + { EntityTypeData* typeData = new EntityTypeData(); typeData.components = hasComponents; ComponentInfo[] components = getComponentsInfo(hasComponents); typeData.deltas.length = hasComponents.length; - foreach (i, comp; components) { + foreach (i, comp; components) + { typeData.deltas[i] = typeData.totalSize; typeData.totalAligment.max(comp.aligment); typeData.totalSize += comp.size; @@ -159,9 +184,11 @@ struct Manager { } alignNum(typeData.totalSize, typeData.totalAligment); - foreach (sys; systems) { + foreach (sys; systems) + { if (!typeData.hasComp.has(sys.requiredComponents) - || !typeData.hasComp.notIn(sys.absenComponents)) { + || !typeData.hasComp.notIn(sys.absenComponents)) + { continue; } entTypeData.systems ~= sys @@ -170,7 +197,8 @@ struct Manager { return typeData; } - void addEntity(Template* templ) { + void addEntity(Template* templ) + { EntitiesBlock* block = getEntitiesBlock(templ.hasComp); Entity* newEntity = block.freeEntitySlot; block.freeEntitySlot = newEntity.nextFreeSlot; @@ -178,21 +206,25 @@ struct Manager { memcpy(temp.entity, newEntity, block.typeData.totalSize); } - void addSystem(Func)(int priority) { + void addSystem(Func)(int priority) + { HasComponentsStore requiredComponents; HasComponentsStore absenComponents; HasComponentsStore maybeComponents; - void systemCaller(ref SystemCallData data, void * componentsStart) { + void systemCaller(ref SystemCallData data, void * componentsStart) + { Func(cast(FUnc.par1Type)(componentsStart + data.componentsDt[0]), cast(FUnc.par1Type)(componentsStart + data.componentsDt[1])...); } System* system = new System(&systemCaller, entTypeData); - systems~=system; + systems ~= system; - foreach (ref entTypeData; entitiesDatas) { + foreach (ref entTypeData; entitiesDatas) + { if (!entTypeData.hasComp.has(requiredComponents) - || !entTypeData.hasComp.notIn(absenComponents)) { + || !entTypeData.hasComp.notIn(absenComponents)) + { continue; } entTypeData.systems ~= system; @@ -200,42 +232,104 @@ struct Manager { } } -void someSystem(CompA a, CompB b, CompC* c) { +void someSystem(CompA a, CompB b, CompC* c) +{ } -void main() { +void main() +{ writeln("Edit source/app.d to start your project."); } +class System +{ - - - - - - - - - - - - -class System{ - - void start(){ + void start() + { } - void end(){ + void end() + { } - void update(ref ObjRend a){ + void update(ref ObjRend a) + { } - void useEvent(EventData evvv, ref ObjRend a){ + void useEvent(EventData evvv, ref ObjRend a) + { } } +alias SerializeVector = ubyte[]; + +__ghsared EntityManager gEntityManager; + +unittest +{ + struct ComponentA + { + __gshared static int component_id; + int a; + ulong b; + + static void serializeComponent(ref ComponentA comp, SerializeVector output) + { + + } + + static void deerializeComponent(ref ComponentA comp, ubyte[] data) + { + + } + + } + + gEM.addComponet!ComponentA(); + assert(ComponentA.component_id == 0); + ComponentData* ccc = &gEM.componnets[ComponentA.component_id]; + assert(ccc.totalAligment == 8); + assert(ccc.totalSize == 8); + + HasComponentsStore hasComponents; + hasComponents.addComponet(ComponentA.component_id); + EntityTempalte* tmpl = gEM.allocateTemplate(hasComponents); + + ComponentA* comp = tmpl.getComponent!ComponentA(ComponentA.component_id); + comp.a = 111; + comp.b = 222; + + gEM.addEntity(tmpl); + + struct SystemAdd + { + void update(ref ComponentA a) + { + a.a+=1000; + b.b+=2000; + + } + + void handleEvent(EventData evvv, ref ComponentA a) + { + } + } + + int priority=10; + gEM.registerSystem!(SystemAdd)(priority); + gEM.updateStepAll(); + foreach(EntityID id; gEM.IterateByAllEntiteis){ + assert(id.getComponent(ComponentA.component_id)); + ComponentA* ccc=id.getComponent(ComponentA.component_id); + assert(ccc.a==1111); + assert(ccc.b==2222); + } + + + +} +