Skip to content

Commit

Permalink
merge: Merge pull request #11 from G-Epitech/8-library-loader
Browse files Browse the repository at this point in the history
Library loader
  • Loading branch information
Yann-Masson authored Mar 22, 2024
2 parents c7f6dd3 + a280446 commit 7e0cc36
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 6 deletions.
2 changes: 1 addition & 1 deletion common/games/IGameProvider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ class shared::games::IGameProvider
*
* @return Created game instance
*/
virtual std::shared_ptr<game::IGame> createInstance(void) = 0;
virtual std::shared_ptr<shared::games::IGame> createInstance(void) = 0;
};
4 changes: 2 additions & 2 deletions common/games/export.cpp.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
*/

#include "IGame.hpp"
#include "../types/LibraryType.hpp"
#include "../types/Libraries.hpp"

extern "C" {
shared::types::LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void)
{
return shared::types::LibraryType::GAME;
}

std::shared_ptr<shared::games::IGame> SHARED_GRAPHICS_FACTORY_LOADER_NAME(void)
std::shared_ptr<shared::games::IGameProvider> SHARED_GAME_PROVIDER_LOADER_NAME(void)
{
return std::make_shared<GameClass>(...)
}
Expand Down
2 changes: 1 addition & 1 deletion common/graphics/IGraphicsProvider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class shared::graphics::IGraphicsProvider {
*
* @return Manifest of the graphics library
*/
virtual const GameManifest &getManifest(void) const noexcept = 0;
virtual const GraphicsManifest &getManifest(void) const noexcept = 0;

/**
* @brief Create a renderer object
Expand Down
2 changes: 1 addition & 1 deletion common/graphics/export.cpp.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern "C" {
return shared::types::LibraryType::GRAPHIC;
}

std::shared_ptr<shared::graphics::IGraphicsFactory> SHARED_GAME_PROVIDER_LOADER_NAME(void)
std::shared_ptr<shared::graphics::IGraphicsProvider> SHARED_GRAPHICS_PROVIDER_LOADER_NAME(void)
{
return std::make_shared<RendererClass>(...);
}
Expand Down
3 changes: 2 additions & 1 deletion common/types/Libraries.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
#define SHARED_GAME_PROVIDER_LOADER_NAME arcadeLibGetGameProvider
#define SHARED_GRAPHICS_PROVIDER_LOADER_NAME arcadeLibGetGraphicsProvider
#define SHARED_LIBRARY_TYPE_GETTER_NAME arcadeLibGetType
#define SHARED_STRINGIFY(x) #x
#define STRINGIFY(x) #x
#define SHARED_STRINGIFY(x) STRINGIFY(x)

namespace shared::types
{
Expand Down
5 changes: 5 additions & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
add_executable(arcade
main.cpp
)

target_include_directories(arcade PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..)
target_include_directories(arcade PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src)

add_subdirectory(src)
11 changes: 11 additions & 0 deletions core/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@
** main
*/

#include "loader/DLLoader.hpp"

int main(void)
{
DLLoader loader;

try {
loader.loadLibraries("./lib");
std::cout << "Games libraries:" << loader.getGamesLibraries().size() << std::endl;
std::cout << "Graphics libraries:" << loader.getGraphicsLibraries().size() << std::endl;
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
2 changes: 2 additions & 0 deletions core/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_subdirectory(exception)
add_subdirectory(loader)
14 changes: 14 additions & 0 deletions core/src/exception/ArcadeError.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
** EPITECH PROJECT, 2024
** arcade
** File description:
** ArcadeError
*/

#include "ArcadeError.hpp"

ArcadeError::ArcadeError(std::string const &message) : _message(message) {}

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

#pragma once

#include <iostream>

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

const char *what() const noexcept;
private:
const std::string _message;
};
3 changes: 3 additions & 0 deletions core/src/exception/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target_sources(arcade PRIVATE
ArcadeError.cpp
)
3 changes: 3 additions & 0 deletions core/src/loader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target_sources(arcade PRIVATE
DLLoader.cpp
)
82 changes: 82 additions & 0 deletions core/src/loader/DLLoader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
** EPITECH PROJECT, 2024
** arcade
** File description:
** DLLoader
*/

#include <dlfcn.h>
#include <dirent.h>
#include <memory.h>
#include <iostream>
#include "DLLoader.hpp"
#include "exception/ArcadeError.hpp"

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

getter = reinterpret_cast<shared::types::LibraryTypeGetter>(dlsym(handle, SHARED_STRINGIFY(SHARED_LIBRARY_TYPE_GETTER_NAME)));
if (!getter)
throw ArcadeError("Cannot find library type getter in library: " + filepath);
return getter();
}

void DLLoader::_loadGameLibrary(const std::string &filepath, void *handle) {
shared::types::GameProvider game = nullptr;

game = reinterpret_cast<shared::types::GameProvider>(dlsym(handle, SHARED_STRINGIFY(SHARED_GAME_PROVIDER_LOADER_NAME)));
if (!game)
throw ArcadeError("Cannot find game provider in library: " + filepath);
this->_gamesLibraries.push_back(game());
}

void DLLoader::_loadGraphicsLibrary(const std::string &filepath, void *handle) {
shared::types::GraphicsProvider graphics = nullptr;

graphics = reinterpret_cast<shared::types::GraphicsProvider>(dlsym(handle, SHARED_STRINGIFY(SHARED_GRAPHICS_PROVIDER_LOADER_NAME)));
if (!graphics)
throw ArcadeError("Cannot find graphics provider in library: " + filepath);
this->_graphicsLibraries.push_back(graphics());
}

void DLLoader::registerLibrary(const std::string &filepath) {
void *handle = dlopen(filepath.c_str(), RTLD_LAZY);
shared::types::LibraryType type;

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

void DLLoader::loadLibraries(std::string path) {
DIR *dir;
struct dirent *ent;

dir = opendir(path.c_str());
if (!dir)
throw ArcadeError("Cannot open directory: " + path);
ent = readdir(dir);
while (ent) {
if (ent->d_name[0] == '.') {
ent = readdir(dir);
continue;
}
this->registerLibrary(path + "/" + ent->d_name);
ent = readdir(dir);
}
closedir(dir);
}

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

const GraphicsProviders &DLLoader::getGraphicsLibraries() const {
return this->_graphicsLibraries;
}
66 changes: 66 additions & 0 deletions core/src/loader/DLLoader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
** EPITECH PROJECT, 2024
** arcade
** File description:
** DLLoader
*/

#pragma once

#include <iostream>
#include "types/Providers.hpp"

class DLLoader {
public:

/**
* @brief Register a library
* @param path std::string
*/
void registerLibrary(const std::string &filepath);

/**
* @brief Load all libraries in the given folder path
* @param path std::string
*/
void loadLibraries(std::string path);

/**
* @brief Get all games libraries
* @return Loaded games libraries
*/
const GameProviders &getGamesLibraries() const;

/**
* @brief Get all graphics libraries
* @return Loaded graphics libraries
*/
const GraphicsProviders &getGraphicsLibraries() const;

private:
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);

/**
* @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);

/**
* @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);
};
13 changes: 13 additions & 0 deletions core/src/types/Providers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
** EPITECH PROJECT, 2024
** arcade
** File description:
** Providers
*/

#pragma once

#include "common/types/Libraries.hpp"

typedef std::vector<std::shared_ptr<shared::games::IGameProvider>> GameProviders;
typedef std::vector<std::shared_ptr<shared::graphics::IGraphicsProvider>> GraphicsProviders;

0 comments on commit 7e0cc36

Please sign in to comment.