Merge branch 'master' into SDL2
This commit is contained in:
@@ -1,175 +1,347 @@
|
||||
#include <Nazara/Core/MovablePtr.hpp>
|
||||
#include <Nazara/Core/StackVector.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
#include <array>
|
||||
#include <numeric>
|
||||
|
||||
// This is a quick way to check that checks are valid
|
||||
#define USE_STD_VECTOR 0
|
||||
|
||||
class DestructionCounter
|
||||
{
|
||||
public:
|
||||
DestructionCounter() :
|
||||
m_counter(nullptr),
|
||||
m_value(0)
|
||||
{
|
||||
}
|
||||
|
||||
DestructionCounter(std::size_t* counter, int value) :
|
||||
m_counter(counter),
|
||||
m_value(value)
|
||||
{
|
||||
if (m_counter)
|
||||
(*m_counter)++;
|
||||
}
|
||||
|
||||
DestructionCounter(const DestructionCounter& counter) :
|
||||
m_counter(counter.m_counter),
|
||||
m_value(counter.m_value)
|
||||
{
|
||||
if (m_counter)
|
||||
(*m_counter)++;
|
||||
}
|
||||
|
||||
DestructionCounter(DestructionCounter&& counter) :
|
||||
m_counter(counter.m_counter),
|
||||
m_value(counter.m_value)
|
||||
{
|
||||
if (m_counter)
|
||||
(*m_counter)++;
|
||||
}
|
||||
|
||||
~DestructionCounter()
|
||||
{
|
||||
if (m_counter)
|
||||
{
|
||||
assert(*m_counter > 0);
|
||||
(*m_counter)--;
|
||||
}
|
||||
}
|
||||
|
||||
operator int() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
DestructionCounter& operator=(const DestructionCounter& counter)
|
||||
{
|
||||
if (m_counter)
|
||||
{
|
||||
assert(*m_counter > 0);
|
||||
(*m_counter)--;
|
||||
}
|
||||
|
||||
m_counter = counter.m_counter;
|
||||
m_value = counter.m_value;
|
||||
|
||||
if (m_counter)
|
||||
(*m_counter)++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DestructionCounter& operator=(DestructionCounter&& counter)
|
||||
{
|
||||
if (this == &counter)
|
||||
return *this;
|
||||
|
||||
if (m_counter)
|
||||
{
|
||||
assert(*m_counter > 0);
|
||||
(*m_counter)--;
|
||||
}
|
||||
|
||||
m_counter = counter.m_counter;
|
||||
m_value = counter.m_value;
|
||||
|
||||
if (m_counter)
|
||||
(*m_counter)++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t* m_counter;
|
||||
int m_value;
|
||||
};
|
||||
|
||||
SCENARIO("StackVector", "[CORE][STACKVECTOR]")
|
||||
{
|
||||
GIVEN("A StackVector to contain multiple int")
|
||||
{
|
||||
volatile std::size_t capacity = 50;
|
||||
Nz::StackVector<int> vector = NazaraStackVector(int, capacity);
|
||||
|
||||
WHEN("At construction, the vector is empty but has capacity")
|
||||
std::size_t counter = 0;
|
||||
{
|
||||
CHECK(vector.capacity() == capacity);
|
||||
CHECK(vector.empty());
|
||||
CHECK(vector.size() == 0);
|
||||
}
|
||||
volatile std::size_t capacity = 50;
|
||||
#if USE_STD_VECTOR
|
||||
std::vector<DestructionCounter> vector;
|
||||
vector.reserve(capacity);
|
||||
#else
|
||||
Nz::StackVector<DestructionCounter> vector = NazaraStackVector(DestructionCounter, capacity);
|
||||
#endif
|
||||
|
||||
WHEN("Emplacing five elements, vector size increase accordingly")
|
||||
{
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
WHEN("At construction, the vector is empty but has capacity")
|
||||
{
|
||||
int val = int(i);
|
||||
CHECK(vector.emplace_back(val) == val);
|
||||
CHECK(vector.capacity() == capacity);
|
||||
CHECK(vector.empty());
|
||||
CHECK(vector.size() == 0);
|
||||
#if !USE_STD_VECTOR
|
||||
CHECK(vector.max_size() == capacity);
|
||||
#endif
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 0, 1, 2, 3, 4 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
WHEN("Pushing three elements, vector size increase accordingly")
|
||||
{
|
||||
for (std::size_t i = 0; i < 3; ++i)
|
||||
WHEN("Resizing it changes its size and create/destroy elements")
|
||||
{
|
||||
int val = int(i);
|
||||
CHECK(vector.push_back(val) == val);
|
||||
vector.resize(vector.capacity());
|
||||
CHECK(vector.size() == vector.capacity());
|
||||
CHECK(counter == 0);
|
||||
vector.resize(0);
|
||||
CHECK(vector.empty());
|
||||
CHECK(vector.size() == 0);
|
||||
CHECK(counter == 0);
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 3);
|
||||
|
||||
std::array<int, 3> expectedValues = { 0, 1, 2 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
|
||||
THEN("We resize to five")
|
||||
WHEN("Resizing it allocates elements")
|
||||
{
|
||||
vector.resize(5);
|
||||
vector.resize(vector.capacity(), DestructionCounter(&counter, 0));
|
||||
CHECK(vector.size() == vector.capacity());
|
||||
CHECK(counter == capacity);
|
||||
vector.resize(0);
|
||||
CHECK(vector.empty());
|
||||
CHECK(vector.size() == 0);
|
||||
CHECK(counter == 0);
|
||||
}
|
||||
|
||||
WHEN("Emplacing five elements, vector size increase accordingly")
|
||||
{
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
{
|
||||
#if USE_STD_VECTOR
|
||||
vector.emplace_back(&counter, int(i));
|
||||
#else
|
||||
CHECK(vector.emplace_back(&counter, int(i)) == int(i));
|
||||
#endif
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 0, 1, 2, 0, 0 };
|
||||
std::array<int, 5> expectedValues = { 0, 1, 2, 3, 4 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
WHEN("Pushing three elements, vector size increase accordingly")
|
||||
{
|
||||
for (std::size_t i = 0; i < 3; ++i)
|
||||
{
|
||||
DestructionCounter val(&counter, int(i));
|
||||
#if USE_STD_VECTOR
|
||||
vector.push_back(val);
|
||||
#else
|
||||
CHECK(vector.push_back(val) == val);
|
||||
#endif
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 3);
|
||||
|
||||
std::array<int, 3> expectedValues = { 0, 1, 2 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
|
||||
AND_THEN("We resize it back to zero")
|
||||
THEN("We resize to five")
|
||||
{
|
||||
vector.resize(0);
|
||||
vector.resize(5);
|
||||
|
||||
CHECK(vector.empty());
|
||||
CHECK(vector.size() == 0);
|
||||
}
|
||||
AND_THEN("We clear it")
|
||||
{
|
||||
vector.clear();
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
CHECK(vector.empty());
|
||||
CHECK(vector.size() == 0);
|
||||
std::array<int, 5> expectedValues = { 0, 1, 2, 0, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
|
||||
AND_THEN("We resize it back to zero")
|
||||
{
|
||||
vector.resize(0);
|
||||
|
||||
CHECK(vector.empty());
|
||||
CHECK(vector.size() == 0);
|
||||
}
|
||||
AND_THEN("We clear it")
|
||||
{
|
||||
vector.clear();
|
||||
|
||||
CHECK(vector.empty());
|
||||
CHECK(vector.size() == 0);
|
||||
CHECK(counter == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We generate its content will iota")
|
||||
{
|
||||
vector.resize(10);
|
||||
std::iota(vector.begin(), vector.end(), -5);
|
||||
|
||||
std::array<int, 10> expectedValues = { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
WHEN("We generate its content using emplace")
|
||||
{
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
WHEN("We generate its content will iota")
|
||||
{
|
||||
int val = int(i);
|
||||
CHECK(*vector.emplace(vector.end(), val) == val);
|
||||
vector.resize(10);
|
||||
for (std::size_t i = 0; i < vector.size(); ++i)
|
||||
vector[i] = DestructionCounter(&counter, -5 + int(i));
|
||||
|
||||
std::array<int, 10> expectedValues = { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4 };
|
||||
CHECK(vector.size() == expectedValues.size());
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
|
||||
AND_WHEN("We pop back some elements")
|
||||
{
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
vector.pop_back();
|
||||
|
||||
std::array<int, 5> expectedValues = { -5, -4, -3, -2, -1 };
|
||||
CHECK(vector.size() == expectedValues.size());
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
AND_WHEN("We erase elements at the beginning")
|
||||
{
|
||||
vector.erase(vector.begin());
|
||||
vector.erase(vector.begin());
|
||||
|
||||
std::array<int, 8> expectedValues = { -3, -2, -1, 0, 1, 2, 3, 4 };
|
||||
CHECK(vector.size() == expectedValues.size());
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
AND_WHEN("We erase elements in the middle")
|
||||
{
|
||||
vector.erase(vector.begin() + 2);
|
||||
vector.erase(vector.begin() + 2);
|
||||
vector.erase(vector.begin() + 6);
|
||||
|
||||
std::array<int, 7> expectedValues = { -5, -4, -1, 0, 1, 2, 4 };
|
||||
CHECK(vector.size() == expectedValues.size());
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
AND_WHEN("We erase elements at the end")
|
||||
{
|
||||
vector.erase(vector.end() - 1);
|
||||
vector.erase(vector.end() - 1);
|
||||
|
||||
std::array<int, 8> expectedValues = { -5, -4, -3, -2, -1, 0, 1, 2 };
|
||||
CHECK(vector.size() == expectedValues.size());
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
AND_WHEN("We erase a range")
|
||||
{
|
||||
vector.erase(vector.begin() + 2, vector.end() - 3);
|
||||
|
||||
std::array<int, 5> expectedValues = { -5, -4, 2, 3, 4 };
|
||||
CHECK(vector.size() == expectedValues.size());
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
AND_WHEN("We erase everything")
|
||||
{
|
||||
vector.erase(vector.begin(), vector.end());
|
||||
|
||||
CHECK(vector.empty());
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 0, 1, 2, 3, 4 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
WHEN("We generate its content using emplace, in reverse order")
|
||||
{
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
WHEN("We generate its content using emplace")
|
||||
{
|
||||
int val = int(i);
|
||||
CHECK(*vector.emplace(vector.begin(), val) == val);
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
CHECK(*vector.emplace(vector.end(), &counter, int(i)) == int(i));
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 0, 1, 2, 3, 4 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 4, 3, 2, 1, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
WHEN("We generate its content using emplace, at the middle")
|
||||
{
|
||||
for (std::size_t i = 0; i < 10; ++i)
|
||||
WHEN("We generate its content using emplace, in reverse order")
|
||||
{
|
||||
int val = int(i);
|
||||
CHECK(*vector.emplace(vector.begin() + i / 2, val) == val);
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
CHECK(*vector.emplace(vector.begin(), &counter, int(i)) == int(i));
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 4, 3, 2, 1, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 10);
|
||||
|
||||
std::array<int, 10> expectedValues = { 1, 3, 5, 7, 9, 8, 6, 4, 2, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
WHEN("We generate its content using insert")
|
||||
{
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
WHEN("We generate its content using emplace, at the middle")
|
||||
{
|
||||
int val = int(i);
|
||||
CHECK(*vector.insert(vector.end(), val) == val);
|
||||
for (std::size_t i = 0; i < 10; ++i)
|
||||
CHECK(*vector.emplace(vector.begin() + i / 2, &counter, int(i)) == int(i));
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 10);
|
||||
|
||||
std::array<int, 10> expectedValues = { 1, 3, 5, 7, 9, 8, 6, 4, 2, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 0, 1, 2, 3, 4 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
WHEN("We generate its content using insert, in reverse order")
|
||||
{
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
WHEN("We generate its content using insert")
|
||||
{
|
||||
int val = int(i);
|
||||
CHECK(*vector.insert(vector.begin(), val) == val);
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
CHECK(*vector.insert(vector.end(), DestructionCounter(&counter, int(i))) == int(i));
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 0, 1, 2, 3, 4 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 4, 3, 2, 1, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
WHEN("We generate its content using insert, at the middle")
|
||||
{
|
||||
for (std::size_t i = 0; i < 10; ++i)
|
||||
WHEN("We generate its content using insert, in reverse order")
|
||||
{
|
||||
int val = int(i);
|
||||
CHECK(*vector.insert(vector.begin() + i / 2, val) == val);
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
CHECK(*vector.insert(vector.begin(), DestructionCounter(&counter, int(i))) == int(i));
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 5);
|
||||
|
||||
std::array<int, 5> expectedValues = { 4, 3, 2, 1, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 10);
|
||||
WHEN("We generate its content using insert, at the middle")
|
||||
{
|
||||
for (std::size_t i = 0; i < 10; ++i)
|
||||
CHECK(*vector.insert(vector.begin() + i / 2, DestructionCounter(&counter, int(i))) == int(i));
|
||||
|
||||
std::array<int, 10> expectedValues = { 1, 3, 5, 7, 9, 8, 6, 4, 2, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
CHECK(!vector.empty());
|
||||
CHECK(vector.size() == 10);
|
||||
|
||||
std::array<int, 10> expectedValues = { 1, 3, 5, 7, 9, 8, 6, 4, 2, 0 };
|
||||
CHECK(std::equal(vector.begin(), vector.end(), expectedValues.begin(), expectedValues.end()));
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(counter == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ SCENARIO("IpAddress", "[NETWORK][IPADDRESS]")
|
||||
Nz::IpAddress google(8, 8, 8, 8);
|
||||
THEN("Google (DNS) is 8.8.8.8")
|
||||
{
|
||||
CHECK(Nz::IpAddress::ResolveAddress(google) == "google-public-dns-a.google.com");
|
||||
Nz::String dnsAddress = Nz::IpAddress::ResolveAddress(google);
|
||||
bool dnsCheck = dnsAddress == "google-public-dns-a.google.com" || dnsAddress == "dns.google";
|
||||
CHECK(dnsCheck);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <Nazara/Physics2D/RigidBody2D.hpp>
|
||||
#include <Nazara/Physics2D/PhysWorld2D.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
Nz::RigidBody2D CreateBody(Nz::PhysWorld2D& world);
|
||||
@@ -93,6 +94,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||
std::vector<Nz::RigidBody2D> tmp;
|
||||
tmp.push_back(CreateBody(world));
|
||||
tmp.push_back(CreateBody(world));
|
||||
|
||||
world.Step(1.f);
|
||||
|
||||
THEN("They should be valid")
|
||||
@@ -112,11 +114,14 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||
Nz::Rectf aabb(positionAABB.x, positionAABB.y, 1.f, 2.f);
|
||||
Nz::Collider2DRef box = Nz::BoxCollider2D::New(aabb);
|
||||
float mass = 1.f;
|
||||
Nz::RigidBody2D body(&world, mass, box);
|
||||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(box, true, false);
|
||||
|
||||
bool userData = false;
|
||||
body.SetUserdata(&userData);
|
||||
|
||||
Nz::Vector2f position = Nz::Vector2f::Zero();
|
||||
body.SetPosition(position);
|
||||
|
||||
world.Step(1.f);
|
||||
|
||||
@@ -126,7 +131,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||
{
|
||||
CHECK(body.GetAABB() == aabb);
|
||||
CHECK(body.GetAngularVelocity() == 0.f);
|
||||
CHECK(body.GetMassCenter() == Nz::Vector2f::Zero());
|
||||
CHECK(body.GetMassCenter(Nz::CoordSys_Global) == position);
|
||||
CHECK(body.GetGeom() == box);
|
||||
CHECK(body.GetMass() == Approx(mass));
|
||||
CHECK(body.GetPosition() == position);
|
||||
@@ -150,7 +155,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||
{
|
||||
aabb.Translate(velocity);
|
||||
CHECK(body.GetAABB() == aabb);
|
||||
CHECK(body.GetMassCenter() == Nz::Vector2f::Zero());
|
||||
CHECK(body.GetMassCenter(Nz::CoordSys_Global) == position);
|
||||
CHECK(body.GetPosition() == position);
|
||||
CHECK(body.GetVelocity() == velocity);
|
||||
}
|
||||
@@ -211,7 +216,9 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||
float radius = 5.f;
|
||||
Nz::Collider2DRef circle = Nz::CircleCollider2D::New(radius, position);
|
||||
float mass = 1.f;
|
||||
Nz::RigidBody2D body(&world, mass, circle);
|
||||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(circle, true, false);
|
||||
|
||||
world.Step(1.f);
|
||||
|
||||
WHEN("We ask for the aabb of the circle")
|
||||
@@ -240,7 +247,9 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||
Nz::CompoundCollider2DRef compound = Nz::CompoundCollider2D::New(colliders);
|
||||
|
||||
float mass = 1.f;
|
||||
Nz::RigidBody2D body(&world, mass, compound);
|
||||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(compound, true, false);
|
||||
|
||||
world.Step(1.f);
|
||||
|
||||
WHEN("We ask for the aabb of the compound")
|
||||
@@ -267,7 +276,9 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||
Nz::SparsePtr<const Nz::Vector2f> sparsePtr(vertices.data());
|
||||
Nz::ConvexCollider2DRef convex = Nz::ConvexCollider2D::New(sparsePtr, vertices.size());
|
||||
float mass = 1.f;
|
||||
Nz::RigidBody2D body(&world, mass, convex);
|
||||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(convex, true, false);
|
||||
|
||||
world.Step(1.f);
|
||||
|
||||
WHEN("We ask for the aabb of the convex")
|
||||
@@ -289,7 +300,9 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||
Nz::Vector2f positionB(1.f, -4.f);
|
||||
Nz::Collider2DRef segment = Nz::SegmentCollider2D::New(positionA, positionB, 0.f);
|
||||
float mass = 1.f;
|
||||
Nz::RigidBody2D body(&world, mass, segment);
|
||||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(segment, true, false);
|
||||
|
||||
world.Step(1.f);
|
||||
|
||||
WHEN("We ask for the aabb of the segment")
|
||||
@@ -309,7 +322,11 @@ Nz::RigidBody2D CreateBody(Nz::PhysWorld2D& world)
|
||||
Nz::Rectf aabb(positionAABB.x, positionAABB.y, 1.f, 2.f);
|
||||
Nz::Collider2DRef box = Nz::BoxCollider2D::New(aabb);
|
||||
float mass = 1.f;
|
||||
return Nz::RigidBody2D(&world, mass, box);
|
||||
|
||||
Nz::RigidBody2D body(&world, mass, box);
|
||||
body.SetPosition(Nz::Vector2f::Zero());
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
void EQUALITY(const Nz::RigidBody2D& left, const Nz::RigidBody2D& right)
|
||||
|
||||
@@ -105,4 +105,25 @@ SCENARIO("EntityOwner", "[NDK][ENTITYOWNER]")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A vector of EntityOwner")
|
||||
{
|
||||
Ndk::World world(false);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <Catch/catch.hpp>
|
||||
#include <limits>
|
||||
|
||||
Ndk::EntityHandle CreateBaseEntity(Ndk::World& world, const Nz::Vector2f& position, const Nz::Rectf AABB);
|
||||
Ndk::EntityHandle CreateBaseEntity(Ndk::World& world, const Nz::Vector2f& position, const Nz::Rectf& AABB);
|
||||
|
||||
SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]")
|
||||
{
|
||||
@@ -80,6 +80,8 @@ SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]")
|
||||
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);
|
||||
|
||||
@@ -124,6 +126,8 @@ SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]")
|
||||
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);
|
||||
|
||||
@@ -145,7 +149,7 @@ SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]")
|
||||
}
|
||||
}
|
||||
|
||||
Ndk::EntityHandle CreateBaseEntity(Ndk::World& world, const Nz::Vector2f& position, const Nz::Rectf AABB)
|
||||
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>();
|
||||
|
||||
@@ -90,17 +90,17 @@ SCENARIO("RenderSystem", "[NDK][RenderSystem]")
|
||||
{
|
||||
CHECK(physicsComponent2D.GetAngularVelocity() == angularSpeed);
|
||||
CHECK(physicsComponent2D.GetRotation() == angularSpeed);
|
||||
CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(1.f, 4.f, 2.f, 1.f));
|
||||
CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(2.5f, 4.5f, 2.f, 1.f));
|
||||
CompareAABB(physicsComponent2D.GetAABB(), graphicsComponent.GetAABB());
|
||||
|
||||
world.Update(1.f);
|
||||
CHECK(physicsComponent2D.GetRotation() == 2.f * angularSpeed);
|
||||
CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(2.f, 2.f, 1.f, 2.f));
|
||||
CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(3.f, 4.0f, 1.f, 2.f));
|
||||
CompareAABB(physicsComponent2D.GetAABB(), graphicsComponent.GetAABB());
|
||||
|
||||
world.Update(1.f);
|
||||
CHECK(physicsComponent2D.GetRotation() == 3.f * angularSpeed);
|
||||
CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(3.f, 3.f, 2.f, 1.f));
|
||||
CHECK(physicsComponent2D.GetAABB() == Nz::Rectf(2.5f, 4.5f, 2.f, 1.f));
|
||||
CompareAABB(physicsComponent2D.GetAABB(), graphicsComponent.GetAABB());
|
||||
|
||||
world.Update(1.f);
|
||||
|
||||
@@ -126,4 +126,37 @@ SCENARIO("World", "[NDK][WORLD]")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("An empty world")
|
||||
{
|
||||
Ndk::World world(false);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user