diff --git a/.gitignore b/.gitignore index 6fd54a1..c67454b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ bin/ debug/ external/ compile_commands.json +src/*~ diff --git a/src/asset.cpp b/src/asset.cpp index 2b14586..f2fba34 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -9,6 +10,7 @@ #include #include #include +#include namespace fs = std::filesystem; @@ -104,6 +106,7 @@ void RaylibAssetLoader::load_asset(std::string path){ } void RaylibAssetLoader::unload_asset(std::string path){ + if (!assets.contains(path)) return; Asset asset = assets[path]; std::visit([](auto&& arg) { @@ -136,7 +139,9 @@ void RaylibAssetLoader::unload_asset(std::string path){ void RaylibAssetLoader::unload_all_assets(){ - for (auto [path,_] : assets){ + std::vector assets_to_unload; + std::ranges::copy(std::views::keys(assets),std::back_inserter(assets_to_unload)); + for (const auto &path : assets_to_unload){ unload_asset(path); } } diff --git a/src/include/asset/raylib_asset.hpp b/src/include/asset/raylib_asset.hpp index 5e82631..f4b402b 100644 --- a/src/include/asset/raylib_asset.hpp +++ b/src/include/asset/raylib_asset.hpp @@ -25,7 +25,7 @@ class RaylibAssetLoader : public AssetLoader{ }; -extern RaylibAssetLoader asset_loader; +// extern RaylibAssetLoader asset_loader; diff --git a/src/include/locator.hpp b/src/include/locator.hpp index e8383a6..76b5c0a 100644 --- a/src/include/locator.hpp +++ b/src/include/locator.hpp @@ -1,3 +1,24 @@ #pragma once +#include +#include -class ServiceLocator{}; +// A simple Service Locator +class ServiceLocator { +private: + static inline SceneManager* s_scene_manager = nullptr; + static inline RaylibAssetLoader* s_asset_loader = nullptr; + + // static inline Configuration* s_config = nullptr; + + // static inline AssetManager* s_assets = nullptr; + +public: + static void provide(SceneManager* service) { s_scene_manager = service; } + static void provide(RaylibAssetLoader* service) { s_asset_loader = service; } + + static SceneManager& get_scene_manager() { return *s_scene_manager; } + static RaylibAssetLoader& get_asset_loader() { return *s_asset_loader; } + + // static SceneManager& get_config() { return *s_config; } + // static AssetManager& GetAssets() { return *s_assets; } +}; diff --git a/src/include/scene.hpp b/src/include/scene.hpp index 64a7b20..30c4760 100644 --- a/src/include/scene.hpp +++ b/src/include/scene.hpp @@ -10,26 +10,6 @@ enum class SceneType{ }; -// Simple global data structure to hold the switch request -struct EngineState { - bool pendingSwitch = false; - SceneType nextScene; - - bool shouldQuit = false; - - void request_switch(SceneType type) { - nextScene = type; - pendingSwitch = true; - } - - void quit(){ - shouldQuit = true; - } -}; - -// Expose the global state to any file that includes scene.hpp -extern EngineState g_Engine; - class Scene{ @@ -73,9 +53,11 @@ class SceneManager{ private: Scene* current_scene = nullptr; SceneType next_scene_type; - bool should_switch = false; + bool pending_switch = false; + bool should_quit = false; public: + SceneManager(); ~SceneManager(); @@ -83,4 +65,7 @@ class SceneManager{ void render(); void ui(); void process_scene_switch(); + bool should_game_close(); + void request_switch(SceneType type); + void quit(); }; diff --git a/src/locator.cpp b/src/locator.cpp deleted file mode 100644 index c495774..0000000 --- a/src/locator.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include - -// Will contain definition of service locator class diff --git a/src/main.cpp b/src/main.cpp index 03b1d57..7af0efd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include "locator.hpp" #include #include #include @@ -16,13 +17,6 @@ #include #endif -// Globals -EngineState g_Engine; -RaylibAssetLoader asset_loader; - -entt::registry * registry; -SceneManager* scene_manager; - void UpdateDrawFrame(void) { // Update @@ -31,20 +25,20 @@ void UpdateDrawFrame(void) { if (dt > 0.1f) dt = 0.1f; // Draw - scene_manager->update(dt); + ServiceLocator::get_scene_manager().update(dt); BeginDrawing(); ClearBackground(RAYWHITE); - scene_manager->render(); + ServiceLocator::get_scene_manager().render(); rlImGuiBegin(); - scene_manager->ui(); + ServiceLocator::get_scene_manager().ui(); rlImGuiEnd(); EndDrawing(); - scene_manager->process_scene_switch(); // !!! After scene_manager is done with the current loop + ServiceLocator::get_scene_manager().process_scene_switch(); // !!! After scene_manager is done with the current loop } int main(){ @@ -53,9 +47,11 @@ int main(){ int screen_width = 1280; int screen_height = 800; - // initialized scene manager - scene_manager = new SceneManager(); - registry = new entt::registry(); + RaylibAssetLoader asset_loader; + SceneManager scene_manager; + + ServiceLocator::provide(&asset_loader); + ServiceLocator::provide(&scene_manager); // Depends on asset loader! rlImGuiSetup(true); @@ -86,15 +82,13 @@ int main(){ #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(UpdateDrawFrame, 0, 1); #else - while (!WindowShouldClose() && !g_Engine.shouldQuit){ + while (!ServiceLocator::get_scene_manager().should_game_close()){ UpdateDrawFrame(); } #endif CloseWindow(); rlImGuiShutdown(); - delete scene_manager; - delete registry; return 0; } diff --git a/src/scenes/game_play_scene.cpp b/src/scenes/game_play_scene.cpp index 0a7d392..2632428 100644 --- a/src/scenes/game_play_scene.cpp +++ b/src/scenes/game_play_scene.cpp @@ -1,3 +1,4 @@ +#include "locator.hpp" #include #include #include @@ -13,10 +14,10 @@ GamePlayScene::GamePlayScene() { registry = entt::registry(); - asset_loader.load_asset("assets/snake_head.png"); - asset_loader.load_asset("assets/fruit.png"); - create_player(registry,asset_loader.get_texture("assets/snake_head.png")); - create_fruit(registry,asset_loader.get_texture("assets/fruit.png")); + ServiceLocator::get_asset_loader().load_asset("assets/snake_head.png"); + ServiceLocator::get_asset_loader().load_asset("assets/fruit.png"); + create_player(registry,ServiceLocator::get_asset_loader().get_texture("assets/snake_head.png")); + create_fruit(registry,ServiceLocator::get_asset_loader().get_texture("assets/fruit.png")); } @@ -47,13 +48,17 @@ void GamePlayScene::ui() { ImGui::Begin("Exit", nullptr, flags); if (ImGui::Button("X",{40.f,40.f})){ - g_Engine.request_switch(SceneType::MENU); + ServiceLocator::get_scene_manager().request_switch(SceneType::MENU); } ImGui::End(); } GamePlayScene::~GamePlayScene(){ - asset_loader.unload_asset("assets/snake_head.png"); - asset_loader.unload_asset("assets/fruit.png"); + + ServiceLocator::get_scene_manager(); + ServiceLocator::get_asset_loader(); + + ServiceLocator::get_asset_loader().unload_asset("assets/snake_head.png"); + ServiceLocator::get_asset_loader().unload_asset("assets/fruit.png"); } diff --git a/src/scenes/menu_scene.cpp b/src/scenes/menu_scene.cpp index 277f104..ead46cc 100644 --- a/src/scenes/menu_scene.cpp +++ b/src/scenes/menu_scene.cpp @@ -1,3 +1,4 @@ +#include "locator.hpp" #include #include #include @@ -38,13 +39,13 @@ void MenuScene::ui() { // ImGui::SetCursorPos(centeredPos); if (ImGui::Button("Play",button_size)){ - g_Engine.request_switch(SceneType::GAMEPLAY); + ServiceLocator::get_scene_manager().request_switch(SceneType::GAMEPLAY); } ImGui::Dummy(ImVec2(0, 10)); // Gap if (ImGui::Button("Quit",button_size)){ - g_Engine.quit(); + ServiceLocator::get_scene_manager().quit(); } ImGui::End(); diff --git a/src/scenes/scene.cpp b/src/scenes/scene.cpp index 3cdbff6..9c71d83 100644 --- a/src/scenes/scene.cpp +++ b/src/scenes/scene.cpp @@ -1,3 +1,4 @@ +#include "raylib.h" #include SceneManager::SceneManager(){ @@ -9,11 +10,14 @@ SceneManager::~SceneManager(){ } void SceneManager::process_scene_switch(){ - if (!g_Engine.pendingSwitch) return; - delete current_scene; + if (!pending_switch) return; + + if (current_scene){ + delete current_scene; + } - switch(g_Engine.nextScene){ + switch(next_scene_type){ case SceneType::MENU: current_scene = new MenuScene(); break; @@ -21,19 +25,32 @@ void SceneManager::process_scene_switch(){ current_scene = new GamePlayScene(); break; } - g_Engine.pendingSwitch = false; + pending_switch = false; } void SceneManager::update(float dt){ - if (current_scene){ - current_scene->update(dt); - } + if (!current_scene) return; + current_scene->update(dt); } void SceneManager::render(){ - current_scene->render(); + if (!current_scene) return; + current_scene->render(); } void SceneManager::ui(){ - current_scene->ui(); + if (!current_scene) return; + current_scene->ui(); +} + +bool SceneManager::should_game_close(){ + return should_quit || WindowShouldClose(); +} + +void SceneManager::request_switch(SceneType type){ + next_scene_type = type; + pending_switch = true; +} +void SceneManager::quit(){ + should_quit = true; }