Common update:
-added multiple new function to allocate template and add entity -updated README.md (complete initial version) -empty components now don't take memory -fixedd small bug with TestRunner -added many new tests (HashMap, Vector, EntityMeta, ...) -added default hashing function to HashMap -fixed critical bug with adding entities -fixed small bug with adding entity with remplacement components -added asserts into code to better bug detection -small performance improvement for events -added ComponentRef structure which contain data pointer and componentID -remove EntityID from Event structure -now events are handled before removing entiteis -fixed GDC compilation -fixed rendering of rotated sprites -added weapons as separate entities to space ship and others -added Tower enemy to SpaceInvaders demo -added Boss to SpaceInvaders demo (boss has four tower attached to it) -Boss towers shoot multiple bullets upon death -fixed critical bug with demos switching -fixed critical bug related to adding/removing entities form inside onAdd/onRemove entity callback -added animation support -added particles sypport and particles for firing and explostions, and more -multithreaded rendering now has same rendering order as singlethreaded -application automaticallu detect host CPU threads count -added upgrades to SPaceInvaders demo -fixed texture memory freeing -improved documentation -improved multithreaded performance -improve shader code -fixed registration issue -some additional performance improvements -added depth and colors to rendering parameters -jobs now has names corresponding to their systems -change execute() -> willExecute() -added EntityMeta structure to speedup getting fetching components form entity -improved multithreading rendering -added possibility tio change number of threads runtime -added bullets collision detection in SpaceInvaders demo -some CI changes -added VBO batch rendering (current default, no render mode switch yet) -fixed camera positioning calculation -fixed buffer issue with WebGL -added viewport scalling (at least 300 pixels height). Pixels are scalled if screen is bigger. -center demos gameplay area -added fullpage html template for Emscripten build -added many new sprites to atlas -fixed critical bug with CPU usage in multithreaded mode -snake render tile coresponding to body part -snake is destroyed after collision and emit some particles -added some functionality to vectors -fixed documentation issue in Manager.d -more minor code changes and cleanup
This commit is contained in:
parent
2ddb97e9ce
commit
024356df9b
62 changed files with 5918 additions and 1673 deletions
135
tests/access_perf.d
Normal file
135
tests/access_perf.d
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
module tests.access_perf;
|
||||
|
||||
import tests.runner;
|
||||
|
||||
import bubel.ecs.core;
|
||||
import bubel.ecs.manager;
|
||||
import bubel.ecs.entity;
|
||||
|
||||
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;
|
||||
|
||||
struct CLong
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
alias value this;
|
||||
|
||||
long value = 10;
|
||||
}
|
||||
|
||||
struct CInt
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
alias value this;
|
||||
|
||||
int value = 10;
|
||||
}
|
||||
|
||||
struct CUInt
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
alias value this;
|
||||
|
||||
uint value = 12;
|
||||
}
|
||||
|
||||
struct CBig
|
||||
{
|
||||
mixin ECS.Component;
|
||||
uint[32] data;
|
||||
}
|
||||
|
||||
EntityTemplate* tmpl;
|
||||
|
||||
void beforeEveryTest()
|
||||
{
|
||||
gEM.initialize(0);
|
||||
|
||||
gEM.beginRegister();
|
||||
|
||||
gEM.registerComponent!CLong;
|
||||
gEM.registerComponent!CInt;
|
||||
gEM.registerComponent!CUInt;
|
||||
gEM.registerComponent!CBig;
|
||||
|
||||
gEM.endRegister();
|
||||
|
||||
tmpl = gEM.allocateTemplate([CLong.component_id, CInt.component_id, CUInt.component_id, CBig.component_id].staticArray);
|
||||
foreach(i; 0 .. 100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
|
||||
void afterEveryTest()
|
||||
{
|
||||
if(tmpl)gEM.freeTemplate(tmpl);
|
||||
tmpl = null;
|
||||
gEM.destroy();
|
||||
}
|
||||
|
||||
@("DirectAccess100k1comp")
|
||||
unittest
|
||||
{
|
||||
foreach(i;0..25000)
|
||||
{
|
||||
Entity* entity = gEM.getEntity(EntityID(i*4+1,0));
|
||||
CUInt* comp1 = entity.getComponent!CUInt;
|
||||
comp1.value = 4;
|
||||
}
|
||||
}
|
||||
|
||||
@("DirectAccess100k4comp")
|
||||
unittest
|
||||
{
|
||||
foreach(i;0..25000)
|
||||
{
|
||||
Entity* entity = gEM.getEntity(EntityID(i*4+1,0));
|
||||
CUInt* comp1 = entity.getComponent!CUInt;
|
||||
comp1.value = 4;
|
||||
CInt* comp2 = entity.getComponent!CInt;
|
||||
comp2.value = 3;
|
||||
CLong* comp3 = entity.getComponent!CLong;
|
||||
comp3.value = 1;
|
||||
CBig* comp4 = entity.getComponent!CBig;
|
||||
comp4.data[0] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@("DirectAccess100k1compWithMeta")
|
||||
unittest
|
||||
{
|
||||
foreach(i;0..25000)
|
||||
{
|
||||
Entity* entity = gEM.getEntity(EntityID(i*4+1,0));
|
||||
EntityMeta meta = entity.getMeta();
|
||||
CUInt* comp1 = meta.getComponent!CUInt;
|
||||
comp1.value = 4;
|
||||
}
|
||||
}
|
||||
|
||||
@("DirectAccess100k4compWithMeta")
|
||||
unittest
|
||||
{
|
||||
foreach(i;0..25000)
|
||||
{
|
||||
Entity* entity = gEM.getEntity(EntityID(i*4+1,0));
|
||||
EntityMeta meta = entity.getMeta();
|
||||
CUInt* comp1 = meta.getComponent!CUInt;
|
||||
comp1.value = 4;
|
||||
CInt* comp2 = meta.getComponent!CInt;
|
||||
comp2.value = 3;
|
||||
CLong* comp3 = meta.getComponent!CLong;
|
||||
comp3.value = 1;
|
||||
CBig* comp4 = meta.getComponent!CBig;
|
||||
comp4.data[0] = 2;
|
||||
}
|
||||
}
|
||||
403
tests/basic.d
403
tests/basic.d
|
|
@ -1,11 +1,18 @@
|
|||
module tests.basic;
|
||||
|
||||
import ecs.core;
|
||||
import ecs.manager;
|
||||
import ecs.system;
|
||||
import ecs.attributes;
|
||||
import bubel.ecs.core;
|
||||
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
|
||||
{
|
||||
|
|
@ -61,6 +68,11 @@ struct CUnregistered
|
|||
short value = 12;
|
||||
}
|
||||
|
||||
struct CFlag
|
||||
{
|
||||
mixin ECS.Component;
|
||||
}
|
||||
|
||||
struct LongAddSystem
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
|
@ -103,6 +115,7 @@ struct EmptySystem
|
|||
|
||||
void beforeEveryTest()
|
||||
{
|
||||
CUnregistered.component_id = ushort.max;
|
||||
gEM.initialize(0);
|
||||
|
||||
gEM.beginRegister();
|
||||
|
|
@ -112,6 +125,7 @@ void beforeEveryTest()
|
|||
gEM.registerComponent!CDouble;
|
||||
gEM.registerComponent!CLong;
|
||||
gEM.registerComponent!CShort;
|
||||
gEM.registerComponent!CFlag;
|
||||
|
||||
gEM.endRegister();
|
||||
}
|
||||
|
|
@ -121,14 +135,33 @@ void afterEveryTest()
|
|||
gEM.destroy();
|
||||
}
|
||||
|
||||
@("EntityMeta")
|
||||
unittest
|
||||
{
|
||||
EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray);
|
||||
Entity* entity = gEM.addEntity(tmpl_);
|
||||
EntityMeta meta = entity.getMeta();
|
||||
assert(meta.hasComponent(CInt.component_id));
|
||||
assert(meta.getComponent!CInt);
|
||||
assert(meta.hasComponent(CFloat.component_id));
|
||||
assert(meta.getComponent!CFloat);
|
||||
assert(!meta.getComponent!CLong);
|
||||
assert(!meta.hasComponent(CLong.component_id));
|
||||
assert(!meta.getComponent!CUnregistered);
|
||||
assert(!meta.hasComponent(CUnregistered.component_id));
|
||||
assert(*meta.getComponent!CInt == 1);
|
||||
assert(*meta.getComponent!CFloat == 2.0);
|
||||
}
|
||||
|
||||
@("AddEntity")
|
||||
unittest
|
||||
{
|
||||
ushort[2] ids = [CInt.component_id, CFloat.component_id];
|
||||
EntityTemplate* tmpl_ = gEM.allocateTemplate(ids);
|
||||
assert(tmpl_.info.components.length == 2);
|
||||
EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray);
|
||||
assert(tmpl_.info.components.length == 3);
|
||||
assert(tmpl_.info.size == (CInt.sizeof + CFloat.sizeof + EntityID.sizeof));
|
||||
assert(tmpl_.getComponent!CInt);
|
||||
assert(tmpl_.getComponent!CFloat);
|
||||
assert(tmpl_.getComponent!CFlag);
|
||||
assert(!tmpl_.getComponent!CLong);
|
||||
assert(!tmpl_.getComponent!CUnregistered);
|
||||
assert(*tmpl_.getComponent!CInt == 1);
|
||||
|
|
@ -146,6 +179,67 @@ unittest
|
|||
assert(entity2.getComponent!CFloat);
|
||||
assert(*entity2.getComponent!CInt == 2);
|
||||
assert(*entity2.getComponent!CFloat == 2.0);
|
||||
|
||||
//CInt cint = CInt(10);
|
||||
//CLong clong;
|
||||
//Entity* entity3 = gEM.addEntity(tmpl_, [cint.ref_, clong.ref_].staticArray);
|
||||
Entity* entity3 = gEM.addEntity(tmpl_, [CInt(10).ref_, CLong().ref_, CFlag().ref_].staticArray);
|
||||
EntityID id = entity3.id;
|
||||
assert(entity3.hasComponent(CInt.component_id));
|
||||
assert(entity3.hasComponent(CFloat.component_id));
|
||||
assert(*entity3.getComponent!CInt == 10);
|
||||
assert(*entity3.getComponent!CFloat == 2.0);
|
||||
|
||||
gEM.addComponents(entity3.id, [CFlag().ref_,CShort(2).ref_].staticArray);
|
||||
gEM.commit();
|
||||
entity3 = gEM.getEntity(id);
|
||||
assert(entity3.getComponent!CInt);
|
||||
assert(entity3.getComponent!CFloat);
|
||||
assert(entity3.getComponent!CFlag);
|
||||
assert(entity3.getComponent!CShort);
|
||||
assert(*entity3.getComponent!CInt == 10);
|
||||
assert(*entity3.getComponent!CFloat == 2.0);
|
||||
assert(*entity3.getComponent!CShort == 2);
|
||||
|
||||
gEM.removeComponents(entity3.id, [CFlag().component_id,CShort(2).component_id].staticArray);
|
||||
gEM.commit();
|
||||
entity3 = gEM.getEntity(id);
|
||||
assert(entity3.getComponent!CInt);
|
||||
assert(entity3.getComponent!CFloat);
|
||||
assert(!entity3.getComponent!CFlag);
|
||||
assert(!entity3.getComponent!CShort);
|
||||
assert(*entity3.getComponent!CInt == 10);
|
||||
assert(*entity3.getComponent!CFloat == 2.0);
|
||||
|
||||
gEM.addComponents(entity3.id, [CFlag().ref_,CShort(2).ref_].staticArray);
|
||||
gEM.removeComponents(entity3.id, [CUnregistered.component_id].staticArray);
|
||||
gEM.commit();
|
||||
entity3 = gEM.getEntity(id);
|
||||
assert(entity3.getComponent!CInt);
|
||||
assert(entity3.getComponent!CFloat);
|
||||
assert(entity3.getComponent!CFlag);
|
||||
assert(entity3.getComponent!CShort);
|
||||
assert(*entity3.getComponent!CInt == 10);
|
||||
assert(*entity3.getComponent!CFloat == 2.0);
|
||||
assert(*entity3.getComponent!CShort == 2);
|
||||
|
||||
gEM.beginRegister();
|
||||
|
||||
gEM.registerComponent!CUnregistered;
|
||||
|
||||
gEM.endRegister();
|
||||
|
||||
gEM.addComponents(entity3.id, [CUnregistered(4).ref_].staticArray);
|
||||
gEM.commit();
|
||||
entity3 = gEM.getEntity(id);
|
||||
assert(entity3.getComponent!CUnregistered);
|
||||
assert(*entity3.getComponent!CUnregistered == 4);
|
||||
|
||||
gEM.removeComponents(entity3.id, [CUnregistered.component_id].staticArray);
|
||||
gEM.commit();
|
||||
entity3 = gEM.getEntity(id);
|
||||
assert(!entity3.getComponent!CUnregistered);
|
||||
|
||||
}
|
||||
|
||||
//allocate templates
|
||||
|
|
@ -156,32 +250,48 @@ unittest
|
|||
ushort[2] ids = [CInt.component_id, CFloat.component_id];
|
||||
EntityTemplate* tmpl_ = gEM.allocateTemplate(ids);
|
||||
EntityTemplate* tmpl_d = gEM.allocateTemplate([CFloat.component_id, CInt.component_id, CFloat.component_id].staticArray);
|
||||
EntityTemplate* tmpl_cp = gEM.allocateTemplate(tmpl_);
|
||||
assert(tmpl_d.info == tmpl_.info);
|
||||
assert(tmpl_cp.info == tmpl_cp.info);
|
||||
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_cp.getComponent!CFloat);
|
||||
assert(tmpl_cp.getComponent!CInt);
|
||||
assert(tmpl_.getComponent!CInt != tmpl_cp.getComponent!CInt);
|
||||
assert(tmpl_.getComponent!CFloat != tmpl_cp.getComponent!CFloat);
|
||||
assert(*tmpl_.getComponent!CInt == *tmpl_cp.getComponent!CInt);
|
||||
assert(*tmpl_.getComponent!CFloat == *tmpl_cp.getComponent!CFloat);
|
||||
*tmpl_.getComponent!CInt = 4;
|
||||
*tmpl_.getComponent!CFloat = 5.0;
|
||||
|
||||
//allocate template from template with additional component
|
||||
ushort[1] ids2 = [CDouble.component_id];
|
||||
//allocate template from template with additional components
|
||||
ushort[2] ids2 = [CDouble.component_id,CFlag.component_id];
|
||||
EntityTemplate* tmpl_2 = gEM.allocateTemplate(tmpl_, ids2);
|
||||
assert(tmpl_2.info.components.length == 3);
|
||||
assert(tmpl_2.info.components.length == 4);
|
||||
assert(tmpl_2.getComponent!CInt);
|
||||
assert(tmpl_2.getComponent!CFloat);
|
||||
assert(tmpl_2.getComponent!CDouble);
|
||||
assert(tmpl_2.getComponent!CFlag);
|
||||
assert(*tmpl_2.getComponent!CInt == 4);
|
||||
assert(*tmpl_2.getComponent!CFloat == 5.0);
|
||||
assert(*tmpl_2.getComponent!CDouble == 3.0);
|
||||
|
||||
assert(tmpl_.info.blocksCount() == 0);
|
||||
|
||||
Entity* entity = gEM.addEntity(tmpl_);
|
||||
gEM.addComponents(entity.id, CDouble(8.0));
|
||||
gEM.addComponents(entity.id, CFloat(100));
|
||||
gEM.addComponents(entity.id, CDouble(8.0), CFloat(100));
|
||||
|
||||
assert(tmpl_.info.blocksCount() == 1);
|
||||
|
||||
//apply entity changes
|
||||
gEM.commit();
|
||||
|
||||
assert(tmpl_.info.blocksCount() == 0);
|
||||
|
||||
//allocate template as entity copy
|
||||
EntityTemplate* tmpl_3 = gEM.allocateTemplate(entity.id);
|
||||
assert(tmpl_3.info.components.length == 3);
|
||||
|
|
@ -202,18 +312,20 @@ unittest
|
|||
assert(*tmpl_4.getComponent!CFloat == 2.0);
|
||||
assert(*tmpl_4.getComponent!CDouble == 3.0);
|
||||
|
||||
//allocate template from template with two additional component
|
||||
ushort[2] ids3 = [CDouble.component_id, CLong.component_id];
|
||||
EntityTemplate* tmpl_5 = gEM.allocateTemplate(tmpl_, ids3);
|
||||
assert(tmpl_5.info.components.length == 4);
|
||||
//allocate template from template with three additional component
|
||||
ushort[3] ids3 = [CDouble.component_id, CLong.component_id, CShort.component_id];
|
||||
EntityTemplate* tmpl_5 = gEM.allocateTemplate(tmpl_2, ids3);
|
||||
assert(tmpl_5.info.components.length == 6);
|
||||
assert(tmpl_5.getComponent!CInt);
|
||||
assert(tmpl_5.getComponent!CFloat);
|
||||
assert(tmpl_5.getComponent!CDouble);
|
||||
assert(tmpl_5.getComponent!CLong);
|
||||
assert(tmpl_5.getComponent!CShort);
|
||||
assert(*tmpl_5.getComponent!CInt == 4);
|
||||
assert(*tmpl_5.getComponent!CFloat == 5.0);
|
||||
assert(*tmpl_5.getComponent!CDouble == 3.0);
|
||||
assert(*tmpl_5.getComponent!CLong == 10);
|
||||
assert(*tmpl_5.getComponent!CShort == 12);
|
||||
|
||||
//allocate template from template without one component
|
||||
ushort[1] rem_ids = [CFloat.component_id];
|
||||
|
|
@ -224,7 +336,7 @@ unittest
|
|||
|
||||
//allocate template from template without one component and two additional
|
||||
EntityTemplate* tmpl_7 = gEM.allocateTemplate(tmpl_, ids3, rem_ids);
|
||||
assert(tmpl_7.info.components.length == 3);
|
||||
assert(tmpl_7.info.components.length == 4);
|
||||
assert(tmpl_7.getComponent!CInt);
|
||||
assert(tmpl_7.getComponent!CDouble);
|
||||
assert(tmpl_7.getComponent!CLong);
|
||||
|
|
@ -481,6 +593,10 @@ unittest
|
|||
|
||||
gEM.endRegister();
|
||||
|
||||
assert(gEM.getPass("custom"));
|
||||
assert(!gEM.getPass("custommm"));
|
||||
|
||||
|
||||
LongAddSystem* system = gEM.getSystem!LongAddSystem;
|
||||
assert(system !is null);
|
||||
assert(system.updates_count == 0);
|
||||
|
|
@ -1116,9 +1232,9 @@ unittest
|
|||
assert(*entity2.getComponent!CShort == 12);
|
||||
|
||||
gEM.sendEvent(id,ETest());
|
||||
gEM.sendEvent(id,ETest2(id,10));
|
||||
gEM.sendEvent(id,ETest2(10));
|
||||
gEM.sendEvent(id2,ETest());
|
||||
gEM.sendEvent(id2,ETest2(id2,12));
|
||||
gEM.sendEvent(id2,ETest2(12));
|
||||
gEM.commit();
|
||||
assert(ETest2.destory == 2);
|
||||
|
||||
|
|
@ -1129,20 +1245,20 @@ unittest
|
|||
|
||||
gEM.addComponents(id, CInt(2), CShort(1));
|
||||
gEM.sendEvent(id,ETest());
|
||||
gEM.sendEvent(id,ETest2(id,2));
|
||||
gEM.sendEvent(id,ETest2(2));
|
||||
gEM.commit();
|
||||
assert(ETest2.destory == 3);
|
||||
|
||||
entity = gEM.getEntity(id);
|
||||
assert(*entity.getComponent!CLong == 66);
|
||||
assert(*entity.getComponent!CInt == 36);
|
||||
assert(*entity.getComponent!CInt == 2);//36);
|
||||
|
||||
//test for multiple event blocks
|
||||
long result = *entity.getComponent!CLong;
|
||||
foreach(i;0..10000)
|
||||
{
|
||||
gEM.sendEvent(id,ETest());
|
||||
gEM.sendEvent(id,ETest2(id,4));
|
||||
gEM.sendEvent(id,ETest2(4));
|
||||
result += 16;
|
||||
result += 8;
|
||||
}
|
||||
|
|
@ -1220,4 +1336,247 @@ unittest
|
|||
assert(*entity2.getComponent!CInt == 13);
|
||||
|
||||
gEM.end();
|
||||
}
|
||||
|
||||
@("SystemDependencies")
|
||||
unittest
|
||||
{
|
||||
struct TestSystem
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
@readonly CInt[] int_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct TestSystem2
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
CInt[] int_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct TestSystem3
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
@readonly CInt[] int_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct TestSystem4
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
CInt[] int_;
|
||||
CLong[] long_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct TestSystem5
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
@readonly CLong[] int_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
gEM.beginRegister();
|
||||
|
||||
gEM.registerSystem!TestSystem(0);
|
||||
gEM.registerSystem!TestSystem2(1);
|
||||
gEM.registerSystem!TestSystem3(2);
|
||||
gEM.registerSystem!TestSystem4(3);
|
||||
gEM.registerSystem!TestSystem5(4);
|
||||
|
||||
gEM.endRegister();
|
||||
|
||||
const (EntityManager.UpdatePass)* pass = gEM.getPass("update");
|
||||
assert(pass != null);
|
||||
assert(pass.system_callers.length == 5);
|
||||
assert(pass.system_callers[0].system_id == TestSystem.system_id);
|
||||
assert(pass.system_callers[1].system_id == TestSystem2.system_id);
|
||||
assert(pass.system_callers[2].system_id == TestSystem3.system_id);
|
||||
assert(pass.system_callers[3].system_id == TestSystem4.system_id);
|
||||
assert(pass.system_callers[4].system_id == TestSystem5.system_id);
|
||||
assert(pass.system_callers[0].dependencies.length == 0);
|
||||
assert(pass.system_callers[1].dependencies.length == 1);
|
||||
assert(pass.system_callers[2].dependencies.length == 1);
|
||||
assert(pass.system_callers[3].dependencies.length == 3);
|
||||
assert(pass.system_callers[4].dependencies.length == 1);
|
||||
assert(pass.system_callers[1].dependencies[0].system_id == TestSystem.system_id);
|
||||
assert(pass.system_callers[2].dependencies[0].system_id == TestSystem2.system_id);
|
||||
assert(pass.system_callers[3].dependencies[0].system_id == TestSystem.system_id);
|
||||
assert(pass.system_callers[3].dependencies[1].system_id == TestSystem2.system_id);
|
||||
assert(pass.system_callers[3].dependencies[2].system_id == TestSystem3.system_id);
|
||||
assert(pass.system_callers[4].dependencies[0].system_id == TestSystem4.system_id);
|
||||
}
|
||||
|
||||
@("ExternalSystemDependencies")
|
||||
unittest
|
||||
{
|
||||
enum TestDependency = "TestDepencency";
|
||||
|
||||
struct TestSystem
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
mixin ECS.ReadOnlyDependencies!(TestDependency);
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
@readonly CInt[] int_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct TestSystem2
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
mixin ECS.WritableDependencies!(TestDependency);
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
@readonly CInt[] int_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct TestSystem3
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
mixin ECS.ReadOnlyDependencies!(TestDependency);
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint thread_id;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct TestSystem4
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
mixin ECS.WritableDependencies!(TestDependency);
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
@readonly CInt[] int_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct TestSystem5
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
mixin ECS.ReadOnlyDependencies!(TestDependency);
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
@readonly CLong[] int_;
|
||||
}
|
||||
|
||||
void onUpdate(EntitiesData entities)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
gEM.beginRegister();
|
||||
|
||||
gEM.registerDependency(TestDependency);
|
||||
|
||||
gEM.registerSystem!TestSystem(0);
|
||||
gEM.registerSystem!TestSystem2(1);
|
||||
gEM.registerSystem!TestSystem3(2);
|
||||
gEM.registerSystem!TestSystem4(3);
|
||||
gEM.registerSystem!TestSystem5(4);
|
||||
|
||||
gEM.endRegister();
|
||||
|
||||
const (EntityManager.UpdatePass)* pass = gEM.getPass("update");
|
||||
assert(pass != null);
|
||||
assert(pass.system_callers.length == 5);
|
||||
assert(pass.system_callers[0].system_id == TestSystem.system_id);
|
||||
assert(pass.system_callers[1].system_id == TestSystem2.system_id);
|
||||
assert(pass.system_callers[2].system_id == TestSystem3.system_id);
|
||||
assert(pass.system_callers[3].system_id == TestSystem4.system_id);
|
||||
assert(pass.system_callers[4].system_id == TestSystem5.system_id);
|
||||
assert(pass.system_callers[0].dependencies.length == 0);
|
||||
assert(pass.system_callers[1].dependencies.length == 1);
|
||||
assert(pass.system_callers[2].dependencies.length == 1);
|
||||
assert(pass.system_callers[3].dependencies.length == 3);
|
||||
assert(pass.system_callers[4].dependencies.length == 2);
|
||||
assert(pass.system_callers[1].dependencies[0].system_id == TestSystem.system_id);
|
||||
assert(pass.system_callers[2].dependencies[0].system_id == TestSystem2.system_id);
|
||||
assert(pass.system_callers[3].dependencies[0].system_id == TestSystem.system_id);
|
||||
assert(pass.system_callers[3].dependencies[1].system_id == TestSystem2.system_id);
|
||||
assert(pass.system_callers[3].dependencies[2].system_id == TestSystem3.system_id);
|
||||
assert(pass.system_callers[4].dependencies[0].system_id == TestSystem2.system_id);
|
||||
assert(pass.system_callers[4].dependencies[1].system_id == TestSystem4.system_id);
|
||||
}
|
||||
142
tests/bugs.d
Normal file
142
tests/bugs.d
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
module tests.bugs;
|
||||
|
||||
import tests.basic;
|
||||
|
||||
import bubel.ecs.core;
|
||||
import bubel.ecs.manager;
|
||||
import bubel.ecs.system;
|
||||
import bubel.ecs.attributes;
|
||||
|
||||
version(GNU)
|
||||
{
|
||||
pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
}
|
||||
else import std.array : staticArray;
|
||||
|
||||
@("Bug0001")
|
||||
unittest
|
||||
{
|
||||
struct Event1
|
||||
{
|
||||
mixin ECS.Event;
|
||||
|
||||
EntityID id;
|
||||
}
|
||||
|
||||
struct Event2
|
||||
{
|
||||
mixin ECS.Event;
|
||||
}
|
||||
|
||||
struct System1
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
CInt[] int_;
|
||||
}
|
||||
|
||||
EntityTemplate* tmpl;
|
||||
EntityID id;
|
||||
|
||||
void onCreate()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CInt.component_id, CLong.component_id].staticArray);
|
||||
}
|
||||
|
||||
void onDestroy()
|
||||
{
|
||||
gEM.freeTemplate(tmpl);
|
||||
}
|
||||
|
||||
void handleEvent(Entity* entity, Event1 event)
|
||||
{
|
||||
gEM.removeEntity(event.id);
|
||||
gEM.sendEvent(entity.id,Event2());
|
||||
}
|
||||
|
||||
void handleEvent(Entity* entity, Event2 event)
|
||||
{
|
||||
id = gEM.addEntity(tmpl).id;
|
||||
}
|
||||
}
|
||||
|
||||
struct System2
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
Entity[] entity;
|
||||
}
|
||||
|
||||
///check if every entity was removed correctly
|
||||
void onUpdate(EntitiesData data)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
struct System3
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
Entity[] entity;
|
||||
}
|
||||
|
||||
///remove every entity
|
||||
void onUpdate(EntitiesData data)
|
||||
{
|
||||
foreach(i;0..data.length)gEM.removeEntity(data.entity[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
gEM.initialize(0);
|
||||
|
||||
gEM.beginRegister();
|
||||
|
||||
gEM.registerComponent!CInt;
|
||||
gEM.registerComponent!CFloat;
|
||||
gEM.registerComponent!CDouble;
|
||||
gEM.registerComponent!CLong;
|
||||
gEM.registerComponent!CShort;
|
||||
gEM.registerComponent!CFlag;
|
||||
|
||||
gEM.registerEvent!Event1;
|
||||
gEM.registerEvent!Event2;
|
||||
|
||||
gEM.registerSystem!System1(0);
|
||||
gEM.registerSystem!System2(-200);
|
||||
gEM.registerSystem!System3(-200);
|
||||
|
||||
gEM.endRegister();
|
||||
|
||||
EntityTemplate* tmpl = gEM.allocateTemplate([CInt.component_id, CLong.component_id].staticArray);
|
||||
EntityID id = gEM.addEntity(tmpl,[CLong(10).ref_, CInt(6).ref_].staticArray).id;
|
||||
EntityID id2 = gEM.addEntity(tmpl,[CInt(4).ref_].staticArray).id;
|
||||
gEM.freeTemplate(tmpl);
|
||||
gEM.commit();
|
||||
|
||||
gEM.sendEvent(id2, Event1(id));
|
||||
|
||||
gEM.getSystem(System2.system_id).disable();
|
||||
|
||||
gEM.begin();
|
||||
gEM.update();
|
||||
gEM.end();
|
||||
|
||||
gEM.getSystem(System2.system_id).enable();
|
||||
|
||||
gEM.begin();
|
||||
gEM.update();
|
||||
gEM.end();
|
||||
|
||||
gEM.destroy();
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
module tests.id_manager;
|
||||
|
||||
import ecs.id_manager;
|
||||
import ecs.entity;
|
||||
import bubel.ecs.id_manager;
|
||||
import bubel.ecs.entity;
|
||||
|
||||
unittest
|
||||
{
|
||||
|
|
|
|||
53
tests/map.d
Normal file
53
tests/map.d
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
module tests.map;
|
||||
|
||||
import bubel.ecs.hash_map;
|
||||
|
||||
version(GNU)
|
||||
{
|
||||
pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
}
|
||||
else import std.array : staticArray;
|
||||
|
||||
@("HashMap")
|
||||
unittest
|
||||
{
|
||||
HashMap!(string, int) map;
|
||||
|
||||
assert(map.length == 0);
|
||||
map.add("asd",1);
|
||||
assert(map.length == 1);
|
||||
map.clear();
|
||||
assert(map.length == 0);
|
||||
map.add("asd",1);
|
||||
assert(map.length == 1);
|
||||
map.reset();
|
||||
assert(map.length == 0);
|
||||
|
||||
map.add("asd",1);
|
||||
string asd = "asd";
|
||||
assert(map.isIn("asd"));
|
||||
assert(map.isIn(asd));
|
||||
assert(!map.isIn("asdf"));
|
||||
map.tryRemove("asdf");
|
||||
map.tryRemove("asd");
|
||||
assert(map.length == 0);
|
||||
map.add("asdf",1);
|
||||
map.add("asd",2);
|
||||
assert(map["asd"] == 2);
|
||||
assert(map["asdf"] == 1);
|
||||
assert(map.length == 2);
|
||||
map.tryRemove("asdf");
|
||||
assert(map.length == 1);
|
||||
map.remove("asd");
|
||||
assert(map.length == 0);
|
||||
|
||||
map.add("asd",1);
|
||||
map.add("asdwwghe",6);
|
||||
foreach(k,v;&map.byKeyValue)
|
||||
{
|
||||
assert(map[k] == v);
|
||||
}
|
||||
}
|
||||
185
tests/perf.d
Normal file
185
tests/perf.d
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
module tests.perf;
|
||||
|
||||
import tests.runner;
|
||||
|
||||
import bubel.ecs.core;
|
||||
import bubel.ecs.manager;
|
||||
import bubel.ecs.entity;
|
||||
|
||||
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;
|
||||
|
||||
struct CLong
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
alias value this;
|
||||
|
||||
long value = 10;
|
||||
}
|
||||
|
||||
struct CShort
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
alias value this;
|
||||
|
||||
short value = 12;
|
||||
}
|
||||
|
||||
struct CInt
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
alias value this;
|
||||
|
||||
int value = 10;
|
||||
}
|
||||
|
||||
struct CUInt
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
alias value this;
|
||||
|
||||
uint value = 12;
|
||||
}
|
||||
|
||||
struct CBig
|
||||
{
|
||||
mixin ECS.Component;
|
||||
uint[32] data;
|
||||
}
|
||||
|
||||
EntityTemplate* tmpl;
|
||||
|
||||
void beforeEveryTest()
|
||||
{
|
||||
gEM.initialize(0);
|
||||
|
||||
gEM.beginRegister();
|
||||
|
||||
gEM.registerComponent!CLong;
|
||||
gEM.registerComponent!CShort;
|
||||
gEM.registerComponent!CInt;
|
||||
gEM.registerComponent!CUInt;
|
||||
gEM.registerComponent!CBig;
|
||||
|
||||
gEM.endRegister();
|
||||
tmpl = null;
|
||||
}
|
||||
|
||||
void afterEveryTest()
|
||||
{
|
||||
if(tmpl)gEM.freeTemplate(tmpl);
|
||||
tmpl = null;
|
||||
gEM.destroy();
|
||||
}
|
||||
|
||||
void smallTmpl()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CShort.component_id].staticArray);
|
||||
}
|
||||
|
||||
void bigTmpl()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CBig.component_id].staticArray);
|
||||
}
|
||||
|
||||
void multiSmallTmpl()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CShort.component_id, CLong.component_id, CInt.component_id, CUInt.component_id].staticArray);
|
||||
}
|
||||
|
||||
void multiBigTmpl()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CLong.component_id, CInt.component_id, CUInt.component_id, CBig.component_id].staticArray);
|
||||
}
|
||||
|
||||
@("AddEntities100k1comp2b") @(before, &smallTmpl)
|
||||
unittest
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
|
||||
@("AddEntities100k1comp128b") @(before, &bigTmpl)
|
||||
unittest
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
|
||||
@("AddEntities100k4comp18b") @(before, &multiSmallTmpl)
|
||||
unittest
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
|
||||
@("AddEntities100k4comp144b") @(before, &multiBigTmpl)
|
||||
unittest
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
|
||||
void allocDealloc100k()
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
gEM.commit();
|
||||
foreach(i; 0..100_000)gEM.removeEntity(EntityID(i + 1,0));
|
||||
gEM.commit();
|
||||
}
|
||||
|
||||
void smallTmplPreAlloc()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CShort.component_id].staticArray);
|
||||
allocDealloc100k();
|
||||
}
|
||||
|
||||
void bigTmplPreAlloc()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CBig.component_id].staticArray);
|
||||
allocDealloc100k();
|
||||
}
|
||||
|
||||
void multiSmallTmplPreAlloc()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CShort.component_id, CLong.component_id, CInt.component_id, CUInt.component_id].staticArray);
|
||||
allocDealloc100k();
|
||||
}
|
||||
|
||||
void multiBigTmplPreAlloc()
|
||||
{
|
||||
tmpl = gEM.allocateTemplate([CLong.component_id, CInt.component_id, CUInt.component_id, CBig.component_id].staticArray);
|
||||
allocDealloc100k();
|
||||
}
|
||||
|
||||
@("AddEntities100k1comp2bPreAlloc") @(before, &smallTmplPreAlloc)
|
||||
unittest
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
|
||||
@("AddEntities100k1comp128bPreAlloc") @(before, &bigTmplPreAlloc)
|
||||
unittest
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
|
||||
@("AddEntities100k4comp18bPreAlloc") @(before, &multiSmallTmplPreAlloc)
|
||||
unittest
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
|
||||
@("AddEntities100k4comp144bPreAlloc") @(before, &multiBigTmplPreAlloc)
|
||||
unittest
|
||||
{
|
||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
||||
}
|
||||
101
tests/runner.d
101
tests/runner.d
|
|
@ -5,9 +5,22 @@ import core.stdc.stdio;
|
|||
import core.stdc.string;
|
||||
import core.sys.posix.setjmp;
|
||||
|
||||
import ecs.vector;
|
||||
import ecs.simple_vector;
|
||||
import ecs.std;
|
||||
import bubel.ecs.vector;
|
||||
import bubel.ecs.simple_vector;
|
||||
import bubel.ecs.std;
|
||||
|
||||
import std.traits;
|
||||
|
||||
import tests.time;
|
||||
|
||||
version (LDC)
|
||||
{
|
||||
import ldc.attributes;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum optStrategy = 0;
|
||||
}
|
||||
|
||||
enum int ASSERTED = 123;
|
||||
enum string OUT_FILE = "test_report.xml";
|
||||
|
|
@ -95,6 +108,8 @@ struct TestRunner(Args...)
|
|||
write(test.name);
|
||||
write("\" classname=\"");
|
||||
write(suite.name);
|
||||
write("\" time=\"");
|
||||
write(cast(double)test.time*0.000001);
|
||||
write("\">");
|
||||
if (test.msg)
|
||||
{
|
||||
|
|
@ -120,42 +135,65 @@ struct TestRunner(Args...)
|
|||
write("</testsuites>");
|
||||
}
|
||||
|
||||
@(optStrategy,"none")
|
||||
void runTests(string[] include = null, string[] exclude = null)
|
||||
{
|
||||
foreach (i, module_; Args)
|
||||
{
|
||||
TestSuite* suite = &suites[i];
|
||||
suite.name = module_.stringof;
|
||||
|
||||
void function() before;
|
||||
void function() after;
|
||||
|
||||
foreach (index, unittest_; __traits(getUnitTests, module_))
|
||||
{
|
||||
enum attributes = __traits(getAttributes, unittest_);
|
||||
|
||||
static if (attributes.length != 0)
|
||||
{
|
||||
if (include.length > 0)
|
||||
foreach(attr_id, attr; attributes)
|
||||
{
|
||||
bool matched = false;
|
||||
foreach (str; include)
|
||||
static if(isFunctionPointer!(attr)){}
|
||||
else static if(attr == "_tr_before")
|
||||
{
|
||||
if (match(str, attributes[0]))
|
||||
{
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
static assert(attr_id+1 < attributes.length);
|
||||
enum attr2 = attributes[attr_id + 1];
|
||||
//static assert(__traits(hasMember, module_, attr2));
|
||||
//alias func = __traits(getMember, module_, attr2);
|
||||
//attr2();
|
||||
before = attr2;
|
||||
//static assert(is(typeof(__traits(getMember, module_, attr2)) == void function()));
|
||||
}
|
||||
|
||||
foreach (str; exclude)
|
||||
else
|
||||
{
|
||||
if (match(str, attributes[0]))
|
||||
if (include.length > 0)
|
||||
{
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool matched = false;
|
||||
foreach (str; include)
|
||||
{
|
||||
if (match(str, attr))
|
||||
{
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
{
|
||||
suite.skipped++;
|
||||
continue;
|
||||
foreach (str; exclude)
|
||||
{
|
||||
if (match(str, attr))
|
||||
{
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
{
|
||||
suite.skipped++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -172,8 +210,9 @@ struct TestRunner(Args...)
|
|||
else
|
||||
test.name = attributes[0];
|
||||
|
||||
static if (__traits(hasMember, module_, "beforeEveryTest"))
|
||||
static if (__traits(hasMember, module_, "beforeEveryTest") && __traits(compiles, module_.beforeEveryTest()))
|
||||
module_.beforeEveryTest();
|
||||
if(before)before();
|
||||
|
||||
version(D_BetterC)
|
||||
{
|
||||
|
|
@ -189,8 +228,10 @@ struct TestRunner(Args...)
|
|||
}
|
||||
else
|
||||
{
|
||||
long time = Time.getUSecTime();
|
||||
unittest_();
|
||||
test.passed = true;
|
||||
test.time = cast(int)(Time.getUSecTime() - time);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -215,7 +256,7 @@ struct TestRunner(Args...)
|
|||
else
|
||||
suite.failed++;
|
||||
suite.tests ~= test;
|
||||
static if (__traits(hasMember, module_, "afterEveryTest"))
|
||||
static if (__traits(hasMember, module_, "afterEveryTest") && __traits(compiles, module_.beforeEveryTest()))
|
||||
module_.afterEveryTest();
|
||||
}
|
||||
passed += suite.passed;
|
||||
|
|
@ -281,6 +322,14 @@ struct TestRunner(Args...)
|
|||
junit.add(cast(ubyte[]) txt);
|
||||
}
|
||||
|
||||
void write(double num)
|
||||
{
|
||||
ubyte[40] buffer;
|
||||
int len;
|
||||
len = sprintf(cast(char*) buffer.ptr, "%2.8lf", num);
|
||||
junit.add(buffer[0 .. len]);
|
||||
}
|
||||
|
||||
void write(uint num)
|
||||
{
|
||||
ubyte[20] buffer;
|
||||
|
|
@ -304,6 +353,8 @@ version (notBetterC)
|
|||
version (D_Coverage) extern (C) void dmd_coverDestPath(string path);
|
||||
}
|
||||
|
||||
enum before = "_tr_before";
|
||||
|
||||
void extractStrings(ref Vector!string container, string str)
|
||||
{
|
||||
uint s = 0;
|
||||
|
|
@ -369,7 +420,7 @@ extern (C) int main(int argc, char** args)
|
|||
}
|
||||
}
|
||||
|
||||
TestRunner!(tests.runner, tests.id_manager, tests.vector, tests.basic) runner;
|
||||
TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf, tests.bugs, tests.map) runner;
|
||||
|
||||
runner.runTests(include[], exclude[]);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ module tests.tests;
|
|||
import std.experimental.allocator;
|
||||
import std.experimental.allocator.mallocator;*/
|
||||
|
||||
import ecs.entity;
|
||||
import ecs.events;
|
||||
import ecs.manager;
|
||||
import ecs.system;
|
||||
import ecs.attributes;
|
||||
import ecs.core;
|
||||
import bubel.ecs.entity;
|
||||
import bubel.ecs.events;
|
||||
import bubel.ecs.manager;
|
||||
import bubel.ecs.system;
|
||||
import bubel.ecs.attributes;
|
||||
import bubel.ecs.core;
|
||||
|
||||
version (WebAssembly)
|
||||
{
|
||||
|
|
@ -714,7 +714,7 @@ else:
|
|||
|
||||
//foreach(i; 0..1_000_000)gEM.removeEntity(gEM.addEntity(tmpl).id);
|
||||
|
||||
import ecs.std;
|
||||
import bubel.ecs.std;
|
||||
|
||||
EntityID[] idss = Mallocator.makeArray!EntityID(5000); //[5000]
|
||||
//scope(exit)Mallocator.dispose(idss);
|
||||
|
|
|
|||
66
tests/time.d
Normal file
66
tests/time.d
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
module tests.time;
|
||||
|
||||
|
||||
version (WebAssembly)
|
||||
{
|
||||
alias int time_t;
|
||||
alias int clockid_t;
|
||||
enum CLOCK_REALTIME = 0;
|
||||
|
||||
struct timespec
|
||||
{
|
||||
time_t tv_sec;
|
||||
int tv_nsec;
|
||||
}
|
||||
|
||||
extern (C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system;
|
||||
|
||||
struct Time
|
||||
{
|
||||
static long getUSecTime()
|
||||
{
|
||||
time_t time;
|
||||
timespec spec;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &spec);
|
||||
|
||||
//time = spec.tv_sec;
|
||||
return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000; //time / 1000_000;
|
||||
}
|
||||
}
|
||||
}
|
||||
else version (Windows)
|
||||
{
|
||||
import core.stdc.stdio : printf;
|
||||
import core.sys.windows.windows;
|
||||
|
||||
struct Time
|
||||
{
|
||||
static long getUSecTime()
|
||||
{
|
||||
LARGE_INTEGER time, freq;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&time);
|
||||
return time.QuadPart / (freq.QuadPart / 1000_000);
|
||||
}
|
||||
}
|
||||
}
|
||||
else version (Posix)
|
||||
{
|
||||
import core.stdc.stdio : printf;
|
||||
import core.sys.posix.time;
|
||||
|
||||
struct Time
|
||||
{
|
||||
static long getUSecTime()
|
||||
{
|
||||
time_t time;
|
||||
timespec spec;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &spec);
|
||||
|
||||
//time = spec.tv_sec;
|
||||
return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000; //time / 1000_000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,16 @@
|
|||
module tests.vector;
|
||||
|
||||
import ecs.simple_vector;
|
||||
//import ecs.vector;
|
||||
import bubel.ecs.simple_vector;
|
||||
import bubel.ecs.vector;
|
||||
|
||||
version(GNU)
|
||||
{
|
||||
pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
}
|
||||
else import std.array : staticArray;
|
||||
|
||||
@("simple-vector")
|
||||
unittest
|
||||
|
|
@ -33,3 +42,38 @@ unittest
|
|||
assert(vector2[1023] == 'a');
|
||||
assert(vector2[1024] == 'b');
|
||||
}
|
||||
|
||||
@("Vector")
|
||||
unittest
|
||||
{
|
||||
struct G
|
||||
{
|
||||
int a;
|
||||
}
|
||||
|
||||
Vector!G vector;
|
||||
assert(vector.empty());
|
||||
vector.add(G(1));
|
||||
assert(!vector.empty());
|
||||
vector.clear();
|
||||
assert(vector.empty());
|
||||
vector.add(G(1));
|
||||
assert(!vector.empty());
|
||||
vector.reset();
|
||||
assert(vector.empty());
|
||||
|
||||
vector.add(G(1));
|
||||
vector.add([G(2),G(5)].staticArray);
|
||||
assert(vector.length == 3);
|
||||
assert(vector.capacity == 1);
|
||||
|
||||
Vector!G vector2;
|
||||
vector2.add([G(1),G(2),G(5)].staticArray);
|
||||
assert(vector == vector2);
|
||||
vector2.remove(1);
|
||||
assert(vector != vector2);
|
||||
assert(vector2.length == 2);
|
||||
assert(vector2[1] == G(5));
|
||||
vector2.add(G(2),1);
|
||||
assert(vector == vector2);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue