Remove Nazara SDK
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
#include <NazaraSDK/ClientApplication.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
|
||||
SCENARIO("Application", "[NDK][APPLICATION]")
|
||||
{
|
||||
GIVEN("An application")
|
||||
{
|
||||
Nz::Window& window = Ndk::ClientApplication::Instance()->AddWindow<Nz::Window>();
|
||||
|
||||
WHEN("We open a window")
|
||||
{
|
||||
REQUIRE(window.Create(Nz::VideoMode(800, 600, 32), "Nazara Unit Tests"));
|
||||
|
||||
AND_WHEN("We close the open window")
|
||||
{
|
||||
window.Close();
|
||||
|
||||
THEN("Application should close")
|
||||
{
|
||||
REQUIRE(!Ndk::Application::Instance()->Run());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#include <NazaraSDK/System.hpp>
|
||||
#include <NazaraSDK/Components/NodeComponent.hpp>
|
||||
#include <NazaraSDK/Components/VelocityComponent.hpp>
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestSystem : public Ndk::System<TestSystem>
|
||||
{
|
||||
public:
|
||||
TestSystem()
|
||||
{
|
||||
Requires<Ndk::VelocityComponent>();
|
||||
Excludes<Ndk::NodeComponent>();
|
||||
}
|
||||
|
||||
~TestSystem() = default;
|
||||
|
||||
static Ndk::SystemIndex systemIndex;
|
||||
|
||||
private:
|
||||
void OnUpdate(float /*elapsedTime*/) override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
Ndk::SystemIndex TestSystem::systemIndex;
|
||||
}
|
||||
|
||||
SCENARIO("BaseSystem", "[NDK][BASESYSTEM]")
|
||||
{
|
||||
GIVEN("Our TestSystem")
|
||||
{
|
||||
Ndk::World world;
|
||||
|
||||
Ndk::BaseSystem& system = world.AddSystem<TestSystem>();
|
||||
REQUIRE(&system.GetWorld() == &world);
|
||||
|
||||
WHEN("We add an entity")
|
||||
{
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
entity->AddComponent<Ndk::VelocityComponent>();
|
||||
|
||||
THEN("System should have it")
|
||||
{
|
||||
world.Update(1.f);
|
||||
REQUIRE(system.HasEntity(entity));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We add an entity with excluded component")
|
||||
{
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
entity->AddComponent<Ndk::VelocityComponent>();
|
||||
entity->AddComponent<Ndk::NodeComponent>();
|
||||
|
||||
THEN("System should not have it")
|
||||
{
|
||||
world.Update(1.f);
|
||||
REQUIRE(!system.HasEntity(entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#include <NazaraSDK/Component.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestComponent : public Ndk::Component<TestComponent>
|
||||
{
|
||||
public:
|
||||
TestComponent(int value) :
|
||||
m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
int GetValue() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
int m_value;
|
||||
|
||||
static Ndk::ComponentIndex componentIndex;
|
||||
};
|
||||
|
||||
Ndk::ComponentIndex TestComponent::componentIndex;
|
||||
}
|
||||
|
||||
SCENARIO("Component", "[NDK][COMPONENT]")
|
||||
{
|
||||
GIVEN("Our TestComponent")
|
||||
{
|
||||
TestComponent testComponent(42);
|
||||
|
||||
WHEN("We clone it")
|
||||
{
|
||||
std::unique_ptr<Ndk::BaseComponent> clone = testComponent.Clone();
|
||||
|
||||
THEN("We should get a copy")
|
||||
{
|
||||
REQUIRE(static_cast<TestComponent*>(clone.get())->GetValue() == 42);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <NazaraSDK/Component.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
class UpdatableComponent : public Ndk::Component<UpdatableComponent>
|
||||
{
|
||||
public:
|
||||
bool IsUpdated()
|
||||
{
|
||||
return m_updated;
|
||||
}
|
||||
|
||||
void SetUpdated()
|
||||
{
|
||||
m_updated = true;
|
||||
}
|
||||
|
||||
static Ndk::ComponentIndex componentIndex;
|
||||
|
||||
private:
|
||||
bool m_updated = false;
|
||||
};
|
||||
|
||||
Ndk::ComponentIndex UpdatableComponent::componentIndex;
|
||||
|
||||
class UpdateSystem : public Ndk::System<UpdateSystem>
|
||||
{
|
||||
public:
|
||||
UpdateSystem()
|
||||
{
|
||||
Requires<UpdatableComponent>();
|
||||
}
|
||||
|
||||
~UpdateSystem() = default;
|
||||
|
||||
static Ndk::SystemIndex systemIndex;
|
||||
|
||||
private:
|
||||
void OnUpdate(float /*elapsedTime*/) override
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : GetEntities())
|
||||
{
|
||||
UpdatableComponent& updatable = entity->GetComponent<UpdatableComponent>();
|
||||
updatable.SetUpdated();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ndk::SystemIndex UpdateSystem::systemIndex;
|
||||
}
|
||||
|
||||
SCENARIO("Entity", "[NDK][ENTITY]")
|
||||
{
|
||||
GIVEN("A world & an entity")
|
||||
{
|
||||
Ndk::World world;
|
||||
|
||||
Ndk::BaseSystem& system = world.AddSystem<UpdateSystem>();
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
|
||||
WHEN("We add our UpdateComponent")
|
||||
{
|
||||
UpdatableComponent& updatableComponent = entity->AddComponent<UpdatableComponent>();
|
||||
CHECK(!updatableComponent.IsUpdated());
|
||||
|
||||
THEN("Update the world should update the entity's component")
|
||||
{
|
||||
world.Update(1.f);
|
||||
UpdatableComponent& updatableComponentGet = entity->GetComponent<UpdatableComponent>();
|
||||
CHECK(updatableComponentGet.IsUpdated());
|
||||
}
|
||||
|
||||
THEN("Update the world should not update the entity's component if it's disabled")
|
||||
{
|
||||
entity->Enable(false);
|
||||
world.Update(1.f);
|
||||
UpdatableComponent& updatableComponentGet = entity->GetComponent<UpdatableComponent>();
|
||||
CHECK(!updatableComponentGet.IsUpdated());
|
||||
}
|
||||
|
||||
THEN("We can remove its component")
|
||||
{
|
||||
entity->RemoveComponent(Ndk::GetComponentIndex<UpdatableComponent>());
|
||||
world.Update(1.f);
|
||||
CHECK(!entity->HasComponent<UpdatableComponent>());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We kill our entity")
|
||||
{
|
||||
entity->Kill();
|
||||
world.Update(1.f);
|
||||
|
||||
THEN("It's no more valid")
|
||||
{
|
||||
CHECK(!world.IsEntityValid(entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#include <NazaraSDK/EntityList.hpp>
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
SCENARIO("EntityList", "[NDK][ENTITYLIST]")
|
||||
{
|
||||
GIVEN("A world & a set of entities")
|
||||
{
|
||||
Ndk::World world;
|
||||
|
||||
const Ndk::EntityHandle& entity = world.CreateEntity();
|
||||
Ndk::EntityList entityList;
|
||||
entityList.Insert(entity);
|
||||
|
||||
WHEN("We ask if entity is in there")
|
||||
{
|
||||
THEN("These results are expected")
|
||||
{
|
||||
REQUIRE(entityList.Has(entity->GetId()));
|
||||
const Ndk::EntityHandle& newEntity = world.CreateEntity();
|
||||
REQUIRE(!entityList.Has(newEntity->GetId()));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We remove then insert")
|
||||
{
|
||||
entityList.Remove(*entityList.begin());
|
||||
|
||||
THEN("Set should be empty")
|
||||
{
|
||||
REQUIRE(entityList.empty());
|
||||
}
|
||||
|
||||
entityList.Insert(entity);
|
||||
|
||||
THEN("With one element")
|
||||
{
|
||||
REQUIRE(!entityList.empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
#include <NazaraSDK/EntityOwner.hpp>
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
SCENARIO("EntityOwner", "[NDK][ENTITYOWNER]")
|
||||
{
|
||||
GIVEN("A world & an entity")
|
||||
{
|
||||
Ndk::World world;
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
|
||||
WHEN("We set the ownership of the entity to our owner")
|
||||
{
|
||||
THEN("Entity is still valid")
|
||||
{
|
||||
REQUIRE(entity.IsValid());
|
||||
|
||||
Ndk::EntityOwner entityOwner(entity);
|
||||
|
||||
world.Refresh();
|
||||
CHECK(entity.IsValid());
|
||||
}
|
||||
|
||||
THEN("Moving an entity owner by constructor works")
|
||||
{
|
||||
REQUIRE(entity.IsValid());
|
||||
|
||||
Ndk::EntityOwner entityOwner(entity);
|
||||
Ndk::EntityOwner entityOwner2(std::move(entityOwner));
|
||||
entityOwner.Reset();
|
||||
|
||||
world.Refresh();
|
||||
CHECK(entity.IsValid());
|
||||
|
||||
entityOwner2.Reset();
|
||||
|
||||
world.Refresh();
|
||||
CHECK(!entity.IsValid());
|
||||
}
|
||||
|
||||
THEN("Moving an entity owner by operator= works")
|
||||
{
|
||||
REQUIRE(entity.IsValid());
|
||||
|
||||
Ndk::EntityOwner entityOwner(entity);
|
||||
Ndk::EntityOwner entityOwner2;
|
||||
entityOwner2 = std::move(entityOwner);
|
||||
entityOwner.Reset();
|
||||
|
||||
world.Refresh();
|
||||
CHECK(entity.IsValid());
|
||||
|
||||
entityOwner2.Reset();
|
||||
|
||||
world.Refresh();
|
||||
CHECK(!entity.IsValid());
|
||||
}
|
||||
|
||||
THEN("Destroying an entity owner destroys its entity")
|
||||
{
|
||||
REQUIRE(entity.IsValid());
|
||||
|
||||
{
|
||||
Ndk::EntityOwner entityOwner(entity);
|
||||
}
|
||||
|
||||
world.Refresh();
|
||||
CHECK(!entity.IsValid());
|
||||
}
|
||||
|
||||
|
||||
THEN("Resetting an entity owner destroys its entity")
|
||||
{
|
||||
REQUIRE(entity.IsValid());
|
||||
|
||||
Ndk::EntityOwner entityOwner(entity);
|
||||
entityOwner.Reset();
|
||||
|
||||
world.Refresh();
|
||||
CHECK(!entity.IsValid());
|
||||
}
|
||||
|
||||
THEN("Assigning another entity destroys the first entity")
|
||||
{
|
||||
REQUIRE(entity.IsValid());
|
||||
|
||||
Ndk::EntityOwner entityOwner(entity);
|
||||
entityOwner = world.CreateEntity();
|
||||
|
||||
world.Refresh();
|
||||
CHECK(!entity.IsValid());
|
||||
}
|
||||
|
||||
THEN("Moving another entity destroys the first entity")
|
||||
{
|
||||
REQUIRE(entity.IsValid());
|
||||
|
||||
Ndk::EntityOwner entityOwner(entity);
|
||||
Ndk::EntityHandle entity2 = world.CreateEntity();
|
||||
|
||||
entityOwner = std::move(entity2);
|
||||
|
||||
world.Refresh();
|
||||
CHECK(!entity.IsValid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A vector of EntityOwner")
|
||||
{
|
||||
Ndk::World world;
|
||||
|
||||
std::vector<Ndk::EntityOwner> entityOwners;
|
||||
for (std::size_t i = 1; i <= 10; ++i)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : world.CreateEntities(10 * i))
|
||||
entityOwners.emplace_back(entity);
|
||||
|
||||
entityOwners.clear();
|
||||
world.Refresh();
|
||||
|
||||
std::size_t aliveEntities = 0;
|
||||
for (const Ndk::EntityHandle& entity : world.GetEntities())
|
||||
aliveEntities++;
|
||||
|
||||
CHECK(aliveEntities == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
#include <NazaraSDK/StateMachine.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
class TestState : public Ndk::State
|
||||
{
|
||||
public:
|
||||
void Enter(Ndk::StateMachine& /*fsm*/) override
|
||||
{
|
||||
m_isUpdated = false;
|
||||
}
|
||||
|
||||
bool IsUpdated() const
|
||||
{
|
||||
return m_isUpdated;
|
||||
}
|
||||
|
||||
void Leave(Ndk::StateMachine& /*fsm*/) override
|
||||
{
|
||||
}
|
||||
|
||||
bool Update(Ndk::StateMachine& /*fsm*/, float /*elapsedTime*/) override
|
||||
{
|
||||
m_isUpdated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isUpdated;
|
||||
};
|
||||
|
||||
class SecondTestState : public Ndk::State
|
||||
{
|
||||
public:
|
||||
void Enter(Ndk::StateMachine& /*fsm*/) override
|
||||
{
|
||||
m_isUpdated = false;
|
||||
}
|
||||
|
||||
bool IsUpdated() const
|
||||
{
|
||||
return m_isUpdated;
|
||||
}
|
||||
|
||||
void Leave(Ndk::StateMachine& /*fsm*/) override
|
||||
{
|
||||
}
|
||||
|
||||
bool Update(Ndk::StateMachine& fsm, float /*elapsedTime*/) override
|
||||
{
|
||||
if (fsm.IsTopState(this))
|
||||
m_isUpdated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isUpdated;
|
||||
};
|
||||
|
||||
SCENARIO("State & StateMachine", "[NDK][STATE]")
|
||||
{
|
||||
GIVEN("A statemachine with our test states")
|
||||
{
|
||||
std::shared_ptr<TestState> testState = std::make_shared<TestState>();
|
||||
std::shared_ptr<SecondTestState> secondTestState = std::make_shared<SecondTestState>();
|
||||
Ndk::StateMachine stateMachine(secondTestState);
|
||||
stateMachine.PushState(testState);
|
||||
CHECK(!testState->IsUpdated());
|
||||
CHECK(!secondTestState->IsUpdated());
|
||||
|
||||
WHEN("We update our machine")
|
||||
{
|
||||
stateMachine.Update(1.f);
|
||||
|
||||
THEN("Our state on the top has been updated but not the bottom one")
|
||||
{
|
||||
CHECK(stateMachine.IsTopState(testState.get()));
|
||||
CHECK(!stateMachine.IsTopState(secondTestState.get()));
|
||||
|
||||
CHECK(testState->IsUpdated());
|
||||
CHECK(!secondTestState->IsUpdated());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We exchange the states' positions while emptying the stack")
|
||||
{
|
||||
stateMachine.PopStatesUntil(secondTestState);
|
||||
stateMachine.Update(1.f);
|
||||
CHECK(stateMachine.IsTopState(secondTestState.get()));
|
||||
|
||||
stateMachine.ResetState(testState);
|
||||
stateMachine.PushState(secondTestState);
|
||||
|
||||
stateMachine.Update(1.f);
|
||||
|
||||
THEN("Both states should be updated")
|
||||
{
|
||||
CHECK(!stateMachine.IsTopState(testState.get()));
|
||||
CHECK(stateMachine.IsTopState(secondTestState.get()));
|
||||
|
||||
CHECK(testState->IsUpdated());
|
||||
CHECK(secondTestState->IsUpdated());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
#include <NazaraSDK/System.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestSystem : public Ndk::System<TestSystem>
|
||||
{
|
||||
public:
|
||||
TestSystem() :
|
||||
m_updateCounter(0),
|
||||
m_elapsedTime(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
~TestSystem() = default;
|
||||
|
||||
float GetElapsedTime() const
|
||||
{
|
||||
return m_elapsedTime;
|
||||
}
|
||||
|
||||
std::size_t GetLoopCount() const
|
||||
{
|
||||
return m_updateCounter;
|
||||
}
|
||||
|
||||
static Ndk::SystemIndex systemIndex;
|
||||
|
||||
private:
|
||||
std::size_t m_updateCounter;
|
||||
float m_elapsedTime;
|
||||
|
||||
void OnUpdate(float elapsedTime) override
|
||||
{
|
||||
++m_updateCounter;
|
||||
|
||||
m_elapsedTime += elapsedTime;
|
||||
}
|
||||
};
|
||||
|
||||
Ndk::SystemIndex TestSystem::systemIndex;
|
||||
}
|
||||
|
||||
SCENARIO("System", "[NDK][SYSTEM]")
|
||||
{
|
||||
GIVEN("Our TestSystem")
|
||||
{
|
||||
TestSystem testSystem;
|
||||
testSystem.SetMaximumUpdateRate(30.f);
|
||||
|
||||
float maxTimePerFrame = 1 / 30.f;
|
||||
|
||||
WHEN("We update it with a higher framerate")
|
||||
{
|
||||
float timePerFrame = maxTimePerFrame / 2.f;
|
||||
float elapsedTime = 2.f;
|
||||
|
||||
std::size_t loopCount = static_cast<std::size_t>(std::round(elapsedTime / timePerFrame));
|
||||
|
||||
for (std::size_t i = 0; i < loopCount; ++i)
|
||||
testSystem.Update(timePerFrame);
|
||||
|
||||
CHECK(testSystem.GetLoopCount() == loopCount / 2);
|
||||
CHECK(testSystem.GetElapsedTime() == Approx(elapsedTime).epsilon(timePerFrame));
|
||||
}
|
||||
|
||||
WHEN("We update it with a lower framerate")
|
||||
{
|
||||
float timePerFrame = maxTimePerFrame * 2.f;
|
||||
float elapsedTime = 10.f;
|
||||
|
||||
std::size_t loopCount = static_cast<std::size_t>(std::round(elapsedTime / timePerFrame));
|
||||
|
||||
for (std::size_t i = 0; i < loopCount; ++i)
|
||||
testSystem.Update(timePerFrame);
|
||||
|
||||
CHECK(testSystem.GetLoopCount() == loopCount);
|
||||
CHECK(testSystem.GetElapsedTime() == Approx(elapsedTime).epsilon(timePerFrame));
|
||||
|
||||
AND_WHEN("We suddenly increase framerate")
|
||||
{
|
||||
float newTimePerFrame = 1 / 300.f;
|
||||
float newElapsedTime = 100.f;
|
||||
|
||||
std::size_t newLoopCount = static_cast<std::size_t>(std::round(newElapsedTime / newTimePerFrame));
|
||||
|
||||
for (std::size_t i = 0; i < newLoopCount; ++i)
|
||||
testSystem.Update(newTimePerFrame);
|
||||
|
||||
CHECK(testSystem.GetLoopCount() == loopCount + newLoopCount / 10);
|
||||
CHECK(testSystem.GetElapsedTime() == Approx(elapsedTime + newElapsedTime).epsilon(newTimePerFrame));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WHEN("We update it with a very low framerate")
|
||||
{
|
||||
float timePerFrame = 0.5f;
|
||||
|
||||
for (std::size_t i = 0; i < 10; ++i)
|
||||
testSystem.Update(timePerFrame);
|
||||
|
||||
CHECK(testSystem.GetLoopCount() == 10);
|
||||
CHECK(testSystem.GetElapsedTime() == Approx(5.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#include <NazaraSDK/Systems/ListenerSystem.hpp>
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <NazaraSDK/Components/ListenerComponent.hpp>
|
||||
#include <NazaraSDK/Components/NodeComponent.hpp>
|
||||
#include <NazaraSDK/Components/VelocityComponent.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
|
||||
SCENARIO("ListenerSystem", "[NDK][LISTENERSYSTEM]")
|
||||
{
|
||||
GIVEN("A world and an entity with listener & node components")
|
||||
{
|
||||
Ndk::World world;
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
Ndk::ListenerComponent& listenerComponent = entity->AddComponent<Ndk::ListenerComponent>();
|
||||
Ndk::NodeComponent& nodeComponent = entity->AddComponent<Ndk::NodeComponent>();
|
||||
|
||||
WHEN("We move our entity")
|
||||
{
|
||||
Nz::Vector3f position = Nz::Vector3f::Unit() * 3.f;
|
||||
nodeComponent.SetPosition(position);
|
||||
Nz::Quaternionf rotation = Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::Up());
|
||||
nodeComponent.SetRotation(rotation);
|
||||
world.Update(1.f);
|
||||
|
||||
THEN("Our listener should have moved")
|
||||
{
|
||||
REQUIRE(Nz::Audio::Instance()->GetListenerPosition() == position);
|
||||
REQUIRE(Nz::Audio::Instance()->GetListenerRotation() == rotation);
|
||||
}
|
||||
|
||||
THEN("With a component of velocity")
|
||||
{
|
||||
Ndk::VelocityComponent& velocityComponent = entity->AddComponent<Ndk::VelocityComponent>();
|
||||
Nz::Vector3f velocity = Nz::Vector3f::Unit() * 2.f;
|
||||
velocityComponent.linearVelocity = velocity;
|
||||
|
||||
world.Update(1.f);
|
||||
REQUIRE(Nz::Audio::Instance()->GetListenerVelocity() == velocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
#include <NazaraSDK/Systems/PhysicsSystem2D.hpp>
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <NazaraSDK/Components/CollisionComponent2D.hpp>
|
||||
#include <NazaraSDK/Components/NodeComponent.hpp>
|
||||
#include <NazaraSDK/Components/PhysicsComponent2D.hpp>
|
||||
#include <NazaraSDK/Systems/PhysicsSystem2D.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
#include <limits>
|
||||
|
||||
Ndk::EntityHandle CreateBaseEntity(Ndk::World& world, const Nz::Vector2f& position, const Nz::Rectf& AABB);
|
||||
|
||||
SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]")
|
||||
{
|
||||
GIVEN("A world and an entity")
|
||||
{
|
||||
Ndk::World world;
|
||||
world.AddSystem<Ndk::PhysicsSystem2D>();
|
||||
|
||||
Nz::Vector2f position(2.f, 3.f);
|
||||
Nz::Rectf movingAABB(0.f, 0.f, 16.f, 18.f);
|
||||
Ndk::EntityHandle movingEntity = CreateBaseEntity(world, position, movingAABB);
|
||||
Ndk::NodeComponent& nodeComponent = movingEntity->GetComponent<Ndk::NodeComponent>();
|
||||
Ndk::PhysicsComponent2D& physicsComponent2D = movingEntity->AddComponent<Ndk::PhysicsComponent2D>();
|
||||
|
||||
world.GetSystem<Ndk::PhysicsSystem2D>().SetMaximumUpdateRate(0.f);
|
||||
world.GetSystem<Ndk::PhysicsSystem2D>().SetMaxStepCount(std::numeric_limits<std::size_t>::max());
|
||||
|
||||
WHEN("We update the world")
|
||||
{
|
||||
world.Update(1.f);
|
||||
|
||||
THEN("Entity should have correct bounding box")
|
||||
{
|
||||
REQUIRE(nodeComponent.GetPosition() == position);
|
||||
movingAABB.Translate(position);
|
||||
REQUIRE(physicsComponent2D.GetAABB() == movingAABB);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We make it collide with a wall")
|
||||
{
|
||||
int rawDistance = 3;
|
||||
Nz::Vector2f distance(float(rawDistance), 0.f);
|
||||
Nz::Vector2f wallPosition = position + Nz::Vector2f(movingAABB.width, 0.f) + distance;
|
||||
Nz::Rectf wallAABB(0.f, 0.f, 100.f, 100.f);
|
||||
Ndk::EntityHandle wallEntity = CreateBaseEntity(world, wallPosition, wallAABB);
|
||||
|
||||
world.Update(1.f);
|
||||
|
||||
THEN("It should move freely")
|
||||
{
|
||||
REQUIRE(nodeComponent.GetPosition() == position);
|
||||
movingAABB.Translate(position);
|
||||
REQUIRE(physicsComponent2D.GetAABB() == movingAABB);
|
||||
|
||||
physicsComponent2D.SetVelocity(Nz::Vector2f::UnitX());
|
||||
|
||||
for (int i = 0; i < rawDistance; ++i)
|
||||
{
|
||||
world.Update(1.f);
|
||||
position += Nz::Vector2f::UnitX();
|
||||
REQUIRE(nodeComponent.GetPosition() == position);
|
||||
movingAABB.Translate(Nz::Vector2f::UnitX());
|
||||
REQUIRE(physicsComponent2D.GetAABB() == movingAABB);
|
||||
}
|
||||
}
|
||||
|
||||
AND_THEN("It should be stopped by it")
|
||||
{
|
||||
world.Update(1.f);
|
||||
REQUIRE(nodeComponent.GetPosition().SquaredDistance(position) < 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A world and a simple entity")
|
||||
{
|
||||
Ndk::World world;
|
||||
world.AddSystem<Ndk::PhysicsSystem2D>();
|
||||
|
||||
Nz::Vector2f position(0.f, 0.f);
|
||||
Nz::Rectf movingAABB(0.f, 0.f, 1.f, 2.f);
|
||||
Ndk::EntityHandle movingEntity = CreateBaseEntity(world, position, movingAABB);
|
||||
Ndk::NodeComponent& nodeComponent = movingEntity->GetComponent<Ndk::NodeComponent>();
|
||||
Ndk::PhysicsComponent2D& physicsComponent2D = movingEntity->AddComponent<Ndk::PhysicsComponent2D>();
|
||||
physicsComponent2D.SetMassCenter(Nz::Vector2f::Zero());
|
||||
physicsComponent2D.SetPosition(position);
|
||||
|
||||
world.GetSystem<Ndk::PhysicsSystem2D>().SetFixedUpdateRate(30.f);
|
||||
|
||||
WHEN("We make rotate our entity")
|
||||
{
|
||||
Nz::RadianAnglef angularSpeed = Nz::RadianAnglef::FromDegrees(45.f);
|
||||
physicsComponent2D.SetAngularVelocity(angularSpeed);
|
||||
world.Update(2.f);
|
||||
|
||||
THEN("It should have been rotated")
|
||||
{
|
||||
CHECK(physicsComponent2D.GetAngularVelocity() == angularSpeed);
|
||||
CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(-2.f, 0.f, 2.f, 1.f));
|
||||
CHECK(physicsComponent2D.GetRotation() == Nz::RadianAnglef::FromDegrees(90.f));
|
||||
CHECK(nodeComponent.GetRotation().ToEulerAngles().roll == Nz::DegreeAnglef(90.f));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We put a force on it")
|
||||
{
|
||||
float stepSize = world.GetSystem<Ndk::PhysicsSystem2D>().GetStepSize();
|
||||
Nz::Vector2f velocity = Nz::Vector2f::UnitX();
|
||||
physicsComponent2D.AddForce(velocity / stepSize);
|
||||
world.Update(1.f);
|
||||
|
||||
THEN("Velocity should be the one targetted")
|
||||
{
|
||||
REQUIRE(physicsComponent2D.GetVelocity() == velocity);
|
||||
world.Update(99.f);
|
||||
REQUIRE(physicsComponent2D.GetPosition().Distance(Nz::Vector2f::UnitX() * 100.f) < 1.f);
|
||||
REQUIRE(nodeComponent.GetPosition().Distance(Nz::Vector2f::UnitX() * 100.f) < 1.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A world and a simple entity not at the origin")
|
||||
{
|
||||
Ndk::World world;
|
||||
world.AddSystem<Ndk::PhysicsSystem2D>();
|
||||
|
||||
Nz::Vector2f position(3.f, 4.f);
|
||||
Nz::Rectf movingAABB(0.f, 0.f, 1.f, 2.f);
|
||||
Ndk::EntityHandle movingEntity = CreateBaseEntity(world, position, movingAABB);
|
||||
Ndk::NodeComponent& nodeComponent = movingEntity->GetComponent<Ndk::NodeComponent>();
|
||||
Ndk::PhysicsComponent2D& physicsComponent2D = movingEntity->AddComponent<Ndk::PhysicsComponent2D>();
|
||||
physicsComponent2D.SetMassCenter(Nz::Vector2f::Zero());
|
||||
physicsComponent2D.SetPosition(position);
|
||||
|
||||
world.GetSystem<Ndk::PhysicsSystem2D>().SetFixedUpdateRate(30.f);
|
||||
|
||||
WHEN("We make rotate our entity")
|
||||
{
|
||||
Nz::RadianAnglef angularSpeed = Nz::RadianAnglef::FromDegrees(45.f);
|
||||
physicsComponent2D.SetAngularVelocity(angularSpeed);
|
||||
world.Update(2.f);
|
||||
|
||||
THEN("It should have been rotated")
|
||||
{
|
||||
CHECK(physicsComponent2D.GetAngularVelocity() == angularSpeed);
|
||||
CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(1.f, 4.f, 2.f, 1.f));
|
||||
CHECK(physicsComponent2D.GetRotation() == 2.f * angularSpeed);
|
||||
CHECK(nodeComponent.GetPosition() == position);
|
||||
CHECK(nodeComponent.GetRotation().ToEulerAngles().roll == Nz::DegreeAnglef(90.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ndk::EntityHandle CreateBaseEntity(Ndk::World& world, const Nz::Vector2f& position, const Nz::Rectf& AABB)
|
||||
{
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
Ndk::NodeComponent& nodeComponent = entity->AddComponent<Ndk::NodeComponent>();
|
||||
nodeComponent.SetPosition(position);
|
||||
std::shared_ptr<Nz::BoxCollider2D> collisionBox = std::make_shared<Nz::BoxCollider2D>(AABB);
|
||||
entity->AddComponent<Ndk::CollisionComponent2D>(collisionBox);
|
||||
return entity;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#include <NazaraSDK/Systems/PhysicsSystem3D.hpp>
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <NazaraSDK/Components/CollisionComponent3D.hpp>
|
||||
#include <NazaraSDK/Components/NodeComponent.hpp>
|
||||
#include <NazaraSDK/Components/PhysicsComponent3D.hpp>
|
||||
#include <NazaraSDK/Systems/PhysicsSystem3D.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
SCENARIO("PhysicsSystem3D", "[NDK][PHYSICSSYSTEM3D]")
|
||||
{
|
||||
GIVEN("A world and a static entity & a dynamic entity")
|
||||
{
|
||||
Ndk::World world;
|
||||
world.AddSystem<Ndk::PhysicsSystem3D>();
|
||||
|
||||
const Ndk::EntityHandle& staticEntity = world.CreateEntity();
|
||||
Ndk::CollisionComponent3D& collisionComponentStatic = staticEntity->AddComponent<Ndk::CollisionComponent3D>();
|
||||
Ndk::NodeComponent& nodeComponentStatic = staticEntity->AddComponent<Ndk::NodeComponent>();
|
||||
|
||||
const Ndk::EntityHandle& dynamicEntity = world.CreateEntity();
|
||||
Ndk::NodeComponent& nodeComponentDynamic = dynamicEntity->AddComponent<Ndk::NodeComponent>();
|
||||
Ndk::PhysicsComponent3D& physicsComponentDynamic = dynamicEntity->AddComponent<Ndk::PhysicsComponent3D>();
|
||||
|
||||
WHEN("We make collide these two entities")
|
||||
{
|
||||
nodeComponentDynamic.SetPosition(-Nz::Vector3f::UnitZ());
|
||||
physicsComponentDynamic.AddForce(Nz::Vector3f::UnitZ());
|
||||
|
||||
THEN("The dynamic entity should have hit the static one")
|
||||
{
|
||||
world.Update(1.f); // On origin
|
||||
world.Update(1.f); // On origin due to collision
|
||||
REQUIRE(nodeComponentStatic.GetPosition().SquaredDistance(nodeComponentDynamic.GetPosition()) < 0.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#include <NazaraSDK/Systems/VelocitySystem.hpp>
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <NazaraSDK/Components/NodeComponent.hpp>
|
||||
#include <NazaraSDK/Components/VelocityComponent.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
SCENARIO("VelocitySystem", "[NDK][VELOCITYSYSTEM]")
|
||||
{
|
||||
GIVEN("A world and an entity with velocity & node components")
|
||||
{
|
||||
Ndk::World world;
|
||||
const Ndk::EntityHandle& entity = world.CreateEntity();
|
||||
Ndk::VelocityComponent& velocityComponent = entity->AddComponent<Ndk::VelocityComponent>();
|
||||
Ndk::NodeComponent& nodeComponent = entity->AddComponent<Ndk::NodeComponent>();
|
||||
|
||||
world.AddSystem<Ndk::VelocitySystem>().SetFixedUpdateRate(30.f);
|
||||
|
||||
WHEN("We give a speed to our entity")
|
||||
{
|
||||
Nz::Vector3f velocity = Nz::Vector3f::Unit() * 2.f;
|
||||
velocityComponent.linearVelocity = velocity;
|
||||
world.Update(1.f);
|
||||
|
||||
THEN("Our entity should have moved")
|
||||
{
|
||||
REQUIRE(nodeComponent.GetPosition().SquaredDistance(velocity) < 0.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
#include <NazaraSDK/World.hpp>
|
||||
#include <NazaraSDK/Component.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
class UpdatableComponent : public Ndk::Component<UpdatableComponent>
|
||||
{
|
||||
public:
|
||||
bool IsUpdated()
|
||||
{
|
||||
return m_updated;
|
||||
}
|
||||
|
||||
void SetUpdated()
|
||||
{
|
||||
m_updated = true;
|
||||
}
|
||||
|
||||
static Ndk::ComponentIndex componentIndex;
|
||||
|
||||
private:
|
||||
bool m_updated = false;
|
||||
};
|
||||
|
||||
Ndk::ComponentIndex UpdatableComponent::componentIndex;
|
||||
|
||||
class UpdateSystem : public Ndk::System<UpdateSystem>
|
||||
{
|
||||
public:
|
||||
UpdateSystem()
|
||||
{
|
||||
Requires<UpdatableComponent>();
|
||||
}
|
||||
|
||||
~UpdateSystem() = default;
|
||||
|
||||
static Ndk::SystemIndex systemIndex;
|
||||
|
||||
private:
|
||||
void OnUpdate(float /*elapsedTime*/) override
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : GetEntities())
|
||||
{
|
||||
UpdatableComponent& updatable = entity->GetComponent<UpdatableComponent>();
|
||||
updatable.SetUpdated();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ndk::SystemIndex UpdateSystem::systemIndex;
|
||||
}
|
||||
|
||||
SCENARIO("World", "[NDK][WORLD]")
|
||||
{
|
||||
GIVEN("A brave new world and the update system")
|
||||
{
|
||||
Ndk::World world;
|
||||
Ndk::BaseSystem& system = world.AddSystem<UpdateSystem>();
|
||||
|
||||
WHEN("We had a new entity with an updatable component and a system")
|
||||
{
|
||||
const Ndk::EntityHandle& entity = world.CreateEntity();
|
||||
UpdatableComponent& component = entity->AddComponent<UpdatableComponent>();
|
||||
|
||||
THEN("We can get our entity and our system")
|
||||
{
|
||||
const Ndk::EntityHandle& fetchedEntity = world.GetEntity(entity->GetId());
|
||||
REQUIRE(fetchedEntity->GetWorld() == &world);
|
||||
}
|
||||
|
||||
THEN("We can clone it")
|
||||
{
|
||||
const Ndk::EntityHandle& clone = world.CloneEntity(entity->GetId());
|
||||
REQUIRE(world.IsEntityValid(clone));
|
||||
}
|
||||
}
|
||||
|
||||
AND_WHEN("We update our world with our entity")
|
||||
{
|
||||
REQUIRE(&world.GetSystem(UpdateSystem::systemIndex) == &world.GetSystem<UpdateSystem>());
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
UpdatableComponent& component = entity->AddComponent<UpdatableComponent>();
|
||||
|
||||
THEN("Our entity component must be updated")
|
||||
{
|
||||
world.Update(1.f);
|
||||
|
||||
REQUIRE(component.IsUpdated());
|
||||
}
|
||||
|
||||
THEN("We kill our entity")
|
||||
{
|
||||
REQUIRE(entity->IsValid());
|
||||
|
||||
world.KillEntity(entity);
|
||||
world.Update(1.f);
|
||||
|
||||
REQUIRE(!world.IsEntityValid(entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A newly created entity")
|
||||
{
|
||||
Ndk::World world;
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
|
||||
REQUIRE(entity.IsValid());
|
||||
REQUIRE(entity->IsValid());
|
||||
CHECK_FALSE(entity->IsDying());
|
||||
|
||||
WHEN("We kill it")
|
||||
{
|
||||
entity->Kill();
|
||||
|
||||
CHECK(entity.IsValid());
|
||||
CHECK(entity->IsValid());
|
||||
CHECK(entity->IsDying());
|
||||
|
||||
THEN("We refresh the world")
|
||||
{
|
||||
world.Refresh();
|
||||
|
||||
CHECK_FALSE(entity.IsValid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("An empty world")
|
||||
{
|
||||
Ndk::World world;
|
||||
|
||||
WHEN("We create two entities")
|
||||
{
|
||||
Ndk::EntityHandle a = world.CreateEntity();
|
||||
REQUIRE(a->GetId() == 0);
|
||||
Ndk::EntityHandle b = world.CreateEntity();
|
||||
REQUIRE(b->GetId() == 1);
|
||||
|
||||
b->OnEntityDestruction.Connect([a](Ndk::Entity*)
|
||||
{
|
||||
REQUIRE(a.IsValid());
|
||||
a->Kill();
|
||||
});
|
||||
|
||||
THEN("We kill the second entity which will kill the first one")
|
||||
{
|
||||
b->Kill();
|
||||
world.Refresh();
|
||||
|
||||
AND_THEN("Both entities should be dead next refresh")
|
||||
{
|
||||
world.Refresh();
|
||||
|
||||
REQUIRE_FALSE(a.IsValid());
|
||||
REQUIRE_FALSE(b.IsValid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,13 @@
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/AbstractLogger.hpp>
|
||||
#include <Nazara/Core/Modules.hpp>
|
||||
#include <NazaraSDK/Application.hpp>
|
||||
#include <NazaraSDK/Sdk.hpp>
|
||||
#include <Nazara/Network/Network.hpp>
|
||||
#include <Nazara/Physics2D/Physics2D.hpp>
|
||||
#include <Nazara/Shader/Shader.hpp>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
Nz::Modules<Ndk::Sdk> nazaza;
|
||||
Ndk::Application app(argc, argv);
|
||||
|
||||
Nz::Log::GetLogger()->EnableStdReplication(false);
|
||||
Nz::Modules<Nz::Network, Nz::Physics2D, Nz::Shader> nazaza;
|
||||
|
||||
int result = Catch::Session().run(argc, argv);
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Nazara/Core/AbstractLogger.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/Modules.hpp>
|
||||
#include <NazaraSDK/ClientApplication.hpp>
|
||||
#include <NazaraSDK/ClientSdk.hpp>
|
||||
#include <Nazara/Network/Network.hpp>
|
||||
#include <Nazara/Physics2D/Physics2D.hpp>
|
||||
#include <Nazara/Shader/Shader.hpp>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
Nz::Modules<Ndk::ClientSdk> nazaza;
|
||||
Ndk::ClientApplication app(argc, argv);
|
||||
Nz::Modules<Nz::Audio, Nz::Network, Nz::Physics2D, Nz::Shader> nazaza;
|
||||
|
||||
int result = Catch::Session().run(argc, argv);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ target("NazaraClientUnitTests")
|
||||
set_group("Tests")
|
||||
set_kind("binary")
|
||||
|
||||
add_deps("NazaraClientSDK")
|
||||
add_deps("NazaraAudio", "NazaraCore", "NazaraNetwork", "NazaraPhysics2D", "NazaraShader")
|
||||
add_packages("catch2")
|
||||
|
||||
add_files("main_client.cpp")
|
||||
@@ -20,14 +20,9 @@ target("NazaraUnitTests")
|
||||
set_group("Tests")
|
||||
set_kind("binary")
|
||||
|
||||
add_deps("NazaraSDK")
|
||||
add_deps("NazaraCore", "NazaraNetwork", "NazaraPhysics2D", "NazaraShader")
|
||||
add_packages("catch2")
|
||||
|
||||
add_files("main.cpp")
|
||||
add_files("resources.cpp")
|
||||
add_files("Engine/**.cpp")
|
||||
add_files("SDK/**.cpp")
|
||||
|
||||
del_files("Engine/Audio/**")
|
||||
del_files("SDK/NDK/Application.cpp")
|
||||
del_files("SDK/NDK/Systems/ListenerSystem.cpp")
|
||||
|
||||
Reference in New Issue
Block a user