From 72b3af0f38cbfa0062457ac289f4155d98c579f1 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 14 May 2021 14:10:18 +0200 Subject: [PATCH 01/13] Adding a cmake for wal --- CMakeLists.txt | 6 +++++- lib/wal/CMakeLists.txt | 12 ++++++++++++ lib/wal/Entity/Entity.hpp | 10 ++++------ lib/wal/Wal.cpp | 10 ++++++++++ lib/wal/Wal.hpp | 14 ++++++++++++++ 5 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 lib/wal/CMakeLists.txt create mode 100644 lib/wal/Wal.cpp create mode 100644 lib/wal/Wal.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5255d0ed..4a45a644 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,10 @@ project(Bomberman) set(CMAKE_CXX_STANDARD 20) +add_subdirectory(${PROJECT_SOURCE_DIR}/lib/wal) + add_executable(bomberman sources/main.cpp -) \ No newline at end of file +) + +target_link_libraries(bomberman wal) \ No newline at end of file diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt new file mode 100644 index 00000000..9174be58 --- /dev/null +++ b/lib/wal/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.19) +project(wal) + +set(CMAKE_CXX_STANDARD 20) + +add_library(wal + Entity/Entity.hpp + Component/Component.hpp + System/System.hpp + Wal.cpp + Wal.hpp +) \ No newline at end of file diff --git a/lib/wal/Entity/Entity.hpp b/lib/wal/Entity/Entity.hpp index a0c90acc..029ccf7c 100644 --- a/lib/wal/Entity/Entity.hpp +++ b/lib/wal/Entity/Entity.hpp @@ -6,8 +6,6 @@ #include #include "Component/Component.hpp" -//! @brief I'm deeply sorry for this name -//! @note I am not, he is a liar namespace WAL { //! @brief An entity of the WAL's ECS. @@ -27,10 +25,10 @@ namespace WAL unsigned getUid() const; //! @brief Get the name fo the entity std::string getName() const; - + //! @brief Used if the entity is disabled bool isDisable() const; - + //! @brief Disable this entity. void setDisable(bool disabled); @@ -38,11 +36,11 @@ namespace WAL //! @throw ComponentNotFoundError if the component could not be found template T getComponent(); - + //! @brief Add a component to this entity. The component is constructed in place. //! @return This entity is returned template - Entity &addComponent(...params); + Entity &addComponent(Types ...params); //! @brief Copy a component to this entity. //! @return This entity is returned. diff --git a/lib/wal/Wal.cpp b/lib/wal/Wal.cpp new file mode 100644 index 00000000..81ad105f --- /dev/null +++ b/lib/wal/Wal.cpp @@ -0,0 +1,10 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + +#include "Wal.hpp" + +namespace WAL +{ + +} \ No newline at end of file diff --git a/lib/wal/Wal.hpp b/lib/wal/Wal.hpp new file mode 100644 index 00000000..009033ba --- /dev/null +++ b/lib/wal/Wal.hpp @@ -0,0 +1,14 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + + +#pragma once + +namespace WAL +{ + class WAL + { + + }; +} From 43bbf487a3c8939e1ff95b3e8be3a3a34293c79b Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 14 May 2021 16:26:07 +0200 Subject: [PATCH 02/13] Adding a scene manger and wal functions --- CMakeLists.txt | 2 +- lib/wal/CMakeLists.txt | 18 ++-- lib/wal/{ => sources}/Component/Component.hpp | 0 lib/wal/{ => sources}/Entity/Entity.hpp | 2 +- .../Events/EventManager.cpp} | 7 +- lib/wal/sources/Events/EventManager.hpp | 15 +++ lib/wal/sources/Exception/WalError.cpp | 20 ++++ lib/wal/sources/Exception/WalError.hpp | 54 +++++++++++ lib/wal/sources/Renderer/Renderer.cpp | 5 + .../Renderer/Renderer.hpp} | 2 +- lib/wal/sources/Scene/Scene.cpp | 5 + lib/wal/sources/Scene/Scene.hpp | 20 ++++ lib/wal/sources/Scene/SceneManager.cpp | 31 +++++++ lib/wal/sources/Scene/SceneManager.hpp | 43 +++++++++ lib/wal/{ => sources}/System/System.hpp | 12 ++- lib/wal/sources/Wal.cpp | 19 ++++ lib/wal/sources/Wal.hpp | 91 +++++++++++++++++++ sources/main.cpp | 12 ++- 18 files changed, 339 insertions(+), 19 deletions(-) rename lib/wal/{ => sources}/Component/Component.hpp (100%) rename lib/wal/{ => sources}/Entity/Entity.hpp (97%) rename lib/wal/{Wal.cpp => sources/Events/EventManager.cpp} (54%) create mode 100644 lib/wal/sources/Events/EventManager.hpp create mode 100644 lib/wal/sources/Exception/WalError.cpp create mode 100644 lib/wal/sources/Exception/WalError.hpp create mode 100644 lib/wal/sources/Renderer/Renderer.cpp rename lib/wal/{Wal.hpp => sources/Renderer/Renderer.hpp} (84%) create mode 100644 lib/wal/sources/Scene/Scene.cpp create mode 100644 lib/wal/sources/Scene/Scene.hpp create mode 100644 lib/wal/sources/Scene/SceneManager.cpp create mode 100644 lib/wal/sources/Scene/SceneManager.hpp rename lib/wal/{ => sources}/System/System.hpp (59%) create mode 100644 lib/wal/sources/Wal.cpp create mode 100644 lib/wal/sources/Wal.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a45a644..19add0c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 20) add_subdirectory(${PROJECT_SOURCE_DIR}/lib/wal) add_executable(bomberman - sources/main.cpp + sources/main.cpp ) target_link_libraries(bomberman wal) \ No newline at end of file diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index 9174be58..abfe5129 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -4,9 +4,15 @@ project(wal) set(CMAKE_CXX_STANDARD 20) add_library(wal - Entity/Entity.hpp - Component/Component.hpp - System/System.hpp - Wal.cpp - Wal.hpp -) \ No newline at end of file + sources/Entity/Entity.hpp + sources/Component/Component.hpp + sources/System/System.hpp + sources/Wal.cpp + sources/Wal.hpp + sources/Scene/SceneManager.cpp + sources/Scene/SceneManager.hpp + sources/Scene/Scene.cpp + sources/Scene/Scene.hpp + sources/Renderer/Renderer.cpp sources/Renderer/Renderer.hpp sources/Events/EventManager.cpp sources/Events/EventManager.hpp sources/Exception/WalError.cpp sources/Exception/WalError.hpp) + +target_include_directories(wal PUBLIC sources) \ No newline at end of file diff --git a/lib/wal/Component/Component.hpp b/lib/wal/sources/Component/Component.hpp similarity index 100% rename from lib/wal/Component/Component.hpp rename to lib/wal/sources/Component/Component.hpp diff --git a/lib/wal/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp similarity index 97% rename from lib/wal/Entity/Entity.hpp rename to lib/wal/sources/Entity/Entity.hpp index 029ccf7c..6b71a5f6 100644 --- a/lib/wal/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -39,7 +39,7 @@ namespace WAL //! @brief Add a component to this entity. The component is constructed in place. //! @return This entity is returned - template + template Entity &addComponent(Types ...params); //! @brief Copy a component to this entity. diff --git a/lib/wal/Wal.cpp b/lib/wal/sources/Events/EventManager.cpp similarity index 54% rename from lib/wal/Wal.cpp rename to lib/wal/sources/Events/EventManager.cpp index 81ad105f..69b939b7 100644 --- a/lib/wal/Wal.cpp +++ b/lib/wal/sources/Events/EventManager.cpp @@ -2,9 +2,4 @@ // Created by Zoe Roux on 2021-05-14. // -#include "Wal.hpp" - -namespace WAL -{ - -} \ No newline at end of file +#include "EventManager.hpp" diff --git a/lib/wal/sources/Events/EventManager.hpp b/lib/wal/sources/Events/EventManager.hpp new file mode 100644 index 00000000..a1f608e1 --- /dev/null +++ b/lib/wal/sources/Events/EventManager.hpp @@ -0,0 +1,15 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + + +#pragma once + +namespace WAL +{ + //! @brief A class to handle events. + class EventManager + { + + }; +} diff --git a/lib/wal/sources/Exception/WalError.cpp b/lib/wal/sources/Exception/WalError.cpp new file mode 100644 index 00000000..acfc32d5 --- /dev/null +++ b/lib/wal/sources/Exception/WalError.cpp @@ -0,0 +1,20 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + +#include "WalError.hpp" + +namespace WAL +{ + WalError::WalError(const std::string &what) + : std::runtime_error(what) + {} + + SystemExistError::SystemExistError(const std::string &what) + : WalError(what) + {} + + NotFoundError::NotFoundError(const std::string &what) + : WalError(what) + {} +} \ No newline at end of file diff --git a/lib/wal/sources/Exception/WalError.hpp b/lib/wal/sources/Exception/WalError.hpp new file mode 100644 index 00000000..7b456a53 --- /dev/null +++ b/lib/wal/sources/Exception/WalError.hpp @@ -0,0 +1,54 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + + +#pragma once + +#include +#include + +namespace WAL +{ + //! @brief The base class for WAL's exceptions. + class WalError : public std::runtime_error + { + public: + //! @brief Create a new wal exception + explicit WalError(const std::string &what); + //! @brief A wal exception is copy constructable + WalError(const WalError &) = default; + //! @brief A default destructor + ~WalError() override = default; + //! @brief A default assignment operator + WalError &operator=(const WalError &) = default; + }; + + //! @brief An exception informing the user that a system already exists. + class SystemExistError : public WalError + { + public: + //! @brief Create a new wal exception + explicit SystemExistError(const std::string &what); + //! @brief A wal exception is copy constructable + SystemExistError(const SystemExistError &) = default; + //! @brief A default destructor + ~SystemExistError() override = default; + //! @brief A default assignment operator + SystemExistError &operator=(const SystemExistError &) = default; + }; + + //! @brief An exception informing the user that something could not be found + class NotFoundError : public WalError + { + public: + //! @brief Create a new wal exception + explicit NotFoundError(const std::string &what); + //! @brief A wal exception is copy constructable + NotFoundError(const NotFoundError &) = default; + //! @brief A default destructor + ~NotFoundError() override = default; + //! @brief A default assignment operator + NotFoundError &operator=(const NotFoundError &) = default; + }; +} diff --git a/lib/wal/sources/Renderer/Renderer.cpp b/lib/wal/sources/Renderer/Renderer.cpp new file mode 100644 index 00000000..28b61e34 --- /dev/null +++ b/lib/wal/sources/Renderer/Renderer.cpp @@ -0,0 +1,5 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + +#include "Renderer.hpp" diff --git a/lib/wal/Wal.hpp b/lib/wal/sources/Renderer/Renderer.hpp similarity index 84% rename from lib/wal/Wal.hpp rename to lib/wal/sources/Renderer/Renderer.hpp index 009033ba..697f76ad 100644 --- a/lib/wal/Wal.hpp +++ b/lib/wal/sources/Renderer/Renderer.hpp @@ -7,7 +7,7 @@ namespace WAL { - class WAL + class Renderer { }; diff --git a/lib/wal/sources/Scene/Scene.cpp b/lib/wal/sources/Scene/Scene.cpp new file mode 100644 index 00000000..2158ac61 --- /dev/null +++ b/lib/wal/sources/Scene/Scene.cpp @@ -0,0 +1,5 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + +#include "Scene.hpp" diff --git a/lib/wal/sources/Scene/Scene.hpp b/lib/wal/sources/Scene/Scene.hpp new file mode 100644 index 00000000..52a85c4f --- /dev/null +++ b/lib/wal/sources/Scene/Scene.hpp @@ -0,0 +1,20 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + + +#pragma once + +#include +#include "Entity/Entity.hpp" + +namespace WAL +{ + //! @brief Represent a single scene that contains entities. + class Scene + { + private: + //! @brief The list of registered entities + std::vector _entity; + }; +} diff --git a/lib/wal/sources/Scene/SceneManager.cpp b/lib/wal/sources/Scene/SceneManager.cpp new file mode 100644 index 00000000..5ffbcc26 --- /dev/null +++ b/lib/wal/sources/Scene/SceneManager.cpp @@ -0,0 +1,31 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + +#include "SceneManager.hpp" + +namespace WAL +{ + SceneManager &WAL::SceneManager::addScene(WAL::Scene &&scene) + { + this->_scenes.push_front(scene); + return *this; + } + + SceneManager &SceneManager::addBackScene(Scene &&scene) + { + this->_scenes.insert(++this->_scenes.begin(), scene); + return *this; + } + + Scene &SceneManager::getCurrent() + { + return this->_scenes.front(); + } + + SceneManager &SceneManager::closeCurrent() + { + this->_scenes.pop_front(); + return *this; + } +} \ No newline at end of file diff --git a/lib/wal/sources/Scene/SceneManager.hpp b/lib/wal/sources/Scene/SceneManager.hpp new file mode 100644 index 00000000..21765dc9 --- /dev/null +++ b/lib/wal/sources/Scene/SceneManager.hpp @@ -0,0 +1,43 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + + +#pragma once + +#include +#include "Scene/Scene.hpp" + +namespace WAL +{ + //! @brief A class to manage scenes + class SceneManager + { + private: + std::deque _scenes = {}; + public: + //! @brief Add a scene to the container and move to it. + //! @return The manager instance used to call this function is returned. This allow method chaining. + SceneManager &addScene(Scene &&scene); + + //! @brief Add a scene before the current scene to allow + //! @return The manager instance used to call this function is returned. This allow method chaining. + SceneManager &addBackScene(Scene &&scene); + + //! @breif Get the current scene + Scene &getCurrent(); + + //! @brief Remove the current scene and switch to the previous scene on the stack. + //! @return The manager instance used to call this function is returned. This allow method chaining. + SceneManager &closeCurrent(); + + //! @brief A default constructor + SceneManager() = default; + //! @brief A scene manager is copy constructable + SceneManager(const SceneManager &) = default; + //! @brief A default destructor. + ~SceneManager() = default; + //! @brief A scene manager is assignable + SceneManager &operator=(const SceneManager &) = default; + }; +} diff --git a/lib/wal/System/System.hpp b/lib/wal/sources/System/System.hpp similarity index 59% rename from lib/wal/System/System.hpp rename to lib/wal/sources/System/System.hpp index de57d374..5da1d236 100644 --- a/lib/wal/System/System.hpp +++ b/lib/wal/sources/System/System.hpp @@ -12,13 +12,21 @@ namespace WAL public: //! @brief A virtual, default, destructor virtual ~System() = default; - + //! @brief A system can be moved + System(System &&) = default; + //! @brief Get the name of the component corresponding to this system. virtual std::string getComponentName() const = 0; //! @brief Update the corresponding component of the given entity //! @param entity The entity to update. - virtual void onUpdate(Entity &entity) = 0; + //! @param dtime The delta time. + virtual void onUpdate(Entity &entity, float dtime) = 0; + + //! @brief An alternative of onUpdate that is called every 8ms (120 times per seconds). If the system slow down, it will try to catch up. + //! @remark This should be used for Physics, AI and everything that could be imprecise due to float rounding. + //! @param entity The entity to update. + virtual void onFixedUpdate(Entity &entity) = 0; protected: //! @brief A system can't be instantiated, it should be derived. System() = default; diff --git a/lib/wal/sources/Wal.cpp b/lib/wal/sources/Wal.cpp new file mode 100644 index 00000000..2e8e18a8 --- /dev/null +++ b/lib/wal/sources/Wal.cpp @@ -0,0 +1,19 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + +#include "Wal.hpp" + +namespace WAL +{ + + SceneManager &WAL::getSceneManger() + { + return this->_scenes; + } + + void WAL::run() + { + + } +} \ No newline at end of file diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp new file mode 100644 index 00000000..d280f739 --- /dev/null +++ b/lib/wal/sources/Wal.hpp @@ -0,0 +1,91 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + + +#pragma once + +#include +#include +#include +#include +#include "Events/EventManager.hpp" +#include "Renderer/Renderer.hpp" +#include "Scene/SceneManager.hpp" +#include "Entity/Entity.hpp" +#include "System/System.hpp" + +namespace WAL +{ + //! @brief The main WAL class, it is used to setup and run the ECS. + class WAL + { + private: + //! @brief The scene manager that allow multiple scene to work together. + SceneManager _scenes; + //! @brief The event manager + EventManager _eventManager; + //! @brief The list of registered systems + std::vector> _systems = {}; + //! @brief The renderer used to draw entities + std::unique_ptr _renderer; + public: + //! @brief Create a new system in place. + //! @return The wal instance used to call this function is returned. This allow method chaining. + template + WAL &addSystem(Types ...params) + { + const std::type_info &type = typeid(T); + auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { + return typeid(sys) == type; + }); + if (existing != this->_systems.end()) + throw SystemExistError("A system of the type \"" + std::string(type.name()) + "\" already exists."); + this->_systems.push_back(std::make_unique(params...)); + return *this; + } + + //! @brief Add a system by copy. + //! @return The wal instance used to call this function is returned. This allow method chaining. + template + WAL &addSystem(const T &system) + { + const std::type_info &type = typeid(T); + auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { + return typeid(sys) == type; + }); + if (existing != this->_systems.end()) + throw SystemExistError("A system of the type \"" + std::string(type.name()) + "\" already exists."); + this->_systems.push_back(std::make_unique(system)); + return *this; + } + + //! @brief Remove a system using it's type. + template + WAL &removeSystem() + { + const std::type_info &type = typeid(T); + auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { + return typeid(sys) == type; + }); + if (existing == this->_systems.end()) + throw NotFoundError("No system could be found with the type \"" + std::string(type.name()) + "\"."); + return *this; + } + + //! @brief Get the scene manager. + SceneManager &getSceneManger(); + + //! @brief Start the game loop + void run(); + + //! @brief A default constructor + WAL() = default; + //! @brief A WAL can't be copy constructed + WAL(const WAL &) = delete; + //! @brief A default destructor + ~WAL() = default; + //! @brief A default assignment operator + WAL &operator=(const WAL &) = default; + }; +} diff --git a/sources/main.cpp b/sources/main.cpp index 11d982c5..53c8bb20 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -1,7 +1,15 @@ #include +#include int main() { - std::cout << "Hello, World!" << std::endl; - return 0; + WAL::WAL wal; + + try { + wal.run(); + return 0; + } catch (const std::exception &ex) { + std::cerr << ex.what() << std::endl; + return 84; + } } From 9578e4e5806e5d5a1712338e891f850736443663 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 14 May 2021 16:26:46 +0200 Subject: [PATCH 03/13] Cmake coding style --- lib/wal/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index abfe5129..6fc78ef7 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -13,6 +13,12 @@ add_library(wal sources/Scene/SceneManager.hpp sources/Scene/Scene.cpp sources/Scene/Scene.hpp - sources/Renderer/Renderer.cpp sources/Renderer/Renderer.hpp sources/Events/EventManager.cpp sources/Events/EventManager.hpp sources/Exception/WalError.cpp sources/Exception/WalError.hpp) + sources/Renderer/Renderer.cpp + sources/Renderer/Renderer.hpp + sources/Events/EventManager.cpp + sources/Events/EventManager.hpp + sources/Exception/WalError.cpp + sources/Exception/WalError.hpp +) target_include_directories(wal PUBLIC sources) \ No newline at end of file From d6aaf30c3b16a091b48f5d3ea2c9475c241563e5 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 14 May 2021 17:37:14 +0200 Subject: [PATCH 04/13] Adding components --- lib/wal/CMakeLists.txt | 2 +- lib/wal/sources/Component/Component.cpp | 43 +++++++++++++++++ lib/wal/sources/Component/Component.hpp | 46 ++++++++++-------- lib/wal/sources/Entity/Entity.cpp | 55 ++++++++++++++++++++++ lib/wal/sources/Entity/Entity.hpp | 62 +++++++++++++++++++++---- lib/wal/sources/Exception/WalError.cpp | 2 +- lib/wal/sources/Exception/WalError.hpp | 12 ++--- lib/wal/sources/Wal.hpp | 15 +++--- 8 files changed, 195 insertions(+), 42 deletions(-) create mode 100644 lib/wal/sources/Component/Component.cpp create mode 100644 lib/wal/sources/Entity/Entity.cpp diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index 6fc78ef7..02613603 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -19,6 +19,6 @@ add_library(wal sources/Events/EventManager.hpp sources/Exception/WalError.cpp sources/Exception/WalError.hpp -) + sources/Entity/Entity.cpp sources/Component/Component.cpp) target_include_directories(wal PUBLIC sources) \ No newline at end of file diff --git a/lib/wal/sources/Component/Component.cpp b/lib/wal/sources/Component/Component.cpp new file mode 100644 index 00000000..5d2948c7 --- /dev/null +++ b/lib/wal/sources/Component/Component.cpp @@ -0,0 +1,43 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + +#include "Component/Component.hpp" + +namespace WAL +{ + Component::Component(std::string name, Entity &entity) + : _name(std::move(name)), + _entity(entity) + { } + + std::string Component::getName() const + { + return this->_name; + } + + bool Component::isDisabled() const + { + return this->_disabled; + } + + void Component::setDisable(bool disabled) + { + this->_disabled = disabled; + } + + const std::vector &Component::getDependencies() const + { + return this->_dependencies; + } + + void Component::onStart() + { + //TODO handle events here + } + + void Component::onStop() + { + //TODO handle events here + } +} \ No newline at end of file diff --git a/lib/wal/sources/Component/Component.hpp b/lib/wal/sources/Component/Component.hpp index 7589ae6a..64d325a9 100644 --- a/lib/wal/sources/Component/Component.hpp +++ b/lib/wal/sources/Component/Component.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace WAL { @@ -18,35 +19,42 @@ namespace WAL //! @brief The name of this component std::string _name; //! @brief Is this component disabled? - bool _disabled; + bool _disabled = false; + protected: + //! @brief The entity that own this component + Entity &_entity; //! @brief The list of dependencies of this component. - // TODO check if there is a better type than strings - std::vector _dependencies; + std::vector _dependencies; + + //! @brief A component can't be instantiated, it should be derived. + explicit Component(std::string name, Entity &entity); + //! @brief A component can't be instantiated, it should be derived. + Component(const Component &) = default; public: + //! @brief A component can't be assigned + Component &operator=(const Component &) = delete; + //! @brief A virtual destructor + virtual ~Component() = default; + + //! @brief Clone a component for another or the same entity. + //! @param entity The entity that owns the ne component. + virtual Component *clone(Entity &entity) const = 0; + //! @brief Get the name of this component - std::string _getName() const; + std::string getName() const; //! @brief Used if the component is disabled - bool isDisable() const; + bool isDisabled() const; //! @brief Disable this component. void setDisable(bool disabled); + //! @brief Get the dependencies of this component. + const std::vector &getDependencies() const; + //! @brief The entity or this component has just been enabled. - //! @param entity The entity that has this component - virtual void onStart(Entity &entity); + virtual void onStart(); //! @brief The entity or this component has just been disable. - //! @param entity The entity that has this component - virtual void onStop(Entity &entity); - - //! @brief A virtual destructor (that also calls onStop) - virtual ~Component(); - protected: - //! @brief A component can't be instantiated, it should be derived. - Component() = default; - //! @brief A component can't be instantiated, it should be derived. - Component(const Component &) = default; - //! @brief A component can't be instantiated, it should be derived. - Component &operator=(const Component &) = default; + virtual void onStop(); }; } \ No newline at end of file diff --git a/lib/wal/sources/Entity/Entity.cpp b/lib/wal/sources/Entity/Entity.cpp new file mode 100644 index 00000000..859e2e3e --- /dev/null +++ b/lib/wal/sources/Entity/Entity.cpp @@ -0,0 +1,55 @@ +// +// Created by Zoe Roux on 2021-05-14. +// + +#include "Entity/Entity.hpp" + +#include + +namespace WAL +{ + unsigned Entity::nextID = 0; + + Entity::Entity(std::string name) + : _uid(Entity::nextID++), + _name(std::move(name)) + { } + + Entity::Entity(const Entity &other) + : _uid(Entity::nextID++), + _name(other._name), + _disabled(other._disabled) + { + for (const auto &cmp : other._components) + this->addComponent(*cmp); + } + + unsigned Entity::getUid() const + { + return this->_uid; + } + + std::string Entity::getName() const + { + return this->_name; + } + + bool Entity::isDisable() const + { + return this->_disabled; + } + + void Entity::setDisable(bool disabled) + { + this->_disabled = disabled; + } + + Entity &Entity::addComponent(const Component &component) + { + // TODO handle duplicates +// if (this->hasComponent()) +// throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists."); + this->_components.emplace_back(component.clone(*this)); + return *this; + } +} \ No newline at end of file diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 6b71a5f6..7ad68586 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -4,7 +4,10 @@ #include #include +#include +#include #include "Component/Component.hpp" +#include "Exception/WalError.hpp" namespace WAL { @@ -17,9 +20,12 @@ namespace WAL //! @brief An entity name (this is useful for debugging) std::string _name; //! @brief Is this entity enabled? - bool _disabled; + bool _disabled = false; //! @brief The list of the components of this entity - std::vector _components; + std::vector> _components = {}; + + //! @brief This ID will be the one of the next entity created. + static unsigned nextID; public: //! @brief Get the ID of the entity. unsigned getUid() const; @@ -33,30 +39,70 @@ namespace WAL void setDisable(bool disabled); //! @brief Get a component of a specific type - //! @throw ComponentNotFoundError if the component could not be found + //! @throw NotFoundError if the component could not be found template - T getComponent(); + T getComponent() + { + const std::type_info &type = typeid(T); + auto &existing = std::find(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) { + return typeid(*cmp) == type; + }); + if (existing == this->_components.end()) + throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\"."); + return *existing; + } + + template + bool hasComponent() const + { + const std::type_info &type = typeid(T); + auto existing = std::find(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { + return typeid(*cmp) == type; + }); + return existing != this->_components.end(); + } //! @brief Add a component to this entity. The component is constructed in place. + //! @throw DuplicateError is thrown if a component with the same type already exist. //! @return This entity is returned template - Entity &addComponent(Types ...params); + Entity &addComponent(Types ...params) + { + if (this->hasComponent()) + throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists."); + this->_components.push_back(std::make_unique(params...)); + return *this; + } //! @brief Copy a component to this entity. //! @return This entity is returned. Entity &addComponent(const Component &component); //! @brief Remove a specific component (by type). + //! @throw NotFoundError is thrown if the component could not be found. + //! @return This entity is returned. template - Entity &removeComponent(); + Entity &removeComponent() + { + const std::type_info &type = typeid(T); + auto &existing =std::find(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) { + return typeid(*cmp) == type; + }); + if (existing == this->_components.end()) + throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\"."); + this->_components.erase(existing); + return *this; + } //! @brief A default constructor - Entity(const std::string &name); + explicit Entity(std::string name); //! @brief An entity is copyable Entity(const Entity &); + //! @brief An entity is movable. + Entity(Entity &&) = default; //! @brief A default destructor ~Entity() = default; //! @brief An entity is assignable - Entity &operator=(const Entity &); + Entity &operator=(const Entity &) = default; }; } \ No newline at end of file diff --git a/lib/wal/sources/Exception/WalError.cpp b/lib/wal/sources/Exception/WalError.cpp index acfc32d5..53581300 100644 --- a/lib/wal/sources/Exception/WalError.cpp +++ b/lib/wal/sources/Exception/WalError.cpp @@ -10,7 +10,7 @@ namespace WAL : std::runtime_error(what) {} - SystemExistError::SystemExistError(const std::string &what) + DuplicateError::DuplicateError(const std::string &what) : WalError(what) {} diff --git a/lib/wal/sources/Exception/WalError.hpp b/lib/wal/sources/Exception/WalError.hpp index 7b456a53..0c791647 100644 --- a/lib/wal/sources/Exception/WalError.hpp +++ b/lib/wal/sources/Exception/WalError.hpp @@ -24,18 +24,18 @@ namespace WAL WalError &operator=(const WalError &) = default; }; - //! @brief An exception informing the user that a system already exists. - class SystemExistError : public WalError + //! @brief An exception informing the user that something already exists. + class DuplicateError : public WalError { public: //! @brief Create a new wal exception - explicit SystemExistError(const std::string &what); + explicit DuplicateError(const std::string &what); //! @brief A wal exception is copy constructable - SystemExistError(const SystemExistError &) = default; + DuplicateError(const DuplicateError &) = default; //! @brief A default destructor - ~SystemExistError() override = default; + ~DuplicateError() override = default; //! @brief A default assignment operator - SystemExistError &operator=(const SystemExistError &) = default; + DuplicateError &operator=(const DuplicateError &) = default; }; //! @brief An exception informing the user that something could not be found diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index d280f739..4a8bec8a 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -37,10 +37,10 @@ namespace WAL { const std::type_info &type = typeid(T); auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { - return typeid(sys) == type; + return typeid(*sys) == type; }); if (existing != this->_systems.end()) - throw SystemExistError("A system of the type \"" + std::string(type.name()) + "\" already exists."); + throw DuplicateError("A system of the type \"" + std::string(type.name()) + "\" already exists."); this->_systems.push_back(std::make_unique(params...)); return *this; } @@ -52,10 +52,10 @@ namespace WAL { const std::type_info &type = typeid(T); auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { - return typeid(sys) == type; + return typeid(*sys) == type; }); if (existing != this->_systems.end()) - throw SystemExistError("A system of the type \"" + std::string(type.name()) + "\" already exists."); + throw DuplicateError("A system of the type \"" + std::string(type.name()) + "\" already exists."); this->_systems.push_back(std::make_unique(system)); return *this; } @@ -66,10 +66,11 @@ namespace WAL { const std::type_info &type = typeid(T); auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { - return typeid(sys) == type; + return typeid(*sys) == type; }); if (existing == this->_systems.end()) throw NotFoundError("No system could be found with the type \"" + std::string(type.name()) + "\"."); + this->_systems.erase(existing); return *this; } @@ -85,7 +86,7 @@ namespace WAL WAL(const WAL &) = delete; //! @brief A default destructor ~WAL() = default; - //! @brief A default assignment operator - WAL &operator=(const WAL &) = default; + //! @brief A WAL can't be assigned. + WAL &operator=(const WAL &) = delete; }; } From 2015705f1104e82f70d02ddc0c2c118d7e440b66 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 14 May 2021 17:46:14 +0200 Subject: [PATCH 05/13] Starting the game loop --- lib/wal/sources/Scene/SceneManager.cpp | 2 ++ lib/wal/sources/Wal.cpp | 8 ++++++++ lib/wal/sources/Wal.hpp | 2 ++ 3 files changed, 12 insertions(+) diff --git a/lib/wal/sources/Scene/SceneManager.cpp b/lib/wal/sources/Scene/SceneManager.cpp index 5ffbcc26..21c38221 100644 --- a/lib/wal/sources/Scene/SceneManager.cpp +++ b/lib/wal/sources/Scene/SceneManager.cpp @@ -20,6 +20,8 @@ namespace WAL Scene &SceneManager::getCurrent() { + if (this->_scenes.empty()) + throw NotFoundError("No scene exists."); return this->_scenes.front(); } diff --git a/lib/wal/sources/Wal.cpp b/lib/wal/sources/Wal.cpp index 2e8e18a8..b5f62458 100644 --- a/lib/wal/sources/Wal.cpp +++ b/lib/wal/sources/Wal.cpp @@ -2,6 +2,7 @@ // Created by Zoe Roux on 2021-05-14. // +#include #include "Wal.hpp" namespace WAL @@ -14,6 +15,13 @@ namespace WAL void WAL::run() { + auto lastTick = std::chrono::steady_clock::now(); + while (!this->_shouldClose) { + auto now = std::chrono::steady_clock::now(); + auto dtime = now - lastTick; + lastTick = now; + // see https://gist.github.com/mariobadr/673bbd5545242fcf9482 + } } } \ No newline at end of file diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index 4a8bec8a..19456fd6 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -29,6 +29,8 @@ namespace WAL std::vector> _systems = {}; //! @brief The renderer used to draw entities std::unique_ptr _renderer; + //! @brief True if the engine should close after the end of the current tick. + bool _shouldClose = false; public: //! @brief Create a new system in place. //! @return The wal instance used to call this function is returned. This allow method chaining. From e98a73f2eae0f8625cfd0dd51982bb918343d1df Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 17 May 2021 12:31:02 +0200 Subject: [PATCH 06/13] Adding a position componentn and a vector3 --- lib/wal/CMakeLists.txt | 18 +- .../Component/Basics/PositionComponent.cpp | 48 ++++++ .../Component/Basics/PositionComponent.hpp | 45 +++++ lib/wal/sources/Component/Component.cpp | 10 +- lib/wal/sources/Component/Component.hpp | 7 +- lib/wal/sources/Entity/Entity.hpp | 2 +- lib/wal/sources/Models/Vector3.hpp | 157 ++++++++++++++++++ lib/wal/tests/EntityTests.cpp | 16 ++ lib/wal/tests/MainTest.cpp | 6 + 9 files changed, 292 insertions(+), 17 deletions(-) create mode 100644 lib/wal/sources/Component/Basics/PositionComponent.cpp create mode 100644 lib/wal/sources/Component/Basics/PositionComponent.hpp create mode 100644 lib/wal/sources/Models/Vector3.hpp create mode 100644 lib/wal/tests/EntityTests.cpp create mode 100644 lib/wal/tests/MainTest.cpp diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index 02613603..26357827 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -19,6 +19,20 @@ add_library(wal sources/Events/EventManager.hpp sources/Exception/WalError.cpp sources/Exception/WalError.hpp - sources/Entity/Entity.cpp sources/Component/Component.cpp) + sources/Entity/Entity.cpp + sources/Component/Component.cpp + sources/Component/Basics/PositionComponent.cpp + sources/Component/Basics/PositionComponent.hpp + sources/Models/Vector2.hpp + sources/Models/Vector3.hpp +) -target_include_directories(wal PUBLIC sources) \ No newline at end of file +target_include_directories(wal PUBLIC sources) + +add_executable(wal_tests + tests/EntityTests.cpp + tests/MainTest.cpp) + +target_link_libraries(wal_tests PRIVATE wal) +find_package(Catch2 REQUIRED) +target_link_libraries(wal_tests PRIVATE Catch2::Catch2) \ No newline at end of file diff --git a/lib/wal/sources/Component/Basics/PositionComponent.cpp b/lib/wal/sources/Component/Basics/PositionComponent.cpp new file mode 100644 index 00000000..572bacaf --- /dev/null +++ b/lib/wal/sources/Component/Basics/PositionComponent.cpp @@ -0,0 +1,48 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#include "PositionComponent.hpp" + +namespace WAL::Components +{ + PositionComponent::PositionComponent(Entity &entity) + : Component(entity), + _position() + {} + + PositionComponent::PositionComponent(float x, float y, float z, Entity &entity) + : Component(entity), + _position(x, y, z) + {} + + Component *PositionComponent::clone(WAL::Entity &entity) const + { + return new PositionComponent(entity); + } + + Vector3f &PositionComponent::getPosition() + { + return this->_position; + } + + const Vector3f &PositionComponent::getPosition() const + { + return this->_position; + } + + float PositionComponent::getX() const + { + return this->_position.x; + } + + float PositionComponent::getY() const + { + return this->_position.y; + } + + float PositionComponent::getZ() const + { + return this->_position.z; + } +} \ No newline at end of file diff --git a/lib/wal/sources/Component/Basics/PositionComponent.hpp b/lib/wal/sources/Component/Basics/PositionComponent.hpp new file mode 100644 index 00000000..b1f30fbd --- /dev/null +++ b/lib/wal/sources/Component/Basics/PositionComponent.hpp @@ -0,0 +1,45 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#pragma once + +#include "Models/Vector3.hpp" +#include "Component/Component.hpp" + +namespace WAL::Components +{ + //! @brief A basic position component + class PositionComponent : public Component + { + private: + //! @brief The position of the entity as a vector3. + Vector3f _position; + public: + //! @brief Get the editable position of this entity + Vector3f &getPosition(); + //! @brief Get the const position of this entity + const Vector3f &getPosition() const; + + //! @brief Get the X position of this entity. + float getX() const; + //! @brief Get the Y position of this entity. + float getY() const; + //! @brief Get the Z position of this entity. + float getZ() const; + + //! @inherit + Component *clone(Entity &entity) const override; + + //! @brief Create a new PositionComponent linked to a specific entity + explicit PositionComponent(Entity &entity); + //! @brief Create a new PositionComponent at a certain position + PositionComponent(float x, float y, float z, Entity &entity); + //! @brief A position component is copy constructable + PositionComponent(const PositionComponent &) = default; + //! @brief A default destructor + ~PositionComponent() override = default; + //! @brief A position component is not assignable + PositionComponent &operator=(const PositionComponent &) = delete; + }; +} diff --git a/lib/wal/sources/Component/Component.cpp b/lib/wal/sources/Component/Component.cpp index 5d2948c7..f891352b 100644 --- a/lib/wal/sources/Component/Component.cpp +++ b/lib/wal/sources/Component/Component.cpp @@ -6,16 +6,10 @@ namespace WAL { - Component::Component(std::string name, Entity &entity) - : _name(std::move(name)), - _entity(entity) + Component::Component(Entity &entity) + : _entity(entity) { } - std::string Component::getName() const - { - return this->_name; - } - bool Component::isDisabled() const { return this->_disabled; diff --git a/lib/wal/sources/Component/Component.hpp b/lib/wal/sources/Component/Component.hpp index 64d325a9..c05fd507 100644 --- a/lib/wal/sources/Component/Component.hpp +++ b/lib/wal/sources/Component/Component.hpp @@ -16,8 +16,6 @@ namespace WAL class Component { private: - //! @brief The name of this component - std::string _name; //! @brief Is this component disabled? bool _disabled = false; protected: @@ -27,7 +25,7 @@ namespace WAL std::vector _dependencies; //! @brief A component can't be instantiated, it should be derived. - explicit Component(std::string name, Entity &entity); + explicit Component(Entity &entity); //! @brief A component can't be instantiated, it should be derived. Component(const Component &) = default; public: @@ -40,9 +38,6 @@ namespace WAL //! @param entity The entity that owns the ne component. virtual Component *clone(Entity &entity) const = 0; - //! @brief Get the name of this component - std::string getName() const; - //! @brief Used if the component is disabled bool isDisabled() const; //! @brief Disable this component. diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 7ad68586..cc4c3422 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -70,7 +70,7 @@ namespace WAL { if (this->hasComponent()) throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists."); - this->_components.push_back(std::make_unique(params...)); + this->_components.push_back(std::make_unique(params...)); return *this; } diff --git a/lib/wal/sources/Models/Vector3.hpp b/lib/wal/sources/Models/Vector3.hpp new file mode 100644 index 00000000..fa3b23fa --- /dev/null +++ b/lib/wal/sources/Models/Vector3.hpp @@ -0,0 +1,157 @@ +// +// Created by Zoe Roux on 5/17/21. +// + + +#pragma once + +#include +#include + +namespace WAL +{ + //! @brief A Vector3 data type. (templated to allow any kind of vector3) + template + class Vector3 + { + public: + //! @brief The x value of the vector + T x; + //! @brief The y value of the vector + T y; + //! @brief The y value of the vector + T z; + + //! @brief Create a new nil vector3. + Vector3() + : x(0), y(0), z(0) + {} + + //! @brief Create a new vector3 representing a specific coordinate. + Vector3(T x, T y, T z) + : x(x), y(y), z(z) + {} + + //! @brief A default destructor + ~Vector3() = default; + + template + Vector3 &operator+=(const Vector3 &vec) + { + this->x += vec.x; + this->y += vec.y; + this->z += vec.z; + return *this; + } + + template + Vector3 operator+(const Vector3 &vec) const + { + return Vector3(this->x + vec.x, this->y + vec.y, this->z + vec.z); + } + + template + Vector3 &operator-=(const Vector3 &vec) + { + this->x -= vec.x; + this->y -= vec.y; + this->z -= vec.z; + return *this; + } + + template + Vector3 &operator*=(T2 d) + { + this->x *= d; + this->y *= d; + this->z *= d; + return *this; + } + + template + Vector3 operator*(T2 d) const + { + return Vector2(this->x * d, this->y * d, this->z * d); + } + + template + Vector3 operator*(Vector3 &b) const + { + return Vector3(this->x * b.x, this->y * b.y, this->z * b.z); + } + + template + Vector3 operator/=(Vector3 &b) + { + this->x /= b.x; + this->y /= b.y; + this->z /= b.z; + return this; + } + + template + Vector3 operator/(Vector3 &b) const + { + return Vector3(this->x / b.x, this->y / b.y, this->z / b.z); + } + + template + Vector3 operator/=(T2 b) + { + this->x /= b; + this->y /= b; + this->z /= b; + return this; + } + + template + Vector3 operator/(T2 b) const + { + return Vector3(this->x / b, this->y / b, this->z / b); + } + + template + double distance(const Vector3 &o) const + { + return std::sqrt(std::pow(this->x - o.x, 2) + std::pow(this->y - o.y, 2) + std::pow(this->z - o.z, 2)); + } + + double magnitude() const + { + return (std::sqrt(std::pow(this->x, 2) + std::pow(this->y, 2), std::pow(this->z, 2))); + } + + Vector3 normalize() + { + double mag = this->magnitude(); + + this->x /= mag; + this->y /= mag; + this->z /= mag; + return *this; + } + + Vector3 normalized() const + { + T mag = this->magnitude(); + + return Vector3(this->x / mag, this->y / mag, this->z / mag); + } + + Vector3 projection(const Vector3 &point) const + { + return (point * this) / std::pow(this->magnitude(), 2) * this; + } + }; + + typedef Vector3 Vector3f; + typedef Vector3 Vector3u; + typedef Vector3 Vector3i; +} + +template +std::ostream &operator<<(std::ostream &s, const WAL::Vector3 &v) +{ + s << v.x << " " << v.y << " " << v.z; + return s; +} \ No newline at end of file diff --git a/lib/wal/tests/EntityTests.cpp b/lib/wal/tests/EntityTests.cpp new file mode 100644 index 00000000..58363495 --- /dev/null +++ b/lib/wal/tests/EntityTests.cpp @@ -0,0 +1,16 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#include +#include "Entity/Entity.hpp" +#include "Component/Basics/PositionComponent.hpp" + +using namespace WAL; +using namespace WAL::Components; + +TEST_CASE("Get component", "[Entity/getComponent]") +{ + Entity entity("Bob"); + entity.addComponent(); +} \ No newline at end of file diff --git a/lib/wal/tests/MainTest.cpp b/lib/wal/tests/MainTest.cpp new file mode 100644 index 00000000..6f2c3690 --- /dev/null +++ b/lib/wal/tests/MainTest.cpp @@ -0,0 +1,6 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#define CATCH_CONFIG_MAIN +#include \ No newline at end of file From 6ba5ceddd6269ecaf4692f9b5fc24145c217fa48 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 17 May 2021 14:58:43 +0200 Subject: [PATCH 07/13] Adding tests and fixing has components --- .../Component/Basics/PositionComponent.cpp | 2 +- .../Component/Basics/PositionComponent.hpp | 2 +- lib/wal/sources/Entity/Entity.hpp | 10 +++++----- lib/wal/sources/Models/Vector3.hpp | 10 ++++++++++ lib/wal/tests/EntityTests.cpp | 19 +++++++++++++++++-- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/lib/wal/sources/Component/Basics/PositionComponent.cpp b/lib/wal/sources/Component/Basics/PositionComponent.cpp index 572bacaf..a23cded0 100644 --- a/lib/wal/sources/Component/Basics/PositionComponent.cpp +++ b/lib/wal/sources/Component/Basics/PositionComponent.cpp @@ -11,7 +11,7 @@ namespace WAL::Components _position() {} - PositionComponent::PositionComponent(float x, float y, float z, Entity &entity) + PositionComponent::PositionComponent(Entity &entity, float x, float y, float z) : Component(entity), _position(x, y, z) {} diff --git a/lib/wal/sources/Component/Basics/PositionComponent.hpp b/lib/wal/sources/Component/Basics/PositionComponent.hpp index b1f30fbd..99b0902f 100644 --- a/lib/wal/sources/Component/Basics/PositionComponent.hpp +++ b/lib/wal/sources/Component/Basics/PositionComponent.hpp @@ -34,7 +34,7 @@ namespace WAL::Components //! @brief Create a new PositionComponent linked to a specific entity explicit PositionComponent(Entity &entity); //! @brief Create a new PositionComponent at a certain position - PositionComponent(float x, float y, float z, Entity &entity); + PositionComponent(Entity &entity, float x, float y, float z); //! @brief A position component is copy constructable PositionComponent(const PositionComponent &) = default; //! @brief A default destructor diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index cc4c3422..2183945b 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -41,22 +41,22 @@ namespace WAL //! @brief Get a component of a specific type //! @throw NotFoundError if the component could not be found template - T getComponent() + T &getComponent() { const std::type_info &type = typeid(T); - auto &existing = std::find(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) { + auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) { return typeid(*cmp) == type; }); if (existing == this->_components.end()) throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\"."); - return *existing; + return *reinterpret_cast(existing->get()); } template bool hasComponent() const { const std::type_info &type = typeid(T); - auto existing = std::find(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { + auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { return typeid(*cmp) == type; }); return existing != this->_components.end(); @@ -70,7 +70,7 @@ namespace WAL { if (this->hasComponent()) throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists."); - this->_components.push_back(std::make_unique(params...)); + this->_components.push_back(std::make_unique(*this, params...)); return *this; } diff --git a/lib/wal/sources/Models/Vector3.hpp b/lib/wal/sources/Models/Vector3.hpp index fa3b23fa..d468b6b6 100644 --- a/lib/wal/sources/Models/Vector3.hpp +++ b/lib/wal/sources/Models/Vector3.hpp @@ -35,6 +35,16 @@ namespace WAL //! @brief A default destructor ~Vector3() = default; + bool operator==(const Vector3 &other) const + { + return this->x == other.x && this->y == other.y && this->z == other.z; + } + + bool operator!=(const Vector3 &other) const + { + return !this->operator==(other); + } + template Vector3 &operator+=(const Vector3 &vec) { diff --git a/lib/wal/tests/EntityTests.cpp b/lib/wal/tests/EntityTests.cpp index 58363495..5377f3bd 100644 --- a/lib/wal/tests/EntityTests.cpp +++ b/lib/wal/tests/EntityTests.cpp @@ -9,8 +9,23 @@ using namespace WAL; using namespace WAL::Components; -TEST_CASE("Get component", "[Entity/getComponent]") +TEST_CASE("Component", "[Entity]") { Entity entity("Bob"); - entity.addComponent(); + entity.addComponent(2, 3, 4); + + SECTION("Check value") { + auto &pos = entity.getComponent(); + REQUIRE(entity.hasComponent()); + REQUIRE(pos.getPosition() == Vector3f(2, 3, 4)); + } + SECTION("Prevent duplicates") { + REQUIRE_THROWS_AS(entity.addComponent(), DuplicateError); + } +} + +TEST_CASE("ComponentNotFound", "[Entity]") +{ + Entity entity("Bob"); + REQUIRE_THROWS_AS(entity.getComponent(), NotFoundError); } \ No newline at end of file From f9363c7aef71a522d4c429a355f8e11dbc9b1d22 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 17 May 2021 15:24:44 +0200 Subject: [PATCH 08/13] Adding more tests --- lib/wal/CMakeLists.txt | 3 +-- .../Component/Basics/PositionComponent.cpp | 7 ++++++- .../Component/Basics/PositionComponent.hpp | 2 ++ lib/wal/sources/Entity/Entity.hpp | 4 ++-- lib/wal/sources/Models/Vector3.hpp | 2 +- lib/wal/tests/EntityTests.cpp | 17 ++++++++++++++++- lib/wal/tests/tests.hpp | 9 +++++++++ 7 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 lib/wal/tests/tests.hpp diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index 26357827..abac0828 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -23,7 +23,6 @@ add_library(wal sources/Component/Component.cpp sources/Component/Basics/PositionComponent.cpp sources/Component/Basics/PositionComponent.hpp - sources/Models/Vector2.hpp sources/Models/Vector3.hpp ) @@ -31,7 +30,7 @@ target_include_directories(wal PUBLIC sources) add_executable(wal_tests tests/EntityTests.cpp - tests/MainTest.cpp) + tests/MainTest.cpp tests/tests.hpp) target_link_libraries(wal_tests PRIVATE wal) find_package(Catch2 REQUIRED) diff --git a/lib/wal/sources/Component/Basics/PositionComponent.cpp b/lib/wal/sources/Component/Basics/PositionComponent.cpp index a23cded0..3e5b736c 100644 --- a/lib/wal/sources/Component/Basics/PositionComponent.cpp +++ b/lib/wal/sources/Component/Basics/PositionComponent.cpp @@ -11,6 +11,11 @@ namespace WAL::Components _position() {} + PositionComponent::PositionComponent(Entity &entity, Vector3f pos) + : Component(entity), + _position(pos) + {} + PositionComponent::PositionComponent(Entity &entity, float x, float y, float z) : Component(entity), _position(x, y, z) @@ -18,7 +23,7 @@ namespace WAL::Components Component *PositionComponent::clone(WAL::Entity &entity) const { - return new PositionComponent(entity); + return new PositionComponent(entity, this->_position); } Vector3f &PositionComponent::getPosition() diff --git a/lib/wal/sources/Component/Basics/PositionComponent.hpp b/lib/wal/sources/Component/Basics/PositionComponent.hpp index 99b0902f..6c557f01 100644 --- a/lib/wal/sources/Component/Basics/PositionComponent.hpp +++ b/lib/wal/sources/Component/Basics/PositionComponent.hpp @@ -34,6 +34,8 @@ namespace WAL::Components //! @brief Create a new PositionComponent linked to a specific entity explicit PositionComponent(Entity &entity); //! @brief Create a new PositionComponent at a certain position + PositionComponent(Entity &entity, Vector3f pos); + //! @brief Create a new PositionComponent at a certain position PositionComponent(Entity &entity, float x, float y, float z); //! @brief A position component is copy constructable PositionComponent(const PositionComponent &) = default; diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 2183945b..7a501661 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -65,7 +65,7 @@ namespace WAL //! @brief Add a component to this entity. The component is constructed in place. //! @throw DuplicateError is thrown if a component with the same type already exist. //! @return This entity is returned - template + template Entity &addComponent(Types ...params) { if (this->hasComponent()) @@ -85,7 +85,7 @@ namespace WAL Entity &removeComponent() { const std::type_info &type = typeid(T); - auto &existing =std::find(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) { + auto existing =std::find_if(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) { return typeid(*cmp) == type; }); if (existing == this->_components.end()) diff --git a/lib/wal/sources/Models/Vector3.hpp b/lib/wal/sources/Models/Vector3.hpp index d468b6b6..3ea30504 100644 --- a/lib/wal/sources/Models/Vector3.hpp +++ b/lib/wal/sources/Models/Vector3.hpp @@ -162,6 +162,6 @@ namespace WAL template std::ostream &operator<<(std::ostream &s, const WAL::Vector3 &v) { - s << v.x << " " << v.y << " " << v.z; + s << "Vector3<" << typeid(T).name() << ">("<< v.x << ", " << v.y << ", " << v.z << ")"; return s; } \ No newline at end of file diff --git a/lib/wal/tests/EntityTests.cpp b/lib/wal/tests/EntityTests.cpp index 5377f3bd..aafb8b94 100644 --- a/lib/wal/tests/EntityTests.cpp +++ b/lib/wal/tests/EntityTests.cpp @@ -2,9 +2,10 @@ // Created by Zoe Roux on 5/17/21. // -#include +#include "tests.hpp" #include "Entity/Entity.hpp" #include "Component/Basics/PositionComponent.hpp" +#include using namespace WAL; using namespace WAL::Components; @@ -22,10 +23,24 @@ TEST_CASE("Component", "[Entity]") SECTION("Prevent duplicates") { REQUIRE_THROWS_AS(entity.addComponent(), DuplicateError); } + SECTION("Remove component") { + entity.removeComponent(); + REQUIRE_THROWS_AS(entity.getComponent(), NotFoundError); + REQUIRE_THROWS_AS(entity.removeComponent(), NotFoundError); + } } TEST_CASE("ComponentNotFound", "[Entity]") { Entity entity("Bob"); REQUIRE_THROWS_AS(entity.getComponent(), NotFoundError); +} + +TEST_CASE("Add component by reference", "[Entity]") +{ + Entity entity("Bob"); + PositionComponent component(entity, 4, 5, 6); + + REQUIRE(&entity.addComponent(component) == &entity); + REQUIRE(entity.getComponent().getPosition() == Vector3f(4, 5, 6)); } \ No newline at end of file diff --git a/lib/wal/tests/tests.hpp b/lib/wal/tests/tests.hpp new file mode 100644 index 00000000..b447fd9a --- /dev/null +++ b/lib/wal/tests/tests.hpp @@ -0,0 +1,9 @@ +// +// Created by Zoe Roux on 5/17/21. +// + + +#pragma once + +#define private public +#define protected public \ No newline at end of file From 7313a9d4e05defb52d000d7b5aead9eb3b6e1d5e Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 17 May 2021 16:26:21 +0200 Subject: [PATCH 09/13] Creating the game loop --- lib/wal/sources/Entity/Entity.cpp | 13 ++++++-- lib/wal/sources/Entity/Entity.hpp | 13 +++++--- lib/wal/sources/Renderer/Renderer.cpp | 8 +++++ lib/wal/sources/Renderer/Renderer.hpp | 4 ++- lib/wal/sources/Scene/Scene.cpp | 9 ++++++ lib/wal/sources/Scene/Scene.hpp | 3 ++ lib/wal/sources/System/System.hpp | 5 +-- lib/wal/sources/Wal.cpp | 44 +++++++++++++++++++++++++-- lib/wal/sources/Wal.hpp | 9 ++++++ 9 files changed, 95 insertions(+), 13 deletions(-) diff --git a/lib/wal/sources/Entity/Entity.cpp b/lib/wal/sources/Entity/Entity.cpp index 859e2e3e..e5ca8b29 100644 --- a/lib/wal/sources/Entity/Entity.cpp +++ b/lib/wal/sources/Entity/Entity.cpp @@ -46,10 +46,17 @@ namespace WAL Entity &Entity::addComponent(const Component &component) { - // TODO handle duplicates -// if (this->hasComponent()) -// throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists."); + if (this->hasComponent(typeid(component))) + throw DuplicateError("A component of the type \"" + std::string(typeid(component).name()) + "\" already exists."); this->_components.emplace_back(component.clone(*this)); return *this; } + + bool Entity::hasComponent(const std::type_info &type) const + { + auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { + return typeid(*cmp) == type; + }); + return existing != this->_components.end(); + } } \ No newline at end of file diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 7a501661..b8e2e05e 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -49,19 +49,22 @@ namespace WAL }); if (existing == this->_components.end()) throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\"."); - return *reinterpret_cast(existing->get()); + return *static_cast(existing->get()); } + //! @brief Check if this entity has a component. + //! @tparam T The type of the component template bool hasComponent() const { const std::type_info &type = typeid(T); - auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { - return typeid(*cmp) == type; - }); - return existing != this->_components.end(); + return this->hasComponent(type); } + //! @brief Check if this entity has a component. + //! @param type The type of the component + bool hasComponent(const std::type_info &type) const; + //! @brief Add a component to this entity. The component is constructed in place. //! @throw DuplicateError is thrown if a component with the same type already exist. //! @return This entity is returned diff --git a/lib/wal/sources/Renderer/Renderer.cpp b/lib/wal/sources/Renderer/Renderer.cpp index 28b61e34..a77f2515 100644 --- a/lib/wal/sources/Renderer/Renderer.cpp +++ b/lib/wal/sources/Renderer/Renderer.cpp @@ -3,3 +3,11 @@ // #include "Renderer.hpp" + +namespace WAL +{ + void Renderer::render() + { + + } +} \ No newline at end of file diff --git a/lib/wal/sources/Renderer/Renderer.hpp b/lib/wal/sources/Renderer/Renderer.hpp index 697f76ad..af6fbd27 100644 --- a/lib/wal/sources/Renderer/Renderer.hpp +++ b/lib/wal/sources/Renderer/Renderer.hpp @@ -7,8 +7,10 @@ namespace WAL { + //! @brief The renderer class used to display things. class Renderer { - + public: + void render(); }; } diff --git a/lib/wal/sources/Scene/Scene.cpp b/lib/wal/sources/Scene/Scene.cpp index 2158ac61..bde3f639 100644 --- a/lib/wal/sources/Scene/Scene.cpp +++ b/lib/wal/sources/Scene/Scene.cpp @@ -3,3 +3,12 @@ // #include "Scene.hpp" + +namespace WAL +{ + std::vector &Scene::getEntities() + { + return this->_entity; + } +} + diff --git a/lib/wal/sources/Scene/Scene.hpp b/lib/wal/sources/Scene/Scene.hpp index 52a85c4f..29ea2c9a 100644 --- a/lib/wal/sources/Scene/Scene.hpp +++ b/lib/wal/sources/Scene/Scene.hpp @@ -16,5 +16,8 @@ namespace WAL private: //! @brief The list of registered entities std::vector _entity; + public: + //! @brief Get the list of entities. + std::vector &getEntities(); }; } diff --git a/lib/wal/sources/System/System.hpp b/lib/wal/sources/System/System.hpp index 5da1d236..b0cc02d4 100644 --- a/lib/wal/sources/System/System.hpp +++ b/lib/wal/sources/System/System.hpp @@ -2,6 +2,7 @@ #pragma once +#include #include "Entity/Entity.hpp" namespace WAL @@ -16,12 +17,12 @@ namespace WAL System(System &&) = default; //! @brief Get the name of the component corresponding to this system. - virtual std::string getComponentName() const = 0; + virtual std::type_info &getComponent() const = 0; //! @brief Update the corresponding component of the given entity //! @param entity The entity to update. //! @param dtime The delta time. - virtual void onUpdate(Entity &entity, float dtime) = 0; + virtual void onUpdate(Entity &entity, std::chrono::nanoseconds dtime) = 0; //! @brief An alternative of onUpdate that is called every 8ms (120 times per seconds). If the system slow down, it will try to catch up. //! @remark This should be used for Physics, AI and everything that could be imprecise due to float rounding. diff --git a/lib/wal/sources/Wal.cpp b/lib/wal/sources/Wal.cpp index b5f62458..0e4921ff 100644 --- a/lib/wal/sources/Wal.cpp +++ b/lib/wal/sources/Wal.cpp @@ -5,8 +5,11 @@ #include #include "Wal.hpp" +using namespace std::chrono_literals; + namespace WAL { + std::chrono::nanoseconds WAL::_timestep = 8ms; SceneManager &WAL::getSceneManger() { @@ -16,12 +19,49 @@ namespace WAL void WAL::run() { auto lastTick = std::chrono::steady_clock::now(); + std::chrono::nanoseconds dtime(0); while (!this->_shouldClose) { auto now = std::chrono::steady_clock::now(); - auto dtime = now - lastTick; + dtime += now - lastTick; lastTick = now; - // see https://gist.github.com/mariobadr/673bbd5545242fcf9482 + + this->_update(dtime); + while (dtime > WAL::_timestep) { + dtime -= WAL::_timestep; + this->_fixedUpdate(); + } + this->_renderer->render(); + } + } + + void WAL::_update(std::chrono::nanoseconds dtime) + { + auto &entities = this->_scenes.getCurrent().getEntities(); + + for (auto &system : this->_systems) { + for (auto &entity : entities) { + auto &cmp = system->getComponent(); + if (!entity.hasComponent(cmp)) + continue; + // TODO handle dependencies. + system->onUpdate(entity, dtime); + } + } + } + + void WAL::_fixedUpdate() + { + auto &entities = this->_scenes.getCurrent().getEntities(); + + for (auto &system : this->_systems) { + for (auto &entity : entities) { + auto &cmp = system->getComponent(); + if (!entity.hasComponent(cmp)) + continue; + // TODO handle dependencies. + system->onFixedUpdate(entity); + } } } } \ No newline at end of file diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index 19456fd6..e4c9f291 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -31,6 +31,15 @@ namespace WAL std::unique_ptr _renderer; //! @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 std::chrono::nanoseconds _timestep; + + //! @brief Call the onUpdate of every system with every component + void _update(std::chrono::nanoseconds dtime); + + //! @brief Call the onFixedUpdate of every system with every component + void _fixedUpdate(); public: //! @brief Create a new system in place. //! @return The wal instance used to call this function is returned. This allow method chaining. From 76ccd80df738ede9eff6ca4f89bc82aead0e7fc1 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 17 May 2021 17:03:15 +0200 Subject: [PATCH 10/13] Adding a movable system/component --- lib/wal/CMakeLists.txt | 6 +-- .../Component/Movable/MovableComponent.cpp | 22 +++++++++++ .../Component/Movable/MovableComponent.hpp | 39 +++++++++++++++++++ .../PositionComponent.cpp | 26 ++++--------- .../PositionComponent.hpp | 9 +---- lib/wal/sources/Models/Vector3.hpp | 2 +- .../sources/System/Movable/MovableSystem.cpp | 26 +++++++++++++ .../sources/System/Movable/MovableSystem.hpp | 30 ++++++++++++++ lib/wal/sources/System/System.cpp | 15 +++++++ lib/wal/sources/System/System.hpp | 6 +-- lib/wal/sources/Wal.cpp | 8 ++-- lib/wal/sources/Wal.hpp | 6 +-- lib/wal/tests/EntityTests.cpp | 3 +- 13 files changed, 157 insertions(+), 41 deletions(-) create mode 100644 lib/wal/sources/Component/Movable/MovableComponent.cpp create mode 100644 lib/wal/sources/Component/Movable/MovableComponent.hpp rename lib/wal/sources/Component/{Basics => Position}/PositionComponent.cpp (59%) rename lib/wal/sources/Component/{Basics => Position}/PositionComponent.hpp (84%) create mode 100644 lib/wal/sources/System/Movable/MovableSystem.cpp create mode 100644 lib/wal/sources/System/Movable/MovableSystem.hpp create mode 100644 lib/wal/sources/System/System.cpp diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index abac0828..4552fd54 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -21,10 +21,10 @@ add_library(wal sources/Exception/WalError.hpp sources/Entity/Entity.cpp sources/Component/Component.cpp - sources/Component/Basics/PositionComponent.cpp - sources/Component/Basics/PositionComponent.hpp + sources/Component/Position/PositionComponent.cpp + sources/Component/Position/PositionComponent.hpp sources/Models/Vector3.hpp -) + sources/Component/Movable/MovableComponent.cpp sources/Component/Movable/MovableComponent.hpp sources/System/Movable/MovableSystem.cpp sources/System/Movable/MovableSystem.hpp sources/System/System.cpp) target_include_directories(wal PUBLIC sources) diff --git a/lib/wal/sources/Component/Movable/MovableComponent.cpp b/lib/wal/sources/Component/Movable/MovableComponent.cpp new file mode 100644 index 00000000..b989de28 --- /dev/null +++ b/lib/wal/sources/Component/Movable/MovableComponent.cpp @@ -0,0 +1,22 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#include "MovableComponent.hpp" + +namespace WAL::Movable +{ + MovableComponent::MovableComponent(Entity &entity) + : Component(entity) + {} + + Component *MovableComponent::clone(Entity &entity) const + { + return new MovableComponent(entity); + } + + void MovableComponent::addForce(Vector3f force) + { + this->_acceleration += force; + } +} \ No newline at end of file diff --git a/lib/wal/sources/Component/Movable/MovableComponent.hpp b/lib/wal/sources/Component/Movable/MovableComponent.hpp new file mode 100644 index 00000000..0693121a --- /dev/null +++ b/lib/wal/sources/Component/Movable/MovableComponent.hpp @@ -0,0 +1,39 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#pragma once + +#include "Models/Vector3.hpp" +#include "Entity/Entity.hpp" + +namespace WAL +{ + //! @brief A component to place on entities that can move or be moved. + class MovableComponent : public Component + { + private: + //! @brief The acceleration of this entity. + Vector3f _acceleration; + //! @brief The velocity of the entity. + Vector3f _velocity; + public: + //! @brief Add an instant force to this entity. + //! @param force The force to add to this entity's acceleration. The force is added instantly and in one go. + void addForce(Vector3f force); + + //! @inherit + Component *clone(Entity &entity) const override; + + //! @brief Create a new movable component. + explicit MovableComponent(Entity &entity); + //! @brief A movable component is copy constructable. + MovableComponent(const MovableComponent &) = default; + //! @brief A default destructor + ~MovableComponent() override = default; + //! @brief A movable component is not assignable. + MovableComponent &operator=(const MovableComponent &) = delete; + + friend class MovableSystem; + }; +} \ No newline at end of file diff --git a/lib/wal/sources/Component/Basics/PositionComponent.cpp b/lib/wal/sources/Component/Position/PositionComponent.cpp similarity index 59% rename from lib/wal/sources/Component/Basics/PositionComponent.cpp rename to lib/wal/sources/Component/Position/PositionComponent.cpp index 3e5b736c..1e470254 100644 --- a/lib/wal/sources/Component/Basics/PositionComponent.cpp +++ b/lib/wal/sources/Component/Position/PositionComponent.cpp @@ -4,50 +4,40 @@ #include "PositionComponent.hpp" -namespace WAL::Components +namespace WAL { PositionComponent::PositionComponent(Entity &entity) : Component(entity), - _position() + position() {} PositionComponent::PositionComponent(Entity &entity, Vector3f pos) : Component(entity), - _position(pos) + position(pos) {} PositionComponent::PositionComponent(Entity &entity, float x, float y, float z) : Component(entity), - _position(x, y, z) + position(x, y, z) {} Component *PositionComponent::clone(WAL::Entity &entity) const { - return new PositionComponent(entity, this->_position); - } - - Vector3f &PositionComponent::getPosition() - { - return this->_position; - } - - const Vector3f &PositionComponent::getPosition() const - { - return this->_position; + return new PositionComponent(entity, this->position); } float PositionComponent::getX() const { - return this->_position.x; + return this->position.x; } float PositionComponent::getY() const { - return this->_position.y; + return this->position.y; } float PositionComponent::getZ() const { - return this->_position.z; + return this->position.z; } } \ No newline at end of file diff --git a/lib/wal/sources/Component/Basics/PositionComponent.hpp b/lib/wal/sources/Component/Position/PositionComponent.hpp similarity index 84% rename from lib/wal/sources/Component/Basics/PositionComponent.hpp rename to lib/wal/sources/Component/Position/PositionComponent.hpp index 6c557f01..8e11a2e3 100644 --- a/lib/wal/sources/Component/Basics/PositionComponent.hpp +++ b/lib/wal/sources/Component/Position/PositionComponent.hpp @@ -7,19 +7,14 @@ #include "Models/Vector3.hpp" #include "Component/Component.hpp" -namespace WAL::Components +namespace WAL { //! @brief A basic position component class PositionComponent : public Component { - private: - //! @brief The position of the entity as a vector3. - Vector3f _position; public: //! @brief Get the editable position of this entity - Vector3f &getPosition(); - //! @brief Get the const position of this entity - const Vector3f &getPosition() const; + Vector3f position; //! @brief Get the X position of this entity. float getX() const; diff --git a/lib/wal/sources/Models/Vector3.hpp b/lib/wal/sources/Models/Vector3.hpp index 3ea30504..05391c25 100644 --- a/lib/wal/sources/Models/Vector3.hpp +++ b/lib/wal/sources/Models/Vector3.hpp @@ -81,7 +81,7 @@ namespace WAL template Vector3 operator*(T2 d) const { - return Vector2(this->x * d, this->y * d, this->z * d); + return Vector3(this->x * d, this->y * d, this->z * d); } template diff --git a/lib/wal/sources/System/Movable/MovableSystem.cpp b/lib/wal/sources/System/Movable/MovableSystem.cpp new file mode 100644 index 00000000..108b4c93 --- /dev/null +++ b/lib/wal/sources/System/Movable/MovableSystem.cpp @@ -0,0 +1,26 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#include "Component/Position/PositionComponent.hpp" +#include "System/Movable/MovableSystem.hpp" +#include "Component/Movable/MovableComponent.hpp" +#include "Wal.hpp" + +namespace WAL +{ + const std::type_info &MovableSystem::getComponent() const + { + return typeid(MovableComponent); + } + + void MovableSystem::onFixedUpdate(Entity &entity) + { + auto &movable = entity.getComponent(); + auto &position = entity.getComponent(); + + position.position += movable._velocity * WAL::timestep.count(); + movable._velocity = movable._acceleration * WAL::timestep.count(); + movable._acceleration = Vector3f(); + } +} \ No newline at end of file diff --git a/lib/wal/sources/System/Movable/MovableSystem.hpp b/lib/wal/sources/System/Movable/MovableSystem.hpp new file mode 100644 index 00000000..400c7830 --- /dev/null +++ b/lib/wal/sources/System/Movable/MovableSystem.hpp @@ -0,0 +1,30 @@ + +// +// Created by Zoe Roux on 5/17/21. +// + +#pragma once + +#include "System/System.hpp" + +namespace WAL +{ + //! @brief A system to handle movable entities. This system update velocity based on accelerations and positions based on velocity. + class MovableSystem : public System + { + public: + //! @inherit + const std::type_info &getComponent() const override; + //! @inherit + void onFixedUpdate(Entity &entity) override; + + //! @brief A default constructor + MovableSystem() = default; + //! @brief A movable system is copy constructable + MovableSystem(const MovableSystem &) = default; + //! @brief A default destructor + ~MovableSystem() override = default; + //! @brief A movable system is assignable. + MovableSystem &operator=(const MovableSystem &) = default; + }; +} diff --git a/lib/wal/sources/System/System.cpp b/lib/wal/sources/System/System.cpp new file mode 100644 index 00000000..e1cc2ec0 --- /dev/null +++ b/lib/wal/sources/System/System.cpp @@ -0,0 +1,15 @@ +// +// Created by Zoe Roux on 5/17/21. +// + +#include "System.hpp" + +namespace WAL +{ + + void System::onUpdate(Entity &entity, std::chrono::nanoseconds dtime) + {} + + void System::onFixedUpdate(Entity &entity) + {} +} \ No newline at end of file diff --git a/lib/wal/sources/System/System.hpp b/lib/wal/sources/System/System.hpp index b0cc02d4..998da6b9 100644 --- a/lib/wal/sources/System/System.hpp +++ b/lib/wal/sources/System/System.hpp @@ -17,17 +17,17 @@ namespace WAL System(System &&) = default; //! @brief Get the name of the component corresponding to this system. - virtual std::type_info &getComponent() const = 0; + virtual const std::type_info &getComponent() const = 0; //! @brief Update the corresponding component of the given entity //! @param entity The entity to update. //! @param dtime The delta time. - virtual void onUpdate(Entity &entity, std::chrono::nanoseconds dtime) = 0; + virtual void onUpdate(Entity &entity, std::chrono::nanoseconds dtime); //! @brief An alternative of onUpdate that is called every 8ms (120 times per seconds). If the system slow down, it will try to catch up. //! @remark This should be used for Physics, AI and everything that could be imprecise due to float rounding. //! @param entity The entity to update. - virtual void onFixedUpdate(Entity &entity) = 0; + virtual void onFixedUpdate(Entity &entity); protected: //! @brief A system can't be instantiated, it should be derived. System() = default; diff --git a/lib/wal/sources/Wal.cpp b/lib/wal/sources/Wal.cpp index 0e4921ff..de82cddc 100644 --- a/lib/wal/sources/Wal.cpp +++ b/lib/wal/sources/Wal.cpp @@ -9,7 +9,7 @@ using namespace std::chrono_literals; namespace WAL { - std::chrono::nanoseconds WAL::_timestep = 8ms; + std::chrono::nanoseconds WAL::timestep = 8ms; SceneManager &WAL::getSceneManger() { @@ -27,8 +27,8 @@ namespace WAL lastTick = now; this->_update(dtime); - while (dtime > WAL::_timestep) { - dtime -= WAL::_timestep; + while (dtime > WAL::timestep) { + dtime -= WAL::timestep; this->_fixedUpdate(); } this->_renderer->render(); @@ -41,7 +41,7 @@ namespace WAL for (auto &system : this->_systems) { for (auto &entity : entities) { - auto &cmp = system->getComponent(); + const auto &cmp = system->getComponent(); if (!entity.hasComponent(cmp)) continue; // TODO handle dependencies. diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index e4c9f291..d5e9d797 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -32,15 +32,15 @@ namespace WAL //! @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 std::chrono::nanoseconds _timestep; - //! @brief Call the onUpdate of every system with every component void _update(std::chrono::nanoseconds dtime); //! @brief Call the onFixedUpdate of every system with every component void _fixedUpdate(); public: + //! @brief The time between each fixed update. + static std::chrono::nanoseconds timestep; + //! @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/lib/wal/tests/EntityTests.cpp b/lib/wal/tests/EntityTests.cpp index aafb8b94..0ae20e85 100644 --- a/lib/wal/tests/EntityTests.cpp +++ b/lib/wal/tests/EntityTests.cpp @@ -4,11 +4,10 @@ #include "tests.hpp" #include "Entity/Entity.hpp" -#include "Component/Basics/PositionComponent.hpp" +#include "Component/Position/PositionComponent.hpp" #include using namespace WAL; -using namespace WAL::Components; TEST_CASE("Component", "[Entity]") { From 68d17cd0a2b7b7c110a76e6ffc115cb93ffbad6b Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 17 May 2021 17:22:09 +0200 Subject: [PATCH 11/13] Adding tests --- lib/wal/CMakeLists.txt | 2 +- .../Component/Movable/MovableComponent.cpp | 2 +- .../sources/System/Movable/MovableSystem.cpp | 4 +- lib/wal/sources/Wal.cpp | 14 +++---- lib/wal/sources/Wal.hpp | 41 +++++++++++++------ lib/wal/tests/EngineTests.cpp | 36 ++++++++++++++++ lib/wal/tests/EntityTests.cpp | 5 +-- lib/wal/tests/tests.hpp | 9 ---- sources/main.cpp | 2 +- 9 files changed, 78 insertions(+), 37 deletions(-) create mode 100644 lib/wal/tests/EngineTests.cpp delete mode 100644 lib/wal/tests/tests.hpp diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index 4552fd54..36267b7b 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -30,7 +30,7 @@ target_include_directories(wal PUBLIC sources) add_executable(wal_tests tests/EntityTests.cpp - tests/MainTest.cpp tests/tests.hpp) + tests/MainTest.cpp tests/tests.hpp tests/EngineTests.cpp) target_link_libraries(wal_tests PRIVATE wal) find_package(Catch2 REQUIRED) diff --git a/lib/wal/sources/Component/Movable/MovableComponent.cpp b/lib/wal/sources/Component/Movable/MovableComponent.cpp index b989de28..a86a69ab 100644 --- a/lib/wal/sources/Component/Movable/MovableComponent.cpp +++ b/lib/wal/sources/Component/Movable/MovableComponent.cpp @@ -4,7 +4,7 @@ #include "MovableComponent.hpp" -namespace WAL::Movable +namespace WAL { MovableComponent::MovableComponent(Entity &entity) : Component(entity) diff --git a/lib/wal/sources/System/Movable/MovableSystem.cpp b/lib/wal/sources/System/Movable/MovableSystem.cpp index 108b4c93..600f7c8e 100644 --- a/lib/wal/sources/System/Movable/MovableSystem.cpp +++ b/lib/wal/sources/System/Movable/MovableSystem.cpp @@ -19,8 +19,8 @@ namespace WAL auto &movable = entity.getComponent(); auto &position = entity.getComponent(); - position.position += movable._velocity * WAL::timestep.count(); - movable._velocity = movable._acceleration * WAL::timestep.count(); + position.position += movable._velocity * Wal::timestep.count(); + movable._velocity = movable._acceleration * Wal::timestep.count(); movable._acceleration = Vector3f(); } } \ No newline at end of file diff --git a/lib/wal/sources/Wal.cpp b/lib/wal/sources/Wal.cpp index de82cddc..67a1891e 100644 --- a/lib/wal/sources/Wal.cpp +++ b/lib/wal/sources/Wal.cpp @@ -9,14 +9,14 @@ using namespace std::chrono_literals; namespace WAL { - std::chrono::nanoseconds WAL::timestep = 8ms; + std::chrono::nanoseconds Wal::timestep = 8ms; - SceneManager &WAL::getSceneManger() + SceneManager &Wal::getSceneManger() { return this->_scenes; } - void WAL::run() + void Wal::run() { auto lastTick = std::chrono::steady_clock::now(); std::chrono::nanoseconds dtime(0); @@ -27,15 +27,15 @@ namespace WAL lastTick = now; this->_update(dtime); - while (dtime > WAL::timestep) { - dtime -= WAL::timestep; + while (dtime > Wal::timestep) { + dtime -= Wal::timestep; this->_fixedUpdate(); } this->_renderer->render(); } } - void WAL::_update(std::chrono::nanoseconds dtime) + void Wal::_update(std::chrono::nanoseconds dtime) { auto &entities = this->_scenes.getCurrent().getEntities(); @@ -50,7 +50,7 @@ namespace WAL } } - void WAL::_fixedUpdate() + void Wal::_fixedUpdate() { auto &entities = this->_scenes.getCurrent().getEntities(); diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index d5e9d797..c097436f 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -18,7 +18,7 @@ namespace WAL { //! @brief The main WAL class, it is used to setup and run the ECS. - class WAL + class Wal { private: //! @brief The scene manager that allow multiple scene to work together. @@ -44,39 +44,54 @@ namespace WAL //! @brief Create a new system in place. //! @return The wal instance used to call this function is returned. This allow method chaining. template - WAL &addSystem(Types ...params) + Wal &addSystem(Types ...params) { const std::type_info &type = typeid(T); - auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { + auto existing = std::find_if(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { return typeid(*sys) == type; }); if (existing != this->_systems.end()) throw DuplicateError("A system of the type \"" + std::string(type.name()) + "\" already exists."); - this->_systems.push_back(std::make_unique(params...)); + this->_systems.push_back(std::make_unique(params...)); return *this; } //! @brief Add a system by copy. //! @return The wal instance used to call this function is returned. This allow method chaining. template - WAL &addSystem(const T &system) + Wal &addSystem(const T &system) { const std::type_info &type = typeid(T); - auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { + auto existing = std::find_if(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { return typeid(*sys) == type; }); if (existing != this->_systems.end()) throw DuplicateError("A system of the type \"" + std::string(type.name()) + "\" already exists."); - this->_systems.push_back(std::make_unique(system)); + this->_systems.push_back(std::make_unique(system)); return *this; } + //! @brief Get a system of a specific type + //! @tparam T the type of the system. + template + T &getSystem() + { + const std::type_info &type = typeid(T); + auto existing = std::find_if(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { + return typeid(*sys) == type; + }); + if (existing == this->_systems.end()) + throw NotFoundError("A system of the type \"" + std::string(type.name()) + "\" could not be found."); + return *static_cast(existing->get()); + + } + //! @brief Remove a system using it's type. template - WAL &removeSystem() + Wal &removeSystem() { const std::type_info &type = typeid(T); - auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { + auto existing = std::find_if(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) { return typeid(*sys) == type; }); if (existing == this->_systems.end()) @@ -92,12 +107,12 @@ namespace WAL void run(); //! @brief A default constructor - WAL() = default; + Wal() = default; //! @brief A WAL can't be copy constructed - WAL(const WAL &) = delete; + Wal(const Wal &) = delete; //! @brief A default destructor - ~WAL() = default; + ~Wal() = default; //! @brief A WAL can't be assigned. - WAL &operator=(const WAL &) = delete; + Wal &operator=(const Wal &) = delete; }; } diff --git a/lib/wal/tests/EngineTests.cpp b/lib/wal/tests/EngineTests.cpp new file mode 100644 index 00000000..c6074138 --- /dev/null +++ b/lib/wal/tests/EngineTests.cpp @@ -0,0 +1,36 @@ +// +// Created by Zoe Roux on 5/17/21. +// + + +#include "Wal.hpp" +#include "System/Movable/MovableSystem.hpp" +#include + +using namespace WAL; + +TEST_CASE("Create system", "[Engine][System]") +{ + Wal wal; + wal.addSystem(); + + SECTION("Check existence") { + REQUIRE_NOTHROW(wal.getSystem()); + } + SECTION("Duplicate check") { + REQUIRE_THROWS_AS(wal.addSystem(), DuplicateError); + } + SECTION("Remove system") { + wal.removeSystem(); + REQUIRE_THROWS_AS(wal.getSystem(), NotFoundError); + REQUIRE_THROWS_AS(wal.removeSystem(), NotFoundError); + } +} + +TEST_CASE("Create system by reference", "[Engine][System]") +{ + Wal wal; + MovableSystem system; + wal.addSystem(system); + REQUIRE_THROWS_AS(wal.addSystem(), DuplicateError); +} \ No newline at end of file diff --git a/lib/wal/tests/EntityTests.cpp b/lib/wal/tests/EntityTests.cpp index 0ae20e85..6c6c4edf 100644 --- a/lib/wal/tests/EntityTests.cpp +++ b/lib/wal/tests/EntityTests.cpp @@ -2,7 +2,6 @@ // Created by Zoe Roux on 5/17/21. // -#include "tests.hpp" #include "Entity/Entity.hpp" #include "Component/Position/PositionComponent.hpp" #include @@ -17,7 +16,7 @@ TEST_CASE("Component", "[Entity]") SECTION("Check value") { auto &pos = entity.getComponent(); REQUIRE(entity.hasComponent()); - REQUIRE(pos.getPosition() == Vector3f(2, 3, 4)); + REQUIRE(pos.position == Vector3f(2, 3, 4)); } SECTION("Prevent duplicates") { REQUIRE_THROWS_AS(entity.addComponent(), DuplicateError); @@ -41,5 +40,5 @@ TEST_CASE("Add component by reference", "[Entity]") PositionComponent component(entity, 4, 5, 6); REQUIRE(&entity.addComponent(component) == &entity); - REQUIRE(entity.getComponent().getPosition() == Vector3f(4, 5, 6)); + REQUIRE(entity.getComponent().position == Vector3f(4, 5, 6)); } \ No newline at end of file diff --git a/lib/wal/tests/tests.hpp b/lib/wal/tests/tests.hpp deleted file mode 100644 index b447fd9a..00000000 --- a/lib/wal/tests/tests.hpp +++ /dev/null @@ -1,9 +0,0 @@ -// -// Created by Zoe Roux on 5/17/21. -// - - -#pragma once - -#define private public -#define protected public \ No newline at end of file diff --git a/sources/main.cpp b/sources/main.cpp index 53c8bb20..70491566 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -3,7 +3,7 @@ int main() { - WAL::WAL wal; + WAL::Wal wal; try { wal.run(); From c6012f1be6e201c44cd0aa93a70d65976b91f096 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 18 May 2021 09:42:18 +0200 Subject: [PATCH 12/13] Fixing PR issues --- lib/wal/CMakeLists.txt | 2 +- lib/wal/sources/Component/Component.hpp | 5 +++-- lib/wal/sources/Entity/Entity.hpp | 8 +++++--- lib/wal/sources/Scene/Scene.cpp | 2 +- lib/wal/sources/Scene/Scene.hpp | 2 +- lib/wal/sources/Scene/SceneManager.hpp | 2 +- lib/wal/sources/System/System.hpp | 4 +++- lib/wal/sources/Wal.cpp | 2 +- lib/wal/sources/Wal.hpp | 2 +- 9 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index b10c94d9..2e6dff87 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -33,7 +33,7 @@ add_library(wal target_include_directories(wal PUBLIC sources) -add_executable(wal_tests +add_executable(wal_tests EXCLUDE_FROM_ALL tests/EntityTests.cpp tests/MainTest.cpp tests/EngineTests.cpp diff --git a/lib/wal/sources/Component/Component.hpp b/lib/wal/sources/Component/Component.hpp index c05fd507..410a026c 100644 --- a/lib/wal/sources/Component/Component.hpp +++ b/lib/wal/sources/Component/Component.hpp @@ -1,5 +1,6 @@ - - +// +// Created by Zoe Roux on 2021-05-14. +// #pragma once diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index b8e2e05e..7a902ecd 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -1,4 +1,6 @@ - +// +// Created by Zoe Roux on 2021-05-14. +// #pragma once @@ -44,7 +46,7 @@ namespace WAL T &getComponent() { const std::type_info &type = typeid(T); - auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) { + auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { return typeid(*cmp) == type; }); if (existing == this->_components.end()) @@ -88,7 +90,7 @@ namespace WAL Entity &removeComponent() { const std::type_info &type = typeid(T); - auto existing =std::find_if(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) { + auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { return typeid(*cmp) == type; }); if (existing == this->_components.end()) diff --git a/lib/wal/sources/Scene/Scene.cpp b/lib/wal/sources/Scene/Scene.cpp index bde3f639..b0a3b3a7 100644 --- a/lib/wal/sources/Scene/Scene.cpp +++ b/lib/wal/sources/Scene/Scene.cpp @@ -8,7 +8,7 @@ namespace WAL { std::vector &Scene::getEntities() { - return this->_entity; + return this->_entities; } } diff --git a/lib/wal/sources/Scene/Scene.hpp b/lib/wal/sources/Scene/Scene.hpp index 29ea2c9a..bf86de44 100644 --- a/lib/wal/sources/Scene/Scene.hpp +++ b/lib/wal/sources/Scene/Scene.hpp @@ -15,7 +15,7 @@ namespace WAL { private: //! @brief The list of registered entities - std::vector _entity; + std::vector _entities; public: //! @brief Get the list of entities. std::vector &getEntities(); diff --git a/lib/wal/sources/Scene/SceneManager.hpp b/lib/wal/sources/Scene/SceneManager.hpp index 21765dc9..16268e75 100644 --- a/lib/wal/sources/Scene/SceneManager.hpp +++ b/lib/wal/sources/Scene/SceneManager.hpp @@ -20,7 +20,7 @@ namespace WAL //! @return The manager instance used to call this function is returned. This allow method chaining. SceneManager &addScene(Scene &&scene); - //! @brief Add a scene before the current scene to allow + //! @brief Add a scene before the current scene. This could be useful for lobbies or scene where the next scene can be constructed. //! @return The manager instance used to call this function is returned. This allow method chaining. SceneManager &addBackScene(Scene &&scene); diff --git a/lib/wal/sources/System/System.hpp b/lib/wal/sources/System/System.hpp index 998da6b9..76a609e8 100644 --- a/lib/wal/sources/System/System.hpp +++ b/lib/wal/sources/System/System.hpp @@ -1,4 +1,6 @@ - +// +// Created by Zoe Roux on 2021-05-14. +// #pragma once diff --git a/lib/wal/sources/Wal.cpp b/lib/wal/sources/Wal.cpp index 67a1891e..f1c84e72 100644 --- a/lib/wal/sources/Wal.cpp +++ b/lib/wal/sources/Wal.cpp @@ -11,7 +11,7 @@ namespace WAL { std::chrono::nanoseconds Wal::timestep = 8ms; - SceneManager &Wal::getSceneManger() + SceneManager &Wal::getSceneManager() { return this->_scenes; } diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index c097436f..c8dd535c 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -101,7 +101,7 @@ namespace WAL } //! @brief Get the scene manager. - SceneManager &getSceneManger(); + SceneManager &getSceneManager(); //! @brief Start the game loop void run(); From 02874fdc475818f98271db5eef0979c5373f4a6d Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 18 May 2021 10:36:18 +0200 Subject: [PATCH 13/13] Adding self updates and removing the renderer --- lib/wal/CMakeLists.txt | 2 -- lib/wal/sources/Renderer/Renderer.cpp | 13 ------------- lib/wal/sources/Renderer/Renderer.hpp | 16 ---------------- lib/wal/sources/System/System.cpp | 3 +++ lib/wal/sources/System/System.hpp | 3 +++ lib/wal/sources/Wal.cpp | 19 ++++++++++--------- lib/wal/sources/Wal.hpp | 5 +---- 7 files changed, 17 insertions(+), 44 deletions(-) delete mode 100644 lib/wal/sources/Renderer/Renderer.cpp delete mode 100644 lib/wal/sources/Renderer/Renderer.hpp diff --git a/lib/wal/CMakeLists.txt b/lib/wal/CMakeLists.txt index 2e6dff87..81d730f2 100644 --- a/lib/wal/CMakeLists.txt +++ b/lib/wal/CMakeLists.txt @@ -13,8 +13,6 @@ add_library(wal sources/Scene/SceneManager.hpp sources/Scene/Scene.cpp sources/Scene/Scene.hpp - sources/Renderer/Renderer.cpp - sources/Renderer/Renderer.hpp sources/Events/EventManager.cpp sources/Events/EventManager.hpp sources/Exception/WalError.cpp diff --git a/lib/wal/sources/Renderer/Renderer.cpp b/lib/wal/sources/Renderer/Renderer.cpp deleted file mode 100644 index a77f2515..00000000 --- a/lib/wal/sources/Renderer/Renderer.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by Zoe Roux on 2021-05-14. -// - -#include "Renderer.hpp" - -namespace WAL -{ - void Renderer::render() - { - - } -} \ No newline at end of file diff --git a/lib/wal/sources/Renderer/Renderer.hpp b/lib/wal/sources/Renderer/Renderer.hpp deleted file mode 100644 index af6fbd27..00000000 --- a/lib/wal/sources/Renderer/Renderer.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// -// Created by Zoe Roux on 2021-05-14. -// - - -#pragma once - -namespace WAL -{ - //! @brief The renderer class used to display things. - class Renderer - { - public: - void render(); - }; -} diff --git a/lib/wal/sources/System/System.cpp b/lib/wal/sources/System/System.cpp index e1cc2ec0..82f7fe11 100644 --- a/lib/wal/sources/System/System.cpp +++ b/lib/wal/sources/System/System.cpp @@ -12,4 +12,7 @@ namespace WAL void System::onFixedUpdate(Entity &entity) {} + + void System::onSelfUpdate() + {} } \ No newline at end of file diff --git a/lib/wal/sources/System/System.hpp b/lib/wal/sources/System/System.hpp index 76a609e8..3813e216 100644 --- a/lib/wal/sources/System/System.hpp +++ b/lib/wal/sources/System/System.hpp @@ -30,6 +30,9 @@ namespace WAL //! @remark This should be used for Physics, AI and everything that could be imprecise due to float rounding. //! @param entity The entity to update. virtual void onFixedUpdate(Entity &entity); + + //! @brief A method called after all entities that this system manage has been updated. + virtual void onSelfUpdate(); protected: //! @brief A system can't be instantiated, it should be derived. System() = default; diff --git a/lib/wal/sources/Wal.cpp b/lib/wal/sources/Wal.cpp index f1c84e72..569743aa 100644 --- a/lib/wal/sources/Wal.cpp +++ b/lib/wal/sources/Wal.cpp @@ -13,31 +13,31 @@ namespace WAL SceneManager &Wal::getSceneManager() { - return this->_scenes; + return this->_sceneManager; } void Wal::run() { auto lastTick = std::chrono::steady_clock::now(); - std::chrono::nanoseconds dtime(0); + std::chrono::nanoseconds fBehind(0); while (!this->_shouldClose) { auto now = std::chrono::steady_clock::now(); - dtime += now - lastTick; + std::chrono::nanoseconds dtime = now - lastTick; + fBehind += dtime; lastTick = now; - this->_update(dtime); - while (dtime > Wal::timestep) { - dtime -= Wal::timestep; + while (fBehind > Wal::timestep) { + fBehind -= Wal::timestep; this->_fixedUpdate(); } - this->_renderer->render(); + this->_update(dtime); } } void Wal::_update(std::chrono::nanoseconds dtime) { - auto &entities = this->_scenes.getCurrent().getEntities(); + auto &entities = this->_sceneManager.getCurrent().getEntities(); for (auto &system : this->_systems) { for (auto &entity : entities) { @@ -47,12 +47,13 @@ namespace WAL // TODO handle dependencies. system->onUpdate(entity, dtime); } + system->onSelfUpdate(); } } void Wal::_fixedUpdate() { - auto &entities = this->_scenes.getCurrent().getEntities(); + auto &entities = this->_sceneManager.getCurrent().getEntities(); for (auto &system : this->_systems) { for (auto &entity : entities) { diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index c8dd535c..ea72eb05 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -10,7 +10,6 @@ #include #include #include "Events/EventManager.hpp" -#include "Renderer/Renderer.hpp" #include "Scene/SceneManager.hpp" #include "Entity/Entity.hpp" #include "System/System.hpp" @@ -22,13 +21,11 @@ namespace WAL { private: //! @brief The scene manager that allow multiple scene to work together. - SceneManager _scenes; + SceneManager _sceneManager; //! @brief The event manager EventManager _eventManager; //! @brief The list of registered systems std::vector> _systems = {}; - //! @brief The renderer used to draw entities - std::unique_ptr _renderer; //! @brief True if the engine should close after the end of the current tick. bool _shouldClose = false;