From 14d34829e963a83327f3bb8ad7607f3cbd90329e Mon Sep 17 00:00:00 2001 From: Yann Date: Tue, 26 Mar 2024 11:05:59 +0100 Subject: [PATCH 1/4] fix(back): correctly close directory and dynamic libraries when and error occured --- core/CMakeLists.txt | 8 +++-- core/src/loader/DLLoader.cpp | 45 ++++++++++++++++---------- core/src/loader/DLLoader.hpp | 8 +++++ shared/games/IGame.hpp | 6 ---- shared/graphics/IGraphicsProvider.hpp | 13 ++------ shared/graphics/window/IWindow.hpp | 5 ++- shared/graphics/window/IWindowIcon.hpp | 17 ---------- 7 files changed, 46 insertions(+), 56 deletions(-) delete mode 100644 shared/graphics/window/IWindowIcon.hpp diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 95198b9..dab016a 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,8 +1,10 @@ -add_executable(arcade +project(arcade) +add_executable(${PROJECT_NAME} main.cpp ) -target_include_directories(arcade PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) -target_include_directories(arcade PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) +target_compile_options(${PROJECT_NAME} PUBLIC -fno-gnu-unique) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) add_subdirectory(src) diff --git a/core/src/loader/DLLoader.cpp b/core/src/loader/DLLoader.cpp index a31a2bd..a1fb7e9 100644 --- a/core/src/loader/DLLoader.cpp +++ b/core/src/loader/DLLoader.cpp @@ -6,18 +6,27 @@ */ #include -#include #include #include #include "DLLoader.hpp" #include "exception/ArcadeError.hpp" +void DLLoader::_loadError(void *handle) { + std::string error = dlerror(); + + if (this->_dir) + closedir(this->_dir); + if (handle) + dlclose(handle); + throw ArcadeError(error.length() ? error : "Unknown error while loading library"); +} + shared::types::LibraryType DLLoader::_getLibraryGetter(const std::string &filepath, void *handle) { shared::types::LibraryTypeGetter getter = nullptr; getter = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_LIBRARY_TYPE_GETTER_NAME))); if (!getter) - throw ArcadeError("Cannot find library type getter in library: " + filepath); + this->_loadError(handle); return getter(); } @@ -26,7 +35,7 @@ void DLLoader::_loadGameLibrary(const std::string &filepath, void *handle) { game = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GAME_PROVIDER_LOADER_NAME))); if (!game) - throw ArcadeError("Cannot find game provider in library: " + filepath); + this->_loadError(handle); this->_gamesLibraries.push_back(game()); } @@ -35,42 +44,44 @@ void DLLoader::_loadGraphicsLibrary(const std::string &filepath, void *handle) { graphics = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GRAPHICS_PROVIDER_LOADER_NAME))); if (!graphics) - throw ArcadeError("Cannot find graphics provider in library: " + filepath); + this->_loadError(handle); this->_graphicsLibraries.push_back(graphics()); } void DLLoader::registerLibrary(const std::string &filepath) { - void *handle = dlopen(filepath.c_str(), RTLD_LAZY); + void *handle = dlopen(filepath.c_str(), RTLD_LAZY);; shared::types::LibraryType type; if (!handle) - throw ArcadeError("Cannot load library: " + filepath); + this->_loadError(handle); + dlerror(); type = this->_getLibraryGetter(filepath, handle); if (type == shared::types::LibraryType::GAME) - this->_loadGameLibrary(filepath, handle); + return this->_loadGameLibrary(filepath, handle); else if (type == shared::types::LibraryType::GRAPHIC) - this->_loadGraphicsLibrary(filepath, handle); - else - throw ArcadeError("Unknown library type: " + filepath); + return this->_loadGraphicsLibrary(filepath, handle); + dlclose(handle); + if (this->_dir) + closedir(this->_dir); + throw ArcadeError(filepath + ": Unknown library type!"); } void DLLoader::loadLibraries(std::string path) { - DIR *dir; struct dirent *ent; - dir = opendir(path.c_str()); - if (!dir) + this->_dir = opendir(path.c_str()); + if (!this->_dir) throw ArcadeError("Cannot open directory: " + path); - ent = readdir(dir); + ent = readdir(this->_dir); while (ent) { if (ent->d_name[0] == '.') { - ent = readdir(dir); + ent = readdir(this->_dir); continue; } this->registerLibrary(path + "/" + ent->d_name); - ent = readdir(dir); + ent = readdir(this->_dir); } - closedir(dir); + closedir(this->_dir); } const GameProviders &DLLoader::getGamesLibraries() const { diff --git a/core/src/loader/DLLoader.hpp b/core/src/loader/DLLoader.hpp index ec7b363..4f3c51d 100644 --- a/core/src/loader/DLLoader.hpp +++ b/core/src/loader/DLLoader.hpp @@ -8,6 +8,7 @@ #pragma once #include +#include #include "types/Providers.hpp" class DLLoader { @@ -38,6 +39,7 @@ class DLLoader { const GraphicsProviders &getGraphicsLibraries() const; private: + DIR *_dir; const std::string _path; GameProviders _gamesLibraries; GraphicsProviders _graphicsLibraries; @@ -63,4 +65,10 @@ class DLLoader { * @param handle handle pointer to the library */ void _loadGraphicsLibrary(const std::string &filepath, void *handle); + + /** + * @brief Throw an error when loading a library + * @param handle handle pointer to the library + */ + void _loadError(void *handle); }; diff --git a/shared/games/IGame.hpp b/shared/games/IGame.hpp index d888a3f..291ac21 100644 --- a/shared/games/IGame.hpp +++ b/shared/games/IGame.hpp @@ -39,12 +39,6 @@ class shared::games::IGame */ virtual const GameManifest &getManifest(void) const noexcept = 0; - /** - * @brief The minimum window size required for the game (pixels) - * - */ - virtual const Vector2u getWindowMinSize(void) const noexcept = 0; - /** * @brief Number of tiles that represent the game * Tile size is managed by the renderer diff --git a/shared/graphics/IGraphicsProvider.hpp b/shared/graphics/IGraphicsProvider.hpp index eab2ca9..2d2b7cf 100644 --- a/shared/graphics/IGraphicsProvider.hpp +++ b/shared/graphics/IGraphicsProvider.hpp @@ -49,16 +49,9 @@ class shared::graphics::IGraphicsProvider { /** * @brief Create a texture object * - * @param path Path of the texture file + * @param bin Path of the binary texture file + * @param ascii Path of the ascii texture file * @return Created texture object */ - virtual std::shared_ptr createTexture(const std::string &path) = 0; - - /** - * @brief Create a window icon object - * - * @param path Path of the window icon file - * @return Created window icon object - */ - virtual std::unique_ptr createWindowIcon(const std::string &path) = 0; + virtual std::shared_ptr createTexture(const std::string &bin, const std::string &ascii) = 0; }; diff --git a/shared/graphics/window/IWindow.hpp b/shared/graphics/window/IWindow.hpp index 95fac0f..22f3fc3 100644 --- a/shared/graphics/window/IWindow.hpp +++ b/shared/graphics/window/IWindow.hpp @@ -10,7 +10,6 @@ #include #include -#include "IWindowIcon.hpp" #include "../events/IEvent.hpp" #include "../../types/types.hpp" #include "../types/EntityProps.hpp" @@ -101,14 +100,14 @@ class shared::graphics::IWindow { * * @param icon Icon to use */ - virtual void setIcon(std::unique_ptr icon) = 0; + virtual void setIcon(const std::string &icon) = 0; /** * @brief Get the icon of the window * * @return Icon object of the window */ - virtual const IWindowIcon &getIcon(void) const = 0; + virtual const std::string &getIcon(void) const = 0; /** * @brief Render the entity with given properties diff --git a/shared/graphics/window/IWindowIcon.hpp b/shared/graphics/window/IWindowIcon.hpp deleted file mode 100644 index 9dfdb83..0000000 --- a/shared/graphics/window/IWindowIcon.hpp +++ /dev/null @@ -1,17 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IWindowIcon -*/ - -#pragma once - -namespace shared::graphics { - class IWindowIcon; -} - -class shared::graphics::IWindowIcon { - public: - virtual ~IWindowIcon() = default; -}; From f6baa5fa3f8eb4e797b082aba5e3f0639ea2b134 Mon Sep 17 00:00:00 2001 From: Yann Date: Tue, 26 Mar 2024 11:05:59 +0100 Subject: [PATCH 2/4] fix(back): correctly close directory and dynamic libraries when an error occured --- core/CMakeLists.txt | 8 +++-- core/src/loader/DLLoader.cpp | 45 ++++++++++++++++---------- core/src/loader/DLLoader.hpp | 8 +++++ shared/games/IGame.hpp | 6 ---- shared/graphics/IGraphicsProvider.hpp | 13 ++------ shared/graphics/window/IWindow.hpp | 5 ++- shared/graphics/window/IWindowIcon.hpp | 17 ---------- 7 files changed, 46 insertions(+), 56 deletions(-) delete mode 100644 shared/graphics/window/IWindowIcon.hpp diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 95198b9..dab016a 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,8 +1,10 @@ -add_executable(arcade +project(arcade) +add_executable(${PROJECT_NAME} main.cpp ) -target_include_directories(arcade PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) -target_include_directories(arcade PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) +target_compile_options(${PROJECT_NAME} PUBLIC -fno-gnu-unique) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) add_subdirectory(src) diff --git a/core/src/loader/DLLoader.cpp b/core/src/loader/DLLoader.cpp index a31a2bd..a1fb7e9 100644 --- a/core/src/loader/DLLoader.cpp +++ b/core/src/loader/DLLoader.cpp @@ -6,18 +6,27 @@ */ #include -#include #include #include #include "DLLoader.hpp" #include "exception/ArcadeError.hpp" +void DLLoader::_loadError(void *handle) { + std::string error = dlerror(); + + if (this->_dir) + closedir(this->_dir); + if (handle) + dlclose(handle); + throw ArcadeError(error.length() ? error : "Unknown error while loading library"); +} + shared::types::LibraryType DLLoader::_getLibraryGetter(const std::string &filepath, void *handle) { shared::types::LibraryTypeGetter getter = nullptr; getter = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_LIBRARY_TYPE_GETTER_NAME))); if (!getter) - throw ArcadeError("Cannot find library type getter in library: " + filepath); + this->_loadError(handle); return getter(); } @@ -26,7 +35,7 @@ void DLLoader::_loadGameLibrary(const std::string &filepath, void *handle) { game = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GAME_PROVIDER_LOADER_NAME))); if (!game) - throw ArcadeError("Cannot find game provider in library: " + filepath); + this->_loadError(handle); this->_gamesLibraries.push_back(game()); } @@ -35,42 +44,44 @@ void DLLoader::_loadGraphicsLibrary(const std::string &filepath, void *handle) { graphics = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GRAPHICS_PROVIDER_LOADER_NAME))); if (!graphics) - throw ArcadeError("Cannot find graphics provider in library: " + filepath); + this->_loadError(handle); this->_graphicsLibraries.push_back(graphics()); } void DLLoader::registerLibrary(const std::string &filepath) { - void *handle = dlopen(filepath.c_str(), RTLD_LAZY); + void *handle = dlopen(filepath.c_str(), RTLD_LAZY);; shared::types::LibraryType type; if (!handle) - throw ArcadeError("Cannot load library: " + filepath); + this->_loadError(handle); + dlerror(); type = this->_getLibraryGetter(filepath, handle); if (type == shared::types::LibraryType::GAME) - this->_loadGameLibrary(filepath, handle); + return this->_loadGameLibrary(filepath, handle); else if (type == shared::types::LibraryType::GRAPHIC) - this->_loadGraphicsLibrary(filepath, handle); - else - throw ArcadeError("Unknown library type: " + filepath); + return this->_loadGraphicsLibrary(filepath, handle); + dlclose(handle); + if (this->_dir) + closedir(this->_dir); + throw ArcadeError(filepath + ": Unknown library type!"); } void DLLoader::loadLibraries(std::string path) { - DIR *dir; struct dirent *ent; - dir = opendir(path.c_str()); - if (!dir) + this->_dir = opendir(path.c_str()); + if (!this->_dir) throw ArcadeError("Cannot open directory: " + path); - ent = readdir(dir); + ent = readdir(this->_dir); while (ent) { if (ent->d_name[0] == '.') { - ent = readdir(dir); + ent = readdir(this->_dir); continue; } this->registerLibrary(path + "/" + ent->d_name); - ent = readdir(dir); + ent = readdir(this->_dir); } - closedir(dir); + closedir(this->_dir); } const GameProviders &DLLoader::getGamesLibraries() const { diff --git a/core/src/loader/DLLoader.hpp b/core/src/loader/DLLoader.hpp index ec7b363..4f3c51d 100644 --- a/core/src/loader/DLLoader.hpp +++ b/core/src/loader/DLLoader.hpp @@ -8,6 +8,7 @@ #pragma once #include +#include #include "types/Providers.hpp" class DLLoader { @@ -38,6 +39,7 @@ class DLLoader { const GraphicsProviders &getGraphicsLibraries() const; private: + DIR *_dir; const std::string _path; GameProviders _gamesLibraries; GraphicsProviders _graphicsLibraries; @@ -63,4 +65,10 @@ class DLLoader { * @param handle handle pointer to the library */ void _loadGraphicsLibrary(const std::string &filepath, void *handle); + + /** + * @brief Throw an error when loading a library + * @param handle handle pointer to the library + */ + void _loadError(void *handle); }; diff --git a/shared/games/IGame.hpp b/shared/games/IGame.hpp index d888a3f..291ac21 100644 --- a/shared/games/IGame.hpp +++ b/shared/games/IGame.hpp @@ -39,12 +39,6 @@ class shared::games::IGame */ virtual const GameManifest &getManifest(void) const noexcept = 0; - /** - * @brief The minimum window size required for the game (pixels) - * - */ - virtual const Vector2u getWindowMinSize(void) const noexcept = 0; - /** * @brief Number of tiles that represent the game * Tile size is managed by the renderer diff --git a/shared/graphics/IGraphicsProvider.hpp b/shared/graphics/IGraphicsProvider.hpp index eab2ca9..2d2b7cf 100644 --- a/shared/graphics/IGraphicsProvider.hpp +++ b/shared/graphics/IGraphicsProvider.hpp @@ -49,16 +49,9 @@ class shared::graphics::IGraphicsProvider { /** * @brief Create a texture object * - * @param path Path of the texture file + * @param bin Path of the binary texture file + * @param ascii Path of the ascii texture file * @return Created texture object */ - virtual std::shared_ptr createTexture(const std::string &path) = 0; - - /** - * @brief Create a window icon object - * - * @param path Path of the window icon file - * @return Created window icon object - */ - virtual std::unique_ptr createWindowIcon(const std::string &path) = 0; + virtual std::shared_ptr createTexture(const std::string &bin, const std::string &ascii) = 0; }; diff --git a/shared/graphics/window/IWindow.hpp b/shared/graphics/window/IWindow.hpp index 95fac0f..22f3fc3 100644 --- a/shared/graphics/window/IWindow.hpp +++ b/shared/graphics/window/IWindow.hpp @@ -10,7 +10,6 @@ #include #include -#include "IWindowIcon.hpp" #include "../events/IEvent.hpp" #include "../../types/types.hpp" #include "../types/EntityProps.hpp" @@ -101,14 +100,14 @@ class shared::graphics::IWindow { * * @param icon Icon to use */ - virtual void setIcon(std::unique_ptr icon) = 0; + virtual void setIcon(const std::string &icon) = 0; /** * @brief Get the icon of the window * * @return Icon object of the window */ - virtual const IWindowIcon &getIcon(void) const = 0; + virtual const std::string &getIcon(void) const = 0; /** * @brief Render the entity with given properties diff --git a/shared/graphics/window/IWindowIcon.hpp b/shared/graphics/window/IWindowIcon.hpp deleted file mode 100644 index 9dfdb83..0000000 --- a/shared/graphics/window/IWindowIcon.hpp +++ /dev/null @@ -1,17 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IWindowIcon -*/ - -#pragma once - -namespace shared::graphics { - class IWindowIcon; -} - -class shared::graphics::IWindowIcon { - public: - virtual ~IWindowIcon() = default; -}; From b17e39d7929e81d031d95c23b25283cdbc2b0478 Mon Sep 17 00:00:00 2001 From: Yann Date: Tue, 26 Mar 2024 11:13:52 +0100 Subject: [PATCH 3/4] fix: remove useless line in CMakeList --- core/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 58bc5a2..d9ef558 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -3,7 +3,6 @@ add_executable(${PROJECT_NAME} main.cpp ) -# target_compile_options(${PROJECT_NAME} PUBLIC -fno-gnu-unique) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) From 2c54d50bbfe68975711d1bb3d600bb93f537940d Mon Sep 17 00:00:00 2001 From: Yann Date: Tue, 26 Mar 2024 13:02:19 +0100 Subject: [PATCH 4/4] build: update CMakeList executable from Cmake Project --- core/CMakeLists.txt | 1 - core/src/exception/CMakeLists.txt | 2 +- core/src/loader/CMakeLists.txt | 2 +- core/src/loader/DLLoader.cpp | 10 +++++----- core/src/loader/DLLoader.hpp | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d9ef558..2b63a86 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,4 +1,3 @@ -project(arcade) add_executable(${PROJECT_NAME} main.cpp ) diff --git a/core/src/exception/CMakeLists.txt b/core/src/exception/CMakeLists.txt index a591306..7f3f3dc 100644 --- a/core/src/exception/CMakeLists.txt +++ b/core/src/exception/CMakeLists.txt @@ -1,3 +1,3 @@ -target_sources(arcade PRIVATE +target_sources(${CMAKE_PROJECT_NAME} PRIVATE ArcadeError.cpp ) diff --git a/core/src/loader/CMakeLists.txt b/core/src/loader/CMakeLists.txt index 7b85e37..00db786 100644 --- a/core/src/loader/CMakeLists.txt +++ b/core/src/loader/CMakeLists.txt @@ -1,3 +1,3 @@ -target_sources(arcade PRIVATE +target_sources(${CMAKE_PROJECT_NAME} PRIVATE DLLoader.cpp ) diff --git a/core/src/loader/DLLoader.cpp b/core/src/loader/DLLoader.cpp index a1fb7e9..db5df71 100644 --- a/core/src/loader/DLLoader.cpp +++ b/core/src/loader/DLLoader.cpp @@ -11,7 +11,7 @@ #include "DLLoader.hpp" #include "exception/ArcadeError.hpp" -void DLLoader::_loadError(void *handle) { +void DLLoader::_throwLoadError(void *handle) { std::string error = dlerror(); if (this->_dir) @@ -26,7 +26,7 @@ shared::types::LibraryType DLLoader::_getLibraryGetter(const std::string &filepa getter = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_LIBRARY_TYPE_GETTER_NAME))); if (!getter) - this->_loadError(handle); + this->_throwLoadError(handle); return getter(); } @@ -35,7 +35,7 @@ void DLLoader::_loadGameLibrary(const std::string &filepath, void *handle) { game = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GAME_PROVIDER_LOADER_NAME))); if (!game) - this->_loadError(handle); + this->_throwLoadError(handle); this->_gamesLibraries.push_back(game()); } @@ -44,7 +44,7 @@ void DLLoader::_loadGraphicsLibrary(const std::string &filepath, void *handle) { graphics = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GRAPHICS_PROVIDER_LOADER_NAME))); if (!graphics) - this->_loadError(handle); + this->_throwLoadError(handle); this->_graphicsLibraries.push_back(graphics()); } @@ -53,7 +53,7 @@ void DLLoader::registerLibrary(const std::string &filepath) { shared::types::LibraryType type; if (!handle) - this->_loadError(handle); + this->_throwLoadError(handle); dlerror(); type = this->_getLibraryGetter(filepath, handle); if (type == shared::types::LibraryType::GAME) diff --git a/core/src/loader/DLLoader.hpp b/core/src/loader/DLLoader.hpp index 4f3c51d..b204b4d 100644 --- a/core/src/loader/DLLoader.hpp +++ b/core/src/loader/DLLoader.hpp @@ -70,5 +70,5 @@ class DLLoader { * @brief Throw an error when loading a library * @param handle handle pointer to the library */ - void _loadError(void *handle); + void _throwLoadError(void *handle); };