diff --git a/lib/wal/sources/Scene/Scene.cpp b/lib/wal/sources/Scene/Scene.cpp index db5c9d6a..fe9fbb19 100644 --- a/lib/wal/sources/Scene/Scene.cpp +++ b/lib/wal/sources/Scene/Scene.cpp @@ -6,7 +6,9 @@ namespace WAL { - std::vector &Scene::getEntities() + int Scene::_nextID = 0; + + std::list &Scene::getEntities() { return this->_entities; } diff --git a/lib/wal/sources/Scene/Scene.hpp b/lib/wal/sources/Scene/Scene.hpp index c3b000b6..be5e160b 100644 --- a/lib/wal/sources/Scene/Scene.hpp +++ b/lib/wal/sources/Scene/Scene.hpp @@ -6,6 +6,7 @@ #pragma once #include +#include #include #include #include "Entity/Entity.hpp" @@ -16,8 +17,12 @@ namespace WAL class Scene { private: + static int _nextID; + //! @brief An ID representing this scene. + int _id = _nextID++; + //! @brief The list of registered entities - std::vector _entities = {}; + std::list _entities = {}; //! @brief The list of cached views to update. std::vector> _views = {}; @@ -31,7 +36,7 @@ namespace WAL void _componentRemoved(const Entity &entity, const std::type_index &type); public: //! @brief Get the list of entities. - std::vector &getEntities(); + std::list &getEntities(); //! @brief Add a new entity to the scene. //! @param name The name of the created entity. @@ -41,8 +46,13 @@ namespace WAL template View &view() { - static auto view = std::make_shared>(this->_entities); + static std::unordered_map>> cache; + auto existing = cache.find(this->_id); + if (existing != cache.end() && !existing->second.expired()) + return *existing->second.lock(); + auto view = std::make_shared>(this->_entities); this->_views.emplace_back(view); + cache.emplace(this->_id, view); return *view; } diff --git a/lib/wal/sources/View/View.hpp b/lib/wal/sources/View/View.hpp index 2db9e2ff..52a46294 100644 --- a/lib/wal/sources/View/View.hpp +++ b/lib/wal/sources/View/View.hpp @@ -5,7 +5,7 @@ #pragma once -#include +#include #include #include #include @@ -47,7 +47,7 @@ namespace WAL 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) + explicit View(std::list &scene) { this->types = {typeid(Components)...}; std::copy_if(scene.begin(), scene.end(), std::back_inserter(this->entities), [](Entity &entity) { diff --git a/tests/CollisionTest.cpp b/tests/CollisionTest.cpp index d0ed5f78..77188df1 100644 --- a/tests/CollisionTest.cpp +++ b/tests/CollisionTest.cpp @@ -32,7 +32,7 @@ TEST_CASE("Collision test", "[Component][System]") pos.position.z = 1; } catch (std::exception &e) {}; }, [](Entity &, const Entity &){}, 5.0); - Entity &entity = wal.scene->getEntities()[0]; + Entity &entity = wal.scene->getEntities().front(); REQUIRE(entity.getComponent().position == Vector3f()); entity.getComponent().bound.x = 5; @@ -48,7 +48,7 @@ TEST_CASE("Collision test", "[Component][System]") wal.scene->addEntity("block") .addComponent(2,2,2) .addComponent(1); - Entity &player = wal.scene->getEntities()[0]; + Entity &player = wal.scene->getEntities().front(); collision.onUpdate(entity, std::chrono::nanoseconds(1)); REQUIRE(player.hasComponent(typeid(PositionComponent))); collision.onFixedUpdate(player); @@ -79,7 +79,7 @@ TEST_CASE("Collsion test with movable", "[Component][System]") mov.resetVelocity(); } catch (std::exception &e) {}; }, 1); - Entity &entity = wal.scene->getEntities()[0]; + Entity &entity = wal.scene->getEntities().front(); REQUIRE(entity.getComponent().position == Vector3f()); entity.getComponent().bound.x = 5; diff --git a/tests/MoveTests.cpp b/tests/MoveTests.cpp index ba46a55d..ac035c86 100644 --- a/tests/MoveTests.cpp +++ b/tests/MoveTests.cpp @@ -25,7 +25,7 @@ TEST_CASE("Move test", "[Component][System]") .addComponent() .addComponent() .addComponent(); - Entity &entity = scene.getEntities()[0]; + Entity &entity = *scene.getEntities().begin(); REQUIRE(entity.getComponent().position == Vector3f()); diff --git a/tests/ViewTest.cpp b/tests/ViewTest.cpp index 8e0c1aef..194e04a6 100644 --- a/tests/ViewTest.cpp +++ b/tests/ViewTest.cpp @@ -50,6 +50,22 @@ TEST_CASE("View cache", "[View]") REQUIRE(&view == &scene.view()); } +TEST_CASE("View cache switch", "[View]") +{ + Scene scene; + scene.addEntity("player") + .addComponent() + .addComponent(); + auto &view = scene.view(); + Scene scene2; + scene2.addEntity("box") + .addComponent(); + + REQUIRE(&view == &scene.view()); + REQUIRE(view.entities.begin()->get().getName() == "player"); + REQUIRE(scene2.view().entities.begin()->get().getName() == "box"); +} + //TEST_CASE("View iteration", "[View]") //{ // Scene scene;