From 9589a5cb2d051e18f32039daad4077150b72870f Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 14 May 2020 22:18:57 +0200 Subject: [PATCH] FIxed GDC compilation (basic betterC WIP) and some improvements -fixed issue with adding/removing entities inside events handling -fixed EntityMeta.getComponent() (added check if component_id is valid) -added function hasComponent to entity to check if component exists --- demos/external/sources/mmutils/thread_pool.d | 7 +- demos/source/demos/snake.d | 2 +- demos/utils/source/ecs_utils/utils.d | 14 +- dub.json | 14 +- source/bubel/ecs/entity.d | 18 ++ source/bubel/ecs/manager.d | 164 ++++++++++--------- source/bubel/ecs/std.d | 8 + source/bubel/ecs/vector.d | 14 +- tests/access_perf.d | 9 +- tests/basic.d | 9 +- tests/perf.d | 9 +- 11 files changed, 174 insertions(+), 94 deletions(-) diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index 48d2932..52136d4 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -182,6 +182,12 @@ void instructionPause() __builtin_ia32_pause(); } + else version(GNU) + { + import gcc.builtins; + + __builtin_ia32_pause(); + } else version (DigitalMars) { asm @@ -189,7 +195,6 @@ void instructionPause() rep; nop; } - } else { diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 244e5ec..3c62ef6 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -17,7 +17,7 @@ import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; -import std.array : staticArray; +//import std.array : staticArray; enum float px = 1.0/512.0; diff --git a/demos/utils/source/ecs_utils/utils.d b/demos/utils/source/ecs_utils/utils.d index 4c143fd..8ce5cd1 100644 --- a/demos/utils/source/ecs_utils/utils.d +++ b/demos/utils/source/ecs_utils/utils.d @@ -21,7 +21,19 @@ float randomRangef(float min, float max) return rand()%4096; }*/ -extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; +version(GNU) +{ + public import core.stdc.stdio : printf; + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else +{ + extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; + public import std.array : staticArray; +} extern(C) int rand(); version(D_BetterC) diff --git a/dub.json b/dub.json index c23a4e6..01cf85c 100755 --- a/dub.json +++ b/dub.json @@ -74,6 +74,9 @@ "dflags": [ "-betterC", "-defaultlib=" + ], + "dflags-gdc": [ + "-fno-druntime" ] }, { @@ -88,9 +91,7 @@ ], "dflags-gdc": [ "-fno-druntime", - "-fvisibility=hidden" - ], - "lflags-gdc": [ + "-fvisibility=hidden", "-lpthread" ] }, @@ -105,9 +106,7 @@ "-betterC" ], "dflags-gdc": [ - "-fno-druntime" - ], - "lflags-gdc": [ + "-fno-druntime", "-lpthread" ] }, @@ -118,6 +117,9 @@ "-betterC", "-unittest" ], + "dflags-gdc": [ + "-fno-druntime" + ], "sourcePaths": ["source/","tests/"], "mainSourceFile":"tests/runner.d", "excludedSourceFiles":[ diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index 10720a2..1e98ff2 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -46,6 +46,14 @@ struct Entity return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof); } + bool hasComponent(ushort component_id) + { + EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); + EntityManager.EntityInfo* info = block.type_info; + if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false; + return true; + } + EntityMeta getMeta() { EntityMeta meta; @@ -65,8 +73,18 @@ struct EntityMeta T* getComponent(T)() const { + const (EntityManager.EntityInfo)* info = block.type_info; + if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) + return null; return cast(T*)(cast(void*)block + block.type_info.deltas[T.component_id] + index * T.sizeof); } + + bool hasComponent(ushort component_id) + { + EntityManager.EntityInfo* info = block.type_info; + if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false; + return true; + } } /************************************************************************************************************************ diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index c6b02a1..7b6a983 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -126,7 +126,7 @@ export struct EntityManager //if(info.components)Mallocator.dispose(info.components); Mallocator.dispose(info); - } //*/ + } foreach (UpdatePass* pass; passes) { @@ -472,50 +472,52 @@ export struct EntityManager if (member == "length" || member == "thread_id" || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) { - continue; + //continue; } - - string name; - static if (isArray!MemberType) - { // Workaround. This code is never called with: not an array type, but compiler prints an error - name = Unqual!(ForeachType!MemberType).stringof; - } - - bool is_optional; - bool is_read_only; - - if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) + else { - is_read_only = true; - } - - foreach (att; __traits(getAttributes, __traits(getMember, - Sys.EntitiesData, member))) - { - if (att == "optional") - { - is_optional = true; + string name; + static if (isArray!MemberType) + { // Workaround. This code is never called with: not an array type, but compiler prints an error + name = Unqual!(ForeachType!MemberType).stringof; } - if (att == "readonly") + + bool is_optional; + bool is_read_only; + + if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) { is_read_only = true; } - } - if (is_read_only) - { - components_counts.readonly++; - } - else - { - components_counts.mutable++; - } - if (is_optional) - { - components_counts.optional++; - } - else - { - components_counts.req++; + + foreach (att; __traits(getAttributes, __traits(getMember, + Sys.EntitiesData, member))) + { + if (att == "optional") + { + is_optional = true; + } + if (att == "readonly") + { + is_read_only = true; + } + } + if (is_read_only) + { + components_counts.readonly++; + } + else + { + components_counts.mutable++; + } + if (is_optional) + { + components_counts.optional++; + } + else + { + components_counts.req++; + } } } @@ -695,50 +697,52 @@ export struct EntityManager { if (is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) components_info.entites_array = member; - continue; + //continue; } - - string name; - static if (isArray!MemberType) - { // Workaround. This code is never called with: not an array type, but compiler prints an error - name = Unqual!(ForeachType!MemberType).stringof; - } - - bool is_optional; - bool is_read_only; - - if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) + else { - is_read_only = true; - } - - foreach (att; __traits(getAttributes, __traits(getMember, - Sys.EntitiesData, member))) - { - if (att == "optional") - { - is_optional = true; + string name; + static if (isArray!MemberType) + { // Workaround. This code is never called with: not an array type, but compiler prints an error + name = Unqual!(ForeachType!MemberType).stringof; } - if (att == "readonly") + + bool is_optional; + bool is_read_only; + + if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) { is_read_only = true; } - } - if (is_read_only) - { - components_info.addReadonly(CompInfo(member, name)); - } - else - { - components_info.addMutable(CompInfo(member, name)); - } - if (is_optional) - { - components_info.addOptional(CompInfo(member, name)); - } - else - { - components_info.addReq(CompInfo(member, name)); + + foreach (att; __traits(getAttributes, __traits(getMember, + Sys.EntitiesData, member))) + { + if (att == "optional") + { + is_optional = true; + } + if (att == "readonly") + { + is_read_only = true; + } + } + if (is_read_only) + { + components_info.addReadonly(CompInfo(member, name)); + } + else + { + components_info.addMutable(CompInfo(member, name)); + } + if (is_optional) + { + components_info.addOptional(CompInfo(member, name)); + } + else + { + components_info.addReq(CompInfo(member, name)); + } } } @@ -874,7 +878,7 @@ export struct EntityManager } } - static void fillInputData(ref Sys.EntitiesData input_data, EntityInfo* info, + static void fillInputData()(ref Sys.EntitiesData input_data, EntityInfo* info, EntitiesBlock* block, uint offset, uint entities_count, System* system) { //enum ComponentsIndices components_info = getComponentsInfo(); @@ -2863,7 +2867,11 @@ export struct EntityManager id_manager.optimize(); updateBlocks(); changeEntities(); + updateEvents(); + + id_manager.optimize(); + updateBlocks(); removeEntities(); event_manager.clearEvents(); } diff --git a/source/bubel/ecs/std.d b/source/bubel/ecs/std.d index 4cec197..6658639 100644 --- a/source/bubel/ecs/std.d +++ b/source/bubel/ecs/std.d @@ -113,6 +113,14 @@ else version(D_BetterC) alloca_pos += length; return ret; } + + version(GNU) + { + extern(C) void __gdc_personality_v0() + { + + } + } } else { diff --git a/source/bubel/ecs/vector.d b/source/bubel/ecs/vector.d index 413bbce..1ec8a93 100644 --- a/source/bubel/ecs/vector.d +++ b/source/bubel/ecs/vector.d @@ -55,7 +55,8 @@ public: /*foreach (ref el; array[0 .. used]) { destroy(el); }*/ - freeData(cast(void[]) array); + //freeData(cast(void[]) array); + freeData((cast(void*)array.ptr)[0 .. array.length * T.sizeof]); gVectorsDestroyed++; } array = null; @@ -78,7 +79,9 @@ public: } } else { foreach (ref el; array[newLength .. used]) { - destroy(el); + //destroy(el); + static if(__traits(hasMember, T, "__xdtor"))el.__xdtor(); + else static if(__traits(hasMember, T, "__dtor"))el.__dtor(); } } used = newLength; @@ -122,7 +125,8 @@ public: T* memory = cast(T*) malloc(newSize); memcpy(cast(void*) memory, cast(void*) oldArray.ptr, oldSize); array = memory[0 .. newNumOfElements]; - return cast(void[]) oldArray; + //return cast(void[]) oldArray; + return (cast(void*)oldArray.ptr)[0 .. oldArray.length * T.sizeof]; } export Vector!T copy()() { @@ -169,7 +173,9 @@ public: } export void remove(size_t elemNum) { - destroy(array[elemNum]); + //destroy(array[elemNum]); + static if(__traits(hasMember, T, "__xdtor"))array[elemNum].__xdtor(); + else static if(__traits(hasMember, T, "__dtor"))array[elemNum].__dtor(); //swap(array[elemNum], array[used - 1]); array[elemNum] = array[used - 1]; used--; diff --git a/tests/access_perf.d b/tests/access_perf.d index 141a2e6..36da0c0 100644 --- a/tests/access_perf.d +++ b/tests/access_perf.d @@ -6,7 +6,14 @@ import bubel.ecs.core; import bubel.ecs.manager; import bubel.ecs.entity; -import std.array : staticArray; +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; import core.stdc.stdio; diff --git a/tests/basic.d b/tests/basic.d index 10d79b8..3bf2814 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -5,7 +5,14 @@ import bubel.ecs.manager; import bubel.ecs.system; import bubel.ecs.attributes; -import std.array : staticArray; +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; struct CInt { diff --git a/tests/perf.d b/tests/perf.d index 135dc54..b6a2692 100644 --- a/tests/perf.d +++ b/tests/perf.d @@ -6,7 +6,14 @@ import bubel.ecs.core; import bubel.ecs.manager; import bubel.ecs.entity; -import std.array : staticArray; +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; import core.stdc.stdio;