Unittests and demos update

-fixed bug in EntityManager
-added better support for non-betterC unittests
-added many new unittests
-slightly improved JUnit xml output
-fixed WASM compile script
-added new textures
-fixed model texture coordinaes in demos
-some minor bug fixes in demo
TODO: demos cpu usage in non-betterC mode
This commit is contained in:
Mergul 2020-04-16 22:16:20 +02:00
parent 46530ff45b
commit 84e04191c8
13 changed files with 453 additions and 51 deletions

View file

@ -1,7 +1,9 @@
module tests.basic;
import ecs.manager;
import ecs.core;
import ecs.manager;
import ecs.system;
import ecs.attributes;
struct CInt
{
@ -57,15 +59,59 @@ struct CUnregistered
short value = 12;
}
struct LongAddSystem
{
mixin ECS.System;
struct EntitiesData
{
int length;
CLong[] long_;
}
void onUpdate(EntitiesData data)
{
updates_count++;
foreach(i;0..data.length)
{
data.long_[i] += 1;
}
}
int updates_count = 0;
}
struct EmptySystem
{
mixin ECS.System!16;
struct EntitiesData
{
int thread_id;
}
void onUpdate(EntitiesData data)
{
count++;
}
int count = 0;
}
void beforeEveryTest()
{
gEM.initialize(1);
gEM.beginRegister();
gEM.registerComponent!CInt;
gEM.registerComponent!CFloat;
gEM.registerComponent!CDouble;
gEM.registerComponent!CLong;
gEM.registerComponent!CShort;
gEM.endRegister();
}
void afterEveryTest()
@ -183,3 +229,344 @@ unittest
gEM.freeTemplate(tmpl_6);
gEM.freeTemplate(tmpl_7);
}
@("UnsortedComponentIDs")
unittest
{
//basic template allocation
ushort[2] ids = [CFloat.component_id, CInt.component_id];
ushort[2] ids2 = [CInt.component_id, CFloat.component_id];
EntityTemplate* tmpl_ = gEM.allocateTemplate(ids);
EntityTemplate* tmpl_2 = gEM.allocateTemplate(ids2);
assert(tmpl_.info.components.length == 2);
assert(tmpl_.getComponent!CInt);
assert(tmpl_.getComponent!CFloat);
assert(*tmpl_.getComponent!CInt == 1);
assert(*tmpl_.getComponent!CFloat == 2.0);
assert(tmpl_.info == tmpl_2.info);
}
@("MultiRegister")
unittest
{
gEM.beginRegister();
gEM.endRegister();
gEM.beginRegister();
gEM.registerComponent!CLong;
gEM.registerComponent!CShort;
gEM.endRegister();
}
@("EmptySystem")
unittest
{
gEM.beginRegister();
gEM.registerSystem!EmptySystem(0);
gEM.endRegister();
EmptySystem* system = gEM.getSystem!EmptySystem;
assert(system !is null);
assert(system.count == 0);
System* ecs_system = gEM.getSystem(EmptySystem.system_id);
assert(ecs_system !is null);
assert(ecs_system.id == EmptySystem.system_id);
assert(ecs_system.name == "EmptySystem");
gEM.begin();
gEM.update();
gEM.end();
assert(system.count == 1);
}
@("SystemCallbacks")
unittest
{
struct TestSystem
{
mixin ECS.System!16;
mixin ECS.ExcludedComponents!(CShort);
struct EntitiesData
{
int length;
CLong[] long_;
@optional CInt[] int_;
}
void onCreate()
{
create++;
}
void onDestroy()
{
(*destroy)++;
}
void onEnable()
{
enable++;
}
void onDisable()
{
disable++;
}
bool onBegin()
{
begin++;
update = 0;
return pass;
}
void onEnd()
{
end++;
}
void onUpdate(EntitiesData data)
{
update++;
}
int create = 0;
int* destroy;
int update = 0;
int begin = 0;
int end = 0;
int enable = 0;
int disable = 0;
bool pass = true;
}
gEM.beginRegister();
gEM.registerSystem!TestSystem(0);
gEM.endRegister();
TestSystem* system = gEM.getSystem!TestSystem;
int destroy = 0;
system.destroy = &destroy;
gEM.beginRegister();
gEM.registerSystem!TestSystem(0);
gEM.endRegister();
system = gEM.getSystem!TestSystem;
system.destroy = &destroy;
assert(system !is null);
assert(system.create == 1);
assert(system.begin == 0);
assert(system.end == 0);
assert(system.enable == 1);
assert(system.disable == 0);
//FIXME: currently destroy is only called with Manager.destory which is bug, but there is no workaround for this by now
//assert(destroy == 1);
System* ecs_system = gEM.getSystem(system.system_id);
ecs_system.enable();
assert(system.enable == 1);
ecs_system.disable();
ecs_system.disable();
ecs_system.enable();
assert(system.enable == 2);
assert(system.disable == 1);
ushort[2] ids = [CLong.component_id,CFloat.component_id];
EntityTemplate* tmpl = gEM.allocateTemplate(ids);
scope (exit) gEM.freeTemplate(tmpl);
gEM.addEntity(tmpl);
gEM.begin();
assert(system.begin == 1);
gEM.update();
assert(system.update == 1);
gEM.end();
assert(system.end == 1);
ushort[2] ids2 = [CLong.component_id, CInt.component_id];
EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2);
scope (exit) gEM.freeTemplate(tmpl2);
gEM.addEntity(tmpl2);
gEM.addEntity(tmpl2);
gEM.begin();
assert(system.begin == 2);
gEM.update();
assert(system.update == 2);//system is updated number of entity blocks times
gEM.end();
assert(system.end == 2);
ushort[2] ids3 = [CLong.component_id, CShort.component_id];
EntityTemplate* tmpl3 = gEM.allocateTemplate(ids3);
scope (exit) gEM.freeTemplate(tmpl3);
gEM.addEntity(tmpl3);
//entity with excluded component shouldn't be updated
gEM.begin();
assert(system.begin == 3);
gEM.update();
assert(system.update == 2);
gEM.end();
assert(system.end == 3);
//system can be disable form update in onBegin() callback, onEnd() callback is called
system.pass = false;
gEM.begin();
assert(system.begin == 4);
gEM.update();
assert(system.update == 0);
gEM.end();
assert(system.end == 4);
system.pass = true;
//disabled system is't called
ecs_system.disable();
gEM.begin();
assert(system.begin == 4);
gEM.update();
assert(system.update == 0);
gEM.end();
assert(system.end == 4);
ecs_system.enable();
}
@("CustomPass")
unittest
{
gEM.beginRegister();
gEM.registerPass("custom");
gEM.registerSystem!LongAddSystem(-1,"custom");
gEM.endRegister();
LongAddSystem* system = gEM.getSystem!LongAddSystem;
assert(system !is null);
assert(system.updates_count == 0);
System* ecs_system = gEM.getSystem(LongAddSystem.system_id);
assert(ecs_system !is null);
assert(ecs_system.id == LongAddSystem.system_id);
assert(ecs_system.priority == -1);
assert(ecs_system.name == "LongAddSystem");
ushort[1] ids = [CLong.component_id];
EntityTemplate* tmpl = gEM.allocateTemplate(ids);
scope (exit) gEM.freeTemplate(tmpl);
gEM.addEntity(tmpl);
gEM.begin();
gEM.update();
assert(system.updates_count == 0);
gEM.update("custom");
assert(system.updates_count == 1);
gEM.end();
}
@("SystemEntityCallbacks")
unittest
{
struct TestSystem
{
mixin ECS.System!16;
mixin ECS.ExcludedComponents!(CShort);
struct EntitiesData
{
int length;
CLong[] long_;
@optional CInt[] int_;
}
void onAddEntity(EntitiesData data)
{
add++;
}
void onRemoveEntity(EntitiesData data)
{
remove++;
}
void onChangeEntity(EntitiesData data)
{
change++;
}
void onUpdate(EntitiesData data)
{
}
int add = 0;
int remove = 0;
int change = 0;
}
gEM.beginRegister();
gEM.registerSystem!TestSystem(0);
gEM.endRegister();
TestSystem* system = gEM.getSystem!TestSystem;
assert(system !is null);
assert(system.add == 0);
assert(system.remove == 0);
assert(system.change == 0);
ushort[2] ids = [CLong.component_id,CFloat.component_id];
EntityTemplate* tmpl = gEM.allocateTemplate(ids);
scope (exit) gEM.freeTemplate(tmpl);
EntityID id0 = gEM.addEntity(tmpl).id;
gEM.commit();
assert(system.add == 1);
ushort[2] ids2 = [CLong.component_id, CInt.component_id];
EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2);
scope (exit) gEM.freeTemplate(tmpl2);
EntityID id1 = gEM.addEntity(tmpl2).id;
gEM.commit();
assert(system.add == 2);
ushort[2] ids3 = [CLong.component_id, CShort.component_id];
EntityTemplate* tmpl3 = gEM.allocateTemplate(ids3);
scope (exit) gEM.freeTemplate(tmpl3);
EntityID id2 = gEM.addEntity(tmpl3).id;
gEM.commit();
assert(system.add == 2);
gEM.commit();
}