From d7456c4228a8045b5a911b7d5df0faacdaa402c5 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 14 May 2019 12:42:38 +0700 Subject: [PATCH] operator accessories for component wrappers --- headers/ecs_hpp/ecs.hpp | 52 +++++++++++++++++++++++++++++++++++++++++ untests/CMakeLists.txt | 7 ++++++ untests/ecs_tests.cpp | 48 +++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/headers/ecs_hpp/ecs.hpp b/headers/ecs_hpp/ecs.hpp index 0ce6d80..b0738bb 100644 --- a/headers/ecs_hpp/ecs.hpp +++ b/headers/ecs_hpp/ecs.hpp @@ -991,6 +991,14 @@ namespace ecs_hpp T* find() noexcept; const T* find() const noexcept; + + T& operator*(); + const T& operator*() const; + + T* operator->() noexcept; + const T* operator->() const noexcept; + + explicit operator bool() const noexcept; private: entity owner_; }; @@ -1047,6 +1055,10 @@ namespace ecs_hpp const T& get() const; const T* find() const noexcept; + + const T& operator*() const; + const T* operator->() const noexcept; + explicit operator bool() const noexcept; private: const_entity owner_; }; @@ -1689,6 +1701,31 @@ namespace ecs_hpp return detail::as_const(owner_).template find_component(); } + template < typename T > + T& component::operator*() { + return get(); + } + + template < typename T > + const T& component::operator*() const { + return get(); + } + + template < typename T > + T* component::operator->() noexcept { + return find(); + } + + template < typename T > + const T* component::operator->() const noexcept { + return find(); + } + + template < typename T > + component::operator bool() const noexcept { + return exists(); + } + template < typename T > bool operator<(const component& l, const component& r) noexcept { return l.owner() < r.owner(); @@ -1751,6 +1788,21 @@ namespace ecs_hpp return detail::as_const(owner_).template find_component(); } + template < typename T > + const T& const_component::operator*() const { + return get(); + } + + template < typename T > + const T* const_component::operator->() const noexcept { + return find(); + } + + template < typename T > + const_component::operator bool() const noexcept { + return exists(); + } + template < typename T > bool operator<(const const_component& l, const const_component& r) noexcept { return l.owner() < r.owner(); diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 4f0130b..c6f7633 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -29,4 +29,11 @@ add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES}) target_link_libraries(${PROJECT_NAME} Catch2 ecs.hpp) +target_compile_options(${PROJECT_NAME} + PRIVATE + $<$: + /W4> + PRIVATE + $<$,$,$>: + -Wall -Wextra -Wpedantic>) add_test(${PROJECT_NAME} ${PROJECT_NAME}) diff --git a/untests/ecs_tests.cpp b/untests/ecs_tests.cpp index c519e0f..6cf11d8 100644 --- a/untests/ecs_tests.cpp +++ b/untests/ecs_tests.cpp @@ -518,6 +518,54 @@ TEST_CASE("registry") { REQUIRE_FALSE(c1.remove()); } + { + using namespace ecs::detail; + + ecs::registry w; + ecs::entity e1 = w.create_entity(); + + ecs::component c1 = w.wrap_component(e1); + ecs::const_component c2 = w.wrap_component(e1); + + REQUIRE_FALSE(c1); + REQUIRE_FALSE(as_const(c1)); + REQUIRE_FALSE(c2); + REQUIRE_FALSE(as_const(c2)); + + REQUIRE_THROWS_AS(*c1, std::logic_error); + REQUIRE_THROWS_AS(*as_const(c1), std::logic_error); + REQUIRE_THROWS_AS(*c2, std::logic_error); + REQUIRE_THROWS_AS(*as_const(c2), std::logic_error); + + c1.assign(1,2); + + REQUIRE(c1); + REQUIRE(as_const(c1)); + REQUIRE(c2); + REQUIRE(as_const(c2)); + + REQUIRE(*c1 == position_c(1,2)); + REQUIRE(*as_const(c1) == position_c(1,2)); + REQUIRE(*c2 == position_c(1,2)); + REQUIRE(*as_const(c2) == position_c(1,2)); + + REQUIRE(c1->x == 1); + REQUIRE(c1->y == 2); + REQUIRE(as_const(c1)->x == 1); + REQUIRE(as_const(c1)->y == 2); + + REQUIRE(c2->x == 1); + REQUIRE(c2->y == 2); + REQUIRE(as_const(c2)->x == 1); + REQUIRE(as_const(c2)->y == 2); + + c1.remove(); + + REQUIRE_FALSE(c1); + REQUIRE_FALSE(as_const(c1)); + REQUIRE_FALSE(c2); + REQUIRE_FALSE(as_const(c2)); + } } SECTION("prototypes") { {