From da5d26d27e3e0020b4a08dabe2e6c021297a0418 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sat, 7 Oct 2023 17:19:32 +0100 Subject: [PATCH 01/18] fix(quadrados): skip CUBOS_REFLECT on code gen --- tools/quadrados-gen/src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/quadrados-gen/src/main.cpp b/tools/quadrados-gen/src/main.cpp index ea86e5033c..a777eb5d78 100644 --- a/tools/quadrados-gen/src/main.cpp +++ b/tools/quadrados-gen/src/main.cpp @@ -515,7 +515,7 @@ bool parseComponent(Parser& parser, Component& component) consumed = false; } - // Parse statements within the componnet's scope. + // Parse statements within the component's scope. if (scope == 1 && !ignoreUntilOpenBrace) { if (!consumed && parser.acceptKeywords({"struct", "class"})) @@ -525,7 +525,8 @@ bool parseComponent(Parser& parser, Component& component) } // Skip some non-field statements. - if (!consumed && parser.acceptKeywords({"static", "const", "constexpr", "using", "[[cubos::ignore]]"})) + if (!consumed && + parser.acceptKeywords({"static", "const", "constexpr", "using", "[[cubos::ignore]]", "CUBOS_REFLECT"})) { while (!parser.acceptPunctuation(";")) { From 3bc37934feaceeb45260aba2c525103230d7165e Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:21:30 +0100 Subject: [PATCH 02/18] feat(reflection): implement reflection for uuid --- core/CMakeLists.txt | 1 + .../cubos/core/reflection/external/uuid.hpp | 11 +++++++++++ core/src/cubos/core/reflection/external/uuid.cpp | 15 +++++++++++++++ core/tests/CMakeLists.txt | 1 + core/tests/reflection/external/uuid.cpp | 12 ++++++++++++ 5 files changed, 40 insertions(+) create mode 100644 core/include/cubos/core/reflection/external/uuid.hpp create mode 100644 core/src/cubos/core/reflection/external/uuid.cpp create mode 100644 core/tests/reflection/external/uuid.cpp diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 97c4adfad1..946035748b 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -37,6 +37,7 @@ set(CUBOS_CORE_SOURCE "src/cubos/core/reflection/traits/array.cpp" "src/cubos/core/reflection/traits/dictionary.cpp" "src/cubos/core/reflection/external/primitives.cpp" + "src/cubos/core/reflection/external/uuid.cpp" "src/cubos/core/reflection/external/glm.cpp" "src/cubos/core/data/old/serializer.cpp" diff --git a/core/include/cubos/core/reflection/external/uuid.hpp b/core/include/cubos/core/reflection/external/uuid.hpp new file mode 100644 index 0000000000..9d85d2d0d1 --- /dev/null +++ b/core/include/cubos/core/reflection/external/uuid.hpp @@ -0,0 +1,11 @@ +/// @file +/// @brief Reflection declaration for uuids::uuid. +/// @ingroup core-reflection + +#pragma once + +#include + +#include + +CUBOS_REFLECT_EXTERNAL_DECL(uuids::uuid); diff --git a/core/src/cubos/core/reflection/external/uuid.cpp b/core/src/cubos/core/reflection/external/uuid.cpp new file mode 100644 index 0000000000..9186e0c910 --- /dev/null +++ b/core/src/cubos/core/reflection/external/uuid.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +CUBOS_REFLECT_EXTERNAL_IMPL(uuids::uuid) +{ + using namespace cubos::core::reflection; + + return Type::create("uuids::uuid") + .with(ConstructibleTrait::typed() + .withDefaultConstructor() + .withCopyConstructor() + .withMoveConstructor() + .build()); +} diff --git a/core/tests/CMakeLists.txt b/core/tests/CMakeLists.txt index dd4768957d..21beefc097 100644 --- a/core/tests/CMakeLists.txt +++ b/core/tests/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable( reflection/traits/constructible.cpp reflection/traits/fields.cpp reflection/external/primitives.cpp + reflection/external/uuid.cpp reflection/external/glm.cpp reflection/external/vector.cpp reflection/external/map.cpp diff --git a/core/tests/reflection/external/uuid.cpp b/core/tests/reflection/external/uuid.cpp new file mode 100644 index 0000000000..a5e2de819a --- /dev/null +++ b/core/tests/reflection/external/uuid.cpp @@ -0,0 +1,12 @@ +#include + +#include + +#include "../traits/constructible.hpp" + +TEST_CASE("reflection::reflect()") +{ + uuids::uuid id = uuids::uuid::from_string("61a10fbd-899e-417d-9ef5-c83d8f6643ba").value(); + CHECK(reflect().name() == "uuids::uuid"); + testConstructible(&id); +} From 148238403bd09bf0a4eca03d1e5fdacad420b28a Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:27:09 +0100 Subject: [PATCH 03/18] feat(ecs): add ComponentTypeBuilder --- .../cubos/core/ecs/component/reflection.hpp | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 core/include/cubos/core/ecs/component/reflection.hpp diff --git a/core/include/cubos/core/ecs/component/reflection.hpp b/core/include/cubos/core/ecs/component/reflection.hpp new file mode 100644 index 0000000000..e711bd810c --- /dev/null +++ b/core/include/cubos/core/ecs/component/reflection.hpp @@ -0,0 +1,60 @@ +/// @file +/// @brief Class @ref cubos::core::ecs::ComponentTypeBuilder. +/// @ingroup core-ecs-component + +#pragma once + +#include +#include +#include + +namespace cubos::core::ecs +{ + /// @brief Builder for @ref reflection::Type objects which represent component types. + /// + /// Used to reduce the amount of boilerplate code required to define a component type. + /// Automatically adds the @ref reflection::ConstructibleTrait and @ref reflection::FieldsTrait. + /// The type @p T must be default-constructible, copy-constructible and move-constructible. + /// + /// @tparam T Component type. + template + class ComponentTypeBuilder + { + public: + /// @brief Constructs. + /// @param name Component type name, including namespace. + ComponentTypeBuilder(std::string name) + : mType(reflection::Type::create(std::move(name))) + { + mType.with(reflection::ConstructibleTrait::typed() + .withDefaultConstructor() + .withCopyConstructor() + .withMoveConstructor() + .build()); + } + + /// @brief Adds a field to the component type. + /// @tparam F Field type. + /// @param name Field name. + /// @param pointer Field pointer. + /// @return Builder. + template + ComponentTypeBuilder&& withField(std::string name, F T::*pointer) && + { + mFields.addField(std::move(name), pointer); + return std::move(*this); + } + + /// @brief Builds the component type. + /// @return Component type. + reflection::Type& build() && + { + mType.with(std::move(mFields)); + return mType; + } + + private: + reflection::Type& mType; + reflection::FieldsTrait mFields; + }; +} // namespace cubos::core::ecs \ No newline at end of file From 7ea7087584c3787ec5e2db438f382c098c064983 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:28:33 +0100 Subject: [PATCH 04/18] feat(reflection): add FieldsTrait:addField --- .../cubos/core/reflection/traits/fields.hpp | 19 +++++++++++++++---- .../cubos/core/reflection/traits/fields.cpp | 6 +++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/core/include/cubos/core/reflection/traits/fields.hpp b/core/include/cubos/core/reflection/traits/fields.hpp index 85e0923af7..303e5e0b59 100644 --- a/core/include/cubos/core/reflection/traits/fields.hpp +++ b/core/include/cubos/core/reflection/traits/fields.hpp @@ -54,19 +54,30 @@ namespace cubos::core::reflection /// @param type Field type. /// @param name Field name. /// @param addressOf Getter for the address of the field on a given instance. + void addField(const Type& type, std::string name, AddressOf* addressOf); + + /// @copydoc addField(const Type&, std::string, AddressOf*) /// @return Trait. FieldsTrait&& withField(const Type& type, std::string name, AddressOf* addressOf) &&; - /// @brief Sets the copy constructor of the type. + /// @brief Adds a field to the type. /// @tparam O Object type. /// @tparam F Field type. - /// @param field Field name. + /// @param name Field name. /// @param pointer Field pointer. + template + void addField(std::string name, F O::*pointer) + { + this->addField(reflect(), std::move(name), new AddressOfImpl(pointer)); + } + + /// @copydoc addField(std::string, F O::*) /// @return Trait. template - FieldsTrait&& withField(const std::string& field, F O::*pointer) && + FieldsTrait&& withField(std::string name, F O::*pointer) && { - return std::move(*this).withField(reflect(), field, new AddressOfImpl(pointer)); + this->addField(std::move(name), pointer); + return std::move(*this); } /// @brief Gets the field with the given name. diff --git a/core/src/cubos/core/reflection/traits/fields.cpp b/core/src/cubos/core/reflection/traits/fields.cpp index 6dc225dda2..3500497e40 100644 --- a/core/src/cubos/core/reflection/traits/fields.cpp +++ b/core/src/cubos/core/reflection/traits/fields.cpp @@ -88,7 +88,7 @@ FieldsTrait::~FieldsTrait() } } -FieldsTrait&& FieldsTrait::withField(const Type& type, std::string name, AddressOf* addressOf) && +void FieldsTrait::addField(const Type& type, std::string name, AddressOf* addressOf) { for (auto* field = mFirstField; field != nullptr; field = field->mNext) { @@ -106,7 +106,11 @@ FieldsTrait&& FieldsTrait::withField(const Type& type, std::string name, Address mFirstField = field; mLastField = field; } +} +FieldsTrait&& FieldsTrait::withField(const Type& type, std::string name, AddressOf* addressOf) && +{ + this->addField(type, std::move(name), addressOf); return std::move(*this); } From 8bc029dfcc0fe781935b37c28a3dcc3f1ad418a3 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:29:08 +0100 Subject: [PATCH 05/18] feat(geometry): implement reflection for types --- core/CMakeLists.txt | 3 +++ core/include/cubos/core/geom/box.hpp | 3 +++ core/include/cubos/core/geom/capsule.hpp | 3 +++ core/src/cubos/core/geom/box.cpp | 18 ++++++++++++++++++ core/src/cubos/core/geom/capsule.cpp | 18 ++++++++++++++++++ 5 files changed, 45 insertions(+) create mode 100644 core/src/cubos/core/geom/box.cpp create mode 100644 core/src/cubos/core/geom/capsule.cpp diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 946035748b..8a4413fb0d 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -83,6 +83,9 @@ set(CUBOS_CORE_SOURCE "src/cubos/core/ecs/system/commands.cpp" "src/cubos/core/ecs/blueprint.cpp" "src/cubos/core/ecs/world.cpp" + + "src/cubos/core/geom/box.cpp" + "src/cubos/core/geom/capsule.cpp" ) # Create core library diff --git a/core/include/cubos/core/geom/box.hpp b/core/include/cubos/core/geom/box.hpp index 54c1b197a1..715a132ae3 100644 --- a/core/include/cubos/core/geom/box.hpp +++ b/core/include/cubos/core/geom/box.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace cubos::core::geom { @@ -15,6 +16,8 @@ namespace cubos::core::geom /// @ingroup core-geom struct Box { + CUBOS_REFLECT; + glm::vec3 halfSize{0.5F}; ///< Half size of the box. /// @brief Computes two opposite corners of the box on the major diagonal. diff --git a/core/include/cubos/core/geom/capsule.hpp b/core/include/cubos/core/geom/capsule.hpp index 0d92829cbe..f31f7c05c6 100644 --- a/core/include/cubos/core/geom/capsule.hpp +++ b/core/include/cubos/core/geom/capsule.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace cubos::core::geom { @@ -14,6 +15,8 @@ namespace cubos::core::geom /// @ingroup core-geom struct Capsule { + CUBOS_REFLECT; + float radius = 1.0F; ///< Radius of the capsule. float length = 0.0F; ///< Length of the capsule. diff --git a/core/src/cubos/core/geom/box.cpp b/core/src/cubos/core/geom/box.cpp new file mode 100644 index 0000000000..18f0949b08 --- /dev/null +++ b/core/src/cubos/core/geom/box.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +CUBOS_REFLECT_IMPL(cubos::core::geom::Box) +{ + using namespace core::reflection; + + return Type::create("cubos::core::geom::Box") + .with(ConstructibleTrait::typed() + .withDefaultConstructor() + .withCopyConstructor() + .withMoveConstructor() + .build()) + .with(FieldsTrait().withField("halfSize", &Box::halfSize)); +} diff --git a/core/src/cubos/core/geom/capsule.cpp b/core/src/cubos/core/geom/capsule.cpp new file mode 100644 index 0000000000..3ac072e552 --- /dev/null +++ b/core/src/cubos/core/geom/capsule.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +CUBOS_REFLECT_IMPL(cubos::core::geom::Capsule) +{ + using namespace core::reflection; + + return Type::create("cubos::core::geom::Capsule") + .with(ConstructibleTrait::typed() + .withDefaultConstructor() + .withCopyConstructor() + .withMoveConstructor() + .build()) + .with(FieldsTrait().withField("radius", &Capsule::radius).withField("length", &Capsule::length)); +} From 32b01c80d748e4c5b63e8763ae0595b93dfe1d47 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:30:12 +0100 Subject: [PATCH 06/18] feat(reflection): add Reflectable concept --- core/include/cubos/core/reflection/reflect.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/include/cubos/core/reflection/reflect.hpp b/core/include/cubos/core/reflection/reflect.hpp index 75b8c6be7b..c537dc719a 100644 --- a/core/include/cubos/core/reflection/reflect.hpp +++ b/core/include/cubos/core/reflection/reflect.hpp @@ -69,6 +69,14 @@ namespace cubos::core::reflection static const Type& type = Reflect::type(); return type; } + + /// @brief Checks whether the given type @p T is reflectable. + /// @tparam T %Type to check. + template + concept Reflectable = requires + { + reflect(); + }; } // namespace cubos::core::reflection /// @brief Helper macro used to pass arguments with commas to other macros, wrapped in parentheses. From 6d4252170186f59dd90f997aa443dd7ecb2c85af Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:31:27 +0100 Subject: [PATCH 07/18] feat(voxels): implement reflection for types --- engine/include/cubos/engine/voxels/grid.hpp | 3 +++ engine/include/cubos/engine/voxels/palette.hpp | 4 ++++ engine/src/cubos/engine/voxels/grid.cpp | 10 ++++++++++ engine/src/cubos/engine/voxels/palette.cpp | 10 ++++++++++ 4 files changed, 27 insertions(+) diff --git a/engine/include/cubos/engine/voxels/grid.hpp b/engine/include/cubos/engine/voxels/grid.hpp index 060fce5c2f..f1a14b5f6a 100644 --- a/engine/include/cubos/engine/voxels/grid.hpp +++ b/engine/include/cubos/engine/voxels/grid.hpp @@ -10,6 +10,7 @@ #include #include +#include namespace cubos::engine { @@ -31,6 +32,8 @@ namespace cubos::engine class VoxelGrid final { public: + CUBOS_REFLECT; + ~VoxelGrid() = default; /// @brief Constructs an empty single-voxel grid. diff --git a/engine/include/cubos/engine/voxels/palette.hpp b/engine/include/cubos/engine/voxels/palette.hpp index 6ff4b1dee0..ea8b3b6963 100644 --- a/engine/include/cubos/engine/voxels/palette.hpp +++ b/engine/include/cubos/engine/voxels/palette.hpp @@ -6,6 +6,8 @@ #include +#include + #include namespace cubos::engine @@ -35,6 +37,8 @@ namespace cubos::engine class VoxelPalette final { public: + CUBOS_REFLECT; + ~VoxelPalette() = default; /// @brief Constructs a palette with the given materials. diff --git a/engine/src/cubos/engine/voxels/grid.cpp b/engine/src/cubos/engine/voxels/grid.cpp index 2d9df62e81..2ee1e057dd 100644 --- a/engine/src/cubos/engine/voxels/grid.cpp +++ b/engine/src/cubos/engine/voxels/grid.cpp @@ -1,12 +1,22 @@ #include #include +#include +#include #include #include using namespace cubos::engine; +CUBOS_REFLECT_IMPL(VoxelGrid) +{ + using namespace cubos::core::reflection; + + return Type::create("cubos::engine::VoxelGrid") + .with(ConstructibleTrait::typed().withDefaultConstructor().withMoveConstructor().build()); +} + VoxelGrid::VoxelGrid(const glm::uvec3& size) { if (size.x < 1 || size.y < 1 || size.z < 1) diff --git a/engine/src/cubos/engine/voxels/palette.cpp b/engine/src/cubos/engine/voxels/palette.cpp index 4305cab45d..e6cd6bebf9 100644 --- a/engine/src/cubos/engine/voxels/palette.cpp +++ b/engine/src/cubos/engine/voxels/palette.cpp @@ -1,11 +1,21 @@ #include #include +#include +#include #include using namespace cubos::engine; +CUBOS_REFLECT_IMPL(VoxelPalette) +{ + using namespace cubos::core::reflection; + + return Type::create("cubos::engine::VoxelPalette") + .with(ConstructibleTrait::typed().withDefaultConstructor().withMoveConstructor().build()); +} + VoxelPalette::VoxelPalette(std::vector&& materials) : mMaterials(std::move(materials)) { From 00122b23267660aadd74358b39357306eb0128f3 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:34:39 +0100 Subject: [PATCH 08/18] feat(assets): implement reflection for handles --- engine/include/cubos/engine/assets/asset.hpp | 30 +++++++++++-- engine/src/cubos/engine/assets/asset.cpp | 47 ++++++++++++++++---- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/engine/include/cubos/engine/assets/asset.hpp b/engine/include/cubos/engine/assets/asset.hpp index 3683e33d47..60af5a604e 100644 --- a/engine/include/cubos/engine/assets/asset.hpp +++ b/engine/include/cubos/engine/assets/asset.hpp @@ -6,6 +6,8 @@ #include +#include + namespace cubos::core::data::old { class Serializer; @@ -14,7 +16,7 @@ namespace cubos::core::data::old namespace cubos::engine { - template + template class Asset; /// @brief Handle to an asset of any type. May either be weak or strong. @@ -32,6 +34,12 @@ namespace cubos::engine class AnyAsset { public: + CUBOS_REFLECT; + + /// @brief Avoid using this field, use @ref getId() instead. + /// @todo This was added as a dirty fix for #692, should be removed once the issue is fixed. + uuids::uuid reflectedId; + ~AnyAsset(); /// @brief Constructs a null handle. @@ -85,12 +93,21 @@ namespace cubos::engine /// @brief Converts this handle to a handle of a specific type. /// @tparam T Type of the asset. /// @return Handle to the same asset, but of the specified type. - template + template inline operator Asset() const; void serialize(core::data::old::Serializer& ser, const char* name) const; void deserialize(core::data::old::Deserializer& des); + protected: + /// @brief Constructs a type with the given name, constructible trait and UUID field. + /// + /// Added so that typed asset handles don't duplicate the existing reflection code of the + /// base class. + /// + /// @param name Type name. + static core::reflection::Type& makeType(std::string name); + private: friend class Assets; @@ -109,10 +126,15 @@ namespace cubos::engine /// @see AnyAsset /// @tparam T Type of the asset. /// @ingroup assets-plugin - template + template class Asset : public AnyAsset { public: + CUBOS_REFLECT + { + return AnyAsset::makeType("cubos::engine::Asset<" + core::reflection::reflect().name() + ">"); + } + using AnyAsset::AnyAsset; /// @brief Constructs a generic handle version of this handle. @@ -143,7 +165,7 @@ namespace cubos::engine // Implementation. - template + template inline AnyAsset::operator Asset() const { Asset asset; diff --git a/engine/src/cubos/engine/assets/asset.cpp b/engine/src/cubos/engine/assets/asset.cpp index 49456eac0f..ba7e279f55 100644 --- a/engine/src/cubos/engine/assets/asset.cpp +++ b/engine/src/cubos/engine/assets/asset.cpp @@ -1,11 +1,20 @@ #include #include #include +#include +#include +#include +#include #include using namespace cubos::engine; +CUBOS_REFLECT_IMPL(AnyAsset) +{ + return AnyAsset::makeType("cubos::engine::AnyAsset"); +} + AnyAsset::~AnyAsset() { this->decRef(); @@ -18,7 +27,8 @@ AnyAsset::AnyAsset(std::nullptr_t) } AnyAsset::AnyAsset(uuids::uuid id) - : mId(id) + : reflectedId(id) + , mId(id) , mRefCount(nullptr) , mVersion(-1) { @@ -30,6 +40,7 @@ AnyAsset::AnyAsset(std::string_view str) { if (auto id = uuids::uuid::from_string(str)) { + reflectedId = id.value(); mId = id.value(); } else @@ -39,7 +50,8 @@ AnyAsset::AnyAsset(std::string_view str) } AnyAsset::AnyAsset(const AnyAsset& other) - : mId(other.mId) + : reflectedId(other.reflectedId) + , mId(other.mId) , mRefCount(other.mRefCount) , mVersion(other.mVersion) { @@ -47,7 +59,8 @@ AnyAsset::AnyAsset(const AnyAsset& other) } AnyAsset::AnyAsset(AnyAsset&& other) noexcept - : mId(other.mId) + : reflectedId(other.reflectedId) + , mId(other.mId) , mRefCount(other.mRefCount) , mVersion(other.mVersion) { @@ -57,6 +70,7 @@ AnyAsset::AnyAsset(AnyAsset&& other) noexcept AnyAsset& AnyAsset::operator=(const AnyAsset& other) { this->decRef(); + reflectedId = other.reflectedId; mId = other.mId; mRefCount = other.mRefCount; mVersion = other.mVersion; @@ -67,6 +81,7 @@ AnyAsset& AnyAsset::operator=(const AnyAsset& other) AnyAsset& AnyAsset::operator=(AnyAsset&& other) noexcept { this->decRef(); + reflectedId = other.mId; mId = other.mId; mRefCount = other.mRefCount; mVersion = other.mVersion; @@ -76,22 +91,22 @@ AnyAsset& AnyAsset::operator=(AnyAsset&& other) noexcept int AnyAsset::getVersion() const { - return mVersion; + return reflectedId == mId ? mVersion : 0; } uuids::uuid AnyAsset::getId() const { - return mId; + return reflectedId; } bool AnyAsset::isNull() const { - return mId.is_nil(); + return reflectedId.is_nil(); } bool AnyAsset::isStrong() const { - return mRefCount != nullptr; + return reflectedId == mId && mRefCount != nullptr; } void AnyAsset::makeWeak() @@ -100,9 +115,22 @@ void AnyAsset::makeWeak() mRefCount = nullptr; } +cubos::core::reflection::Type& AnyAsset::makeType(std::string name) +{ + using namespace cubos::core::reflection; + + return Type::create(std::move(name)) + .with(ConstructibleTrait::typed() + .withDefaultConstructor() + .withCopyConstructor() + .withMoveConstructor() + .build()) + .with(FieldsTrait().withField("id", &AnyAsset::reflectedId)); +} + void AnyAsset::incRef() const { - if (mRefCount != nullptr) + if (reflectedId == mId && mRefCount != nullptr) { static_cast*>(mRefCount)->fetch_add(1); } @@ -110,7 +138,7 @@ void AnyAsset::incRef() const void AnyAsset::decRef() const { - if (mRefCount != nullptr) + if (reflectedId == mId && mRefCount != nullptr) { static_cast*>(mRefCount)->fetch_sub(1); } @@ -128,6 +156,7 @@ void AnyAsset::deserialize(core::data::old::Deserializer& des) if (auto id = uuids::uuid::from_string(str)) { this->decRef(); + reflectedId = id.value(); mId = id.value(); mRefCount = nullptr; mVersion = -1; From 2e24d9600c02275b683a5b99c703da45b48ff3c9 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:36:45 +0100 Subject: [PATCH 09/18] docs(ecs): implement reflection for sample components --- core/samples/ecs/general/main.cpp | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/core/samples/ecs/general/main.cpp b/core/samples/ecs/general/main.cpp index 88babffdb3..7c05411097 100644 --- a/core/samples/ecs/general/main.cpp +++ b/core/samples/ecs/general/main.cpp @@ -9,28 +9,60 @@ #include #include #include +#include +#include using namespace cubos::core; +using reflection::ConstructibleTrait; +using reflection::Type; + struct Player { + CUBOS_REFLECT; }; struct Position { + CUBOS_REFLECT; + float x, y, z; }; struct Velocity { + CUBOS_REFLECT; + float x, y, z; }; struct Parent { + CUBOS_REFLECT; + ecs::Entity entity; }; +CUBOS_REFLECT_IMPL(Player) +{ + return Type::create("Player").with(ConstructibleTrait::typed().withMoveConstructor().build()); +} + +CUBOS_REFLECT_IMPL(Position) +{ + return Type::create("Position").with(ConstructibleTrait::typed().withMoveConstructor().build()); +} + +CUBOS_REFLECT_IMPL(Velocity) +{ + return Type::create("Velocity").with(ConstructibleTrait::typed().withMoveConstructor().build()); +} + +CUBOS_REFLECT_IMPL(Parent) +{ + return Type::create("Parent").with(ConstructibleTrait::typed().withMoveConstructor().build()); +} + namespace cubos::core::data::old { void serialize(Serializer& /*unused*/, const Player& /*unused*/, const char* /*unused*/) From c49b601807d68913c3185a6235c1895dbca19cc6 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:37:11 +0100 Subject: [PATCH 10/18] test(ecs): implement reflection for test components --- core/tests/CMakeLists.txt | 2 ++ core/tests/ecs/utils.cpp | 30 ++++++++++++++++++++++++++++++ core/tests/ecs/utils.hpp | 7 +++++++ core/tests/utils.cpp | 13 +++++++++++++ core/tests/utils.hpp | 4 ++++ 5 files changed, 56 insertions(+) create mode 100644 core/tests/ecs/utils.cpp create mode 100644 core/tests/utils.cpp diff --git a/core/tests/CMakeLists.txt b/core/tests/CMakeLists.txt index 21beefc097..bbd083df98 100644 --- a/core/tests/CMakeLists.txt +++ b/core/tests/CMakeLists.txt @@ -6,6 +6,7 @@ include(QuadradosGenerate) add_executable( cubos-core-tests main.cpp + utils.cpp reflection/reflect.cpp reflection/type.cpp @@ -23,6 +24,7 @@ add_executable( data/fs/file_system.cpp data/context.cpp + ecs/utils.cpp ecs/registry.cpp ecs/world.cpp ecs/query.cpp diff --git a/core/tests/ecs/utils.cpp b/core/tests/ecs/utils.cpp new file mode 100644 index 0000000000..75652bd0e4 --- /dev/null +++ b/core/tests/ecs/utils.cpp @@ -0,0 +1,30 @@ +#include "utils.hpp" + +#include +#include + +CUBOS_REFLECT_IMPL(IntegerComponent) +{ + return cubos::core::ecs::ComponentTypeBuilder("IntegerComponent") + .withField("value", &IntegerComponent::value) + .build(); +} + +CUBOS_REFLECT_IMPL(ParentComponent) +{ + return cubos::core::ecs::ComponentTypeBuilder("ParentComponent") + .withField("id", &ParentComponent::id) + .build(); +} + +CUBOS_REFLECT_IMPL(DetectDestructorComponent) +{ + using namespace cubos::core::reflection; + + return Type::create("DetectDestructorComponent") + .with(ConstructibleTrait::typed() + .withDefaultConstructor() + .withMoveConstructor() + .build()) + .with(FieldsTrait().withField("detect", &DetectDestructorComponent::detect)); +} diff --git a/core/tests/ecs/utils.hpp b/core/tests/ecs/utils.hpp index 6d4750cc73..30f5f8cdf1 100644 --- a/core/tests/ecs/utils.hpp +++ b/core/tests/ecs/utils.hpp @@ -4,24 +4,31 @@ #pragma once #include +#include #include "../utils.hpp" /// A component which stores a single integer. struct [[cubos::component("integer")]] IntegerComponent { + CUBOS_REFLECT; + int value; }; /// A component which references another entity. struct [[cubos::component("parent")]] ParentComponent { + CUBOS_REFLECT; + cubos::core::ecs::Entity id; }; /// A component used to test if components are destructed properly. struct [[cubos::component("detect_destructor")]] DetectDestructorComponent { + CUBOS_REFLECT; + [[cubos::ignore]] DetectDestructor detect; }; diff --git a/core/tests/utils.cpp b/core/tests/utils.cpp new file mode 100644 index 0000000000..335bb3735c --- /dev/null +++ b/core/tests/utils.cpp @@ -0,0 +1,13 @@ +#include "utils.hpp" + +#include +#include + +using cubos::core::reflection::ConstructibleTrait; +using cubos::core::reflection::Type; + +CUBOS_REFLECT_IMPL(DetectDestructor) +{ + return Type::create("DetectDestructor") + .with(ConstructibleTrait::typed().withDefaultConstructor().withMoveConstructor().build()); +} diff --git a/core/tests/utils.hpp b/core/tests/utils.hpp index df2e358820..7468e2dad8 100644 --- a/core/tests/utils.hpp +++ b/core/tests/utils.hpp @@ -2,6 +2,8 @@ #include +#include + /// Utility macro which adds two subcases to the current test case, one for true and one for false. #define PARAMETRIZE_TRUE_OR_FALSE(what, var) \ do \ @@ -67,6 +69,8 @@ class DetectDestructor { public: + CUBOS_REFLECT; + DetectDestructor(bool* destructed = nullptr) : mDestructed(destructed) { From f4316152d5009b596051cc7b454616936bcd132d Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:38:53 +0100 Subject: [PATCH 11/18] docs(engine): implement reflection for sample components --- engine/samples/hello-cubos/components.hpp | 3 +++ engine/samples/hello-cubos/main.cpp | 10 ++++++++++ engine/samples/scene/components.hpp | 7 ++++++- engine/samples/scene/main.cpp | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/engine/samples/hello-cubos/components.hpp b/engine/samples/hello-cubos/components.hpp index b52a042f48..96cd8e1fd0 100644 --- a/engine/samples/hello-cubos/components.hpp +++ b/engine/samples/hello-cubos/components.hpp @@ -1,8 +1,11 @@ #pragma once #include +#include struct [[cubos::component("num", VecStorage)]] Num { + CUBOS_REFLECT; + int value; }; diff --git a/engine/samples/hello-cubos/main.cpp b/engine/samples/hello-cubos/main.cpp index 3e5ccdf90f..aa2512c20d 100644 --- a/engine/samples/hello-cubos/main.cpp +++ b/engine/samples/hello-cubos/main.cpp @@ -15,6 +15,16 @@ using cubos::core::ecs::Read; using cubos::core::ecs::Write; /// [Include Entity Stuff] +/// [Component Refl] +#include +#include + +CUBOS_REFLECT_IMPL(Num) +{ + return cubos::core::ecs::ComponentTypeBuilder("Num").withField("value", &Num::value).build(); +} +/// [Component Refl] + /// [Resource Decl] struct Pop { diff --git a/engine/samples/scene/components.hpp b/engine/samples/scene/components.hpp index 36e7fc677b..38279c9db4 100644 --- a/engine/samples/scene/components.hpp +++ b/engine/samples/scene/components.hpp @@ -1,13 +1,18 @@ #pragma once -#include +#include +#include struct [[cubos::component("num", VecStorage)]] Num { + CUBOS_REFLECT; + int value; }; struct [[cubos::component("parent", VecStorage)]] Parent { + CUBOS_REFLECT; + cubos::core::ecs::Entity entity; }; diff --git a/engine/samples/scene/main.cpp b/engine/samples/scene/main.cpp index 216a312fc8..0fa9b99b0b 100644 --- a/engine/samples/scene/main.cpp +++ b/engine/samples/scene/main.cpp @@ -15,6 +15,21 @@ using cubos::core::ecs::Write; using namespace cubos::engine; +/// [Component Refl] +#include +#include + +CUBOS_REFLECT_IMPL(Num) +{ + return cubos::core::ecs::ComponentTypeBuilder("Num").withField("value", &Num::value).build(); +} + +CUBOS_REFLECT_IMPL(Parent) +{ + return cubos::core::ecs::ComponentTypeBuilder("Parent").withField("entity", &Parent::entity).build(); +} +/// [Component Refl] + /// [Setting the asset] static const Asset SceneAsset = AnyAsset("f0d86ba8-5f34-440f-a180-d9d12c8e8b91"); /// [Setting the asset] From 312a433152d99e6526c7566b53f98c53925b65a9 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:39:36 +0100 Subject: [PATCH 12/18] build(engine): remove quadrados from samples when unnecessary --- engine/samples/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/samples/CMakeLists.txt b/engine/samples/CMakeLists.txt index 5471d5d57c..363073e960 100644 --- a/engine/samples/CMakeLists.txt +++ b/engine/samples/CMakeLists.txt @@ -45,6 +45,6 @@ make_sample(DIR "assets/bridge" ASSETS) make_sample(DIR "assets/json" ASSETS) make_sample(DIR "assets/saving" ASSETS) make_sample(DIR "renderer") -make_sample(DIR "collisions" COMPONENTS) +make_sample(DIR "collisions") make_sample(DIR "scene" COMPONENTS ASSETS) -make_sample(DIR "voxels" COMPONENTS ASSETS) +make_sample(DIR "voxels" ASSETS) From 9214ba355b589a9038c2feaca6a45a6790de74d5 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:41:00 +0100 Subject: [PATCH 13/18] feat(transform): implement reflection for components --- engine/CMakeLists.txt | 4 ++++ .../include/cubos/engine/transform/local_to_world.hpp | 6 +++++- engine/include/cubos/engine/transform/position.hpp | 6 +++++- engine/include/cubos/engine/transform/rotation.hpp | 4 ++++ engine/include/cubos/engine/transform/scale.hpp | 4 +++- engine/src/cubos/engine/transform/local_to_world.cpp | 11 +++++++++++ engine/src/cubos/engine/transform/position.cpp | 11 +++++++++++ engine/src/cubos/engine/transform/rotation.cpp | 11 +++++++++++ engine/src/cubos/engine/transform/scale.cpp | 9 +++++++++ 9 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 engine/src/cubos/engine/transform/local_to_world.cpp create mode 100644 engine/src/cubos/engine/transform/position.cpp create mode 100644 engine/src/cubos/engine/transform/rotation.cpp create mode 100644 engine/src/cubos/engine/transform/scale.cpp diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index cc7f8f3f42..7cad8f03f7 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -30,6 +30,10 @@ set(CUBOS_ENGINE_SOURCE "src/cubos/engine/tools/scene_editor/plugin.cpp" "src/cubos/engine/transform/plugin.cpp" + "src/cubos/engine/transform/local_to_world.cpp" + "src/cubos/engine/transform/position.cpp" + "src/cubos/engine/transform/rotation.cpp" + "src/cubos/engine/transform/scale.cpp" "src/cubos/engine/assets/plugin.cpp" "src/cubos/engine/assets/assets.cpp" diff --git a/engine/include/cubos/engine/transform/local_to_world.hpp b/engine/include/cubos/engine/transform/local_to_world.hpp index 3038123607..976c11236a 100644 --- a/engine/include/cubos/engine/transform/local_to_world.hpp +++ b/engine/include/cubos/engine/transform/local_to_world.hpp @@ -4,7 +4,9 @@ #pragma once -#include +#include + +#include namespace cubos::engine { @@ -21,6 +23,8 @@ namespace cubos::engine /// @ingroup transform-plugin struct [[cubos::component("cubos/local_to_world", VecStorage)]] LocalToWorld { + CUBOS_REFLECT; + glm::mat4 mat = glm::mat4(1.0F); ///< Local to world space matrix. }; diff --git a/engine/include/cubos/engine/transform/position.hpp b/engine/include/cubos/engine/transform/position.hpp index c30a8286a8..b4742bdefa 100644 --- a/engine/include/cubos/engine/transform/position.hpp +++ b/engine/include/cubos/engine/transform/position.hpp @@ -4,7 +4,9 @@ #pragma once -#include +#include + +#include namespace cubos::engine { @@ -13,6 +15,8 @@ namespace cubos::engine /// @ingroup transform-plugin struct [[cubos::component("cubos/position", VecStorage)]] Position { + CUBOS_REFLECT; + glm::vec3 vec = {0.0F, 0.0F, 0.0F}; ///< Position of the entity. }; } // namespace cubos::engine diff --git a/engine/include/cubos/engine/transform/rotation.hpp b/engine/include/cubos/engine/transform/rotation.hpp index d1dd2a17ad..6f8337ddff 100644 --- a/engine/include/cubos/engine/transform/rotation.hpp +++ b/engine/include/cubos/engine/transform/rotation.hpp @@ -6,6 +6,8 @@ #include +#include + namespace cubos::engine { /// @brief Component which assigns a rotation to an entity. @@ -13,6 +15,8 @@ namespace cubos::engine /// @ingroup transform-plugin struct [[cubos::component("cubos/rotation", VecStorage)]] Rotation { + CUBOS_REFLECT; + glm::quat quat = glm::quat(1.0F, 0.0F, 0.0F, 0.0F); ///< Rotation of the entity. }; } // namespace cubos::engine diff --git a/engine/include/cubos/engine/transform/scale.hpp b/engine/include/cubos/engine/transform/scale.hpp index 91e2df12dc..738cf13b94 100644 --- a/engine/include/cubos/engine/transform/scale.hpp +++ b/engine/include/cubos/engine/transform/scale.hpp @@ -4,7 +4,7 @@ #pragma once -#include +#include namespace cubos::engine { @@ -13,6 +13,8 @@ namespace cubos::engine /// @ingroup transform-plugin struct [[cubos::component("cubos/scale", VecStorage)]] Scale { + CUBOS_REFLECT; + float factor; ///< Uniform scale factor of the entity. }; } // namespace cubos::engine diff --git a/engine/src/cubos/engine/transform/local_to_world.cpp b/engine/src/cubos/engine/transform/local_to_world.cpp new file mode 100644 index 0000000000..c62f5099b6 --- /dev/null +++ b/engine/src/cubos/engine/transform/local_to_world.cpp @@ -0,0 +1,11 @@ +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::LocalToWorld) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::LocalToWorld") + .withField("mat", &LocalToWorld::mat) + .build(); +} diff --git a/engine/src/cubos/engine/transform/position.cpp b/engine/src/cubos/engine/transform/position.cpp new file mode 100644 index 0000000000..773c3f9737 --- /dev/null +++ b/engine/src/cubos/engine/transform/position.cpp @@ -0,0 +1,11 @@ +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::Position) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::Position") + .withField("vec", &Position::vec) + .build(); +} diff --git a/engine/src/cubos/engine/transform/rotation.cpp b/engine/src/cubos/engine/transform/rotation.cpp new file mode 100644 index 0000000000..c1c4a87fda --- /dev/null +++ b/engine/src/cubos/engine/transform/rotation.cpp @@ -0,0 +1,11 @@ +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::Rotation) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::Rotation") + .withField("quat", &Rotation::quat) + .build(); +} diff --git a/engine/src/cubos/engine/transform/scale.cpp b/engine/src/cubos/engine/transform/scale.cpp new file mode 100644 index 0000000000..b14d77dbb5 --- /dev/null +++ b/engine/src/cubos/engine/transform/scale.cpp @@ -0,0 +1,9 @@ +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::Scale) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::Scale").withField("mat", &Scale::factor).build(); +} From 425d3706ca38c12d8fad1bed5c40a54d064158f1 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:52:14 +0100 Subject: [PATCH 14/18] feat(rendering): implement reflection for components --- engine/CMakeLists.txt | 4 ++++ engine/include/cubos/engine/renderer/camera.hpp | 10 ++++++---- .../cubos/engine/renderer/directional_light.hpp | 8 ++++++-- engine/include/cubos/engine/renderer/plugin.hpp | 4 ++++ .../include/cubos/engine/renderer/point_light.hpp | 10 +++++++--- .../include/cubos/engine/renderer/spot_light.hpp | 12 ++++++++---- engine/src/cubos/engine/renderer/camera.cpp | 13 +++++++++++++ .../cubos/engine/renderer/directional_light.cpp | 13 +++++++++++++ engine/src/cubos/engine/renderer/plugin.cpp | 10 ++++++++++ engine/src/cubos/engine/renderer/point_light.cpp | 14 ++++++++++++++ engine/src/cubos/engine/renderer/spot_light.cpp | 15 +++++++++++++++ 11 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 engine/src/cubos/engine/renderer/camera.cpp create mode 100644 engine/src/cubos/engine/renderer/directional_light.cpp create mode 100644 engine/src/cubos/engine/renderer/point_light.cpp create mode 100644 engine/src/cubos/engine/renderer/spot_light.cpp diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 7cad8f03f7..d93cfe8f7b 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -64,6 +64,10 @@ set(CUBOS_ENGINE_SOURCE "src/cubos/engine/renderer/plugin.cpp" "src/cubos/engine/renderer/vertex.cpp" "src/cubos/engine/renderer/frame.cpp" + "src/cubos/engine/renderer/camera.cpp" + "src/cubos/engine/renderer/directional_light.cpp" + "src/cubos/engine/renderer/point_light.cpp" + "src/cubos/engine/renderer/spot_light.cpp" "src/cubos/engine/renderer/renderer.cpp" "src/cubos/engine/renderer/deferred_renderer.cpp" "src/cubos/engine/renderer/pps/bloom.cpp" diff --git a/engine/include/cubos/engine/renderer/camera.hpp b/engine/include/cubos/engine/renderer/camera.hpp index 0dcf40d0ea..0ffeade193 100644 --- a/engine/include/cubos/engine/renderer/camera.hpp +++ b/engine/include/cubos/engine/renderer/camera.hpp @@ -4,7 +4,7 @@ #pragma once -#include +#include namespace cubos::engine { @@ -13,8 +13,10 @@ namespace cubos::engine /// @ingroup renderer-plugin struct [[cubos::component("cubos/camera", VecStorage)]] Camera { - float fovY; ///< Vertical field of view in degrees. - float zNear; ///< Near clipping plane. - float zFar; ///< Far clipping plane. + CUBOS_REFLECT; + + float fovY = 60.0F; ///< Vertical field of view in degrees. + float zNear = 0.1F; ///< Near clipping plane. + float zFar = 1000.0F; ///< Far clipping plane. }; } // namespace cubos::engine diff --git a/engine/include/cubos/engine/renderer/directional_light.hpp b/engine/include/cubos/engine/renderer/directional_light.hpp index 44594015b4..b0e584cc8b 100644 --- a/engine/include/cubos/engine/renderer/directional_light.hpp +++ b/engine/include/cubos/engine/renderer/directional_light.hpp @@ -6,6 +6,8 @@ #include +#include + namespace cubos::engine { /// @brief Component which makes an entity behave like a directional light. @@ -14,7 +16,9 @@ namespace cubos::engine /// @ingroup renderer-plugin struct [[cubos::component("cubos/directional_light", VecStorage)]] DirectionalLight { - glm::vec3 color; - float intensity; + CUBOS_REFLECT; + + glm::vec3 color = {1.0F, 1.0F, 1.0F}; ///< Color of the light. + float intensity = 1.0F; ///< Intensity of the light. }; } // namespace cubos::engine diff --git a/engine/include/cubos/engine/renderer/plugin.hpp b/engine/include/cubos/engine/renderer/plugin.hpp index 1001843ac8..a786b07aab 100644 --- a/engine/include/cubos/engine/renderer/plugin.hpp +++ b/engine/include/cubos/engine/renderer/plugin.hpp @@ -9,6 +9,8 @@ #pragma once +#include + #include #include #include @@ -67,6 +69,8 @@ namespace cubos::engine /// @ingroup renderer-plugin struct [[cubos::component("cubos/renderable_grid", VecStorage)]] RenderableGrid { + CUBOS_REFLECT; + Asset asset; ///< Handle to the grid asset to be rendered. glm::vec3 offset = {0.0F, 0.0F, 0.0F}; ///< Translation applied to the voxel grid before any other. [[cubos::ignore]] RendererGrid handle = nullptr; ///< Handle to the uploaded grid - set automatically. diff --git a/engine/include/cubos/engine/renderer/point_light.hpp b/engine/include/cubos/engine/renderer/point_light.hpp index 853da0b82a..842aeb8dee 100644 --- a/engine/include/cubos/engine/renderer/point_light.hpp +++ b/engine/include/cubos/engine/renderer/point_light.hpp @@ -6,6 +6,8 @@ #include +#include + namespace cubos::engine { /// @brief Component which makes an entity behave like a point light. @@ -13,8 +15,10 @@ namespace cubos::engine /// @ingroup renderer-plugin struct [[cubos::component("cubos/point_light", VecStorage)]] PointLight { - glm::vec3 color; - float intensity; - float range; + CUBOS_REFLECT; + + glm::vec3 color = {1.0F, 1.0F, 1.0F}; ///< Color of the light. + float intensity = 1.0F; ///< Intensity of the light. + float range = 5.0F; ///< Range of the light. }; } // namespace cubos::engine diff --git a/engine/include/cubos/engine/renderer/spot_light.hpp b/engine/include/cubos/engine/renderer/spot_light.hpp index 627e363419..bd4ea61717 100644 --- a/engine/include/cubos/engine/renderer/spot_light.hpp +++ b/engine/include/cubos/engine/renderer/spot_light.hpp @@ -6,6 +6,8 @@ #include +#include + namespace cubos::engine { /// @brief Component which makes an entity emit a spot light. @@ -14,9 +16,11 @@ namespace cubos::engine /// @ingroup renderer-plugin struct [[cubos::component("cubos/spot_light", VecStorage)]] SpotLight { - glm::vec3 color; - float intensity; - float range; - float spotAngle; + CUBOS_REFLECT; + + glm::vec3 color = {1.0F, 1.0F, 1.0F}; ///< Color of the light. + float intensity = 1.0F; ///< Intensity of the light. + float range = 5.0F; ///< Range of the light. + float spotAngle = 60.0F; ///< Angle of the spot light in degrees. }; } // namespace cubos::engine diff --git a/engine/src/cubos/engine/renderer/camera.cpp b/engine/src/cubos/engine/renderer/camera.cpp new file mode 100644 index 0000000000..32a2a0e023 --- /dev/null +++ b/engine/src/cubos/engine/renderer/camera.cpp @@ -0,0 +1,13 @@ +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::Camera) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::Camera") + .withField("fovY", &Camera::fovY) + .withField("zNear", &Camera::zNear) + .withField("zFar", &Camera::zFar) + .build(); +} diff --git a/engine/src/cubos/engine/renderer/directional_light.cpp b/engine/src/cubos/engine/renderer/directional_light.cpp new file mode 100644 index 0000000000..fee2f00b14 --- /dev/null +++ b/engine/src/cubos/engine/renderer/directional_light.cpp @@ -0,0 +1,13 @@ +#include +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::DirectionalLight) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::DirectionalLight") + .withField("color", &DirectionalLight::color) + .withField("intensity", &DirectionalLight::intensity) + .build(); +} diff --git a/engine/src/cubos/engine/renderer/plugin.cpp b/engine/src/cubos/engine/renderer/plugin.cpp index b2456b8250..ba8f573bf1 100644 --- a/engine/src/cubos/engine/renderer/plugin.cpp +++ b/engine/src/cubos/engine/renderer/plugin.cpp @@ -1,4 +1,6 @@ +#include #include +#include #include #include @@ -22,6 +24,14 @@ using cubos::core::io::WindowEvent; using namespace cubos::engine; +CUBOS_REFLECT_IMPL(RenderableGrid) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::RenderableGrid") + .withField("asset", &RenderableGrid::asset) + .withField("offset", &RenderableGrid::offset) + .build(); +} + static void init(Write renderer, Read window, Write settings) { auto& renderDevice = (*window)->renderDevice(); diff --git a/engine/src/cubos/engine/renderer/point_light.cpp b/engine/src/cubos/engine/renderer/point_light.cpp new file mode 100644 index 0000000000..ed5a28696f --- /dev/null +++ b/engine/src/cubos/engine/renderer/point_light.cpp @@ -0,0 +1,14 @@ +#include +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::PointLight) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::PointLight") + .withField("color", &PointLight::color) + .withField("range", &PointLight::range) + .withField("intensity", &PointLight::intensity) + .build(); +} diff --git a/engine/src/cubos/engine/renderer/spot_light.cpp b/engine/src/cubos/engine/renderer/spot_light.cpp new file mode 100644 index 0000000000..f6e2359ba5 --- /dev/null +++ b/engine/src/cubos/engine/renderer/spot_light.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::SpotLight) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::SpotLight") + .withField("color", &SpotLight::color) + .withField("intensity", &SpotLight::intensity) + .withField("range", &SpotLight::range) + .withField("spotAngle", &SpotLight::spotAngle) + .build(); +} From 255c8d5c4f1f0b2c7042462ac524b085f1217d32 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 13:53:51 +0100 Subject: [PATCH 15/18] feat(collisions): implement reflection for components --- engine/CMakeLists.txt | 3 +++ engine/include/cubos/engine/collisions/collider.hpp | 3 +++ engine/include/cubos/engine/collisions/shapes/box.hpp | 3 +++ .../cubos/engine/collisions/shapes/capsule.hpp | 3 +++ engine/src/cubos/engine/collisions/collider.cpp | 11 +++++++++++ engine/src/cubos/engine/collisions/shapes/box.cpp | 10 ++++++++++ engine/src/cubos/engine/collisions/shapes/capsule.cpp | 10 ++++++++++ 7 files changed, 43 insertions(+) create mode 100644 engine/src/cubos/engine/collisions/collider.cpp create mode 100644 engine/src/cubos/engine/collisions/shapes/box.cpp create mode 100644 engine/src/cubos/engine/collisions/shapes/capsule.cpp diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index d93cfe8f7b..ae90b8b174 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -51,6 +51,9 @@ set(CUBOS_ENGINE_SOURCE "src/cubos/engine/voxels/palette.cpp" "src/cubos/engine/collisions/plugin.cpp" + "src/cubos/engine/collisions/collider.cpp" + "src/cubos/engine/collisions/shapes/box.cpp" + "src/cubos/engine/collisions/shapes/capsule.cpp" "src/cubos/engine/collisions/broad_phase/plugin.cpp" "src/cubos/engine/collisions/broad_phase/sweep_and_prune.cpp" "src/cubos/engine/collisions/broad_phase/candidates.cpp" diff --git a/engine/include/cubos/engine/collisions/collider.hpp b/engine/include/cubos/engine/collisions/collider.hpp index f8be59be41..1472c7f53f 100644 --- a/engine/include/cubos/engine/collisions/collider.hpp +++ b/engine/include/cubos/engine/collisions/collider.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace cubos::engine { @@ -14,6 +15,8 @@ namespace cubos::engine /// @ingroup collisions-plugin struct [[cubos::component("cubos/collider", VecStorage)]] Collider { + CUBOS_REFLECT; + glm::mat4 transform{1.0F}; ///< Transform of the collider. core::geom::AABB localAABB{}; ///< Local space AABB of the collider. diff --git a/engine/include/cubos/engine/collisions/shapes/box.hpp b/engine/include/cubos/engine/collisions/shapes/box.hpp index 01e6268a51..89e1f791ab 100644 --- a/engine/include/cubos/engine/collisions/shapes/box.hpp +++ b/engine/include/cubos/engine/collisions/shapes/box.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace cubos::engine { @@ -12,6 +13,8 @@ namespace cubos::engine /// @ingroup collisions-plugin struct [[cubos::component("cubos/box_collision_shape", VecStorage)]] BoxCollisionShape { + CUBOS_REFLECT; + cubos::core::geom::Box box; ///< Box shape. }; } // namespace cubos::engine diff --git a/engine/include/cubos/engine/collisions/shapes/capsule.hpp b/engine/include/cubos/engine/collisions/shapes/capsule.hpp index 9a62f15bf5..b373237f3c 100644 --- a/engine/include/cubos/engine/collisions/shapes/capsule.hpp +++ b/engine/include/cubos/engine/collisions/shapes/capsule.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace cubos::engine { @@ -12,6 +13,8 @@ namespace cubos::engine /// @ingroup collisions-plugin struct [[cubos::component("cubos/capsule_collision_shape", VecStorage)]] CapsuleCollisionShape { + CUBOS_REFLECT; + cubos::core::geom::Capsule capsule; ///< Capsule shape. }; } // namespace cubos::engine diff --git a/engine/src/cubos/engine/collisions/collider.cpp b/engine/src/cubos/engine/collisions/collider.cpp new file mode 100644 index 0000000000..8d54355849 --- /dev/null +++ b/engine/src/cubos/engine/collisions/collider.cpp @@ -0,0 +1,11 @@ +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::Collider) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::Collider") + .withField("transform", &Collider::transform) + .build(); +} diff --git a/engine/src/cubos/engine/collisions/shapes/box.cpp b/engine/src/cubos/engine/collisions/shapes/box.cpp new file mode 100644 index 0000000000..5f9bde5ecf --- /dev/null +++ b/engine/src/cubos/engine/collisions/shapes/box.cpp @@ -0,0 +1,10 @@ +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::BoxCollisionShape) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::BoxCollisionShape") + .withField("box", &BoxCollisionShape::box) + .build(); +} diff --git a/engine/src/cubos/engine/collisions/shapes/capsule.cpp b/engine/src/cubos/engine/collisions/shapes/capsule.cpp new file mode 100644 index 0000000000..8435bf99dc --- /dev/null +++ b/engine/src/cubos/engine/collisions/shapes/capsule.cpp @@ -0,0 +1,10 @@ +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::CapsuleCollisionShape) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::CapsuleCollisionShape") + .withField("capsule", &CapsuleCollisionShape::capsule) + .build(); +} From c98821110cc4ac512ff9398e8175f7fd8f7c1bc0 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 16:14:21 +0100 Subject: [PATCH 16/18] feat(reflection): add ConstructibleTrait withBasic* --- .../cubos/core/reflection/traits/constructible.hpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/include/cubos/core/reflection/traits/constructible.hpp b/core/include/cubos/core/reflection/traits/constructible.hpp index abf4947447..30219c08ef 100644 --- a/core/include/cubos/core/reflection/traits/constructible.hpp +++ b/core/include/cubos/core/reflection/traits/constructible.hpp @@ -142,7 +142,7 @@ namespace cubos::core::reflection return mTrait; } - /// @brief Sets the copy constructor of the type. + /// @brief Sets the default constructor of the type. /// @return Builder. Builder&& withDefaultConstructor() && { @@ -168,6 +168,13 @@ namespace cubos::core::reflection return memory::move(*this); } + /// @brief Sets the default, copy and move constructors of the type. + /// @return Builder. + Builder&& withBasicConstructors() && + { + return memory::move(*this).withDefaultConstructor().withCopyConstructor().withMoveConstructor(); + } + private: ConstructibleTrait mTrait; }; From 442a7ad47fe3a5a63eba9aaa89a42a440d8af6d6 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 16:14:40 +0100 Subject: [PATCH 17/18] refactor: use ConstructibleTrait withBasic* --- core/include/cubos/core/ecs/component/reflection.hpp | 6 +----- core/src/cubos/core/ecs/entity/entity.cpp | 6 +----- core/src/cubos/core/geom/box.cpp | 6 +----- core/src/cubos/core/geom/capsule.cpp | 6 +----- core/src/cubos/core/reflection/external/glm.cpp | 3 +-- core/src/cubos/core/reflection/external/primitives.cpp | 6 +----- core/src/cubos/core/reflection/external/uuid.cpp | 7 +------ engine/src/cubos/engine/assets/asset.cpp | 6 +----- 8 files changed, 8 insertions(+), 38 deletions(-) diff --git a/core/include/cubos/core/ecs/component/reflection.hpp b/core/include/cubos/core/ecs/component/reflection.hpp index e711bd810c..cdfff8109b 100644 --- a/core/include/cubos/core/ecs/component/reflection.hpp +++ b/core/include/cubos/core/ecs/component/reflection.hpp @@ -26,11 +26,7 @@ namespace cubos::core::ecs ComponentTypeBuilder(std::string name) : mType(reflection::Type::create(std::move(name))) { - mType.with(reflection::ConstructibleTrait::typed() - .withDefaultConstructor() - .withCopyConstructor() - .withMoveConstructor() - .build()); + mType.with(reflection::ConstructibleTrait::typed().withBasicConstructors().build()); } /// @brief Adds a field to the component type. diff --git a/core/src/cubos/core/ecs/entity/entity.cpp b/core/src/cubos/core/ecs/entity/entity.cpp index bafeb63b83..8c8c51fdd8 100644 --- a/core/src/cubos/core/ecs/entity/entity.cpp +++ b/core/src/cubos/core/ecs/entity/entity.cpp @@ -17,11 +17,7 @@ using cubos::core::reflection::Type; CUBOS_REFLECT_IMPL(Entity) { return Type::create("cubos::core::ecs::Entity") - .with(ConstructibleTrait::typed() - .withCopyConstructor() - .withMoveConstructor() - .withDefaultConstructor() - .build()) + .with(ConstructibleTrait::typed().withBasicConstructors().build()) .with(FieldsTrait().withField("index", &Entity::index).withField("generation", &Entity::generation)); } diff --git a/core/src/cubos/core/geom/box.cpp b/core/src/cubos/core/geom/box.cpp index 18f0949b08..11d049540e 100644 --- a/core/src/cubos/core/geom/box.cpp +++ b/core/src/cubos/core/geom/box.cpp @@ -9,10 +9,6 @@ CUBOS_REFLECT_IMPL(cubos::core::geom::Box) using namespace core::reflection; return Type::create("cubos::core::geom::Box") - .with(ConstructibleTrait::typed() - .withDefaultConstructor() - .withCopyConstructor() - .withMoveConstructor() - .build()) + .with(ConstructibleTrait::typed().withBasicConstructors().build()) .with(FieldsTrait().withField("halfSize", &Box::halfSize)); } diff --git a/core/src/cubos/core/geom/capsule.cpp b/core/src/cubos/core/geom/capsule.cpp index 3ac072e552..cea7054013 100644 --- a/core/src/cubos/core/geom/capsule.cpp +++ b/core/src/cubos/core/geom/capsule.cpp @@ -9,10 +9,6 @@ CUBOS_REFLECT_IMPL(cubos::core::geom::Capsule) using namespace core::reflection; return Type::create("cubos::core::geom::Capsule") - .with(ConstructibleTrait::typed() - .withDefaultConstructor() - .withCopyConstructor() - .withMoveConstructor() - .build()) + .with(ConstructibleTrait::typed().withBasicConstructors().build()) .with(FieldsTrait().withField("radius", &Capsule::radius).withField("length", &Capsule::length)); } diff --git a/core/src/cubos/core/reflection/external/glm.cpp b/core/src/cubos/core/reflection/external/glm.cpp index 9a4861bb19..555beb958a 100644 --- a/core/src/cubos/core/reflection/external/glm.cpp +++ b/core/src/cubos/core/reflection/external/glm.cpp @@ -30,8 +30,7 @@ class AddressOfImpl final : public FieldsTrait::AddressOf glm::length_t mColumn; }; -#define AUTO_CONSTRUCTIBLE(type) \ - ConstructibleTrait::typed().withDefaultConstructor().withCopyConstructor().withMoveConstructor().build() +#define AUTO_CONSTRUCTIBLE(type) ConstructibleTrait::typed().withBasicConstructors().build() #define AUTO_VEC1(type) FieldsTrait().withField("x", &type::x) #define AUTO_VEC2(type) AUTO_VEC1(type).withField("y", &type::y) diff --git a/core/src/cubos/core/reflection/external/primitives.cpp b/core/src/cubos/core/reflection/external/primitives.cpp index 318578638e..2a315470e6 100644 --- a/core/src/cubos/core/reflection/external/primitives.cpp +++ b/core/src/cubos/core/reflection/external/primitives.cpp @@ -5,11 +5,7 @@ #define AUTO_IMPL(type, name) \ CUBOS_REFLECT_EXTERNAL_IMPL(type) \ { \ - return Type::create(name).with(ConstructibleTrait::typed() \ - .withDefaultConstructor() \ - .withCopyConstructor() \ - .withMoveConstructor() \ - .build()); \ + return Type::create(name).with(ConstructibleTrait::typed().withBasicConstructors().build()); \ } AUTO_IMPL(bool, "bool") diff --git a/core/src/cubos/core/reflection/external/uuid.cpp b/core/src/cubos/core/reflection/external/uuid.cpp index 9186e0c910..25053d2fbc 100644 --- a/core/src/cubos/core/reflection/external/uuid.cpp +++ b/core/src/cubos/core/reflection/external/uuid.cpp @@ -6,10 +6,5 @@ CUBOS_REFLECT_EXTERNAL_IMPL(uuids::uuid) { using namespace cubos::core::reflection; - return Type::create("uuids::uuid") - .with(ConstructibleTrait::typed() - .withDefaultConstructor() - .withCopyConstructor() - .withMoveConstructor() - .build()); + return Type::create("uuids::uuid").with(ConstructibleTrait::typed().withBasicConstructors().build()); } diff --git a/engine/src/cubos/engine/assets/asset.cpp b/engine/src/cubos/engine/assets/asset.cpp index ba7e279f55..abc6a086ce 100644 --- a/engine/src/cubos/engine/assets/asset.cpp +++ b/engine/src/cubos/engine/assets/asset.cpp @@ -120,11 +120,7 @@ cubos::core::reflection::Type& AnyAsset::makeType(std::string name) using namespace cubos::core::reflection; return Type::create(std::move(name)) - .with(ConstructibleTrait::typed() - .withDefaultConstructor() - .withCopyConstructor() - .withMoveConstructor() - .build()) + .with(ConstructibleTrait::typed().withBasicConstructors().build()) .with(FieldsTrait().withField("id", &AnyAsset::reflectedId)); } From f728064ac70ca2c443cb320319860421becf5531 Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sun, 8 Oct 2023 16:15:14 +0100 Subject: [PATCH 18/18] style(reflection): add missing newline at EOF --- core/include/cubos/core/ecs/component/reflection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/cubos/core/ecs/component/reflection.hpp b/core/include/cubos/core/ecs/component/reflection.hpp index cdfff8109b..60acd459a5 100644 --- a/core/include/cubos/core/ecs/component/reflection.hpp +++ b/core/include/cubos/core/ecs/component/reflection.hpp @@ -53,4 +53,4 @@ namespace cubos::core::ecs reflection::Type& mType; reflection::FieldsTrait mFields; }; -} // namespace cubos::core::ecs \ No newline at end of file +} // namespace cubos::core::ecs