Skip to content

Commit

Permalink
merge: Merge pull request #22 from G-Epitech/20-refactor-dlloader
Browse files Browse the repository at this point in the history
refactor: DLLoader
  • Loading branch information
Yann-Masson authored Mar 28, 2024
2 parents 4ca0022 + b419ed3 commit 8c8b73e
Show file tree
Hide file tree
Showing 47 changed files with 683 additions and 837 deletions.
4 changes: 2 additions & 2 deletions core/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
** main
*/

#include "loader/DLLoader.hpp"
#include "loader/Loader.hpp"

int main(void)
{
DLLoader loader;
Loader loader;

try {
loader.loadLibraries("./lib");
Expand Down
1 change: 1 addition & 0 deletions core/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(exception)
add_subdirectory(loader)
add_subdirectory(utils)
2 changes: 1 addition & 1 deletion core/src/loader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
DLLoader.cpp
Loader.cpp
)
93 changes: 0 additions & 93 deletions core/src/loader/DLLoader.cpp

This file was deleted.

64 changes: 64 additions & 0 deletions core/src/loader/Loader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
** EPITECH PROJECT, 2024
** arcade
** File description:
** Loader
*/

#include <filesystem>
#include "Loader.hpp"
#include "exception/ArcadeError.hpp"

Loader::Loader() {}

Loader::~Loader() {}

shared::types::LibraryType Loader::_getLibraryGetter(const std::string &filepath, DLLoader &dlLoader) {
shared::types::LibraryTypeGetter getter = nullptr;

getter = dlLoader.loadSymbol<shared::types::LibraryTypeGetter>(SHARED_STRINGIFY(SHARED_LIBRARY_TYPE_GETTER_NAME));
return getter();
}

void Loader::_loadGameLibrary(const std::string &filepath, DLLoader &dlLoader) {
shared::types::GameProviderGetter game = nullptr;

game = dlLoader.loadSymbol<shared::types::GameProviderGetter>(SHARED_STRINGIFY(SHARED_GAME_PROVIDER_GETTER_NAME));
this->_gamesLibraries.push_back(std::unique_ptr<shared::games::IGameProvider>(game()));
}

void Loader::_loadGraphicsLibrary(const std::string &filepath, DLLoader &dlLoader) {
shared::types::GraphicsProviderGetter graphics = nullptr;

graphics = dlLoader.loadSymbol<shared::types::GraphicsProviderGetter>(SHARED_STRINGIFY(SHARED_GRAPHICS_PROVIDER_GETTER_NAME));
this->_graphicsLibraries.push_back(std::unique_ptr<shared::graphics::IGraphicsProvider>(graphics()));
}

void Loader::registerLibrary(const std::string &filepath) {
shared::types::LibraryType type;
DLLoader dlLoader(filepath);

dlLoader.open();
type = this->_getLibraryGetter(filepath, dlLoader);
if (type == shared::types::LibraryType::GAME)
this->_loadGameLibrary(filepath, dlLoader);
else if (type == shared::types::LibraryType::GRAPHIC)
this->_loadGraphicsLibrary(filepath, dlLoader);
else
throw ArcadeError(filepath + ": Unknown library type!");
}

void Loader::loadLibraries(std::string path) {
for (const auto &entry : std::filesystem::directory_iterator(path)) {
if (entry.is_regular_file() && entry.path().extension() == ".so")
this->registerLibrary(entry.path());
}
}

const GameProviders &Loader::getGamesLibraries() const {
return this->_gamesLibraries;
}

const GraphicsProviders &Loader::getGraphicsLibraries() const {
return this->_graphicsLibraries;
}
29 changes: 18 additions & 11 deletions core/src/loader/DLLoader.hpp → core/src/loader/Loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,28 @@
** EPITECH PROJECT, 2024
** arcade
** File description:
** DLLoader
** Loader
*/

#pragma once

#include <iostream>
#include <dirent.h>
#include "types/Providers.hpp"
#include "utils/DLLoader/DLLoader.hpp"

class DLLoader {
class Loader {
public:

/**
* @brief Construct a new Loader object
*/
Loader();

/**
* @brief Destroy the Loader object
*/
~Loader();

/**
* @brief Register a library
* @param path std::string
Expand All @@ -39,36 +49,33 @@ class DLLoader {
const GraphicsProviders &getGraphicsLibraries() const;

private:
DIR *_dir;
const std::string _path;
GameProviders _gamesLibraries;
GraphicsProviders _graphicsLibraries;

/**
* @brief Get the Library Getter object
* @param filepath file path of the library
* @param handle handle pointer to the library
* @return getter function
*/
shared::types::LibraryType _getLibraryGetter(const std::string &filepath, void *handle);
shared::types::LibraryType _getLibraryGetter(const std::string &filepath, DLLoader &dlLoader);

/**
* @brief Load a game library
* @param filepath file path of the library
* @param handle handle pointer to the library
*/
void _loadGameLibrary(const std::string &filepath, void *handle);
void _loadGameLibrary(const std::string &filepath, DLLoader &dlLoader);

/**
* @brief Load a graphics library
* @param filepath file path of the library
* @param handle handle pointer to the library
*/
void _loadGraphicsLibrary(const std::string &filepath, void *handle);
void _loadGraphicsLibrary(const std::string &filepath, DLLoader &dlLoader);

/**
* @brief Throw an error when loading a library
* @param handle handle pointer to the library
* @param e exception
*/
void _throwLoadError(void *handle);
void _throwError(std::exception const &e);
};
4 changes: 2 additions & 2 deletions core/src/types/Providers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@

#include "shared/types/Libraries.hpp"

typedef std::vector<std::shared_ptr<shared::games::IGameProvider>> GameProviders;
typedef std::vector<std::shared_ptr<shared::graphics::IGraphicsProvider>> GraphicsProviders;
typedef std::vector<std::unique_ptr<shared::games::IGameProvider>> GameProviders;
typedef std::vector<std::unique_ptr<shared::graphics::IGraphicsProvider>> GraphicsProviders;
1 change: 1 addition & 0 deletions core/src/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(DLLoader)
3 changes: 3 additions & 0 deletions core/src/utils/DLLoader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
DLLoader.cpp
)
38 changes: 38 additions & 0 deletions core/src/utils/DLLoader/DLLoader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
** EPITECH PROJECT, 2024
** arcade
** File description:
** DLLoader
*/

#include "DLLoader.hpp"

void DLLoader::_throwError() {
std::string error = dlerror();

throw DLLoaderExeption(error.empty() ? "Unknown error while loading library" : error);
}

DLLoader::DLLoader(const std::string &filepath) : _filepath(filepath) {
this->_handle = nullptr;
}

DLLoader::~DLLoader() {
if (this->_handle)
dlclose(this->_handle);
}

void DLLoader::open(DLLoader::LoadingMode mode) {
if (this->_handle)
dlclose(this->_handle);
this->_handle = dlopen(this->_filepath.c_str(), mode);
if (!this->_handle)
this->_throwError();
dlerror();
}

DLLoader::DLLoaderExeption::DLLoaderExeption(const std::string &message) : _message(message) {}

const char *DLLoader::DLLoaderExeption::what() const noexcept {
return this->_message.c_str();
}
79 changes: 79 additions & 0 deletions core/src/utils/DLLoader/DLLoader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
** EPITECH PROJECT, 2024
** arcade
** File description:
** DLLoader
*/

#pragma once

#include <dlfcn.h>
#include <iostream>

class DLLoader {
public:

/**
* @brief Construct a new DLLoader object
*
* @param filepath File path of the library
*/
DLLoader(const std::string &filepath);

~DLLoader();

typedef enum {
LAZY = RTLD_LAZY,
NOW = RTLD_NOW,
LOCAL = RTLD_LOCAL,
GLOBAL = RTLD_GLOBAL,
NODELETE = RTLD_NODELETE,
DEEPBIND = RTLD_DEEPBIND,
NOLOAD = RTLD_NOLOAD
} LoadingMode;

/**
* @brief Open the library
*
* @param mode Loading mode
*/
void open(LoadingMode mode = LAZY);

/**
* @brief Get a function from the library
*
* @tparam T Function prototype
* @param name Symbol name
* @return T Function founded
*/
template <typename T>
T loadSymbol(std::string name) {
if (!this->_handle)
throw DLLoaderExeption("Library not loaded");
T symbol = reinterpret_cast<T>(dlsym(this->_handle, name.c_str()));
if (!symbol)
this->_throwError();
return symbol;
}

class DLLoaderExeption : public std::exception {
public:
DLLoaderExeption(const std::string &message);

const char *what() const noexcept override;

private:
const std::string _message;
};

protected:
private:
void *_handle;
const std::string _filepath;

/**
* @brief Throw an error
*
*/
void _throwError();
};
Loading

0 comments on commit 8c8b73e

Please sign in to comment.