Skip to content

Commit

Permalink
test(core): glm reflection
Browse files Browse the repository at this point in the history
  • Loading branch information
RiscadoA committed Jun 18, 2023
1 parent b804b38 commit 8f4a8d3
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 7 deletions.
7 changes: 0 additions & 7 deletions core/src/cubos/core/reflection/external/glm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
AUTO_VEC2(glm::ivec2);
AUTO_VEC2(glm::uvec2);
AUTO_VEC2(glm::vec2);
AUTO_VEC2(glm::dvec2);

#define AUTO_VEC3(type) \
CUBOS_REFLECT_EXTERNAL_IMPL(type) \
Expand All @@ -31,7 +30,6 @@ AUTO_VEC2(glm::dvec2);
AUTO_VEC3(glm::ivec3);
AUTO_VEC3(glm::uvec3);
AUTO_VEC3(glm::vec3);
AUTO_VEC3(glm::dvec3);

#define AUTO_VEC4(type) \
CUBOS_REFLECT_EXTERNAL_IMPL(type) \
Expand All @@ -48,7 +46,6 @@ AUTO_VEC3(glm::dvec3);
AUTO_VEC4(glm::ivec4);
AUTO_VEC4(glm::uvec4);
AUTO_VEC4(glm::vec4);
AUTO_VEC4(glm::dvec4);

#define ACCESS_MAT(type, x, y) \
[](const void* mat) -> uintptr_t { return reinterpret_cast<uintptr_t>(&(*static_cast<const type*>(mat))[x][y]); }
Expand All @@ -68,7 +65,6 @@ AUTO_VEC4(glm::dvec4);
}

AUTO_MAT2(glm::mat2);
AUTO_MAT2(glm::dmat2);

#define AUTO_MAT3(type) \
CUBOS_REFLECT_EXTERNAL_IMPL(type) \
Expand All @@ -89,7 +85,6 @@ AUTO_MAT2(glm::dmat2);
}

AUTO_MAT3(glm::mat3);
AUTO_MAT3(glm::dmat3);

#define AUTO_MAT4(type) \
CUBOS_REFLECT_EXTERNAL_IMPL(type) \
Expand Down Expand Up @@ -117,8 +112,6 @@ AUTO_MAT3(glm::dmat3);
}

AUTO_MAT4(glm::mat4);
AUTO_MAT4(glm::dmat4);

// Reuse the vec4 macro for quaternions.
AUTO_VEC4(glm::quat);
AUTO_VEC4(glm::dquat);
1 change: 1 addition & 0 deletions core/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_executable(
cubos-core-tests
main.cpp

reflection/external/glm.cpp
reflection/external/primitives_and_string.cpp
reflection/external/variant.cpp
reflection/external/vector.cpp
Expand Down
135 changes: 135 additions & 0 deletions core/tests/reflection/external/glm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>

#include <cubos/core/reflection/external/glm.hpp>
#include <cubos/core/reflection/external/primitives.hpp>
#include <cubos/core/reflection/object.hpp>

#include "../utils.hpp"

using cubos::core::reflection::ObjectType;
using cubos::core::reflection::reflect;

template <glm::length_t L, typename T, glm::qualifier Q>
static void testVec(glm::vec<L, T, Q>, const char* name)
{
using Vec = glm::vec<L, T, Q>;
testTypeGetters<Vec, ObjectType>(name, name);
testTypeDefaultConstructor<Vec>();

// The fields of vector must be named x, y, z, w, in that order.
auto& to = reflect<Vec>().template asKind<ObjectType>();
REQUIRE(to.fields().size() == static_cast<std::size_t>(L));

CHECK(to.fields()[0]->name() == "x");
CHECK(to.fields()[1]->name() == "y");

if (L >= 3)
{
CHECK(to.fields()[2]->name() == "z");
}

if (L >= 4)
{
CHECK(to.fields()[3]->name() == "w");
}

// Check if the correct field types are returned.
for (auto& field : to.fields())
{
REQUIRE(field->type().template is<T>());
}

// Check if the fields are set correctly.
for (glm::length_t i = 0; i < L; ++i)
{
Vec vec{};
to.fields()[i]->template get<T>(&vec) = static_cast<T>(1);
CHECK(vec[i] == static_cast<T>(1));
}
}

template <glm::length_t C, glm::length_t R, typename T, glm::qualifier Q>
static void testMat(glm::mat<C, R, T, Q>, const char* name)
{
using Mat = glm::mat<C, R, T, Q>;
testTypeGetters<Mat, ObjectType>(name, name);
testTypeDefaultConstructor<Mat>();

// The fields of matrix must be named 00, 01, 02, 10, 11, etc, in that order.
auto& to = reflect<Mat>().template asKind<ObjectType>();
REQUIRE(to.fields().size() == static_cast<std::size_t>(C * R));
for (glm::length_t c = 0; c < C; ++c)
{
for (glm::length_t r = 0; r < R; ++r)
{
std::string expected = std::to_string(c) + std::to_string(r);
CHECK(to.fields()[c * R + r]->name() == expected);
REQUIRE(to.fields()[c * R + r]->type().template is<T>());
}
}

// Check if the fields are set correctly.
for (glm::length_t c = 0; c < C; ++c)
{
for (glm::length_t r = 0; r < R; ++r)
{
Mat mat{};
to.fields()[c * R + r]->template get<T>(&mat) = static_cast<T>(1);
CHECK(mat[c][r] == static_cast<T>(1));
}
}
}

template <typename T, glm::qualifier Q>
static void testQuat(glm::qua<T, Q>, const char* name)
{
using Quat = glm::qua<T, Q>;
testTypeGetters<Quat, ObjectType>(name, name);
testTypeDefaultConstructor<Quat>();

// The fields of quaternion must be named x, y, z, w, in that order.
auto& to = reflect<Quat>().template asKind<ObjectType>();
REQUIRE(to.fields().size() == 4);
CHECK(to.fields()[0]->name() == "x");
CHECK(to.fields()[1]->name() == "y");
CHECK(to.fields()[2]->name() == "z");
CHECK(to.fields()[3]->name() == "w");

// Check if the correct field types are returned.
for (auto& field : to.fields())
{
REQUIRE(field->type().template is<T>());
}

// Check if the fields are set correctly.
for (glm::length_t i = 0; i < 4; ++i)
{
Quat qua{};
to.fields()[i]->template get<T>(&qua) = static_cast<T>(1);
CHECK(qua[i] == static_cast<T>(1));
}
}

TEST_CASE("reflection::reflect<(external/glm)>()")
{
testVec(glm::ivec2{}, "glm::ivec2");
testVec(glm::uvec2{}, "glm::uvec2");
testVec(glm::vec2{}, "glm::vec2");

testVec(glm::ivec3{}, "glm::ivec3");
testVec(glm::uvec3{}, "glm::uvec3");
testVec(glm::vec3{}, "glm::vec3");

testVec(glm::ivec4{}, "glm::ivec4");
testVec(glm::uvec4{}, "glm::uvec4");
testVec(glm::vec4{}, "glm::vec4");

testMat(glm::mat2{}, "glm::mat2");

testMat(glm::mat3{}, "glm::mat3");

testMat(glm::mat4{}, "glm::mat4");

testQuat(glm::quat{}, "glm::quat");
}

0 comments on commit 8f4a8d3

Please sign in to comment.