BetterC improvement

-fixed some bugs
-non betterC code has better assertion messages
-fixed limited count of components in system
-small dub.json fix
This commit is contained in:
Mergul 2020-04-14 17:29:49 +02:00
parent 2aef76d75a
commit 0670aed506
3 changed files with 124 additions and 37 deletions

View file

@ -97,7 +97,7 @@
{
"name" : "tests-betterC",
"targetType" : "executable",
"sourcePaths" : ["source\/","tests\/"],
"sourceFiles" : ["tests/tests.d"],
"excludedSourceFiles":[
"source\/win_dll.d"
],

View file

@ -351,7 +351,8 @@ export struct EntityManager
void registerSystem(Sys)(int priority, const(char)[] pass_name)
{
ushort pass = passes_map.get(pass_name, ushort.max);
assert(pass != ushort.max); //, "Update pass (Name " ~ pass_name ~ ") doesn't exist.");
version(D_BetterC)assert(pass != ushort.max, "Update pass doesn't exist.");
else assert(pass != ushort.max, "Update pass (Name " ~ pass_name ~ ") doesn't exist.");
registerSystem!(Sys)(priority, pass);
}
@ -370,19 +371,20 @@ export struct EntityManager
assert(register_state,
"registerSystem must be called between beginRegister() and endRegister().");
assert(pass < passes.length); //, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist.");
version(D_BetterC)assert(pass < passes.length, "Update pass doesn't exist.");
else assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist.");
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 assert(0, "Add \"mixin ECS.System;\" in top of system structure;");
}
static if (!(hasMember!(Sys, "EntitiesData")))
{
static assert(0); //, "System should gave \"EntitiesData\" struct for input components");
static assert(0, "System should gave \"EntitiesData\" struct for input components");
}
static if (hasMember!(Sys, "handleEvent"))
@ -434,9 +436,104 @@ export struct EntityManager
string type;
}
static struct ComponentsIndices
static struct ComponentsCounts
{
uint readonly;
uint mutable;
uint excluded;
uint optional;
uint req;
}
static ComponentsCounts getComponentsCounts()()
{
ComponentsCounts components_counts;
bool checkExcludedComponentsSomething(Sys)()
{
return __traits(compiles, allSameType!(string, typeof(Sys.ExcludedComponents))) && allSameType!(string,
typeof(Sys.ExcludedComponents)) && isExpressions!(Sys.ExcludedComponents);
}
foreach (member; __traits(allMembers, Sys.EntitiesData))
{
alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member));
if (member == "length" || member == "thread_id"
|| is(MemberType == Entity[]) || is(MemberType == const(Entity)[]))
{
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)))
{
is_read_only = true;
}
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++;
}
}
static if (__traits(hasMember, Sys, "ExcludedComponents"))
{
static if (is(Sys.ExcludedComponents == enum))
{
foreach (str; __traits(allMembers, Sys.ExcludedComponents))
{
components_counts.excluded++;
}
}
else //static if (checkExcludedComponentsSomething!Sys)
{
foreach (str; Sys.ExcludedComponents)
{
components_counts.excluded++;
}
}
}
return components_counts;
}
enum ComponentsCounts component_counts = getComponentsCounts();
static struct ComponentsIndices(ComponentsCounts counts)
{
CompInfo[] readonly()
{
return m_readonly[0 .. m_readonly_counter];
@ -487,11 +584,11 @@ export struct EntityManager
m_req[m_req_counter++] = info;
}
CompInfo[64] m_readonly;
CompInfo[64] m_mutable;
CompInfo[64] m_excluded;
CompInfo[64] m_optional;
CompInfo[64] m_req;
CompInfo[counts.readonly] m_readonly;
CompInfo[counts.mutable] m_mutable;
CompInfo[counts.excluded] m_excluded;
CompInfo[counts.optional] m_optional;
CompInfo[counts.req] m_req;
uint m_readonly_counter;
uint m_mutable_counter;
@ -502,7 +599,7 @@ export struct EntityManager
string entites_array;
}
static void allocateSystemComponents(ComponentsIndices components_info)(ref System system)
static void allocateSystemComponents(ComponentsIndices!component_counts components_info)(ref System system)
{
size_t req = components_info.req.length;
size_t opt = components_info.optional.length;
@ -523,9 +620,9 @@ export struct EntityManager
}
static ComponentsIndices getComponentsInfo()()
static ComponentsIndices!component_counts getComponentsInfo()()
{
ComponentsIndices components_info;
ComponentsIndices!component_counts components_info;
bool checkExcludedComponentsSomething(Sys)()
{
@ -573,31 +670,19 @@ export struct EntityManager
if (is_read_only)
{
components_info.addReadonly(CompInfo(member, name));
//components_info.readonly ~= CompInfo(member,name);
}
else
{
components_info.addMutable(CompInfo(member, name));
//components_info.mutable ~= CompInfo(member,name);
}
if (is_optional)
{
components_info.addOptional(CompInfo(member, name));
//components_info.optional ~= CompInfo(member,name);
}
else
{
components_info.addReq(CompInfo(member, name));
//components_info.req ~= CompInfo(member,name);
}
/*if (is_read_only)
{
//components_info.readonly ~= CompInfo(member,name);
}
if (is_optional == false)
{ //is Req
//components_info.req ~= CompInfo(member,name);
}*/
}
static if (__traits(hasMember, Sys, "ExcludedComponents"))
@ -607,7 +692,6 @@ export struct EntityManager
foreach (str; __traits(allMembers, Sys.ExcludedComponents))
{
components_info.addExcluded(CompInfo(str, str));
//components_info.excluded ~= CompInfo(str,str);
}
}
else //static if (checkExcludedComponentsSomething!Sys)
@ -615,7 +699,6 @@ export struct EntityManager
foreach (str; Sys.ExcludedComponents)
{
components_info.addExcluded(CompInfo(str.stringof, str.stringof));
//components_info.excluded ~= CompInfo(str,str);
}
}
@ -624,7 +707,7 @@ export struct EntityManager
return components_info;
}
enum ComponentsIndices components_info = getComponentsInfo();
enum ComponentsIndices!component_counts components_info = getComponentsInfo();
static void genCompList()(ref System system, ref HashMap!(char[], ushort) components_map)
{
@ -659,7 +742,7 @@ export struct EntityManager
foreach (iii, comp_info; components_info.req)
{
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
version (betterC)
version (D_BetterC)
assert(comp != ushort.max,
"Can't register system due to non existing component.");
else
@ -670,25 +753,29 @@ export struct EntityManager
foreach (iii, comp_info; components_info.excluded)
{
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
assert(comp != ushort.max); //, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\".");
version (D_BetterC)assert(comp != ushort.max, "Can't register system due to non existing component.");
else assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\".");
system.m_excluded_components[iii] = comp;
}
foreach (iii, comp_info; components_info.optional)
{
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
assert(comp != ushort.max); //, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\".");
version (D_BetterC)assert(comp != ushort.max, "Can't register system due to non existing component.");
else assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\".");
system.m_optional_components[iii] = comp;
}
foreach (iii, comp_info; components_info.readonly)
{
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
assert(comp != ushort.max); //, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\".");
version (D_BetterC)assert(comp != ushort.max, "Can't register system due to non existing component.");
else assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\".");
system.m_read_only_components[iii] = comp;
}
foreach (iii, comp_info; components_info.mutable)
{
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
assert(comp != ushort.max); //, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\".");
version (D_BetterC)assert(comp != ushort.max, "Can't register system due to non existing component.");
else assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\".");
system.m_modified_components[iii] = comp;
}
@ -1009,7 +1096,7 @@ export struct EntityManager
static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort))
{
static assert(0, "Add \"mixin ECS.Component;\" in top of component structure;"); //"Component should have \"__gshared ushort component_id");
static assert(0, "Add \"mixin ECS.Component;\" in top of component structure;");
}
static if (hasMember!(Comp, "onDestroy") && isFunction!(Comp.onDestroy)
@ -1063,7 +1150,7 @@ export struct EntityManager
static if (!(hasMember!(Ev, "event_id")) || !is(typeof(Ev.event_id) == ushort))
{
static assert(0, "Add \"mixin ECS.Event;\" in top of event structure;"); //"Event should have \"__gshared ushort event_id");
static assert(0, "Add \"mixin ECS.Event;\" in top of event structure;");
}
static if (hasMember!(Ev, "onDestroy") && isFunction!(Ev.onDestroy)

View file

@ -15,7 +15,7 @@ enum string OUT_FILE = "test_report.xml";
static jmp_buf gEnvBuffer;
static AssertInfo gAssertInfo;
version(betterC){}
version(D_BetterC){}
else version = notBetterC;
struct AssertInfo