diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index 088188b4..ba2a60a0 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -17,6 +17,6 @@ add_library(wal sources/Component/Component.cpp sources/System/System.cpp sources/Models/Callback.hpp - sources/View/BaseView.hpp) + sources/View/View.hpp) target_include_directories(wal PUBLIC sources) \ No newline at end of file diff --git a/lib/wal/sources/Scene/Scene.hpp b/lib/wal/sources/Scene/Scene.hpp index e233debc..c3b000b6 100644 --- a/lib/wal/sources/Scene/Scene.hpp +++ b/lib/wal/sources/Scene/Scene.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include "Entity/Entity.hpp" namespace WAL diff --git a/lib/wal/sources/View/BaseView.hpp b/lib/wal/sources/View/BaseView.hpp deleted file mode 100644 index 4a8502d4..00000000 --- a/lib/wal/sources/View/BaseView.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// Created by Zoe Roux on 2021-06-03. -// - - -#pragma once - -#include -#include -#include -#include -#include "Entity/Entity.hpp" - -namespace WAL -{ - class BaseView - { - public: - std::vector> entities = {}; - - std::vector types = {}; - - size_t size() - { - return entities.size(); - } - -// std::vector> &view(const Components &...index) requires(std::is_same_v) -// { -// static std::vector> view; -// -// std::copy_if(this->_entities.begin(), this->_entities.end(), std::back_inserter(view), [&index...](Entity &entity) { -// return (entity.hasComponent(index) && ...); -// }); -// return view; -// } - }; - - template - class View : public BaseView - { - public: - explicit View(std::vector &scene) - { - std::copy_if(scene.begin(), scene.end(), std::back_inserter(this->entities), [](Entity &entity) { - return (entity.hasComponent() && ...); - }); - } - }; -} \ No newline at end of file diff --git a/lib/wal/sources/View/View.hpp b/lib/wal/sources/View/View.hpp new file mode 100644 index 00000000..9df63f55 --- /dev/null +++ b/lib/wal/sources/View/View.hpp @@ -0,0 +1,65 @@ +// +// Created by Zoe Roux on 2021-06-03. +// + + +#pragma once + +#include +#include +#include +#include +#include "Entity/Entity.hpp" + +namespace WAL +{ + //! @brief A basic view used to manipulate view without knowing their type at compile time. + class BaseView + { + public: + //! @brief The list of entities in the view. + std::vector> entities = {}; + + //! @brief The list of types that every entity of the view has. + std::vector types = {}; + + size_t size() + { + return entities.size(); + } + + //! @brief A default destructor + ~BaseView() = default; + protected: + //! @brief A basic view can't be constructed, you should use the View templated class. + BaseView() = default; + //! @brief A basic view can't be constructed, you should use the View templated class. + BaseView(const BaseView &) = default; + //! @brief A basic view can't be assigned. See the View template class. + BaseView &operator=(const BaseView &) = default; + }; + + //! @brief A view allowing one to easily access entities containing a set list of component. + //! A view is always updated and only references to entities are kept. + template + class View : public BaseView + { + public: + //! @brief Construct a view from a list of entities. + //! Those entities are never copied but references to them are kept internally. + explicit View(std::vector &scene) + { + this->types = {typeid(Components)...}; + std::copy_if(scene.begin(), scene.end(), std::back_inserter(this->entities), [](Entity &entity) { + return (entity.hasComponent() && ...); + }); + } + + //! @brief Copying a view is not possible since a view must be managed by a scene. + View(const View &) = delete; + //! @brief A default destructor + ~View() = default; + //! @brief A view is not assignable. + View &operator=(const View &) = delete; + }; +} \ No newline at end of file diff --git a/tests/ViewTest.cpp b/tests/ViewTest.cpp index 21315f2b..8e0c1aef 100644 --- a/tests/ViewTest.cpp +++ b/tests/ViewTest.cpp @@ -4,15 +4,10 @@ #include "Entity/Entity.hpp" #include "Component/Position/PositionComponent.hpp" -#include "System/Movable/MovableSystem.hpp" -#include "System/Controllable/ControllableSystem.hpp" #include #include #include -#define private public -#include - using namespace WAL; using namespace BBM; @@ -29,4 +24,45 @@ TEST_CASE("View creation", "[View]") Entity &entity = *scene.getEntities().begin(); Entity &firstView = *scene.view().entities.begin(); REQUIRE(&entity == &firstView); -} \ No newline at end of file +} + +TEST_CASE("View update", "[View]") +{ + Scene scene; + scene.addEntity("player") + .addComponent() + .addComponent(); + auto &view = scene.view(); + auto &entity = scene.addEntity("Box") + .addComponent(); + REQUIRE(view.size() == 2); + entity.removeComponent(); + REQUIRE(view.size() == 1); +} + +TEST_CASE("View cache", "[View]") +{ + Scene scene; + scene.addEntity("player") + .addComponent() + .addComponent(); + auto &view = scene.view(); + REQUIRE(&view == &scene.view()); +} + +//TEST_CASE("View iteration", "[View]") +//{ +// Scene scene; +// scene.addEntity("player") +// .addComponent() +// .addComponent(); +// scene.addEntity("Box") +// .addComponent(); +// int i = 0; +// for (auto &entity : scene.view()) { +// if (i == 0) +// REQUIRE(entity.getName() == "player"); +// else +// REQUIRE(entity.getName() == "Box"); +// } +//} \ No newline at end of file