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>,
"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));
services_[typeId] = std::static_pointer_cast<IService>(service);
orderedServices_.push_back(service);
@ -64,7 +64,7 @@ public:
static_assert(std::is_base_of_v<IService, T>,
"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));
factories_[typeId] = [factory]() -> SharedPtr<IService> {
return std::static_pointer_cast<IService>(factory());
@ -86,7 +86,7 @@ public:
static_assert(std::is_base_of_v<IService, T>,
"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 it = services_.find(typeId);
@ -113,7 +113,7 @@ public:
static_assert(std::is_base_of_v<IService, T>,
"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 it = services_.find(typeId);
if (it != services_.end()) {
@ -128,7 +128,7 @@ public:
* @return true
*/
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));
return services_.find(typeId) != services_.end() ||
factories_.find(typeId) != factories_.end();
@ -139,7 +139,7 @@ public:
* @tparam T
*/
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 it = services_.find(typeId);
@ -214,7 +214,7 @@ private:
std::unordered_map<std::type_index, std::function<SharedPtr<IService>()>>
factories_;
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() {
std::lock_guard<std::mutex> lock(mutex_);
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& service : orderedServices_) {
if (!service) continue;
@ -31,7 +31,7 @@ bool ServiceLocator::initializeAll() {
}
void ServiceLocator::shutdownAll() {
std::lock_guard<std::mutex> lock(mutex_);
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto it = orderedServices_.rbegin();
it != orderedServices_.rend(); ++it) {
@ -44,7 +44,7 @@ void ServiceLocator::shutdownAll() {
}
void ServiceLocator::updateAll(float deltaTime) {
std::lock_guard<std::mutex> lock(mutex_);
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& service : orderedServices_) {
if (service && service->isInitialized()) {
@ -57,7 +57,7 @@ void ServiceLocator::updateAll(float deltaTime) {
}
void ServiceLocator::pauseAll() {
std::lock_guard<std::mutex> lock(mutex_);
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& service : orderedServices_) {
if (service && service->isInitialized()) {
@ -67,7 +67,7 @@ void ServiceLocator::pauseAll() {
}
void ServiceLocator::resumeAll() {
std::lock_guard<std::mutex> lock(mutex_);
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& service : orderedServices_) {
if (service && service->isInitialized()) {
@ -77,12 +77,12 @@ void ServiceLocator::resumeAll() {
}
std::vector<SharedPtr<IService>> ServiceLocator::getAllServices() const {
std::lock_guard<std::mutex> lock(mutex_);
std::lock_guard<std::recursive_mutex> lock(mutex_);
return orderedServices_;
}
void ServiceLocator::clear() {
std::lock_guard<std::mutex> lock(mutex_);
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto it = orderedServices_.rbegin();
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,40 +3,42 @@
namespace extra2d {
HelloModule::HelloModule(const HelloCfg& cfg) : cfg_(cfg) {}
HelloModule::HelloModule(const HelloCfg &cfg) : cfg_(cfg) {}
HelloModule::HelloModule(std::function<void(HelloCfg&)> configFn) {
configFn(cfg_);
HelloModule::HelloModule(std::function<void(HelloCfg &)> configFn) {
configFn(cfg_);
}
HelloModule::~HelloModule() {
if (initialized_) {
shutdown();
}
if (initialized_) {
shutdown();
}
}
bool HelloModule::init() {
if (initialized_) return true;
std::cout << "HelloModule initialized" << std::endl;
std::cout << " Greeting: " << cfg_.greeting << std::endl;
std::cout << " Repeat count: " << cfg_.repeatCount << std::endl;
initialized_ = true;
if (initialized_)
return true;
E2D_INFO("HelloModule initialized");
E2D_INFO(" Greeting: {}", cfg_.greeting);
E2D_INFO(" Repeat count: {}", cfg_.repeatCount);
initialized_ = true;
return true;
}
void HelloModule::shutdown() {
if (!initialized_) return;
std::cout << "HelloModule shutdown" << std::endl;
initialized_ = false;
if (!initialized_)
return;
E2D_INFO("HelloModule shutdown");
initialized_ = false;
}
void HelloModule::sayHello() const {
for (int i = 0; i < cfg_.repeatCount; ++i) {
std::cout << cfg_.greeting << std::endl;
}
for (int i = 0; i < cfg_.repeatCount; ++i) {
std::cout << cfg_.greeting << std::endl;
}
}
} // namespace extra2d

View File

@ -1,8 +1,9 @@
#pragma once
#include <extra2d/core/module.h>
#include <string>
#include <extra2d/extra2d.h>
#include <functional>
#include <string>
namespace extra2d {
@ -10,14 +11,11 @@ namespace extra2d {
* @brief Hello模块配置结构
*/
struct HelloCfg {
std::string greeting;
int repeatCount;
int priority;
std::string greeting;
int repeatCount;
int priority;
HelloCfg()
: greeting("Hello, Extra2D!")
, repeatCount(1)
, priority(100) {}
HelloCfg() : greeting("Hello, Extra2D!"), repeatCount(1), priority(100) {}
};
/**
@ -26,42 +24,42 @@ struct HelloCfg {
*/
class HelloModule : public Module {
public:
/**
* @brief
*/
using Cfg = HelloCfg;
/**
* @brief
*/
using Cfg = HelloCfg;
/**
* @brief
* @param cfg
*/
explicit HelloModule(const HelloCfg& cfg = HelloCfg{});
/**
* @brief
* @param cfg
*/
explicit HelloModule(const HelloCfg &cfg = HelloCfg{});
/**
* @brief Lambda
* @param configFn
*/
explicit HelloModule(std::function<void(HelloCfg&)> configFn);
/**
* @brief
*/
~HelloModule() override;
bool init() override;
void shutdown() override;
bool ok() const override { return initialized_; }
const char* name() const override { return "hello"; }
int priority() const override { return cfg_.priority; }
/**
* @brief
*/
void sayHello() const;
/**
* @brief Lambda
* @param configFn
*/
explicit HelloModule(std::function<void(HelloCfg &)> configFn);
/**
* @brief
*/
~HelloModule() override;
bool init() override;
void shutdown() override;
bool ok() const override { return initialized_; }
const char *name() const override { return "hello"; }
int priority() const override { return cfg_.priority; }
/**
* @brief
*/
void sayHello() const;
private:
HelloCfg cfg_;
bool initialized_ = false;
HelloCfg cfg_;
bool initialized_ = false;
};
} // namespace extra2d

View File

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