From c94237dedc967d587f6c7d7ddf55bbf649376bbd Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Wed, 9 Jun 2021 16:00:06 +0200 Subject: [PATCH] Adding a onStart onStop --- lib/wal/sources/Entity/Entity.hpp | 1 + lib/wal/sources/Scene/Scene.cpp | 9 ++++++ lib/wal/sources/Scene/Scene.hpp | 3 ++ lib/wal/sources/System/System.hpp | 2 +- lib/wal/sources/Wal.hpp | 30 +++++++++++++++++-- sources/Component/Shaders/ShaderComponent.cpp | 10 ++++++- sources/Component/Shaders/ShaderComponent.hpp | 8 +++-- sources/Map/Map.cpp | 8 ++--- sources/Runner/Runner.cpp | 2 +- .../System/BombHolder/BombHolderSystem.cpp | 2 +- sources/System/Renderer/RenderSystem.cpp | 16 ++++------ tests/CollisionTest.cpp | 20 ++++++------- tests/MoveTests.cpp | 6 ++-- 13 files changed, 79 insertions(+), 38 deletions(-) diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 9eab09a4..aa752136 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -44,6 +44,7 @@ namespace WAL void _componentRemoved(const std::type_index &type); friend Scene; + friend class Wal; protected: //! @brief A reference to the ECS. Scene &_scene; diff --git a/lib/wal/sources/Scene/Scene.cpp b/lib/wal/sources/Scene/Scene.cpp index 34ca940c..493c7932 100644 --- a/lib/wal/sources/Scene/Scene.cpp +++ b/lib/wal/sources/Scene/Scene.cpp @@ -62,6 +62,8 @@ namespace WAL this->_entities.remove_if([this](auto &entity) { if (!entity.shouldDelete()) return false; + for (auto &cmp : entity._components) + cmp.second->onStop(); this->_entityRemoved(entity); return true; }); @@ -74,7 +76,14 @@ namespace WAL view->emplace_back(entity); } entity._notifyScene = true; + for (auto &cmp : entity._components) + cmp.second->onStart(); } this->_entities.splice(this->_entities.end(), this->_newEntities); } + + int Scene::getID() const + { + return this->_id; + } } // namespace WAL \ No newline at end of file diff --git a/lib/wal/sources/Scene/Scene.hpp b/lib/wal/sources/Scene/Scene.hpp index 3d7f702a..e0aad880 100644 --- a/lib/wal/sources/Scene/Scene.hpp +++ b/lib/wal/sources/Scene/Scene.hpp @@ -40,6 +40,9 @@ namespace WAL //! @param entity The entity to remove. void _entityRemoved(const Entity &entity); public: + //! @brief Get the ID of this scene. + int getID() const; + //! @brief Get the list of entities. std::list &getEntities(); diff --git a/lib/wal/sources/System/System.hpp b/lib/wal/sources/System/System.hpp index 58f49970..88a1c73b 100644 --- a/lib/wal/sources/System/System.hpp +++ b/lib/wal/sources/System/System.hpp @@ -30,7 +30,7 @@ namespace WAL //! @brief Get a view of all entities containing every dependencies of this system. View &getView() override { - return this->_wal.scene->template view(); + return this->_wal.getScene()->template view(); } //! @brief Update the corresponding component of the given entity diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index 4748e84e..b69e3eba 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include #include #include @@ -29,6 +30,9 @@ namespace WAL //! @brief The list of registered systems std::vector> _systems = {}; + //! @brief The scene that contains entities. + std::shared_ptr _scene; + //! @brief Start the game loop //! @param callback A callback called after each update of the game. It allow you to update the engine based on a specific game state. (you can also update the game state here) //! @param state An initial game state. If not specified, it will be defaulted. @@ -52,7 +56,7 @@ namespace WAL } for (auto &system : this->_systems) system->update(dtime); - this->scene->applyChanges(); + this->_scene->applyChanges(); callback(*this, state); } } @@ -81,13 +85,33 @@ namespace WAL } #endif public: - //! @brief The scene that contains entities. - std::shared_ptr scene; //! @brief True if the engine should close after the end of the current tick. bool shouldClose = false; //! @brief The time between each fixed update. static constexpr std::chrono::nanoseconds timestep = std::chrono::milliseconds(32); + //! @brief Retrieve the current scene + std::shared_ptr getScene() const + { + return this->_scene; + } + + //! @brief Change the current scene + void changeScene(std::shared_ptr newScene) + { + if (this->_scene) { + for (auto &entity : this->_scene->getEntities()) { + for (auto &cmp : entity._components) + cmp.second->onStop(); + } + } + this->_scene = std::move(newScene); + for (auto &entity : this->_scene->getEntities()) { + for (auto &cmp : entity._components) + cmp.second->onStart(); + } + } + //! @brief Create a new system in place. //! @return The wal instance used to call this function is returned. This allow method chaining. template diff --git a/sources/Component/Shaders/ShaderComponent.cpp b/sources/Component/Shaders/ShaderComponent.cpp index 1b28a5bd..0320864e 100644 --- a/sources/Component/Shaders/ShaderComponent.cpp +++ b/sources/Component/Shaders/ShaderComponent.cpp @@ -5,6 +5,7 @@ #include "ShaderComponent.hpp" #include +#include namespace BBM { @@ -20,7 +21,6 @@ namespace BBM ShaderComponent::ShaderComponent(WAL::Entity &entity, const std::string &fragmentFilePath, const std::string &vertexFilePath) : WAL::Component(entity), - _refEntity(entity), _shader(vertexFilePath, fragmentFilePath), _fragmentFilePath(fragmentFilePath), _vertexFilePath(vertexFilePath) @@ -42,6 +42,14 @@ namespace BBM { } + void ShaderComponentModel::onStart() + { + auto &drawable = this->_entity.getComponent(); + this->model = dynamic_cast(drawable.drawable.get()); + if (!this->model) + throw std::runtime_error("No model available with a shader model component. This is unsupported."); + } + ShaderComponentDrawable2D::ShaderComponentDrawable2D(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath) : ShaderComponent(entity, std::move(fragmentFilePath), std::move(vertexFilePath)) { diff --git a/sources/Component/Shaders/ShaderComponent.hpp b/sources/Component/Shaders/ShaderComponent.hpp index 4b541d0c..51428de2 100644 --- a/sources/Component/Shaders/ShaderComponent.hpp +++ b/sources/Component/Shaders/ShaderComponent.hpp @@ -8,15 +8,13 @@ #include #include #include +#include namespace BBM { class ShaderComponent : public WAL::Component { private: - //! @brief efefefefez - WAL::Entity &_refEntity; - //! @brief The shader to be applied RAY::Shader _shader; //! @brief The path to the fragment file @@ -51,6 +49,10 @@ namespace BBM class ShaderComponentModel : public ShaderComponent { public: + RAY::Drawables::Drawables3D::Model *model = nullptr; + + void onStart() override; + //! @brief ctor //! @note use empty string to omit a file ShaderComponentModel(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath = ""); diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 8e43f8ef..a253f06c 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -132,12 +132,10 @@ namespace BBM {UPPERFLOOR, &createUpperFloor}, }; - try { - auto element = elements.at(blockType); - element(coords, scene); - } catch (std::exception const &err) { + if (blockType == NOTHING || blockType == SPAWNER) return; - } + auto element = elements.at(blockType); + element(coords, std::move(scene)); } void MapGenerator::createBreakable(Vector3f coords, std::shared_ptr scene) diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index a1982107..3a051f9b 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -126,7 +126,7 @@ namespace BBM WAL::Wal wal; addSystems(wal); enableRaylib(wal); - wal.scene = loadGameScene(); + wal.changeScene(loadGameScene()); try { wal.run(updateState); diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index 2d46b3b8..c191bf64 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -39,7 +39,7 @@ namespace BBM void BombHolderSystem::_spawnBomb(Vector3f position) { - this->_wal.scene->scheduleNewEntity("Bomb") + this->_wal.getScene()->scheduleNewEntity("Bomb") .addComponent(position) .addComponent(BombHolderSystem::explosionTimer, &BombHolderSystem::_bombExplosion) .addComponent("assets/bombs/bomb.obj", diff --git a/sources/System/Renderer/RenderSystem.cpp b/sources/System/Renderer/RenderSystem.cpp index a6efe35d..f10ac726 100644 --- a/sources/System/Renderer/RenderSystem.cpp +++ b/sources/System/Renderer/RenderSystem.cpp @@ -33,24 +33,20 @@ namespace BBM this->_window.clear(); this->_window.useCamera(this->_camera); - for (auto &[entity, pos, drawable] : this->_wal.scene->view()) { + for (auto &[entity, pos, drawable] : this->_wal.getScene()->view()) { auto *modelShader = entity.tryGetComponent(); - if (modelShader) { - auto &model = dynamic_cast(*drawable.drawable); - model.setShader(modelShader->getShader()); - } + if (modelShader) + modelShader->model->setShader(modelShader->getShader()); drawable.drawable->setPosition(pos.position); drawable.drawable->drawOn(this->_window); - if (modelShader) { - auto &model = dynamic_cast(*drawable.drawable); - model.resetShader(); - } + if (modelShader) + modelShader->model->resetShader(); } this->_window.unuseCamera(); // TODO sort entities based on the Z axis - for (auto &[entity, pos, drawable] : this->_wal.scene->view()) { + for (auto &[entity, pos, drawable] : this->_wal.getScene()->view()) { auto *shader = entity.tryGetComponent(); if (shader) { diff --git a/tests/CollisionTest.cpp b/tests/CollisionTest.cpp index 34bff636..2532a490 100644 --- a/tests/CollisionTest.cpp +++ b/tests/CollisionTest.cpp @@ -22,8 +22,8 @@ TEST_CASE("Collision test", "[Component][System]") { Wal wal; CollisionSystem collision(wal); - wal.scene = std::make_shared(); - wal.scene->addEntity("player") + wal.changeScene(std::make_shared()); + wal.getScene()->addEntity("player") .addComponent() .addComponent([](Entity &actual, const Entity &, int _) { try { @@ -33,7 +33,7 @@ TEST_CASE("Collision test", "[Component][System]") pos.position.z = 1; } catch (std::exception &e) {}; }, [](Entity &, const Entity &, int) {}, 0, 5.0); - Entity &entity = wal.scene->getEntities().front(); + Entity &entity = wal.getScene()->getEntities().front(); REQUIRE(entity.getComponent().position == Vector3f()); entity.getComponent().bound.x = 5; @@ -46,14 +46,14 @@ TEST_CASE("Collision test", "[Component][System]") REQUIRE(entity.getComponent().position.y == 0.0); REQUIRE(entity.getComponent().position.z == 0.0); - wal.scene->addEntity("block") + wal.getScene()->addEntity("block") .addComponent(2, 2, 2) .addComponent(0, 1); - Entity &player = wal.scene->getEntities().front(); + Entity &player = wal.getScene()->getEntities().front(); collision.update(std::chrono::nanoseconds(1)); REQUIRE(player.hasComponent(typeid(PositionComponent))); collision.fixedUpdate(); - REQUIRE(wal.scene->getEntities().size() == 2); + REQUIRE(wal.getScene()->getEntities().size() == 2); REQUIRE(player.hasComponent(typeid(PositionComponent))); REQUIRE(player.getComponent().position.x == 1.0); REQUIRE(player.getComponent().position.y == 1); @@ -66,14 +66,14 @@ TEST_CASE("Collsion test with movable", "[Component][System]") Wal wal; CollisionSystem collision(wal); MovableSystem movable(wal); - wal.scene = std::make_shared(); - wal.scene->addEntity("player") + wal.changeScene(std::make_shared()); + wal.getScene()->addEntity("player") .addComponent() .addComponent([](Entity &actual, const Entity &, int) {}, [](Entity &actual, const Entity &, int) {}, 0, 5.0) .addComponent(); - wal.scene->addEntity("block") + wal.getScene()->addEntity("block") .addComponent(0, 0, 0) .addComponent([](Entity &actual, const Entity &, int) {}, [](Entity &actual, const Entity &, int) { @@ -82,7 +82,7 @@ TEST_CASE("Collsion test with movable", "[Component][System]") mov._velocity = Vector3f(); } catch (std::exception &e) {}; }, 0, 1); - Entity &entity = wal.scene->getEntities().front(); + Entity &entity = wal.getScene()->getEntities().front(); REQUIRE(entity.getComponent().position == Vector3f()); entity.getComponent().bound.x = 5; diff --git a/tests/MoveTests.cpp b/tests/MoveTests.cpp index b19a68fc..75ff2bbd 100644 --- a/tests/MoveTests.cpp +++ b/tests/MoveTests.cpp @@ -20,12 +20,12 @@ using namespace BBM; TEST_CASE("Move test", "[Component][System]") { Wal wal; - wal.scene = std::make_shared(); - wal.scene->addEntity("player") + wal.changeScene(std::make_shared()); + wal.getScene()->addEntity("player") .addComponent() .addComponent() .addComponent(); - Entity &entity = wal.scene->getEntities().front(); + Entity &entity = wal.getScene()->getEntities().front(); REQUIRE(entity.getComponent().position == Vector3f());