From 0e920d06f48a4e7b879d40b7e0a9121afca12f58 Mon Sep 17 00:00:00 2001 From: guillaume abel Date: Sun, 1 Oct 2023 01:31:34 +0200 Subject: [PATCH] ECS: Add layer gestion MINOR --- src/Client/Raylib/Graphics/Graphics.cpp | 7 ++- src/Client/Raylib/Graphics/Graphics.hpp | 7 ++- src/Client/Systems/Events/EventsSystems.cpp | 9 ++- src/Client/Systems/Graphic/GraphicSystems.cpp | 59 ++++++++++++----- src/ECS/Registry.cpp | 63 ++++++++++++++++++- src/ECS/Registry.hpp | 36 ++++++++++- src/ECS/SparseArray.hpp | 16 ++++- src/ECS/Systems/Systems.cpp | 39 +++++++++--- 8 files changed, 202 insertions(+), 34 deletions(-) diff --git a/src/Client/Raylib/Graphics/Graphics.cpp b/src/Client/Raylib/Graphics/Graphics.cpp index 1e09d9c5..d8a400a8 100644 --- a/src/Client/Raylib/Graphics/Graphics.cpp +++ b/src/Client/Raylib/Graphics/Graphics.cpp @@ -438,7 +438,11 @@ namespace Raylib { // Texture functions - Sprite::Sprite(const std::string &fileName, float width, float height) + Sprite::Sprite( + const std::string &fileName, + float width, + float height, + std::size_t id) : _texture(LoadTexture(fileName.c_str())), _width(width), _height(height) @@ -449,6 +453,7 @@ namespace Raylib { _texture = LoadTextureFromImage( GenImageColor(badImageSize, badImageSize, badTexture)); } + Registry::getInstance().setToDefaultLayer(id); } Sprite::Sprite(Image image, float width, float height) diff --git a/src/Client/Raylib/Graphics/Graphics.hpp b/src/Client/Raylib/Graphics/Graphics.hpp index f5b1a17f..0bab7d3e 100644 --- a/src/Client/Raylib/Graphics/Graphics.hpp +++ b/src/Client/Raylib/Graphics/Graphics.hpp @@ -11,6 +11,7 @@ #include "raylib.h" #include "Geometry.hpp" #include "Inputs.hpp" +#include "Registry.hpp" namespace Raylib { @@ -143,7 +144,11 @@ namespace Raylib { class Sprite { public: - Sprite(const std::string &fileName, float width, float height); + Sprite( + const std::string &fileName, + float width, + float height, + std::size_t id); Sprite(Image image, float width, float height); unsigned int getId() const; float getWidth() const; diff --git a/src/Client/Systems/Events/EventsSystems.cpp b/src/Client/Systems/Events/EventsSystems.cpp index 293357c2..be1968e1 100644 --- a/src/Client/Systems/Events/EventsSystems.cpp +++ b/src/Client/Systems/Events/EventsSystems.cpp @@ -16,12 +16,11 @@ namespace Systems { std::size_t /*unused*/, std::size_t /*unused*/) { + Registry ®istry = Registry::getInstance(); Registry::components arrPosition = - Registry::getInstance().getComponents(); - - std::vector playerId = Registry::getInstance() - .getComponents() - .getExistingsId(); + registry.getComponents(); + std::vector playerId = + registry.getComponents().getExistingsId(); for (std::size_t id : playerId) { if (Raylib::isKeyDown(Raylib::KeyboardKey::KB_RIGHT)) { diff --git a/src/Client/Systems/Graphic/GraphicSystems.cpp b/src/Client/Systems/Graphic/GraphicSystems.cpp index 756bb20b..ea393845 100644 --- a/src/Client/Systems/Graphic/GraphicSystems.cpp +++ b/src/Client/Systems/Graphic/GraphicSystems.cpp @@ -14,10 +14,11 @@ namespace Systems { void GraphicSystems::rectRenderer(std::size_t /*unused*/, std::size_t /*unused*/) { + Registry ®istry = Registry::getInstance(); Registry::components arrPosition = - Registry::getInstance().getComponents(); + registry.getComponents(); Registry::components arrRect = - Registry::getInstance().getComponents(); + registry.getComponents(); std::vector rectShapeIndexes = arrRect.getExistingsId(); const float denominator = 100.0; @@ -104,27 +105,50 @@ namespace Systems { tint); } - void GraphicSystems::spriteRenderer( - std::size_t /*unused*/, - std::size_t /*unused*/) + static void renderEntityList(std::vector list) { + Registry ®istry = Registry::getInstance(); Registry::components arrSprite = - Registry::getInstance().getComponents(); + registry.getComponents(); Registry::components arrRect = - Registry::getInstance().getComponents(); + registry.getComponents(); Registry::components arrPosition = - Registry::getInstance().getComponents(); - std::vector spriteIndexes = arrSprite.getExistingsId(); - - for (auto id : spriteIndexes) { - if (arrRect.exist(id) && arrPosition.exist(id)) { - drawSpriteWithRect(arrPosition[id], arrSprite[id], arrRect[id]); - } else if (arrPosition.exist(id)) { - drawSpriteWithoutRect(arrPosition[id], arrSprite[id]); + registry.getComponents(); + + for (auto id : list) { + if (arrPosition.exist(id)) { + if (arrRect.exist(id)) { + drawSpriteWithRect( + arrPosition[id], + arrSprite[id], + arrRect[id]); + } else { + drawSpriteWithoutRect(arrPosition[id], arrSprite[id]); + } } } } + void GraphicSystems::spriteRenderer( + std::size_t /*unused*/, + std::size_t /*unused*/) + { + Registry ®istry = Registry::getInstance(); + std::vector> backLayers = + registry.getBackLayers(); + std::vector defaultLayer = registry.getDefaultLayer(); + std::vector> frontLayers = + registry.getFrontLayers(); + + for (auto list : backLayers) { + renderEntityList(list); + } + renderEntityList(defaultLayer); + for (auto list : frontLayers) { + renderEntityList(list); + } + } + void GraphicSystems::soundEffectPlayer( std::size_t /*unused*/, std::size_t /*unused*/) @@ -195,10 +219,11 @@ namespace Systems { std::size_t /*unused*/, std::size_t /*unused*/) { + Registry ®istry = Registry::getInstance(); Registry::components arrMusics = - Registry::getInstance().getComponents(); + registry.getComponents(); Registry::components arrSounds = - Registry::getInstance().getComponents(); + registry.getComponents(); for (auto &music : arrMusics) { if (music.getPath() == musicPath diff --git a/src/ECS/Registry.cpp b/src/ECS/Registry.cpp index 008c44e6..03c1a22d 100644 --- a/src/ECS/Registry.cpp +++ b/src/ECS/Registry.cpp @@ -17,12 +17,13 @@ Registry &Registry::getInstance() return _instance; } -void Registry::addEntity() +std::size_t Registry::addEntity() { for (auto function : _addComponentPlaceFunctions) { function(*this); } _entitiesNb++; + return _entitiesNb - 1; } void Registry::removeEntity(std::size_t id) @@ -40,6 +41,66 @@ void Registry::clear() _entitiesNb = 0; } +void Registry::setToBackLayers(std::size_t id, BackLayers layer) +{ + removeFromDefaultLayer(id); + _backLayers[layer].push_back(id); +} + +void Registry::setToDefaultLayer(std::size_t id) +{ + _defaultLayer.push_back(id); +} + +void Registry::setToFrontLayers(std::size_t id, FrontLayers layer) +{ + _backLayers[layer].push_back(id); +} + +std::vector> Registry::getBackLayers() +{ + return _backLayers; +} + +std::vector Registry::getDefaultLayer() +{ + return _defaultLayer; +} + +std::vector> Registry::getFrontLayers() +{ + return _frontLayers; +} + +void Registry::initLayers(bool back) +{ + auto max = static_cast( + back ? BackLayers::BACKMAX : FrontLayers::FRONTMAX); + + for (std::size_t i = 0; i < max; i++) { + std::vector> &layers = + back ? _backLayers : _frontLayers; + layers.emplace_back(); + } + if (back) { + initLayers(false); + } +} + +void Registry::removeFromDefaultLayer(std::size_t id) +{ + auto i = _defaultLayer.end(); + + while (i != _defaultLayer.begin()) { + --i; + if (*i == id) { + _defaultLayer.erase(i); + break; + } + } +} + Registry::Registry() : _entitiesNb(0) { + initLayers(true); } diff --git a/src/ECS/Registry.hpp b/src/ECS/Registry.hpp index 88e520ca..311c2839 100644 --- a/src/ECS/Registry.hpp +++ b/src/ECS/Registry.hpp @@ -19,6 +19,17 @@ #include "SceneManager.hpp" #include "SparseArray.hpp" +enum LayerType { BACKLAYER, FRONTLAYER, DEFAULTLAYER }; + +enum BackLayers { BACK = 0, BACKMAX }; + +/* + * FRONT is the frontest layer, so when adding a new one increment the FRONT + * value and add the new one above + */ + +enum FrontLayers { FRONT = 0, FRONTMAX }; + class Registry { public: template @@ -33,12 +44,27 @@ class Registry { return castReturn(); } - void addEntity(); + std::size_t addEntity(); void removeEntity(std::size_t /*id*/); void clear(); + void + setToBackLayers(std::size_t id, BackLayers layer = BackLayers::BACK); + + void setToDefaultLayer(std::size_t id); + + void setToFrontLayers( + std::size_t id, + FrontLayers layer = FrontLayers::FRONT); + + std::vector> getBackLayers(); + + std::vector getDefaultLayer(); + + std::vector> getFrontLayers(); + Registry &operator=(const Registry &) = delete; Registry(const Registry &) = delete; void operator=(const Registry &&) = delete; @@ -47,6 +73,10 @@ class Registry { private: Registry(); + void initLayers(bool back); + + void removeFromDefaultLayer(std::size_t id); + template void checkAddSparseArray() { @@ -93,4 +123,8 @@ class Registry { std::unordered_map _data; std::size_t _entitiesNb; + + std::vector> _backLayers; + std::vector _defaultLayer; + std::vector> _frontLayers; }; diff --git a/src/ECS/SparseArray.hpp b/src/ECS/SparseArray.hpp index d571451e..5c468755 100644 --- a/src/ECS/SparseArray.hpp +++ b/src/ECS/SparseArray.hpp @@ -66,6 +66,12 @@ class SparseArray { return _dense[_sparse[id]]; } + /* + * A dense sparseArrays is not sort by entities id, the begin of two + * sparseArrays could be different entities, only _sparse are + * synchronized You can only use iterator in a system dealing with only + * one component at time + */ typename std::vector::iterator begin() { return _dense.begin(); @@ -78,7 +84,15 @@ class SparseArray { bool exist(std::size_t id) { - return id < _sparse.size() && _sparse[id] != -1; + if (id >= _sparse.size()) { + return false; + } + for (auto elemId : _revSparse) { + if (id == elemId) { + return true; + } + } + return false; } std::vector getExistingsId() diff --git a/src/ECS/Systems/Systems.cpp b/src/ECS/Systems/Systems.cpp index a55f6cb9..2a9ad6ff 100644 --- a/src/ECS/Systems/Systems.cpp +++ b/src/ECS/Systems/Systems.cpp @@ -15,14 +15,14 @@ namespace Systems { void windowCollision(std::size_t /*unused*/, std::size_t /*unused*/) { + Registry ®istry = Registry::getInstance(); Registry::components arrPosition = - Registry::getInstance().getComponents(); + registry.getComponents(); Registry::components arrCollisionRect = - Registry::getInstance().getComponents(); + registry.getComponents(); - std::vector playerIdx = Registry::getInstance() - .getComponents() - .getExistingsId(); + std::vector playerIdx = + registry.getComponents().getExistingsId(); const float maxPercent = 100.0F; for (std::size_t id : playerIdx) { @@ -56,17 +56,42 @@ namespace Systems { void init(std::size_t managerId, std::size_t systemId) { - Registry::getInstance().addEntity(); + std::size_t id = Registry::getInstance().addEntity(); Registry::getInstance().getComponents().insertBack( {playerData, playerData}); Registry::getInstance().getComponents().insertBack( - {playerPath, playerWidth, playerHeight}); + {playerPath, playerWidth, playerHeight, id}); + Registry::getInstance().getComponents().insertBack( + spriteRect); + Registry::getInstance() + .getComponents() + .insertBack(collisionRect); + Registry::getInstance().setToBackLayers(id); + + id = Registry::getInstance().addEntity(); + Registry::getInstance().getComponents().insertBack( + {playerData, playerData}); + Registry::getInstance().getComponents().insertBack( + {playerPath, playerWidth, playerHeight, id}); Registry::getInstance().getComponents().insertBack( spriteRect); Registry::getInstance() .getComponents() .insertBack(collisionRect); Registry::getInstance().getComponents().insertBack({}); + + id = Registry::getInstance().addEntity(); + Registry::getInstance().getComponents().insertBack( + {playerData, playerData + playerData + playerData}); + Registry::getInstance().getComponents().insertBack( + {playerPath, playerWidth, playerHeight, id}); + Registry::getInstance().getComponents().insertBack( + spriteRect); + Registry::getInstance() + .getComponents() + .insertBack(collisionRect); + Registry::getInstance().setToFrontLayers(id); + Registry::getInstance().getComponents().insertBack( {musicPath, musicVolume}); Registry::getInstance().getComponents().insertBack(