diff --git a/lib/Ray/CMakeLists.txt b/lib/Ray/CMakeLists.txt index 17d97db0..d713eb1e 100644 --- a/lib/Ray/CMakeLists.txt +++ b/lib/Ray/CMakeLists.txt @@ -56,6 +56,7 @@ set(HEADERS sources/Model/ModelAnimations.hpp sources/Vector/Vector2.hpp sources/Vector/Vector3.hpp + sources/Utils/Cache.hpp ) set(SRC diff --git a/lib/Ray/sources/Drawables/Image.cpp b/lib/Ray/sources/Drawables/Image.cpp index d7c357df..9676bc95 100644 --- a/lib/Ray/sources/Drawables/Image.cpp +++ b/lib/Ray/sources/Drawables/Image.cpp @@ -10,11 +10,11 @@ #include "Drawables/2D/Rectangle.hpp" namespace RAY { - std::unordered_map> Image::_ImageCache; + Cache<::Image> Image::_imagesCache(LoadImage, UnloadImage); Image::Image(const std::string &filename): Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE), - _image(fetchImageInCache(filename)) + _image(_imagesCache.fetch(filename)) { this->_dimensions = Vector2(this->_image->width, this->_image->height); } @@ -35,17 +35,6 @@ namespace RAY { return this->_image.get(); } - std::shared_ptr<::Image> Image::fetchImageInCache(const std::string &path) - { - if (Image::_ImageCache.find(path) == Image::_ImageCache.end()) - Image::_ImageCache.emplace(path, std::shared_ptr<::Image>( - new ::Image(LoadImage(path.c_str())), [](::Image *p) { - UnloadImage(*p); - delete p; - })); - return _ImageCache[path]; - } - void Image::draw(Drawables::ADrawable2D &drawable) { drawable.drawOn(*this); diff --git a/lib/Ray/sources/Drawables/Image.hpp b/lib/Ray/sources/Drawables/Image.hpp index 6f6355bf..840be518 100644 --- a/lib/Ray/sources/Drawables/Image.hpp +++ b/lib/Ray/sources/Drawables/Image.hpp @@ -11,8 +11,7 @@ #include #include #include "Texture.hpp" -#include -#include +#include "Utils/Cache.hpp" #include "Drawables/2D/Rectangle.hpp" namespace RAY @@ -50,10 +49,8 @@ namespace RAY private: //! @brief Image, really, that's just it... std::shared_ptr<::Image> _image; - //! @brief, look through cache to see if a model using same file - std::shared_ptr<::Image>fetchImageInCache(const std::string &path); - static std::unordered_map> _ImageCache; + static Cache<::Image> _imagesCache; INTERNAL: diff --git a/lib/Ray/sources/Drawables/Texture.cpp b/lib/Ray/sources/Drawables/Texture.cpp index 93b3d36b..befe8579 100644 --- a/lib/Ray/sources/Drawables/Texture.cpp +++ b/lib/Ray/sources/Drawables/Texture.cpp @@ -9,10 +9,10 @@ namespace RAY { - std::unordered_map> Texture::_textureCache; + Cache<::Texture> Texture::_texturesCache(LoadTexture, UnloadTexture); Texture::Texture(const std::string &filename): - _texture(fetchTextureInCache(filename)), + _texture(_texturesCache.fetch(filename)), _resourcePath(filename) { } @@ -27,15 +27,4 @@ namespace RAY { { return *this->_texture; } - - std::shared_ptr<::Texture> Texture::fetchTextureInCache(const std::string &path) - { - if (Texture::_textureCache.find(path) == Texture::_textureCache.end()) - Texture::_textureCache.emplace(path, std::shared_ptr<::Texture>( - new ::Texture(LoadTexture(path.c_str())), [](::Texture *p) { - UnloadTexture(*p); - delete p; - })); - return _textureCache[path]; - } } diff --git a/lib/Ray/sources/Drawables/Texture.hpp b/lib/Ray/sources/Drawables/Texture.hpp index 265a63c2..6fb2be66 100644 --- a/lib/Ray/sources/Drawables/Texture.hpp +++ b/lib/Ray/sources/Drawables/Texture.hpp @@ -10,8 +10,7 @@ #include #include -#include -#include +#include "Utils/Cache.hpp" namespace RAY { @@ -42,10 +41,7 @@ namespace RAY //! @brief path to the file the texture is loaded from std::string _resourcePath; - //! @param path path of the file to load - //! @return a newly loaded texture if it hasn't be previously loaded, or one from cache - std::shared_ptr<::Texture> fetchTextureInCache(const std::string &path); - static std::unordered_map> _textureCache; + static Cache<::Texture> _texturesCache; INTERNAL: //! @return libray Texture struct diff --git a/lib/Ray/sources/Font.cpp b/lib/Ray/sources/Font.cpp index 00711def..c4288463 100644 --- a/lib/Ray/sources/Font.cpp +++ b/lib/Ray/sources/Font.cpp @@ -7,16 +7,14 @@ #include "Font.hpp" +RAY::Cache<::Font> RAY::Font::_fontsCache(LoadFont, UnloadFont); + RAY::Font::Font(const std::string &filename): - _font(LoadFont(filename.c_str())) + _font(_fontsCache.fetch(filename)) { } -RAY::Font::Font() +RAY::Font::Font(): + _font(std::make_shared<::Font>()) { } - -RAY::Font::~Font() -{ - UnloadFont(this->_font); -} diff --git a/lib/Ray/sources/Font.hpp b/lib/Ray/sources/Font.hpp index 1ad65a1e..a403dcb3 100644 --- a/lib/Ray/sources/Font.hpp +++ b/lib/Ray/sources/Font.hpp @@ -10,6 +10,7 @@ #include #include +#include "Utils/Cache.hpp" namespace RAY { @@ -29,13 +30,15 @@ namespace RAY //! @brief An font is assignable Font &operator=(const Font &) = default; - //! @brief Unload font at destruction - ~Font(); + //! @brief Default destructor + ~Font() = default; protected: private: //! @brief Font, really, that's just it... - ::Font _font; + std::shared_ptr<::Font> _font; + + static Cache<::Font> _fontsCache; }; } diff --git a/lib/Ray/sources/Model/Model.cpp b/lib/Ray/sources/Model/Model.cpp index 8554a40c..92bf427c 100644 --- a/lib/Ray/sources/Model/Model.cpp +++ b/lib/Ray/sources/Model/Model.cpp @@ -12,7 +12,8 @@ namespace RAY::Drawables::Drawables3D { - std::unordered_map> Model::_modelsCache; + RAY::Cache<::Model> Model::_modelsCache(LoadModel, UnloadModel); + Model::Model(const std::string &filename, std::optional> texture, const RAY::Vector3 &position, @@ -20,7 +21,7 @@ namespace RAY::Drawables::Drawables3D { float rotationAngle, const RAY::Vector3 &scale) : ADrawable3D(position, WHITE), - _model(fetchModelInCache(filename)), + _model(_modelsCache.fetch(filename)), _rotationAxis(rotationAxis), _rotationAngle(rotationAngle), _scale(scale) @@ -105,15 +106,4 @@ namespace RAY::Drawables::Drawables3D { { DrawModelEx(*this->_model, this->_position, this->_rotationAxis, this->_rotationAngle, this->_scale, this->_color); } - - std::shared_ptr<::Model> Model::fetchModelInCache(const std::string &path) - { - if (Model::_modelsCache.find(path) == Model::_modelsCache.end()) - Model::_modelsCache.emplace(path, std::shared_ptr<::Model>( - new ::Model(LoadModel(path.c_str())), [](::Model *p) { - UnloadModel(*p); - delete p; - })); - return _modelsCache[path]; - } } \ No newline at end of file diff --git a/lib/Ray/sources/Model/Model.hpp b/lib/Ray/sources/Model/Model.hpp index 47689edb..8ab6a6e4 100644 --- a/lib/Ray/sources/Model/Model.hpp +++ b/lib/Ray/sources/Model/Model.hpp @@ -14,8 +14,7 @@ #include #include #include -#include -#include +#include "Utils/Cache.hpp" namespace RAY::Drawables::Drawables3D { //! @brief Basic 3D Model type @@ -91,10 +90,8 @@ namespace RAY::Drawables::Drawables3D { float _rotationAngle; //! @brief Scale of the shape RAY::Vector3 _scale; - //! @brief, look through cache to see if a model using same file - std::shared_ptr<::Model>fetchModelInCache(const std::string &path); - static std::unordered_map> _modelsCache; + static RAY::Cache<::Model> _modelsCache; INTERNAL: //! @brief A RAY Model is cast-able in libray's model diff --git a/lib/Ray/sources/Model/ModelAnimations.cpp b/lib/Ray/sources/Model/ModelAnimations.cpp index 224b9979..0bd88c03 100644 --- a/lib/Ray/sources/Model/ModelAnimations.cpp +++ b/lib/Ray/sources/Model/ModelAnimations.cpp @@ -7,8 +7,10 @@ #include "Model/ModelAnimations.hpp" +RAY::Cache<::ModelAnimation> RAY::ModelAnimations::_animationsCache(LoadModelAnimations, UnloadModelAnimations); + RAY::ModelAnimations::ModelAnimations(const std::string &filePath): - _animationsPtr(LoadModelAnimations(filePath.c_str(), &this->_animationCount)) + _animationsPtr(_animationsCache.fetch(filePath, &this->_animationCount)) { ::ModelAnimation *ptr = this->_animationsPtr.get(); @@ -16,11 +18,6 @@ RAY::ModelAnimations::ModelAnimations(const std::string &filePath): this->_animations.push_back(RAY::ModelAnimation(ptr[i])); } -RAY::ModelAnimations::~ModelAnimations() -{ - UnloadModelAnimations(this->_animationsPtr.release(), this->_animationCount); -} - RAY::ModelAnimation &RAY::ModelAnimations::operator[](int index) { return this->_animations[index]; diff --git a/lib/Ray/sources/Model/ModelAnimations.hpp b/lib/Ray/sources/Model/ModelAnimations.hpp index cad0d038..ba46a0e4 100644 --- a/lib/Ray/sources/Model/ModelAnimations.hpp +++ b/lib/Ray/sources/Model/ModelAnimations.hpp @@ -11,6 +11,7 @@ #include "Model/ModelAnimation.hpp" #include #include +#include "Utils/Cache.hpp" namespace RAY { //! @brief A Holder for Model Animations @@ -23,8 +24,8 @@ namespace RAY { //! @brief Only single entity can hold these animations pointers ModelAnimations(const ModelAnimations &) = delete; - //! @brief Unloads all animations - ~ModelAnimations(); + //! @brief Default constructor + ~ModelAnimations() = default; //! @brief Only single entity can hold these animations pointers ModelAnimations &operator=(const ModelAnimations &) = delete; @@ -37,13 +38,15 @@ namespace RAY { private: //! @brief Holds the pointer returned by the loading function - std::unique_ptr<::ModelAnimation> _animationsPtr; + std::shared_ptr<::ModelAnimation> _animationsPtr; //! @brief A holder for animations std::vector _animations; //! @brief the number of loaded animations int _animationCount; + + static Cache<::ModelAnimation> _animationsCache; }; } diff --git a/lib/Ray/sources/Utils/Cache.hpp b/lib/Ray/sources/Utils/Cache.hpp new file mode 100644 index 00000000..c8566578 --- /dev/null +++ b/lib/Ray/sources/Utils/Cache.hpp @@ -0,0 +1,81 @@ +/* +** EPITECH PROJECT, 2021 +** Bomberman +** File description: +** Cache +*/ + +#pragma once +#include +#include +#include + +namespace RAY { + //! @brief A templated class used to cache ressources, indexed with a string + template + class Cache { + public: + //! @brief + Cache(std::function dataLoader, std::function dataUnloader): + _dataLoader(dataLoader), _dataUnloader(dataUnloader) + {}; + + //! @brief Default destructor, will destroy ray's data + ~Cache() = default; + + //! @brief default copy constructor + Cache(const Cache &) = default; + + //! @brief a cache is assignable + Cache &operator=(const Cache &) = default; + + //! @param path path of the file + //! @return a newly loaded ressource if it hasn't be previously loaded, or one from cache + std::shared_ptrfetch(const std::string &path) + { + if (this->_cache.find(path) == this->_cache.end()) + this->_cache.emplace(path, std::shared_ptr( + new T(this->_dataLoader(path.c_str())), [this](T *p) { + this->_dataUnloader(*p); + delete p; + })); + return _cache[path]; + }; + private: + //! @brief function to call to load data + std::function _dataLoader; + + //! @brief function to call when the ray data will be unloaded + std::function _dataUnloader; + + //! @brief map storing shared ptr of caches + std::unordered_map> _cache; + }; + + template<> + class Cache<::ModelAnimation> { + public: + Cache(std::function<::ModelAnimation *(const char *, int *)> dataLoader, std::functiondataUnloader): + _dataLoader(dataLoader), _dataUnloader(dataUnloader) + {}; + std::shared_ptr<::ModelAnimation> fetch(const std::string &path, int *counter) + { + if (this->_cache.find(path) == this->_cache.end()) + this->_cache.emplace(path, std::shared_ptr<::ModelAnimation>( + this->_dataLoader(path.c_str(), counter), [this, counter](::ModelAnimation *p) { + this->_dataUnloader(p, *counter); + delete p; + })); + return _cache[path]; + }; + private: + //! @brief function to call to load data + std::function<::ModelAnimation *(const char *, int *)> _dataLoader; + + //! @brief function to call when the ray data will be unloaded + std::function _dataUnloader; + + //! @brief map storing shared ptr of caches + std::unordered_map> _cache; + }; +}