From cf19c5b086294dda6d4350e9f7e9633c05724a0f Mon Sep 17 00:00:00 2001 From: Joseph Walton-Rivers <joseph@walton-rivers.uk> Date: Mon, 27 Jun 2022 21:24:43 +0100 Subject: [PATCH] new module system replacing the old one --- demo/demo/main.cpp | 47 ++- demo/demo/rollball.cpp | 2 +- fggl/app.cpp | 18 +- fggl/audio/openal/audio.cpp | 3 - fggl/debug/debug.cpp | 3 +- fggl/gfx/ogl/renderer.cpp | 8 +- fggl/gfx/ogl4/canvas.cpp | 1 - fggl/gfx/window.cpp | 323 +++++++++--------- fggl/gui/fonts.cpp | 2 +- fggl/scenes/game.cpp | 2 +- fggl/scenes/menu.cpp | 2 +- include/fggl/app.hpp | 26 +- include/fggl/audio/audio.hpp | 7 +- include/fggl/audio/null_audio.hpp | 19 +- include/fggl/audio/openal/audio.hpp | 3 +- include/fggl/audio/openal/module.hpp | 52 +++ include/fggl/data/module.hpp | 51 +++ include/fggl/data/storage.hpp | 5 +- include/fggl/debug/debug.h | 4 +- include/fggl/display/glfw/module.hpp | 57 ++++ include/fggl/display/glfw/services.hpp | 52 +++ include/fggl/{gfx => display/glfw}/window.hpp | 47 ++- .../{gfx => display/glfw}/window_input.hpp | 20 +- .../{gfx/windowing.hpp => display/window.hpp} | 53 ++- include/fggl/fggl.hpp | 10 + include/fggl/gfx/compat.hpp | 68 ---- include/fggl/gfx/interfaces.hpp | 52 +++ include/fggl/gfx/ogl/backend.hpp | 2 +- include/fggl/gfx/ogl/renderer.hpp | 3 +- include/fggl/gfx/ogl4/canvas.hpp | 2 +- include/fggl/gfx/ogl4/module.hpp | 57 ++++ include/fggl/gfx/ogl4/setup.hpp | 56 +++ include/fggl/gfx/setup.hpp | 48 +++ include/fggl/gui/fonts.hpp | 9 +- include/fggl/gui/module.hpp | 49 +++ include/fggl/input/input.hpp | 6 + include/fggl/input/module.hpp | 47 +++ include/fggl/modules/manager.hpp | 206 +++++++++++ include/fggl/modules/module.hpp | 91 +++++ include/fggl/subsystem/cursed/god_object.hpp | 6 - 40 files changed, 1165 insertions(+), 354 deletions(-) create mode 100644 include/fggl/audio/openal/module.hpp create mode 100644 include/fggl/data/module.hpp create mode 100644 include/fggl/display/glfw/module.hpp create mode 100644 include/fggl/display/glfw/services.hpp rename include/fggl/{gfx => display/glfw}/window.hpp (73%) rename include/fggl/{gfx => display/glfw}/window_input.hpp (73%) rename include/fggl/{gfx/windowing.hpp => display/window.hpp} (63%) delete mode 100644 include/fggl/gfx/compat.hpp create mode 100644 include/fggl/gfx/interfaces.hpp create mode 100644 include/fggl/gfx/ogl4/module.hpp create mode 100644 include/fggl/gfx/ogl4/setup.hpp create mode 100644 include/fggl/gfx/setup.hpp create mode 100644 include/fggl/gui/module.hpp create mode 100644 include/fggl/input/module.hpp create mode 100644 include/fggl/modules/manager.hpp create mode 100644 include/fggl/modules/module.hpp diff --git a/demo/demo/main.cpp b/demo/demo/main.cpp index 59a6cb0..617b83c 100644 --- a/demo/demo/main.cpp +++ b/demo/demo/main.cpp @@ -25,23 +25,18 @@ #include "fggl/phys/bullet/bullet.hpp" #endif -#include "fggl/subsystem/subsystem.hpp" +#include "fggl/fggl.hpp" -#include "fggl/app.hpp" #include "fggl/audio/openal/audio.hpp" #include "fggl/gfx/atlas.hpp" -#include "fggl/gfx/window.hpp" -#include "fggl/gfx/compat.hpp" +#include "fggl/display/glfw/window.hpp" #include "fggl/gfx/ogl/compat.hpp" -#include "fggl/data/storage.hpp" -#include "fggl/util/service.hpp" #include "fggl/platform/paths.hpp" -#include "fggl/ecs3/types.hpp" - #include "fggl/scenes/menu.hpp" +#include "fggl/modules/manager.hpp" #include "GameScene.h" #include "rollball.hpp" @@ -77,29 +72,29 @@ static void test_atlas_api() { } int main(int argc, const char* argv[]) { - auto pathConfig = fggl::platform::calc_engine_paths("fggl-demo"); - fggl::subsystem::SubsystemManager manager; - manager.provide<fggl::data::Storage>(new fggl::data::Storage(pathConfig)); - manager.provide<fggl::audio::AudioService>(new fggl::audio::openAL()); + // DAG initialisation test + fggl::modules::Manager moduleManager; + moduleManager.use<fggl::input::Generic>(); + moduleManager.use<fggl::data::LocalStorage>(); + moduleManager.use<fggl::audio::NullAudio>(); + moduleManager.use<fggl::gui::FreeType>(); - manager.setTypeRegistry(new fggl::ecs3::TypeRegistry()); - manager.setFontLibrary(new fggl::gui::FontLibrary()); - manager.setInput(new fggl::input::Input()); + moduleManager.use<fggl::gfx::OpenGL4>(); + moduleManager.use<fggl::display::GLFW>(); - manager.setup(); + moduleManager.resolve(); // create the application - fggl::App app( &manager, "fggl-demo" ); + fggl::App app( &moduleManager, "fggl-demo" ); - // Would be nice to not take args like this, it messes with lifetimes - auto& windowing = app.use<fggl::gfx::ecsGlfwModule>( manager.getInput() ); + auto* windowing = app.service<fggl::display::WindowService>(); - // -- should not be our problem - this is a broken api - auto window = windowing.createWindow("Demo Game"); - window->make_graphics<fggl::gfx::OpenGL4>(manager.getStorage(), manager.getFontLibrary()); - window->fullscreen( true ); - app.setWindow( std::move(window) ); + // make a window for our application + auto* window = windowing->create(); + window->setTitle( "fggl-demo" ); + window->setFullscreen( true ); + app.setWindow(window); // load a bunch of modules to provide game functionality //app.use<fggl::ecs3::ecsTypes>(); @@ -108,13 +103,11 @@ int main(int argc, const char* argv[]) { app.use<FGGL_MODULE_BULLET>(); #endif - test_atlas_api(); - // Add a basic main menu auto *menu = app.add_state<fggl::scenes::BasicMenu>("menu"); // add some menu items for the game states - auto* audio = manager.getAudio(); + auto* audio = app.service<fggl::audio::AudioService>(); menu->add("terrain", [&app, &audio]() { audio->play("click.ogg", false); app.change_state("game"); diff --git a/demo/demo/rollball.cpp b/demo/demo/rollball.cpp index 8271336..24f188c 100644 --- a/demo/demo/rollball.cpp +++ b/demo/demo/rollball.cpp @@ -146,7 +146,7 @@ namespace demo { Game::activate(); Prefabs prefabs{}; - setup_prefabs(m_owner.services()->getStorage(), world(), prefabs); + setup_prefabs(m_owner.service<fggl::data::Storage>(), world(), prefabs); // collectable callbacks auto* collectableCallbacks = world().get<fggl::phys::CollisionCallbacks>(prefabs.collectable); diff --git a/fggl/app.cpp b/fggl/app.cpp index db9fbd3..63f078f 100644 --- a/fggl/app.cpp +++ b/fggl/app.cpp @@ -24,10 +24,10 @@ namespace fggl { - App::App(subsystem::ServiceProvider* services, const Identifer& name) : App::App( services, name, name ) { + App::App(modules::Manager* services, const Identifer& name) : App::App( services, name, name ) { } - App::App(subsystem::ServiceProvider* services, const Identifer& name, const Identifer& folder ) : + App::App(modules::Manager* services, const Identifer& name, const Identifer& folder ) : m_running(true), m_types(std::make_unique<ecs3::TypeRegistry>()), m_modules(std::make_unique<ecs3::ModuleManager>(*m_types)), @@ -36,6 +36,7 @@ namespace fggl { m_subsystems(services){} int App::run(int argc, const char** argv) { + auto* windowing = m_subsystems->get<display::WindowService>(); { // activate the first state @@ -53,14 +54,19 @@ namespace fggl { } } - auto& state = m_states.active(); + // process window events + if ( windowing != nullptr) { + windowing->pollEvents(); + } m_modules->onUpdate(); - state.update(); + + auto& state = m_states.active(); + state.update(); // window rendering to frame buffer if ( m_window != nullptr ) { - m_modules->onFrameStart(); - m_window->frameStart(); + m_modules->onFrameStart(); + m_window->frameStart(); // get draw instructions auto& graphics = m_window->graphics(); diff --git a/fggl/audio/openal/audio.cpp b/fggl/audio/openal/audio.cpp index d79ae61..2f7295b 100644 --- a/fggl/audio/openal/audio.cpp +++ b/fggl/audio/openal/audio.cpp @@ -54,7 +54,4 @@ namespace fggl::audio::openal { } } - void AudioServiceOAL::setup(data::Storage* storage) { - m_storage = storage; - } } \ No newline at end of file diff --git a/fggl/debug/debug.cpp b/fggl/debug/debug.cpp index 0a33632..629e7fd 100644 --- a/fggl/debug/debug.cpp +++ b/fggl/debug/debug.cpp @@ -18,10 +18,9 @@ #include "imgui/include/imgui_impl_glfw.h" #include "imgui/include/imgui_impl_opengl3.h" -using fggl::gfx::Window; using fggl::debug::DebugUI; -DebugUI::DebugUI(std::shared_ptr<fggl::gfx::GlfwWindow>& win) : m_visible(false) { +DebugUI::DebugUI(std::shared_ptr<fggl::display::glfw::Window>& win) : m_visible(false) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); diff --git a/fggl/gfx/ogl/renderer.cpp b/fggl/gfx/ogl/renderer.cpp index 564a754..45a42aa 100644 --- a/fggl/gfx/ogl/renderer.cpp +++ b/fggl/gfx/ogl/renderer.cpp @@ -17,7 +17,7 @@ #include "fggl/debug/pragmas.hpp" #include "fggl/gfx/ogl/common.hpp" -#include "fggl/gfx/window.hpp" +#include "fggl/display/glfw/window.hpp" #include <fggl/gfx/camera.hpp> #include <fggl/gfx/ogl/renderer.hpp> @@ -135,7 +135,7 @@ namespace fggl::gfx { using data::Mesh2D; using data::Vertex2D; - OpenGL4Backend::OpenGL4Backend(const Window &owner, data::Storage* storage, gui::FontLibrary* fonts) : fggl::gfx::Graphics(), m_canvasPipeline(INVALID_SHADER_ID), m_storage(storage) { + OpenGL4Backend::OpenGL4Backend(data::Storage* storage, gui::FontLibrary* fonts) : fggl::gfx::Graphics(), m_canvasPipeline(INVALID_SHADER_ID), m_storage(storage) { // initialise GLEW, or fail // FIXME this binds the graphics stack to GLFW :'( int version = gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress ); @@ -155,8 +155,8 @@ namespace fggl::gfx { } // setup the viewport based on the window's framebuffer - auto fbSize = owner.frameSize(); - glViewport(0, 0, fbSize.x, fbSize.y); + //auto fbSize = owner.frameSize(); + //glViewport(0, 0, fbSize.x, fbSize.y); // setup the shader cache m_cache = std::make_unique<ShaderCache>(m_storage); diff --git a/fggl/gfx/ogl4/canvas.cpp b/fggl/gfx/ogl4/canvas.cpp index 59f1bab..fc0a38f 100644 --- a/fggl/gfx/ogl4/canvas.cpp +++ b/fggl/gfx/ogl4/canvas.cpp @@ -23,7 +23,6 @@ #include "fggl/util/service.hpp" #include "fggl/gui/fonts.hpp" -#include "fggl/gfx/windowing.hpp" #define FGGL_OPENGL_CORRECTNESS diff --git a/fggl/gfx/window.cpp b/fggl/gfx/window.cpp index 1a7a117..0420c77 100644 --- a/fggl/gfx/window.cpp +++ b/fggl/gfx/window.cpp @@ -13,210 +13,217 @@ */ #include <utility> -#include <fggl/gfx/window.hpp> -#include <fggl/gfx/window_input.hpp> -#include <iostream> +#include "fggl/display/glfw/window.hpp" +#include "fggl/display/glfw/window_input.hpp" +#include "fggl/debug/logging.hpp" + #include <string> #include <stdexcept> -#include <utility> #include <GLFW/glfw3.h> #include <spdlog/spdlog.h> -using namespace fggl::gfx; - +namespace fggl::display::glfw { -static void glfw_error(int code, const char* description) { - spdlog::warn("[GLFW error] {}: {}", code, description); -} + static void glfw_error(int code, const char *description) { + debug::log(debug::Level::error, "[GLFW] {}: {}", code, description); + } -static void framebuffer_resize(GLFWwindow* window, int width, int height) { - auto *fgglWindow = static_cast<GlfwWindow*>(glfwGetWindowUserPointer( window )); - fgglWindow->framesize( width, height ); -} + static void framebuffer_resize(GLFWwindow *window, int width, int height) { + auto *fgglWindow = static_cast<Window *>(glfwGetWindowUserPointer(window)); + fgglWindow->framesize(width, height); + } -static void fggl_input_cursor(GLFWwindow* window, double x, double y) { - auto& input = GlfwInputManager::instance(); - auto *fgglWin = static_cast<GlfwWindow*>(glfwGetWindowUserPointer(window)); + static void fggl_input_cursor(GLFWwindow *window, double x, double y) { + auto &input = GlfwInputManager::instance(); + auto *fgglWin = static_cast<Window *>(glfwGetWindowUserPointer(window)); - #ifndef FGGL_INPUT_SCREEN_COORDS + #ifndef FGGL_INPUT_SCREEN_COORDS // convert to nice ranges... x = (x / fgglWin->width() * 2) - 1.0; // [-1, 1] y = (y / fgglWin->height() * 2) - 1.0; // [-1, 1] - #endif - - // inform the input system - input.onMouseMove(x, y); -} - -static void fggl_input_scroll(GLFWwindow* window, double x, double y) { - auto& input = GlfwInputManager::instance(); - input.onMouseScroll(x, y); -} - -static void fggl_input_mouse_btn(GLFWwindow* window, int btn, int action, int mods) { - auto& input = GlfwInputManager::instance(); - input.onMouseButton(btn, action == GLFW_PRESS); -} - -static void fggl_input_keyboard(GLFWwindow* window, int key, int scancode, int action, int mods) { - auto& input = GlfwInputManager::instance(); - input.onKeyEvent( scancode, action == GLFW_PRESS || action == GLFW_REPEAT); -} - -static void fggl_update_joystick(fggl::input::GamepadInput& input, int jid) { - bool isGamepad = glfwJoystickIsGamepad(jid); - - if ( isGamepad ) { - if( !input.present(jid) ) { - std::string name = glfwGetJoystickName(jid); - input.setActive(jid, true); - input.name(jid, name); - } + #endif + + // inform the input system + input.onMouseMove(x, y); + } + + static void fggl_input_scroll(GLFWwindow *window, double x, double y) { + auto &input = GlfwInputManager::instance(); + input.onMouseScroll(x, y); + } - GLFWgamepadstate state; - glfwGetGamepadState(jid, &state); + static void fggl_input_mouse_btn(GLFWwindow *window, int btn, int action, int mods) { + auto &input = GlfwInputManager::instance(); + input.onMouseButton(btn, action == GLFW_PRESS); + } + + static void fggl_input_keyboard(GLFWwindow *window, int key, int scancode, int action, int mods) { + auto &input = GlfwInputManager::instance(); + input.onKeyEvent(scancode, action == GLFW_PRESS || action == GLFW_REPEAT); + } + + static void fggl_update_joystick(fggl::input::GamepadInput &input, int jid) { + bool isGamepad = glfwJoystickIsGamepad(jid); + + if (isGamepad) { + if (!input.present(jid)) { + std::string name = glfwGetJoystickName(jid); + input.setActive(jid, true); + input.name(jid, name); + } - fggl::input::GamepadState gamepadState; - for (int i=0; i<=GLFW_GAMEPAD_BUTTON_LAST; i++) { - gamepadState.buttons[i] = state.buttons[i]; + GLFWgamepadstate state; + glfwGetGamepadState(jid, &state); + + fggl::input::GamepadState gamepadState; + for (int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) { + gamepadState.buttons[i] = state.buttons[i]; + } + + for (int i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++) { + gamepadState.axes[i] = state.axes[i]; + } + + input.update(jid, gamepadState); + } else { + input.setActive(jid, false); } + } - for (int i=0; i<=GLFW_GAMEPAD_AXIS_LAST; i++) { - gamepadState.axes[i] = state.axes[i]; + static void fggl_joystick_poll() { + auto &input = GlfwInputManager::instance(); + if (!input.alive()) { + return; } - input.update(jid, gamepadState); - } else { - input.setActive(jid, false); + auto &gamepadCtl = input.gamepads(); + for (int jid = 0; jid < GLFW_JOYSTICK_LAST; jid++) { + if (glfwJoystickPresent(jid)) { + fggl_update_joystick(gamepadCtl, jid); + } else { + gamepadCtl.setActive(jid, false); + } + } } -} -static void fggl_joystick_poll() { - auto& input = GlfwInputManager::instance(); - if ( !input.alive() ) { - return; - } + static void fggl_joystick(int jid, int state) { + auto &input = GlfwInputManager::instance(); + if (!input.alive()) { + return; + } - auto& gamepadCtl = input.gamepads(); - for (int jid=0; jid < GLFW_JOYSTICK_LAST; jid++) { - if ( glfwJoystickPresent(jid) ) { + auto &gamepadCtl = input.gamepads(); + if (state == GLFW_CONNECTED) { fggl_update_joystick(gamepadCtl, jid); } else { gamepadCtl.setActive(jid, false); } } -} - -static void fggl_joystick(int jid, int state) { - auto& input = GlfwInputManager::instance(); - if ( !input.alive() ) { - return; - } - auto& gamepadCtl = input.gamepads(); - if ( state == GLFW_CONNECTED ) { - fggl_update_joystick( gamepadCtl, jid ); - } else { - gamepadCtl.setActive(jid, false); - } -} + GlfwContext::GlfwContext(fggl::input::Input *input) { + debug::log(debug::Level::info, "[GLFW] Initializing..."); + auto &glfwCallbacks = GlfwInputManager::instance(); + glfwCallbacks.setup(input); -GlfwContext::GlfwContext( fggl::input::Input* input ) { - spdlog::debug("[glfw] context creation stated"); - auto& glfwCallbacks = GlfwInputManager::instance(); - glfwCallbacks.setup( input ); + glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE); + glfwSetErrorCallback(glfw_error); - glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE); - glfwSetErrorCallback(glfw_error); + int state = glfwInit(); + if (state == GLFW_FALSE) { + const char **error = nullptr; + glfwGetError(error); + throw std::runtime_error(*error); + } - int state = glfwInit(); - if ( state == GLFW_FALSE ) { - const char **error = nullptr; - glfwGetError(error); - throw std::runtime_error( *error ); + // joysticks are global + fggl_joystick_poll(); + glfwSetJoystickCallback(fggl_joystick); + debug::log(debug::Level::info, "[GLFW] Initialization complete."); } - // joysticks are global - fggl_joystick_poll(); - glfwSetJoystickCallback(fggl_joystick); - spdlog::debug("[glfw] context creation complete"); -} - -GlfwContext::~GlfwContext() { - glfwTerminate(); - spdlog::debug("[glfw] context terminated"); -} + GlfwContext::~GlfwContext() { + glfwTerminate(); + spdlog::debug("[glfw] context terminated"); + } -void GlfwContext::pollEvents() { - auto& glfwCallbacks = GlfwInputManager::instance(); - glfwCallbacks.frame(); + void GlfwContext::pollEvents() { + auto &glfwCallbacks = GlfwInputManager::instance(); + glfwCallbacks.frame(); - glfwPollEvents(); - fggl_joystick_poll(); -} + glfwPollEvents(); + fggl_joystick_poll(); + } -GlfwWindow::GlfwWindow(std::shared_ptr<GlfwContext> context) : m_context(std::move(context)), m_window(nullptr), m_framesize() { - spdlog::debug("[glfw] creating window"); + Window::Window(std::shared_ptr<GlfwContext> context, gfx::WindowGraphics* graphics) + : m_context(std::move(context)), m_window(nullptr), m_framesize() { + spdlog::debug("[glfw] creating window"); + + // FIXME - this ties the graphics API before window creation + auto graphicsConfig = graphics->config(); + if (graphicsConfig.api == gfx::GraphicsAPI::OpenGL) { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, graphicsConfig.majorVersion); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, graphicsConfig.minorVersion); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, graphicsConfig.debug ? GLFW_TRUE : GLFW_FALSE); + } - // FIXME - this ties the graphics API before window creation - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); + m_window = glfwCreateWindow(1920, 1080, "main", nullptr, nullptr); + if (m_window == nullptr) { + return; + } - m_window = glfwCreateWindow(1920, 1080, "main", nullptr, nullptr); - if ( m_window == nullptr ) { - return; - } + glfwSetWindowUserPointer(m_window, this); - glfwSetWindowUserPointer(m_window, this); + // setup callback wrappers (will invoke the methods via the user ptr above) + glfwSetFramebufferSizeCallback(m_window, framebuffer_resize); + glfwSetScrollCallback(m_window, fggl_input_scroll); + glfwSetCursorPosCallback(m_window, fggl_input_cursor); + glfwSetMouseButtonCallback(m_window, fggl_input_mouse_btn); + glfwSetKeyCallback(m_window, fggl_input_keyboard); - // setup callback wrappers (will invoke the methods via the user ptr above) - glfwSetFramebufferSizeCallback( m_window, framebuffer_resize ); - glfwSetScrollCallback(m_window, fggl_input_scroll); - glfwSetCursorPosCallback(m_window, fggl_input_cursor); - glfwSetMouseButtonCallback(m_window, fggl_input_mouse_btn); - glfwSetKeyCallback(m_window, fggl_input_keyboard); + // bind the graphics API + glfwMakeContextCurrent(m_window); + m_graphics = std::unique_ptr<gfx::Graphics>(graphics->create(*this)); - spdlog::debug("[glfw] window creation complete"); -} + spdlog::debug("[glfw] window creation complete"); + } -GlfwWindow::~GlfwWindow() { - if ( m_window != nullptr ) { - // prevent dangling pointers - glfwSetWindowUserPointer(m_window, nullptr); - glfwDestroyWindow(m_window); - m_window = nullptr; + Window::~Window() { + if (m_window != nullptr) { + // prevent dangling pointers + glfwSetWindowUserPointer(m_window, nullptr); + glfwDestroyWindow(m_window); + m_window = nullptr; + } } -} -void GlfwWindow::frameStart() { - assert( m_window != nullptr ); - assert( m_graphics != nullptr ); + void Window::frameStart() { + assert(m_window != nullptr); + assert(m_graphics != nullptr); - glfwMakeContextCurrent(m_window); - m_graphics->clear(); -} + glfwMakeContextCurrent(m_window); + m_graphics->clear(); + } -void GlfwWindow::frameEnd() { - glfwSwapBuffers(m_window); -} + void Window::frameEnd() { + glfwSwapBuffers(m_window); + } -void GlfwWindow::activate() const { - assert( m_window != nullptr ); - glfwMakeContextCurrent(m_window); -} + void Window::activate() const { + assert(m_window != nullptr); + glfwMakeContextCurrent(m_window); + } -fggl::math::vec2i GlfwWindow::frameSize() const { - assert( m_window != nullptr ); - math::vec2i size; - glfwGetFramebufferSize(m_window, &size.x, &size.y); - return size; -} - -bool GlfwWindow::wantClose() const { - assert( m_window != nullptr ); - return glfwWindowShouldClose(m_window) == GLFW_TRUE; -} + fggl::math::vec2i Window::frameSize() const { + assert(m_window != nullptr); + math::vec2i size; + glfwGetFramebufferSize(m_window, &size.x, &size.y); + return size; + } + bool Window::wantClose() const { + assert(m_window != nullptr); + return glfwWindowShouldClose(m_window) == GLFW_TRUE; + } +} \ No newline at end of file diff --git a/fggl/gui/fonts.cpp b/fggl/gui/fonts.cpp index 4e7ba38..0efb616 100644 --- a/fggl/gui/fonts.cpp +++ b/fggl/gui/fonts.cpp @@ -23,7 +23,7 @@ namespace fggl::gui { FT_Done_Face(m_face); } - FontLibrary::FontLibrary() { + FontLibrary::FontLibrary(data::Storage* storage) : m_context(nullptr), m_storage(storage) { FT_Init_FreeType(&m_context); } diff --git a/fggl/scenes/game.cpp b/fggl/scenes/game.cpp index 8f749c9..e90819b 100644 --- a/fggl/scenes/game.cpp +++ b/fggl/scenes/game.cpp @@ -26,7 +26,7 @@ namespace fggl::scenes { Game::Game(fggl::App &app) : AppState(app) { - m_input = app.services()->getInput(); + m_input = app.service<input::Input>(); } void Game::activate() { diff --git a/fggl/scenes/menu.cpp b/fggl/scenes/menu.cpp index 36e2ec7..d5071ec 100644 --- a/fggl/scenes/menu.cpp +++ b/fggl/scenes/menu.cpp @@ -26,7 +26,7 @@ namespace fggl::scenes { BasicMenu::BasicMenu(fggl::App& app) : AppState(app), m_inputs(nullptr), m_active(), m_hover(nullptr) { - m_inputs = app.services()->getInput(); + m_inputs = app.service<input::Input>(); } void BasicMenu::update() { diff --git a/include/fggl/app.hpp b/include/fggl/app.hpp index 5a63c0a..62175b2 100644 --- a/include/fggl/app.hpp +++ b/include/fggl/app.hpp @@ -24,10 +24,10 @@ #include <fggl/ecs3/types.hpp> #include "fggl/ecs3/module/module.hpp" -#include <fggl/gfx/window.hpp> +#include "fggl/display/glfw/window.hpp" #include <fggl/gfx/paint.hpp> #include <fggl/util/states.hpp> -#include "fggl/subsystem/provider.hpp" +#include "fggl/modules/manager.hpp" namespace fggl { @@ -83,8 +83,8 @@ namespace fggl { class App { public: - explicit App(subsystem::ServiceProvider* serivces, const Identifer &name); - App(subsystem::ServiceProvider* services, const Identifer &name, const Identifer &folderName); + explicit App(modules::Manager* serivces, const Identifer &name); + App(modules::Manager* services, const Identifer &name, const Identifer &folderName); // class is non copy-able App(const App &app) = delete; @@ -93,8 +93,8 @@ namespace fggl { App &operator=(const App& other) = delete; App &operator=(App&& other) = delete; - inline void setWindow(std::unique_ptr<gfx::Window>&& window) { - m_window = std::move(window); + inline void setWindow(display::Window* window) { + m_window = window; } /** @@ -125,8 +125,14 @@ namespace fggl { return m_states.active(); } - inline subsystem::ServiceProvider* services() { - return m_subsystems; + template<typename T> + inline T* service() { + try { + return m_subsystems->template get<T>(); + } catch (std::out_of_range &e) { + debug::log(debug::Level::error, "Service not found: {}", T::service); + return nullptr; + } } inline ecs3::TypeRegistry* registry() { @@ -145,10 +151,10 @@ namespace fggl { bool m_running; std::unique_ptr<ecs3::TypeRegistry> m_types; std::unique_ptr<ecs3::ModuleManager> m_modules; - std::unique_ptr<gfx::Window> m_window; + display::Window* m_window; AppMachine m_states; Identifer m_expectedScene; - subsystem::ServiceProvider* m_subsystems; + modules::Manager* m_subsystems; }; } diff --git a/include/fggl/audio/audio.hpp b/include/fggl/audio/audio.hpp index e1d1651..ccb3029 100644 --- a/include/fggl/audio/audio.hpp +++ b/include/fggl/audio/audio.hpp @@ -18,6 +18,7 @@ #include <string> #include "fggl/subsystem/types.hpp" #include "fggl/data/storage.hpp" +#include "fggl/modules/module.hpp" namespace fggl::audio { @@ -33,13 +34,15 @@ namespace fggl::audio { short* data; }; + constexpr modules::ModuleService SERVICE_AUDIO_PLAYBACK = modules::make_service("fggl::audio::AudioService"); + class AudioService { public: + constexpr static const modules::ModuleService service = SERVICE_AUDIO_PLAYBACK; + AudioService() = default; virtual ~AudioService() = default; - virtual void setup(data::Storage* provider) = 0; - virtual void play(const std::string& filename, bool looping = false) = 0; virtual void play(AudioClip& clip, bool looping = false) = 0; }; diff --git a/include/fggl/audio/null_audio.hpp b/include/fggl/audio/null_audio.hpp index ccefb33..e89f99a 100644 --- a/include/fggl/audio/null_audio.hpp +++ b/include/fggl/audio/null_audio.hpp @@ -28,11 +28,28 @@ namespace fggl::audio { NullAudioService() = default; virtual ~NullAudioService() = default; - void setup(data::Storage* storage) override {} void play(const std::string& filename, bool looping = false) override {} void play(AudioClip& clip, bool looping = false) override {} }; + struct NullAudio { + constexpr static const char* name = "fggl::audio::NULL"; + constexpr static const std::array<modules::ModuleService, 1> provides = { + SERVICE_AUDIO_PLAYBACK + }; + constexpr static const std::array<modules::ModuleService, 0> depends = {}; + static const modules::ServiceFactory factory; + }; + + bool null_factory(modules::ModuleService service, modules::Services& services) { + if (service == SERVICE_AUDIO_PLAYBACK) { + services.bind<audio::AudioService, audio::NullAudioService>(); + return true; + } + return false; + } + const modules::ServiceFactory NullAudio::factory = null_factory; + } // namespace fggl::audio #endif //FGGL_AUDIO_NULL_AUDIO_HPP diff --git a/include/fggl/audio/openal/audio.hpp b/include/fggl/audio/openal/audio.hpp index 88e59d0..4834c97 100644 --- a/include/fggl/audio/openal/audio.hpp +++ b/include/fggl/audio/openal/audio.hpp @@ -154,7 +154,7 @@ namespace fggl::audio::openal { class AudioServiceOAL : public AudioService { public: - AudioServiceOAL() : m_device(alcOpenDevice(nullptr)) { + explicit AudioServiceOAL(data::Storage* storage) : m_device(alcOpenDevice(nullptr)), m_storage(storage) { if ( m_device != nullptr ) { m_context = alcCreateContext(m_device, nullptr); alcMakeContextCurrent(m_context); @@ -172,7 +172,6 @@ namespace fggl::audio::openal { } } - void setup(data::Storage* storage) override; void play(const std::string& filename, bool looping = false) override; void play(AudioClip& clip, bool looping = false) override; diff --git a/include/fggl/audio/openal/module.hpp b/include/fggl/audio/openal/module.hpp new file mode 100644 index 0000000..dd37f67 --- /dev/null +++ b/include/fggl/audio/openal/module.hpp @@ -0,0 +1,52 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_AUDIO_OPENAL_MODULE_HPP +#define FGGL_AUDIO_OPENAL_MODULE_HPP + +#include <array> +#include <string> +#include "fggl/audio/audio.hpp" +#include "fggl/audio/openal/audio.hpp" + +namespace fggl::audio { + + struct OpenAL { + constexpr static const char* name = "fggl::audio::OpenAL"; + constexpr static const std::array<modules::ModuleService, 1> provides = { + SERVICE_AUDIO_PLAYBACK + }; + constexpr static const std::array<modules::ModuleService, 1> depends = { + modules::make_service("fggl::data::Storage") + }; + static const modules::ServiceFactory factory; + }; + + bool openal_factory(modules::ModuleService service, modules::Services& services) { + if (service == SERVICE_AUDIO_PLAYBACK) { + auto storage = services.get<data::Storage>(); + services.bind<audio::AudioService, openal::AudioServiceOAL>(storage); + return true; + } + return false; + } + const modules::ServiceFactory OpenAL::factory = openal_factory; + +} // namespace fggl::audio + +#endif //FGGL_AUDIO_OPENAL_MODULE_HPP diff --git a/include/fggl/data/module.hpp b/include/fggl/data/module.hpp new file mode 100644 index 0000000..6628f7f --- /dev/null +++ b/include/fggl/data/module.hpp @@ -0,0 +1,51 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_DATA_MODULE_HPP +#define FGGL_DATA_MODULE_HPP + +#include "fggl/modules/module.hpp" +#include "fggl/data/storage.hpp" +#include "fggl/platform/paths.hpp" + +namespace fggl::data { + + + struct LocalStorage { + constexpr static const char* name = "fggl::data::Storage"; + constexpr static const std::array<modules::ModuleService, 1> provides = { + SERVICE_STORAGE + }; + constexpr static const std::array<modules::ModuleService, 0> depends = {}; + static const modules::ServiceFactory factory; + }; + + bool storage_factory(modules::ModuleService service, modules::Services& data) { + if (service == SERVICE_STORAGE) { + // FIXME: no easy way to set the application name + auto pathConfig = fggl::platform::calc_engine_paths("fggl-demo"); + data.create<Storage>(pathConfig); + return true; + } + return false; + } + const modules::ServiceFactory LocalStorage::factory = storage_factory; + +} // namespace fggl::data + +#endif //FGGL_DATA_MODULE_HPP diff --git a/include/fggl/data/storage.hpp b/include/fggl/data/storage.hpp index f52dad1..2704ec0 100644 --- a/include/fggl/data/storage.hpp +++ b/include/fggl/data/storage.hpp @@ -22,6 +22,7 @@ #include <vector> #include "fggl/debug/logging.hpp" +#include "fggl/modules/module.hpp" #include "fggl/platform/paths.hpp" namespace fggl::data { @@ -34,9 +35,11 @@ namespace fggl::data { enum StorageType { Data, Config, Cache }; - class Storage { + constexpr const modules::ModuleService SERVICE_STORAGE = modules::make_service("fggl::data::Storage"); + class Storage { public: + constexpr static modules::ModuleService service = SERVICE_STORAGE; Storage( fggl::platform::EnginePaths paths ) : m_paths(std::move( paths )) {} template<typename T> diff --git a/include/fggl/debug/debug.h b/include/fggl/debug/debug.h index a2ff447..e1d9cb6 100644 --- a/include/fggl/debug/debug.h +++ b/include/fggl/debug/debug.h @@ -21,7 +21,7 @@ #include <functional> #include <unordered_map> -#include "fggl/gfx/window.hpp" +#include "fggl/display/glfw/window.hpp" namespace fggl::debug { @@ -34,7 +34,7 @@ namespace fggl::debug { class DebugUI { public: - explicit DebugUI(std::shared_ptr<gfx::GlfwWindow> &window); + explicit DebugUI(std::shared_ptr<display::glfw::Window> &window); ~DebugUI(); void frameStart(); diff --git a/include/fggl/display/glfw/module.hpp b/include/fggl/display/glfw/module.hpp new file mode 100644 index 0000000..e3df059 --- /dev/null +++ b/include/fggl/display/glfw/module.hpp @@ -0,0 +1,57 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_DISPLAY_GLFW_MODULE_HPP +#define FGGL_DISPLAY_GLFW_MODULE_HPP + +#include "fggl/display/window.hpp" +#include "fggl/input/module.hpp" + +#include "fggl/display/glfw/window.hpp" +#include "fggl/display/glfw/services.hpp" + +namespace fggl::display { + + struct GLFW { + constexpr static const char* name = "fggl::display::glfw"; + constexpr static const std::array<modules::ModuleService, 1> provides = { + WindowService::service + }; + constexpr static const std::array<modules::ModuleService, 2> depends = { + fggl::input::Input::service, + fggl::gfx::WindowGraphics::service + }; + static const modules::ServiceFactory factory; + }; + + bool glfw_factory(modules::ModuleService service, modules::Services& services) { + if (service == WindowService::service) { + auto input = services.get<input::Input>(); + auto graphics = services.get<gfx::WindowGraphics>(); + + auto context = std::make_shared<glfw::GlfwContext>(input); + services.bind<WindowService, glfw::WindowService>(context, graphics); + return true; + } + return false; + } + const modules::ServiceFactory GLFW::factory = glfw_factory; + +} // namespace fggl::display + +#endif //FGGL_DISPLAY_GLFW_MODULE_HPP diff --git a/include/fggl/display/glfw/services.hpp b/include/fggl/display/glfw/services.hpp new file mode 100644 index 0000000..6661f03 --- /dev/null +++ b/include/fggl/display/glfw/services.hpp @@ -0,0 +1,52 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_DISPLAY_GLFW_SERVICES_HPP +#define FGGL_DISPLAY_GLFW_SERVICES_HPP + +#include "fggl/display/window.hpp" +#include "fggl/gfx/setup.hpp" +#include <memory> +#include <utility> +#include <vector> + +namespace fggl::display::glfw { + + class WindowService : public display::WindowService { + public: + explicit WindowService(std::shared_ptr<GlfwContext> context, gfx::WindowGraphics* gfx) : m_context(std::move(context)), m_gfx(gfx), m_windows() {} + virtual ~WindowService() = default; + + display::Window* create() override { + m_windows.push_back(std::make_unique<Window>(m_context, m_gfx)); + return m_windows.back().get(); + } + + void pollEvents() override { + m_context->pollEvents(); + } + + private: + std::shared_ptr<GlfwContext> m_context; + gfx::WindowGraphics* m_gfx; + std::vector<std::unique_ptr<Window>> m_windows; + }; + +} // namespace fggl::display + +#endif //FGGL_DISPLAY_GLFW_SERVICES_HPP diff --git a/include/fggl/gfx/window.hpp b/include/fggl/display/glfw/window.hpp similarity index 73% rename from include/fggl/gfx/window.hpp rename to include/fggl/display/glfw/window.hpp index a51a456..d570298 100644 --- a/include/fggl/gfx/window.hpp +++ b/include/fggl/display/glfw/window.hpp @@ -12,6 +12,20 @@ * If not, see <https://www.gnu.org/licenses/>. */ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + #ifndef FGGL_GFX_WINDOW_HPP #define FGGL_GFX_WINDOW_HPP @@ -19,14 +33,15 @@ #include <string> #include <memory> -#include <fggl/input/input.hpp> -#include <fggl/gfx/common.hpp> -#include <fggl/math/types.hpp> -#include <fggl/gfx/windowing.hpp> +#include "fggl/input/input.hpp" +#include "fggl/gfx/common.hpp" +#include "fggl/math/types.hpp" +#include "fggl/display/window.hpp" +#include "fggl/gfx/setup.hpp" -namespace fggl::gfx { +namespace fggl::display::glfw { - class GlfwWindow; + class Window; class GlfwContext { public: @@ -36,7 +51,7 @@ namespace fggl::gfx { void pollEvents(); private: - std::vector<std::unique_ptr<GlfwWindow>> m_windows; + std::vector<std::unique_ptr<Window>> m_windows; }; enum MutWindowHint { @@ -60,13 +75,13 @@ namespace fggl::gfx { NoError = GLFW_CONTEXT_NO_ERROR }; - class GlfwWindow : public Window { + class Window : public display::Window { public: - GlfwWindow(std::shared_ptr<GlfwContext> context); - ~GlfwWindow(); + explicit Window(std::shared_ptr<GlfwContext> context, gfx::WindowGraphics*); + ~Window() override; - GlfwWindow(Window &) = delete; - GlfwWindow(Window &&) = delete; + Window(Window &) = delete; + Window(Window &&) = delete; [[nodiscard]] math::vec2i frameSize() const override; @@ -102,18 +117,18 @@ namespace fggl::gfx { return glfwWindowShouldClose(m_window); } - inline void title(const std::string &title) { + inline void setTitle(const char* title) override { assert(m_window != nullptr); - glfwSetWindowTitle(m_window, title.c_str()); + glfwSetWindowTitle(m_window, title); } [[nodiscard]] - inline bool fullscreen() const { + inline bool isFullscreen() const override { assert(m_window != nullptr); return glfwGetWindowMonitor(m_window) != nullptr; } - inline void fullscreen(bool state) { + inline void setFullscreen(bool state) override { assert(m_window != nullptr); if (state) { auto monitor = glfwGetPrimaryMonitor(); diff --git a/include/fggl/gfx/window_input.hpp b/include/fggl/display/glfw/window_input.hpp similarity index 73% rename from include/fggl/gfx/window_input.hpp rename to include/fggl/display/glfw/window_input.hpp index ca74bec..6fb7efb 100644 --- a/include/fggl/gfx/window_input.hpp +++ b/include/fggl/display/glfw/window_input.hpp @@ -12,16 +12,30 @@ * If not, see <https://www.gnu.org/licenses/>. */ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + #ifndef FGGL_GFX_WINDOW_INPUT_HPP #define FGGL_GFX_WINDOW_INPUT_HPP #include <memory> #include <string> -#include <fggl/gfx/window.hpp> -#include <fggl/input/input.hpp> +#include "fggl/display/glfw/window.hpp" +#include "fggl/input/input.hpp" -namespace fggl::gfx { +namespace fggl::display::glfw { class GlfwInputManager { public: diff --git a/include/fggl/gfx/windowing.hpp b/include/fggl/display/window.hpp similarity index 63% rename from include/fggl/gfx/windowing.hpp rename to include/fggl/display/window.hpp index 250edbf..f044a54 100644 --- a/include/fggl/gfx/windowing.hpp +++ b/include/fggl/display/window.hpp @@ -12,33 +12,18 @@ * If not, see <https://www.gnu.org/licenses/>. */ -#ifndef FGGL_GFX_WINDOWING_HPP -#define FGGL_GFX_WINDOWING_HPP +// +// Created by webpigeon on 27/06/22. +// -#include <memory> -#include <fggl/gfx/paint.hpp> -#include "fggl/ecs3/ecs.hpp" +#ifndef FGGL_DISPLAY_WINDOW_HPP +#define FGGL_DISPLAY_WINDOW_HPP -namespace fggl::gfx { +#include "fggl/modules/module.hpp" +#include "fggl/math/types.hpp" +#include "fggl/gfx/interfaces.hpp" - struct Bounds { - float top; - float right; - float bottom; - float left; - }; - - class Graphics { - public: - virtual ~Graphics() = default; - virtual void clear() = 0; - virtual void resize(int width, int height) = 0; - - virtual Bounds canvasBounds() = 0; - virtual void draw2D(const Paint &paint) = 0; - - virtual void drawScene(ecs3::World&) = 0; - }; +namespace fggl::display { class Window { public: @@ -62,19 +47,29 @@ namespace fggl::gfx { virtual void frameStart() = 0; virtual void frameEnd() = 0; - Graphics &graphics() { + gfx::Graphics &graphics() { return *m_graphics; } + virtual void setTitle(const char* title) = 0; + + virtual void setFullscreen(bool state) = 0; + + [[nodiscard]] + virtual bool isFullscreen() const = 0; + protected: - std::unique_ptr<Graphics> m_graphics; + std::unique_ptr<gfx::Graphics> m_graphics; }; class WindowService { public: - Window &create(); + constexpr static const modules::ModuleService service = modules::make_service("fggl::display::WindowService"); + + virtual Window* create() = 0; + virtual void pollEvents() = 0; }; -} // namespace fggl::gfx +} // namespace fggl::display -#endif +#endif //FGGL_DISPLAY_WINDOW_HPP diff --git a/include/fggl/fggl.hpp b/include/fggl/fggl.hpp index 4b034f7..decee35 100644 --- a/include/fggl/fggl.hpp +++ b/include/fggl/fggl.hpp @@ -18,6 +18,16 @@ #include "fggl/app.hpp" #include "fggl/util/service.hpp" +#include "fggl/data/module.hpp" +#include "fggl/input/module.hpp" +#include "fggl/gui/module.hpp" + +#include "fggl/display/glfw/module.hpp" +#include "fggl/audio/null_audio.hpp" +#include "fggl/audio/openal/module.hpp" + +#include "fggl/gfx/ogl4/module.hpp" + namespace fggl { } diff --git a/include/fggl/gfx/compat.hpp b/include/fggl/gfx/compat.hpp deleted file mode 100644 index 0e860e1..0000000 --- a/include/fggl/gfx/compat.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of FGGL. - * - * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along with FGGL. - * If not, see <https://www.gnu.org/licenses/>. - */ - -#ifndef FGGL_GFX_COMPAT_HPP -#define FGGL_GFX_COMPAT_HPP -/** - * Window management Calls. - * - * This shouldn't be exposed to the demo app, but the ECS we're using isn't smart enouph to allow us to - * abstract this yet. It's next thing on the list, but this branch is about cleaning up OpenGL not about - * extending our ECS. - * - * Should be removed when the engine has suitable abstractions in place. - */ - -#include <memory> - -#include <utility> -#include <fggl/gfx/window.hpp> -#include <fggl/ecs3/ecs.hpp> - -namespace fggl::gfx { - - // - // fake module support - allows us to still RAII - // - struct ecsGlfwModule : ecs3::Module { - - inline explicit - ecsGlfwModule(fggl::input::Input* inputs) : context( std::make_shared<GlfwContext>(inputs)) { - } - - inline - std::unique_ptr<GlfwWindow> createWindow(const std::string &title) { - std::unique_ptr<GlfwWindow> window = std::make_unique<GlfwWindow>(context); - window->title(title); - return std::move(window); - } - - void onUpdate() override { - context->pollEvents(); - } - - [[nodiscard]] - std::string name() const override { - return "gfx::glfw"; - } - - private: - std::shared_ptr<GlfwContext> context; - - }; - - using Glfw = ecsGlfwModule; -} - -#endif diff --git a/include/fggl/gfx/interfaces.hpp b/include/fggl/gfx/interfaces.hpp new file mode 100644 index 0000000..f546ab2 --- /dev/null +++ b/include/fggl/gfx/interfaces.hpp @@ -0,0 +1,52 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_GFX_INTERFACES_HPP +#define FGGL_GFX_INTERFACES_HPP + +#include "fggl/gfx/paint.hpp" +#include "fggl/ecs3/ecs.hpp" +#include "fggl/modules/module.hpp" + +namespace fggl::gfx { + + struct Bounds { + float top; + float right; + float bottom; + float left; + }; + + class Graphics { + public: + constexpr static const modules::ModuleService service = modules::make_service("fggl::gfx::Graphics"); + + virtual ~Graphics() = default; + virtual void clear() = 0; + virtual void resize(int width, int height) = 0; + + virtual Bounds canvasBounds() = 0; + virtual void draw2D(const Paint &paint) = 0; + + virtual void drawScene(ecs3::World&) = 0; + }; + + +} // namespace fggl::gfx + +#endif //FGGL_GFX_INTERFACES_HPP diff --git a/include/fggl/gfx/ogl/backend.hpp b/include/fggl/gfx/ogl/backend.hpp index ae2f177..5116f0d 100644 --- a/include/fggl/gfx/ogl/backend.hpp +++ b/include/fggl/gfx/ogl/backend.hpp @@ -16,7 +16,7 @@ #define FGGL_GFX_OGL_BACKEND_HPP #include "common.hpp" -#include <fggl/gfx/window.hpp> +#include "fggl/display/glfw/window.hpp" #include <stdexcept> diff --git a/include/fggl/gfx/ogl/renderer.hpp b/include/fggl/gfx/ogl/renderer.hpp index 4838655..acda731 100644 --- a/include/fggl/gfx/ogl/renderer.hpp +++ b/include/fggl/gfx/ogl/renderer.hpp @@ -67,7 +67,7 @@ namespace fggl::gfx { */ class OpenGL4Backend : public Graphics { public: - explicit OpenGL4Backend(const Window &owner, data::Storage* storage, gui::FontLibrary* fonts); + explicit OpenGL4Backend(data::Storage* storage, gui::FontLibrary* fonts); ~OpenGL4Backend() override = default; // copy bad @@ -124,7 +124,6 @@ namespace fggl::gfx { gui::FontLibrary* m_fontLibrary; }; - using OpenGL4 = OpenGL4Backend; }; // namespace fggl::gfx #endif diff --git a/include/fggl/gfx/ogl4/canvas.hpp b/include/fggl/gfx/ogl4/canvas.hpp index b060e68..74a9c47 100644 --- a/include/fggl/gfx/ogl4/canvas.hpp +++ b/include/fggl/gfx/ogl4/canvas.hpp @@ -21,7 +21,7 @@ #include "fggl/gfx/paint.hpp" #include "fggl/gfx/ogl/types.hpp" -#include "fggl/gfx/windowing.hpp" +#include "fggl/gfx/interfaces.hpp" #include "fggl/gui/fonts.hpp" diff --git a/include/fggl/gfx/ogl4/module.hpp b/include/fggl/gfx/ogl4/module.hpp new file mode 100644 index 0000000..6dc9be3 --- /dev/null +++ b/include/fggl/gfx/ogl4/module.hpp @@ -0,0 +1,57 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_GFX_OGL4_MODULE_HPP +#define FGGL_GFX_OGL4_MODULE_HPP + +#include <array> +#include "fggl/modules/module.hpp" +#include "fggl/gfx/interfaces.hpp" +#include "fggl/gfx/setup.hpp" + +#include "fggl/gfx/ogl/renderer.hpp" +#include "fggl/gfx/ogl4/setup.hpp" + +namespace fggl::gfx { + + struct OpenGL4 { + constexpr static const char* name = "fggl::gfx::OpenGL4"; + constexpr static const std::array<modules::ModuleService, 1> provides = { + WindowGraphics::service + }; + constexpr static const std::array<modules::ModuleService, 2> depends = { + data::Storage::service, + gui::FontLibrary::service + }; + static const modules::ServiceFactory factory; + }; + + bool ogl4_factory(modules::ModuleService service, modules::Services& services) { + if (service == WindowGraphics::service) { + auto storage = services.get<data::Storage>(); + auto font_library = services.get<gui::FontLibrary>(); + services.bind<WindowGraphics, ogl4::WindowGraphics>(storage, font_library); + return true; + } + return false; + } + const modules::ServiceFactory OpenGL4::factory = ogl4_factory; + +} //namespace fggl::gfx + +#endif //FGGL_GFX_OGL4_MODULE_HPP diff --git a/include/fggl/gfx/ogl4/setup.hpp b/include/fggl/gfx/ogl4/setup.hpp new file mode 100644 index 0000000..2da109c --- /dev/null +++ b/include/fggl/gfx/ogl4/setup.hpp @@ -0,0 +1,56 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_GFX_OGL4_SETUP_HPP +#define FGGL_GFX_OGL4_SETUP_HPP + +#include "fggl/gfx/setup.hpp" +#include "fggl/gfx/ogl/renderer.hpp" + +namespace fggl::gfx::ogl4 { + + constexpr GraphicsDetails openGL4Details { + GraphicsAPI::OpenGL, + 4, + 3, + false + }; + + class WindowGraphics : public gfx::WindowGraphics { + public: + WindowGraphics(data::Storage* storage, gui::FontLibrary* fonts) : m_storage(storage), m_fonts(fonts) {}; + virtual ~WindowGraphics() = default; + + fggl::gfx::Graphics* create(display::Window& window) override; + + [[nodiscard]] + inline GraphicsDetails config() const override { + return openGL4Details; + } + private: + data::Storage* m_storage; + gui::FontLibrary* m_fonts; + }; + + fggl::gfx::Graphics *WindowGraphics::create(display::Window &window) { + return new OpenGL4Backend(m_storage, m_fonts); + } + +} // namespace fggl::gfx::ogl4 + +#endif //FGGL_GFX_OGL4_SETUP_HPP diff --git a/include/fggl/gfx/setup.hpp b/include/fggl/gfx/setup.hpp new file mode 100644 index 0000000..6a58005 --- /dev/null +++ b/include/fggl/gfx/setup.hpp @@ -0,0 +1,48 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_GFX_INTERFACES2_HPP +#define FGGL_GFX_INTERFACES2_HPP + +#include "fggl/gfx/interfaces.hpp" +#include "fggl/display/window.hpp" + +namespace fggl::gfx { + + enum class GraphicsAPI { + OpenGL, Vulkan + }; + + struct GraphicsDetails { + GraphicsAPI api; + int majorVersion; + int minorVersion; + bool debug; + }; + + class WindowGraphics { + public: + constexpr const static modules::ModuleService service = modules::make_service("fggl::gfx::WindowGraphics"); + + virtual GraphicsDetails config() const = 0; + virtual Graphics* create(display::Window& window) = 0; + }; + +} // namespace fggl::gfx + +#endif //FGGL_GFX_INTERFACES2_HPP diff --git a/include/fggl/gui/fonts.hpp b/include/fggl/gui/fonts.hpp index 7a36a60..a944cb5 100644 --- a/include/fggl/gui/fonts.hpp +++ b/include/fggl/gui/fonts.hpp @@ -26,6 +26,7 @@ #include "fggl/math/types.hpp" #include "fggl/data/storage.hpp" #include "fggl/util/service.hpp" +#include "fggl/modules/module.hpp" #include <ft2build.h> #include FT_FREETYPE_H @@ -68,7 +69,9 @@ namespace fggl::gui { class FontLibrary { public: - FontLibrary(); + constexpr static const modules::ModuleService service = modules::make_service("fggl::gui::font"); + + FontLibrary(data::Storage* storage); ~FontLibrary(); // copy and moving not needed @@ -77,10 +80,6 @@ namespace fggl::gui { FontLibrary& operator=(const FontLibrary&) = delete; FontLibrary& operator=(FontLibrary&&) = delete; - void setup(data::Storage* storage) { - m_storage = storage; - } - inline std::shared_ptr<FontFace> getFont(const std::string& name) { auto fontItr = m_cache.find(name); if ( fontItr != m_cache.end() ) { diff --git a/include/fggl/gui/module.hpp b/include/fggl/gui/module.hpp new file mode 100644 index 0000000..6c926f2 --- /dev/null +++ b/include/fggl/gui/module.hpp @@ -0,0 +1,49 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_GUI_MODULE_HPP +#define FGGL_GUI_MODULE_HPP + +#include "fggl/gui/fonts.hpp" +#include "fggl/data/module.hpp" + +namespace fggl::gui { + + struct FreeType { + constexpr static const char* name = "fggl::gui::FreeType"; + constexpr static const std::array<modules::ModuleService, 1> provides = { + FontLibrary::service + }; + constexpr static const std::array<modules::ModuleService, 1> depends = { + data::Storage::service + }; + static const modules::ServiceFactory factory; + }; + + bool freetype_factory(modules::ModuleService service, modules::Services& services) { + if ( service == FontLibrary::service ) { + auto storage = services.get<data::Storage>(); + services.create< FontLibrary >(storage); + return true; + } + return false; + } + const modules::ServiceFactory FreeType::factory = freetype_factory; +} + +#endif //FGGL_GUI_MODULE_HPP diff --git a/include/fggl/input/input.hpp b/include/fggl/input/input.hpp index f73a0dc..4464994 100644 --- a/include/fggl/input/input.hpp +++ b/include/fggl/input/input.hpp @@ -20,10 +20,16 @@ #include <fggl/input/mouse.hpp> #include <fggl/input/gamepad.hpp> +#include "fggl/modules/module.hpp" + namespace fggl::input { + constexpr const modules::ModuleService SERVICE_INPUT = modules::make_service("fggl::input::Input"); + class Input { public: + constexpr static const modules::ModuleService service = SERVICE_INPUT; + Input() = default; void frame(float dt); diff --git a/include/fggl/input/module.hpp b/include/fggl/input/module.hpp new file mode 100644 index 0000000..125259f --- /dev/null +++ b/include/fggl/input/module.hpp @@ -0,0 +1,47 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_INPUT_MODULE_HPP +#define FGGL_INPUT_MODULE_HPP + +#include <array> +#include "fggl/modules/module.hpp" +#include "fggl/input/input.hpp" + +namespace fggl::input { + + struct Generic { + constexpr static const char* name = "fggl::input::Generic"; + constexpr static const std::array<modules::ModuleService, 1> provides = { + SERVICE_INPUT + }; + constexpr static const std::array<modules::ModuleService, 0> depends = {}; + static const modules::ServiceFactory factory; + }; + + bool input_factory(modules::ModuleService service, modules::Services& services) { + if (service == SERVICE_INPUT) { + services.create<input::Input>(); + return true; + } + return false; + } + const modules::ServiceFactory Generic::factory = input_factory; +} + +#endif //FGGL_INPUT_MODULE_HPP diff --git a/include/fggl/modules/manager.hpp b/include/fggl/modules/manager.hpp new file mode 100644 index 0000000..1348fdd --- /dev/null +++ b/include/fggl/modules/manager.hpp @@ -0,0 +1,206 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_MODULES_MANAGER_HPP +#define FGGL_MODULES_MANAGER_HPP + +#include "fggl/modules/module.hpp" +#include "fggl/debug/logging.hpp" + +#include <queue> +#include <vector> +#include <map> +#include <stack> +#include <set> +#include <iostream> + +namespace fggl::modules { + + template<typename T> + class DependencyGraph { + public: + DependencyGraph() = default; + + void clear() { + m_dependencies.clear(); + } + + void addAll(const T& name, const std::vector<T>& dependencies) { + auto existing = m_dependencies.find(name); + if (existing == m_dependencies.end()) { + m_dependencies[name] = dependencies; + } else { + existing->second.insert(existing->second.end(), dependencies.begin(), dependencies.end()); + } + } + + void add(const T& name, const T& depends) { + m_dependencies[name].push_back(depends); + } + + bool getOrder(std::stack<T>& stack) { + std::set<T> visited{}; + + for (const auto& module : m_dependencies) { + if (!visited.contains(module.first)) { + sortUtil( module.first, visited, stack); + } + } + + return true; + } + + bool getOrderRev(std::queue<T>& stack) { + std::set<T> visited{}; + + for (const auto& module : m_dependencies) { + if (!visited.contains(module.first)) { + sortUtilRev( module.first, visited, stack); + } + } + + return true; + } + private: + std::map<T, std::vector<T>> m_dependencies; + + void sortUtil(T idx, std::set<T>& visited, std::stack<T>& stack) { + visited.emplace(idx); + + for ( auto dep : m_dependencies.at(idx)) { + if ( !visited.contains(dep) ) + sortUtil(dep, visited, stack); + } + + stack.push(idx); + } + + void sortUtilRev(T idx, std::set<T>& visited, std::queue<T>& stack) { + visited.emplace(idx); + + for ( auto dep : m_dependencies.at(idx)) { + if ( !visited.contains(dep) ) + sortUtilRev(dep, visited, stack); + } + + stack.push(idx); + } + }; + + + class Manager { + public: + Manager() = default; + + inline void addVirtual(const Config& config) { + assert( !m_locked ); + + m_modules[config.name] = config; + for ( const auto& service : config.provides ) { + m_serviceProviders[service] = config.name; + } + } + + template<typename T> + void use() { + assert( !m_locked ); + + Config config { .name = T::name }; + for ( auto service : T::provides ) { + config.provides.push_back(service); + } + + for ( auto service : T::depends ) { + config.depends.push_back(service); + } + config.factory = T::factory; + + addVirtual(config); + } + + bool buildGraph() { + // resolve links between modules + for (auto& moduleItr : m_modules) { + if ( moduleItr.second.depends.empty() ) { + m_dependencies.addAll(moduleItr.first, {}); + continue; + } + + for (auto& service : moduleItr.second.depends) { + + auto provider = m_serviceProviders.find(service); + if ( provider == m_serviceProviders.end() ) { + debug::log(debug::Level::warning, "{} depends on {}, but nothing provides it", moduleItr.first, service); + // nothing can provide the service requested, setup is invalid. + return false; + } + + m_dependencies.add(moduleItr.first, provider->second); + } + } + return true; + } + + template<typename T> + T* get() const { + assert( m_locked ); + return m_services.template get<T>(); + } + + void resolve() { + if ( !buildGraph() ) { + return; + } + + std::queue<ModuleIdentifier> stack; + m_dependencies.getOrderRev(stack); + + while ( !stack.empty() ) { + auto nextToInit = stack.front(); + debug::log(debug::Level::info, "Initializing {}", nextToInit); + + auto& module = m_modules.at(nextToInit); + if ( module.factory != nullptr ) { + for (auto& service : module.provides) { + bool result = module.factory(service, m_services); + if ( !result ) { + debug::log(debug::Level::warning, "{} could not create service {}", nextToInit, service); + } + } + } else { + debug::log(debug::Level::warning, "{} has no factory - skipping", nextToInit); + } + stack.pop(); + } + + debug::log(debug::Level::info, "engine boot complete"); + m_locked = true; + } + + private: + bool m_locked = false; + Services m_services; + std::map<ModuleIdentifier, Config> m_modules; + DependencyGraph<ModuleIdentifier> m_dependencies; + std::map<ModuleService, ModuleIdentifier> m_serviceProviders; + + }; + +} // namespace fggl::modules + +#endif //FGGL_MODULES_MANAGER_HPP diff --git a/include/fggl/modules/module.hpp b/include/fggl/modules/module.hpp new file mode 100644 index 0000000..d6c2e75 --- /dev/null +++ b/include/fggl/modules/module.hpp @@ -0,0 +1,91 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 27/06/22. +// + +#ifndef FGGL_MODULES_MODULE_HPP +#define FGGL_MODULES_MODULE_HPP + +#include <string> +#include <vector> +#include <functional> +#include <map> +#include <memory> + +namespace fggl::modules { + + using ModuleIdentifier = std::string; + + struct ModuleService { + private: + std::string_view value; + + public: + constexpr ModuleService(std::string_view value) : value(value) {} + constexpr explicit operator std::string_view() const { return value; } + + bool operator==(const ModuleService& other) const { + return value == other.value; + } + + std::strong_ordering operator<=>(const ModuleService& other) const noexcept { + return value <=> other.value; + } + }; + + constexpr ModuleService make_service(const std::string_view name) { + return {name}; + } + + class Services { + public: + template<typename Svc, typename Impl, typename ...Args> + void bind(Args... args) { + static_assert( std::is_base_of_v<Svc, Impl>, "Service type must be assignable from implementation type" ); + m_services[Svc::service] = std::make_shared<Impl>(args...); + } + + template<typename Svc, typename ...Args> + void create(Args... args){ + m_services[Svc::service] = std::make_shared<Svc>(args...); + } + + template<typename Svc> + void provide(std::shared_ptr<Svc> service) { + m_services[Svc::service] = service; + } + + template<typename S> + S* get() const { + auto serviceWrapper = m_services.at(S::service); + auto ptr = std::static_pointer_cast<S>(serviceWrapper); + return ptr.get(); + } + private: + std::map<ModuleService, std::shared_ptr<void>> m_services; + }; + + using ServiceFactory = std::function<bool(ModuleService, Services&)>; + struct Config { + ModuleIdentifier name; + std::vector<ModuleService> provides; + std::vector<ModuleService> depends; + ServiceFactory factory = nullptr; + }; + +} // namespace fggl::modules + +#endif //FGGL_MODULES_MODULE_HPP diff --git a/include/fggl/subsystem/cursed/god_object.hpp b/include/fggl/subsystem/cursed/god_object.hpp index 01e7a2a..100fa01 100644 --- a/include/fggl/subsystem/cursed/god_object.hpp +++ b/include/fggl/subsystem/cursed/god_object.hpp @@ -66,12 +66,6 @@ namespace fggl::subsystem { inline void setup() { m_setup = true; - ServiceContainer<audio::AudioService>::getPtr()->setup( - ServiceContainer<data::Storage>::getPtr() - ); - m_fonts->setup( - ServiceContainer<data::Storage>::getPtr() - ); } inline void teardown() {} -- GitLab