add service locator

This commit is contained in:
2026-07-14 23:14:54 +01:00
parent 0c3eb01521
commit bdcffaeac5
10 changed files with 88 additions and 62 deletions
+6 -1
View File
@@ -1,3 +1,4 @@
#include <algorithm>
#include <asset/asset.hpp>
#include <asset/raylib_asset.hpp>
@@ -9,6 +10,7 @@
#include <iostream>
#include <filesystem>
#include <variant>
#include <ranges>
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<std::string> 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);
}
}
+1 -1
View File
@@ -25,7 +25,7 @@ class RaylibAssetLoader : public AssetLoader{
};
extern RaylibAssetLoader asset_loader;
// extern RaylibAssetLoader asset_loader;
+22 -1
View File
@@ -1,3 +1,24 @@
#pragma once
#include <scene.hpp>
#include <asset/raylib_asset.hpp>
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; }
};
+6 -21
View File
@@ -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();
};
-3
View File
@@ -1,3 +0,0 @@
#include <locator.hpp>
// Will contain definition of service locator class
+11 -17
View File
@@ -1,3 +1,4 @@
#include "locator.hpp"
#include <asset/raylib_asset.hpp>
#include <scene.hpp>
#include <components.hpp>
@@ -16,13 +17,6 @@
#include <emscripten.h>
#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;
}
+12 -7
View File
@@ -1,3 +1,4 @@
#include "locator.hpp"
#include <player.hpp>
#include <movement.hpp>
#include <scene.hpp>
@@ -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");
}
+3 -2
View File
@@ -1,3 +1,4 @@
#include "locator.hpp"
#include <player.hpp>
#include <movement.hpp>
#include <scene.hpp>
@@ -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();
+26 -9
View File
@@ -1,3 +1,4 @@
#include "raylib.h"
#include <scene.hpp>
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;
}