refactor(service_locator): 将mutex替换为recursive_mutex以支持嵌套调用

重构服务定位器中的互斥锁类型,从std::mutex改为std::recursive_mutex,以支持可能发生的嵌套调用场景
优化hello_module日志输出,使用E2D_INFO宏替代std::cout
删除不再使用的config.json配置文件
This commit is contained in:
ChestnutYueyue 2026-02-18 22:11:00 +08:00
parent b1996dfc44
commit 463965439e
6 changed files with 86 additions and 104 deletions

View File

@ -48,7 +48,7 @@ public:
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
services_[typeId] = std::static_pointer_cast<IService>(service); services_[typeId] = std::static_pointer_cast<IService>(service);
orderedServices_.push_back(service); orderedServices_.push_back(service);
@ -64,7 +64,7 @@ public:
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
factories_[typeId] = [factory]() -> SharedPtr<IService> { factories_[typeId] = [factory]() -> SharedPtr<IService> {
return std::static_pointer_cast<IService>(factory()); return std::static_pointer_cast<IService>(factory());
@ -86,7 +86,7 @@ public:
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
auto it = services_.find(typeId); auto it = services_.find(typeId);
@ -113,7 +113,7 @@ public:
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
auto it = services_.find(typeId); auto it = services_.find(typeId);
if (it != services_.end()) { if (it != services_.end()) {
@ -128,7 +128,7 @@ public:
* @return true * @return true
*/ */
template <typename T> bool hasService() const { template <typename T> bool hasService() const {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
return services_.find(typeId) != services_.end() || return services_.find(typeId) != services_.end() ||
factories_.find(typeId) != factories_.end(); factories_.find(typeId) != factories_.end();
@ -139,7 +139,7 @@ public:
* @tparam T * @tparam T
*/ */
template <typename T> void unregisterService() { template <typename T> void unregisterService() {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
auto it = services_.find(typeId); auto it = services_.find(typeId);
@ -214,7 +214,7 @@ private:
std::unordered_map<std::type_index, std::function<SharedPtr<IService>()>> std::unordered_map<std::type_index, std::function<SharedPtr<IService>()>>
factories_; factories_;
std::vector<SharedPtr<IService>> orderedServices_; std::vector<SharedPtr<IService>> orderedServices_;
mutable std::mutex mutex_; mutable std::recursive_mutex mutex_;
}; };
/** /**

View File

@ -9,7 +9,7 @@ ServiceLocator& ServiceLocator::instance() {
} }
bool ServiceLocator::initializeAll() { bool ServiceLocator::initializeAll() {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& service : orderedServices_) { for (auto& service : orderedServices_) {
if (!service) continue; if (!service) continue;
@ -31,7 +31,7 @@ bool ServiceLocator::initializeAll() {
} }
void ServiceLocator::shutdownAll() { void ServiceLocator::shutdownAll() {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto it = orderedServices_.rbegin(); for (auto it = orderedServices_.rbegin();
it != orderedServices_.rend(); ++it) { it != orderedServices_.rend(); ++it) {
@ -44,7 +44,7 @@ void ServiceLocator::shutdownAll() {
} }
void ServiceLocator::updateAll(float deltaTime) { void ServiceLocator::updateAll(float deltaTime) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& service : orderedServices_) { for (auto& service : orderedServices_) {
if (service && service->isInitialized()) { if (service && service->isInitialized()) {
@ -57,7 +57,7 @@ void ServiceLocator::updateAll(float deltaTime) {
} }
void ServiceLocator::pauseAll() { void ServiceLocator::pauseAll() {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& service : orderedServices_) { for (auto& service : orderedServices_) {
if (service && service->isInitialized()) { if (service && service->isInitialized()) {
@ -67,7 +67,7 @@ void ServiceLocator::pauseAll() {
} }
void ServiceLocator::resumeAll() { void ServiceLocator::resumeAll() {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& service : orderedServices_) { for (auto& service : orderedServices_) {
if (service && service->isInitialized()) { if (service && service->isInitialized()) {
@ -77,12 +77,12 @@ void ServiceLocator::resumeAll() {
} }
std::vector<SharedPtr<IService>> ServiceLocator::getAllServices() const { std::vector<SharedPtr<IService>> ServiceLocator::getAllServices() const {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
return orderedServices_; return orderedServices_;
} }
void ServiceLocator::clear() { void ServiceLocator::clear() {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto it = orderedServices_.rbegin(); for (auto it = orderedServices_.rbegin();
it != orderedServices_.rend(); ++it) { it != orderedServices_.rend(); ++it) {

View File

@ -1,18 +0,0 @@
{
"app": {
"name": "HelloModule Example",
"version": "1.0.0"
},
"window": {
"title": "Hello Module Example",
"width": 800,
"height": 600,
"mode": "windowed",
"vsync": true
},
"hello": {
"greeting": "Hello from custom module!",
"repeatCount": 3,
"enableLogging": true
}
}

View File

@ -3,9 +3,9 @@
namespace extra2d { namespace extra2d {
HelloModule::HelloModule(const HelloCfg& cfg) : cfg_(cfg) {} HelloModule::HelloModule(const HelloCfg &cfg) : cfg_(cfg) {}
HelloModule::HelloModule(std::function<void(HelloCfg&)> configFn) { HelloModule::HelloModule(std::function<void(HelloCfg &)> configFn) {
configFn(cfg_); configFn(cfg_);
} }
@ -16,20 +16,22 @@ HelloModule::~HelloModule() {
} }
bool HelloModule::init() { bool HelloModule::init() {
if (initialized_) return true; if (initialized_)
return true;
std::cout << "HelloModule initialized" << std::endl; E2D_INFO("HelloModule initialized");
std::cout << " Greeting: " << cfg_.greeting << std::endl; E2D_INFO(" Greeting: {}", cfg_.greeting);
std::cout << " Repeat count: " << cfg_.repeatCount << std::endl; E2D_INFO(" Repeat count: {}", cfg_.repeatCount);
initialized_ = true; initialized_ = true;
return true; return true;
} }
void HelloModule::shutdown() { void HelloModule::shutdown() {
if (!initialized_) return; if (!initialized_)
return;
std::cout << "HelloModule shutdown" << std::endl; E2D_INFO("HelloModule shutdown");
initialized_ = false; initialized_ = false;
} }

View File

@ -1,8 +1,9 @@
#pragma once #pragma once
#include <extra2d/core/module.h> #include <extra2d/extra2d.h>
#include <string>
#include <functional> #include <functional>
#include <string>
namespace extra2d { namespace extra2d {
@ -14,10 +15,7 @@ struct HelloCfg {
int repeatCount; int repeatCount;
int priority; int priority;
HelloCfg() HelloCfg() : greeting("Hello, Extra2D!"), repeatCount(1), priority(100) {}
: greeting("Hello, Extra2D!")
, repeatCount(1)
, priority(100) {}
}; };
/** /**
@ -35,13 +33,13 @@ public:
* @brief * @brief
* @param cfg * @param cfg
*/ */
explicit HelloModule(const HelloCfg& cfg = HelloCfg{}); explicit HelloModule(const HelloCfg &cfg = HelloCfg{});
/** /**
* @brief Lambda * @brief Lambda
* @param configFn * @param configFn
*/ */
explicit HelloModule(std::function<void(HelloCfg&)> configFn); explicit HelloModule(std::function<void(HelloCfg &)> configFn);
/** /**
* @brief * @brief
@ -51,7 +49,7 @@ public:
bool init() override; bool init() override;
void shutdown() override; void shutdown() override;
bool ok() const override { return initialized_; } bool ok() const override { return initialized_; }
const char* name() const override { return "hello"; } const char *name() const override { return "hello"; }
int priority() const override { return cfg_.priority; } int priority() const override { return cfg_.priority; }
/** /**

View File

@ -1,21 +1,18 @@
#include "hello_module.h" #include "hello_module.h"
#include <extra2d/extra2d.h> #include <extra2d/extra2d.h>
#include <iostream>
using namespace extra2d; using namespace extra2d;
class HelloScene : public Scene { class HelloScene : public Scene {
public: public:
static Ptr<HelloScene> create() { return makeShared<HelloScene>(); }
void onEnter() override { void onEnter() override {
Scene::onEnter(); Scene::onEnter();
std::cout << "HelloScene entered" << std::endl; E2D_INFO("HelloScene entered");
setBackgroundColor(Color(0.1f, 0.1f, 0.2f, 1.0f)); setBackgroundColor(Color(0.1f, 0.1f, 0.2f, 1.0f));
auto hello = Application::get().get<HelloModule>(); auto hello = Application::get().get<HelloModule>();
if (hello) { if (hello) {
std::cout << "Scene calling HelloModule from onEnter..." << std::endl; E2D_INFO("Scene calling HelloModule from onEnter...");
hello->sayHello(); hello->sayHello();
} }
} }
@ -23,16 +20,16 @@ public:
void onUpdate(float dt) override { void onUpdate(float dt) override {
Scene::onUpdate(dt); Scene::onUpdate(dt);
time_ += dt; time_ += dt;
if (time_ >= 1.0f) {
if (time_ >= 5.0f) {
auto *hello = Application::get().get<HelloModule>(); auto *hello = Application::get().get<HelloModule>();
if (hello) { if (hello) {
std::cout << "Scene calling HelloModule from onUpdate..." << std::endl; E2D_INFO("Scene calling HelloModule from onUpdate...");
hello->sayHello(); hello->sayHello();
} }
time_ = 0.0f; time_ = 0.0f;
} }
} }
void onRender(RenderBackend &renderer) override { Scene::onRender(renderer); }
private: private:
float time_ = 0.0f; float time_ = 0.0f;
@ -48,18 +45,21 @@ int main(int argc, char *argv[]) {
cfg.h = 600; cfg.h = 600;
cfg.backend = "glfw"; cfg.backend = "glfw";
}); });
app.use<RenderModule>([](auto &cfg) { cfg.priority = 10; }); app.use<RenderModule>([](auto &cfg) {
cfg.backend = "opengl";
cfg.priority = 10;
});
app.use<HelloModule>([](auto &cfg) { app.use<HelloModule>([](auto &cfg) {
cfg.greeting = "Hello from custom module!"; cfg.greeting = "Hello from custom module!";
cfg.repeatCount = 3; cfg.repeatCount = 3;
}); });
if (!app.init()) { if (!app.init()) {
std::cerr << "Failed to initialize application" << std::endl; E2D_INFO("Failed to initialize application");
return 1; return 1;
} }
auto scene = HelloScene::create(); auto scene = makeShared<HelloScene>();
app.enterScene(scene); app.enterScene(scene);
app.run(); app.run();
app.shutdown(); app.shutdown();