diff --git a/components/core/include/fggl/services/factory.hpp b/components/core/include/fggl/services/factory.hpp index fc2eb791601397dc46e520dc04398bb6c446630d..14cfecc70bb871f224934c16faf443f3d640be91 100644 --- a/components/core/include/fggl/services/factory.hpp +++ b/components/core/include/fggl/services/factory.hpp @@ -30,13 +30,6 @@ namespace fggl::services { - #ifdef NDEBUG - class Generator; - using GeneratorView = Generator; - #else - class GeneratorView; - #endif - class Generator; struct ServiceBinding { @@ -132,7 +125,7 @@ namespace fggl::services { inline ServiceBindingT<T>& simply() { m_instance = nullptr; - m_factory = [](const GeneratorView* /*generator*/) { + m_factory = [](const Generator* /*generator*/) { return std::make_shared<T>(); }; return *this; @@ -150,7 +143,7 @@ namespace fggl::services { template<Subclass<T> Impl> inline ServiceBindingT<T>& simplyTo(){ m_instance = nullptr; - m_factory = [](const GeneratorView* /*generator*/) { + m_factory = [](const Generator* /*generator*/) { return std::make_shared<Impl>(); }; return *this; @@ -192,24 +185,8 @@ namespace fggl::services { bool m_singleton = false; }; - #ifndef NDEBUG - struct GeneratorView { - public: - inline GeneratorView(Generator* generator, const std::vector<ServiceName>& depends) : m_generator(generator), m_declared(depends) {} - - template<ServiceAPI api> - std::optional<Service<api>> get() const { - assert(std::find( m_declared.begin(), m_declared.end(), api::service ) != m_declared.end()); - return m_generator->get<api>(); - } - private: - Generator* m_generator; - std::vector<ServiceName> m_declared; - }; - #endif - template<ServiceAPI impl, typename... Args> - std::shared_ptr<void> wire_func(GeneratorView* view) { + std::shared_ptr<void> wire_func(Generator* view) { return std::make_shared<impl>( view->getLazy<Args...>() ); } diff --git a/components/core/include/fggl/services/module.hpp b/components/core/include/fggl/services/module.hpp index f6d8936a5bfb5e8811dec5cacba5c5f000e86604..1e32642f3d935af7e54003c1dcc625b4199b844a 100644 --- a/components/core/include/fggl/services/module.hpp +++ b/components/core/include/fggl/services/module.hpp @@ -19,12 +19,12 @@ #include "factory.hpp" #include <iostream> -#define FGGL_MODULE(id, ...) constexpr static const char* MODULE_ID = #id; \ +#define FGGL_MODULE(id, ...) constexpr static const auto MODULE_ID = fggl::services::ModuleID::make(#id); \ constexpr static const auto MODULE_DEPS = fggl::services::mod_extract_names<__VA_ARGS__>(); \ inline fggl::services::ModuleID getName() const override { return MODULE_ID; } \ inline fggl::services::Module::ServiceList getDepends() const override { return fggl::services::mod_svc_list( MODULE_DEPS ); } -#define FGGL_MODULE_CONTRACT(name, id) struct name { constexpr static const char* MODULE_ID = #id; }; +#define FGGL_MODULE_CONTRACT(name, id) struct name { constexpr static const auto MODULE_ID = fggl::services::ModuleID::make(#id); }; #include <functional> @@ -43,7 +43,7 @@ Generator *m_generator; }; - using ModuleID = const char*; + using ModuleID = util::OpaqueName<std::string_view, struct ModuleTag>; template<typename T> concept ModuleAPI = requires(T* type) { { T::MODULE_ID }; diff --git a/components/physics/src/service.cpp b/components/physics/src/service.cpp index fe78355aef1dddc75b645bce792e937496b5bc33..e6173d9b3124ec77344eb500386ddb3884f005a9 100644 --- a/components/physics/src/service.cpp +++ b/components/physics/src/service.cpp @@ -41,7 +41,7 @@ namespace fggl::phys { } void InternalPhysics::wireServices(services::ModuleBinder &binder) { - binder.bind<phys::PhysicsProvider>().simplyTo<InternalPhysicsProvider>(); + binder.bind<phys::PhysicsProvider>().simplyTo<InternalPhysicsProvider>().asSingleton(); } void checkCollisions(entity::EntityManager& manager) { diff --git a/demo/demo/models/viewer.cpp b/demo/demo/models/viewer.cpp index 6f365f33cf2beaeda03209df31747d0649bb3471..5c3ac45338c10977785ab534ba8fc3038aa02bce 100644 --- a/demo/demo/models/viewer.cpp +++ b/demo/demo/models/viewer.cpp @@ -102,7 +102,7 @@ namespace demo { lightComp.specular = fggl::gfx::colours::MIDNIGHT_BLUE; } - Viewer::Viewer(fggl::App &app) : fggl::scenes::Game(app), m_model(fggl::entity::INVALID) { + Viewer::Viewer(fggl::App &app) : fggl::scenes::Game(app), m_model(fggl::entity::INVALID), m_debug(false) { } diff --git a/fggl/entity/module.cpp b/fggl/entity/module.cpp index 9860c38f78f1f14c45b88e119e51c8dce3afe708..c60df808c69aee83f2be84118edefdae329ee936 100644 --- a/fggl/entity/module.cpp +++ b/fggl/entity/module.cpp @@ -66,32 +66,6 @@ namespace fggl::entity { } - auto ECS::factory(modules::ServiceName service, modules::Services &services) -> bool { - /*if (service == EntityFactory::service) { - auto *factory = services.create<EntityFactory>(services); - install_component_factories(factory); - - // we are responsible for prefabs... - auto *assetLoader = services.get<assets::Loader>(); - assetLoader->setFactory(ENTITY_PROTOTYPE, [factory](assets::Loader* loader, const assets::AssetID& a, assets::LoaderContext b, void* ptr) { - EntityFactory* facPtr = factory; - if ( ptr != nullptr ) { - facPtr = (EntityFactory*)ptr; - } - return load_prototype(loader, a, b, facPtr); - }, assets::LoadType::PATH); - assetLoader->setFactory(ENTITY_SCENE, load_scene, assets::LoadType::PATH); - - // allow auto-detection - auto *checkin = services.get<assets::CheckinAdapted>(); - checkin->setLoader(MIME_SCENE, assets::NEEDS_CHECKIN, is_scene); - checkin->setProcessor(MIME_SCENE, get_scene_deps); - - return true; - }*/ - return false; - } - void ECS::setup(services::Generator *generator) { auto loader = generator->getLazy<assets::Loader>(); diff --git a/fggl/gfx/ogl/renderer.cpp b/fggl/gfx/ogl/renderer.cpp index 6b3b60ecf18f4878f24cebcbce0dd1cf5ac71e6f..24ab2c4df314f00ea2fb5c21056ab8109e46c3ce 100644 --- a/fggl/gfx/ogl/renderer.cpp +++ b/fggl/gfx/ogl/renderer.cpp @@ -282,4 +282,8 @@ namespace fggl::gfx { glViewport(0, 0, width, height); } + OpenGL4Backend::~OpenGL4Backend() { + delete m_cache; + } + } // namespace fggl::gfx diff --git a/fggl/gfx/window.cpp b/fggl/gfx/window.cpp index 7612d8d339409d763454213b0d3ee2e817f25491..7ec9ad95ef9929714d8c09affdaa706009da764d 100644 --- a/fggl/gfx/window.cpp +++ b/fggl/gfx/window.cpp @@ -156,7 +156,6 @@ namespace fggl::display::glfw { Window::Window(std::shared_ptr<GlfwContext> context, gfx::WindowGraphics *graphics) : m_context(std::move(context)), m_window(nullptr), m_framesize() { - assert( context != nullptr ); assert( graphics != nullptr ); // don't iconify when focus is lost. diff --git a/fggl/modules/manager.cpp b/fggl/modules/manager.cpp index 391167f46050066954cdaf7f19140606832f82dd..bf77609f0b82c4e8a5853d2544f6c296aad89a71 100644 --- a/fggl/modules/manager.cpp +++ b/fggl/modules/manager.cpp @@ -21,9 +21,14 @@ namespace fggl::modules { bool Manager::buildGraph() { + + for ( auto& api : m_serviceProviders ) { + std::cerr << api.first.get() << " is provided by " << api.second.get() << std::endl; + } + // resolve links between modules for (auto &moduleItr : m_modules) { - debug::trace("Generating vertex for {}", moduleItr.first); + debug::trace("Generating vertex for {}", moduleItr.first.get()); // add us to the module graph m_dependencies.addVertex( moduleItr.first ); @@ -35,8 +40,8 @@ namespace fggl::modules { if (provider == m_serviceProviders.end()) { debug::log(debug::Level::warning, "{} depends on {}, but nothing provides it", - moduleItr.first, - service); + moduleItr.first.get(), + service.get()); // nothing can provide the service requested, setup is invalid. return false; } @@ -60,7 +65,7 @@ namespace fggl::modules { services::ModuleBinder binder(&m_services); while (!stack.empty()) { auto nextToInit = stack.front(); - debug::log(debug::Level::info, "Initializing {}", nextToInit); + debug::log(debug::Level::info, "Initializing {}", nextToInit.get()); auto &module = m_modules.at(nextToInit); module->setup( &m_services ); diff --git a/fggl/scenes/game.cpp b/fggl/scenes/game.cpp index 3fb852571f6fa7ebf59f900fe76ea048b71343bd..9a134fb6b04ce38b25e56896c653c10c4a76ba8f 100644 --- a/fggl/scenes/game.cpp +++ b/fggl/scenes/game.cpp @@ -38,7 +38,7 @@ namespace fggl::scenes { } } - Game::Game(fggl::App &app) : AppState(app) { + Game::Game(fggl::App &app) : AppState(app), m_debug(false) { m_input = app.service<input::Input>(); } diff --git a/include/fggl/data/texture.hpp b/include/fggl/data/texture.hpp index b1cf34c04c25f42855f7e8c15dc226a0042fff63..172940e8f615c2649f7d1a0b82a8fe4ac7abe50a 100644 --- a/include/fggl/data/texture.hpp +++ b/include/fggl/data/texture.hpp @@ -34,7 +34,7 @@ namespace fggl::data { Texture2D(const Texture2D& other) = delete; inline ~Texture2D() { - delete data; + std::free(data); } }; diff --git a/include/fggl/ds/graph.hpp b/include/fggl/ds/graph.hpp index 7c4bdc6a6716d5dacbd9bea01ed08720d848dd36..4433730425791ad99507ff0ccef8963b9b2453a6 100644 --- a/include/fggl/ds/graph.hpp +++ b/include/fggl/ds/graph.hpp @@ -107,7 +107,6 @@ namespace fggl::ds { bool getOrderRev(std::queue<T> &stack) { std::set<T> visited{}; - for (const auto &module : m_edges) { if (!visited.contains(module.first)) { sortUtilRev(module.first, visited, stack); @@ -130,8 +129,9 @@ namespace fggl::ds { visited.emplace(idx); for (auto dep : m_edges.at(idx)) { - if (!visited.contains(dep)) + if (!visited.contains(dep)) { sortUtil(dep, visited, stack); + } } stack.push(idx); @@ -140,11 +140,22 @@ namespace fggl::ds { void sortUtilRev(T idx, std::set<T> &visited, std::queue<T> &stack) { visited.emplace(idx); - assert( m_edges.contains(idx) ); - for (auto dep : m_edges.at(idx)) { - if (!visited.contains(dep)) { - sortUtilRev(dep, visited, stack); + auto myDeps = m_edges.at(idx); + for (auto& dep : myDeps) { + + if ( m_edges.find(dep) == m_edges.end() ) { + debug::warning("dependency was in graph, but does not exist as vertex: {}", dep.get()); + continue; + } + + assert( m_edges.contains(dep) ); + // ensure dependency loops don't cause errors + if ( visited.contains(dep) ) { + debug::warning("Dependency loop detected, aborting"); + continue; } + + sortUtilRev(dep, visited, stack); } stack.push(idx); diff --git a/include/fggl/entity/module.hpp b/include/fggl/entity/module.hpp index 9a15218d23855cab71a35e7072211a5b64abe8a0..707569e698d6efa2b11bcf1e45a97789e31792c6 100644 --- a/include/fggl/entity/module.hpp +++ b/include/fggl/entity/module.hpp @@ -35,15 +35,6 @@ namespace fggl::entity { struct ECS : public services::Module { FGGL_MODULE(fggl::entity::ECS, assets::PackedAssets, assets::AssetFolders) - constexpr static const std::array<modules::ServiceName, 1> provides = { - FGGL_SERVICE(EntityFactory) - }; - constexpr static const std::array<modules::ServiceName, 2> depends = { - FGGL_SERVICE(assets::Loader), - FGGL_SERVICE(assets::CheckinAdapted) - }; - static bool factory(modules::ServiceName name, modules::Services &serviceManager); - void setup(services::Generator* generator) override; void wireServices(services::ModuleBinder& binder) override; }; diff --git a/include/fggl/gfx/ogl/renderer.hpp b/include/fggl/gfx/ogl/renderer.hpp index 4ff76310c2f693c27ad545e81b8ede3b87b79c3e..fba80c348a03151f69e5dee146a814baef19a9c5 100644 --- a/include/fggl/gfx/ogl/renderer.hpp +++ b/include/fggl/gfx/ogl/renderer.hpp @@ -42,7 +42,7 @@ namespace fggl::gfx { class OpenGL4Backend : public Graphics { public: explicit OpenGL4Backend(gui::FontLibrary *fonts, assets::AssetManager *assets, ShaderCache* cache, GlFunctionLoader loader); - ~OpenGL4Backend() override = default; + ~OpenGL4Backend() override; // copy bad OpenGL4Backend(const OpenGL4Backend &) = delete; diff --git a/include/fggl/gfx/ogl4/models.hpp b/include/fggl/gfx/ogl4/models.hpp index fd121d3393a450cbbad1f0306c6c1774c9410fd2..4cc7747834338488a6acce2869b028944b31e50d 100644 --- a/include/fggl/gfx/ogl4/models.hpp +++ b/include/fggl/gfx/ogl4/models.hpp @@ -105,7 +105,7 @@ namespace fggl::gfx::ogl4 { /** * Render all visible objects according to their render tokens. */ - void renderModelsForward(const entity::EntityManager &world, bool debugMode); + void renderModelsForward(const entity::EntityManager &world, bool debugMode = false); assets::AssetManager *m_assets; gfx::ShaderCache *m_shaders;