242 lines
4.8 KiB
C++
242 lines
4.8 KiB
C++
#include <psemek/test/test.hpp>
|
|
|
|
#include <psemek/ecs/entity_container.hpp>
|
|
#include <psemek/ecs/declare_uuid.hpp>
|
|
#include <psemek/random/generator.hpp>
|
|
#include <psemek/random/uniform.hpp>
|
|
|
|
using namespace psemek;
|
|
using namespace psemek::ecs;
|
|
|
|
namespace
|
|
{
|
|
|
|
struct component_1
|
|
{
|
|
int value;
|
|
|
|
psemek_ecs_declare_uuid("component_1")
|
|
};
|
|
|
|
struct component_2
|
|
{
|
|
int value;
|
|
|
|
psemek_ecs_declare_uuid("component_2")
|
|
};
|
|
|
|
void check_impl(entity_container & container, int count0, int count1, int count2, int count12)
|
|
{
|
|
int call_count = 0;
|
|
container.apply<>([&]{ ++call_count; });
|
|
expect_equal(call_count, count0 + count1 + count2 + count12);
|
|
|
|
call_count = 0;
|
|
container.apply<component_1>([&](component_1 const &){ ++call_count; });
|
|
expect_equal(call_count, count1 + count12);
|
|
|
|
call_count = 0;
|
|
container.apply<component_2>([&](component_2 const &){ ++call_count; });
|
|
expect_equal(call_count, count2 + count12);
|
|
|
|
call_count = 0;
|
|
container.apply<component_1, component_2>([&](component_1 const &, component_2 const &){ ++call_count; });
|
|
expect_equal(call_count, count12);
|
|
}
|
|
|
|
}
|
|
|
|
test_case(ecs_attach_empty)
|
|
{
|
|
entity_container container;
|
|
|
|
auto h = container.create();
|
|
|
|
expect(container.get(h).get_if<component_1>() == nullptr);
|
|
expect(container.get(h).get_if<component_2>() == nullptr);
|
|
|
|
check_impl(container, 1, 0, 0, 0);
|
|
}
|
|
|
|
test_case(ecs_attach_one)
|
|
{
|
|
entity_container container;
|
|
|
|
auto h = container.create();
|
|
|
|
container.attach(h, component_1{10});
|
|
|
|
expect_equal(container.get(h).get<component_1>().value, 10);
|
|
expect(container.get(h).get_if<component_2>() == nullptr);
|
|
|
|
check_impl(container, 0, 1, 0, 0);
|
|
}
|
|
|
|
test_case(ecs_attach_twice)
|
|
{
|
|
entity_container container;
|
|
|
|
auto h = container.create();
|
|
|
|
container.attach(h, component_1{10});
|
|
container.attach(h, component_1{11});
|
|
|
|
expect_equal(container.get(h).get<component_1>().value, 11);
|
|
expect(container.get(h).get_if<component_2>() == nullptr);
|
|
|
|
check_impl(container, 0, 1, 0, 0);
|
|
}
|
|
|
|
test_case(ecs_attach_two)
|
|
{
|
|
entity_container container;
|
|
|
|
auto h = container.create();
|
|
|
|
container.attach(h, component_1{10});
|
|
container.attach(h, component_2{20});
|
|
|
|
expect_equal(container.get(h).get<component_1>().value, 10);
|
|
expect_equal(container.get(h).get<component_2>().value, 20);
|
|
|
|
check_impl(container, 0, 0, 0, 1);
|
|
}
|
|
|
|
test_case(ecs_detach_empty)
|
|
{
|
|
entity_container container;
|
|
|
|
auto h = container.create();
|
|
|
|
container.detach<component_1>(h);
|
|
|
|
expect(container.get(h).get_if<component_1>() == nullptr);
|
|
expect(container.get(h).get_if<component_2>() == nullptr);
|
|
|
|
check_impl(container, 1, 0, 0, 0);
|
|
}
|
|
|
|
test_case(ecs_detach_nonexistent)
|
|
{
|
|
entity_container container;
|
|
|
|
auto h = container.create(component_1{10});
|
|
|
|
container.detach<component_2>(h);
|
|
|
|
expect_equal(container.get(h).get<component_1>().value, 10);
|
|
expect(container.get(h).get_if<component_2>() == nullptr);
|
|
|
|
check_impl(container, 0, 1, 0, 0);
|
|
}
|
|
|
|
test_case(ecs_detach_one)
|
|
{
|
|
entity_container container;
|
|
|
|
auto h = container.create(component_1{10}, component_2{20});
|
|
|
|
container.detach<component_2>(h);
|
|
|
|
expect_equal(container.get(h).get<component_1>().value, 10);
|
|
expect(container.get(h).get_if<component_2>() == nullptr);
|
|
|
|
check_impl(container, 0, 1, 0, 0);
|
|
}
|
|
|
|
test_case(ecs_detach_two)
|
|
{
|
|
entity_container container;
|
|
|
|
auto h = container.create(component_1{10}, component_2{20});
|
|
|
|
container.detach<component_1>(h);
|
|
container.detach<component_2>(h);
|
|
|
|
expect(container.get(h).get_if<component_1>() == nullptr);
|
|
expect(container.get(h).get_if<component_2>() == nullptr);
|
|
|
|
check_impl(container, 1, 0, 0, 0);
|
|
}
|
|
|
|
test_case(ecs_attach_random)
|
|
{
|
|
random::generator rng;
|
|
entity_container container;
|
|
|
|
int count0 = 0;
|
|
int count1 = 0;
|
|
int count2 = 0;
|
|
int count12 = 0;
|
|
|
|
for (int i = 0; i < 1024 * 1024; ++i)
|
|
{
|
|
auto h = container.create();
|
|
|
|
bool has1 = random::uniform<bool>(rng);
|
|
bool has2 = random::uniform<bool>(rng);
|
|
|
|
if (has1 && has2)
|
|
{
|
|
container.attach(h, component_1{i}, component_2{2 * i});
|
|
++count12;
|
|
}
|
|
else if (has1 && !has2)
|
|
{
|
|
container.attach(h, component_1{i});
|
|
++count1;
|
|
}
|
|
else if (!has1 && has2)
|
|
{
|
|
container.attach(h, component_2{2 * i});
|
|
++count2;
|
|
}
|
|
else
|
|
{
|
|
++count0;
|
|
}
|
|
}
|
|
|
|
check_impl(container, count0, count1, count2, count12);
|
|
}
|
|
|
|
test_case(ecs_detach_random)
|
|
{
|
|
random::generator rng;
|
|
entity_container container;
|
|
|
|
int count0 = 0;
|
|
int count1 = 0;
|
|
int count2 = 0;
|
|
int count12 = 0;
|
|
|
|
for (int i = 0; i < 1024 * 1024; ++i)
|
|
{
|
|
auto h = container.create(component_1{i}, component_2{2 * i});
|
|
|
|
bool has1 = random::uniform<bool>(rng);
|
|
bool has2 = random::uniform<bool>(rng);
|
|
|
|
if (has1 && has2)
|
|
{
|
|
++count12;
|
|
}
|
|
else if (has1 && !has2)
|
|
{
|
|
container.detach<component_2>(h);
|
|
++count1;
|
|
}
|
|
else if (!has1 && has2)
|
|
{
|
|
container.detach<component_1>(h);
|
|
++count2;
|
|
}
|
|
else
|
|
{
|
|
container.detach<component_1, component_2>(h);
|
|
++count0;
|
|
}
|
|
}
|
|
|
|
check_impl(container, count0, count1, count2, count12);
|
|
}
|