feat(服务定位器): 实现服务自动注册机制并重构服务初始化流程

添加服务自动注册宏E2D_AUTO_REGISTER_SERVICE,通过模板元编程实现编译期服务注册
重构Application初始化流程,移除手动服务注册代码,改为自动注册方式
统一各服务实现类的代码风格,优化缩进和格式
This commit is contained in:
ChestnutYueyue 2026-02-17 12:12:22 +08:00
parent 4f02ad0e39
commit 61dea772f7
13 changed files with 695 additions and 696 deletions

View File

@ -1,11 +1,10 @@
#pragma once #pragma once
#include <extra2d/core/types.h> #include <extra2d/config/app_config.h>
#include <extra2d/core/module.h> #include <extra2d/core/module.h>
#include <extra2d/core/registry.h> #include <extra2d/core/registry.h>
#include <extra2d/core/service_locator.h> #include <extra2d/core/service_locator.h>
#include <extra2d/config/app_config.h> #include <extra2d/core/types.h>
#include <string>
namespace extra2d { namespace extra2d {
@ -21,123 +20,119 @@ class InputModule;
*/ */
class Application { class Application {
public: public:
static Application& get(); static Application &get();
Application(const Application&) = delete; Application(const Application &) = delete;
Application& operator=(const Application&) = delete; Application &operator=(const Application &) = delete;
/** /**
* @brief * @brief
* @tparam T * @tparam T
* @tparam Args * @tparam Args
* @return * @return
*/ */
template<typename T, typename... Args> template <typename T, typename... Args> T *use(Args &&...args) {
T* use(Args&&... args) { return Registry::instance().use<T>(std::forward<Args>(args)...);
return Registry::instance().use<T>(std::forward<Args>(args)...); }
}
/** /**
* @brief * @brief
* @tparam T * @tparam T
* @return * @return
*/ */
template<typename T> template <typename T> T *get() const { return Registry::instance().get<T>(); }
T* get() const {
return Registry::instance().get<T>();
}
/** /**
* @brief * @brief
* @return true * @return true
*/ */
bool init(); bool init();
/** /**
* @brief * @brief
* @param config * @param config
* @return true * @return true
*/ */
bool init(const AppConfig& config); bool init(const AppConfig &config);
/** /**
* @brief * @brief
*/ */
void shutdown(); void shutdown();
/** /**
* @brief * @brief
*/ */
void run(); void run();
/** /**
* @brief 退 * @brief 退
*/ */
void quit(); void quit();
/** /**
* @brief * @brief
*/ */
void pause(); void pause();
/** /**
* @brief * @brief
*/ */
void resume(); void resume();
bool isPaused() const { return paused_; } bool isPaused() const { return paused_; }
bool isRunning() const { return running_; } bool isRunning() const { return running_; }
/** /**
* @brief * @brief
* @return * @return
*/ */
IWindow* window(); IWindow *window();
/** /**
* @brief * @brief
* @return * @return
*/ */
RenderBackend* renderer(); RenderBackend *renderer();
/** /**
* @brief * @brief
* @return * @return
*/ */
IInput* input(); IInput *input();
/** /**
* @brief * @brief
* @param scene * @param scene
*/ */
void enterScene(Ptr<class Scene> scene); void enterScene(Ptr<class Scene> scene);
float deltaTime() const { return deltaTime_; } float deltaTime() const { return deltaTime_; }
float totalTime() const { return totalTime_; } float totalTime() const { return totalTime_; }
int fps() const { return currentFps_; } int fps() const { return currentFps_; }
private: private:
Application(); Application();
~Application(); ~Application();
void mainLoop(); void mainLoop();
void update(); void update();
void render(); void render();
void registerCoreServices(); void configureCameraService();
bool initialized_ = false; bool initialized_ = false;
bool running_ = false; bool running_ = false;
bool paused_ = false; bool paused_ = false;
bool shouldQuit_ = false; bool shouldQuit_ = false;
float deltaTime_ = 0.0f; float deltaTime_ = 0.0f;
float totalTime_ = 0.0f; float totalTime_ = 0.0f;
double lastFrameTime_ = 0.0; double lastFrameTime_ = 0.0;
int frameCount_ = 0; int frameCount_ = 0;
float fpsTimer_ = 0.0f; float fpsTimer_ = 0.0f;
int currentFps_ = 0; int currentFps_ = 0;
AppConfig appConfig_; AppConfig appConfig_;
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -1,22 +1,21 @@
#pragma once #pragma once
#include <algorithm>
#include <extra2d/core/service_interface.h> #include <extra2d/core/service_interface.h>
#include <extra2d/core/types.h> #include <extra2d/core/types.h>
#include <functional>
#include <memory>
#include <mutex>
#include <typeindex>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <mutex>
#include <functional>
#include <typeindex>
#include <memory>
#include <algorithm>
namespace extra2d { namespace extra2d {
/** /**
* @brief * @brief
*/ */
template<typename T> template <typename T> using ServiceFactory = std::function<SharedPtr<T>()>;
using ServiceFactory = std::function<SharedPtr<T>()>;
/** /**
* @brief * @brief
@ -31,222 +30,273 @@ using ServiceFactory = std::function<SharedPtr<T>()>;
*/ */
class ServiceLocator { class ServiceLocator {
public: public:
/** /**
* @brief * @brief
* @return * @return
*/ */
static ServiceLocator& instance(); static ServiceLocator &instance();
ServiceLocator(const ServiceLocator&) = delete; ServiceLocator(const ServiceLocator &) = delete;
ServiceLocator& operator=(const ServiceLocator&) = delete; ServiceLocator &operator=(const ServiceLocator &) = delete;
/** /**
* @brief * @brief
* @tparam T * @tparam T
* @param service * @param service
*/ */
template<typename T> template <typename T> void registerService(SharedPtr<T> service) {
void registerService(SharedPtr<T> service) { 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::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);
sortServices(); sortServices();
}
/**
* @brief
* @tparam T
* @param factory
*/
template <typename T> void registerFactory(ServiceFactory<T> factory) {
static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T));
factories_[typeId] = [factory]() -> SharedPtr<IService> {
return std::static_pointer_cast<IService>(factory());
};
// 立即创建服务实例并添加到有序列表
auto service = factories_[typeId]();
services_[typeId] = service;
orderedServices_.push_back(service);
sortServices();
}
/**
* @brief
* @tparam T
* @return nullptr
*/
template <typename T> SharedPtr<T> getService() const {
static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T));
auto it = services_.find(typeId);
if (it != services_.end()) {
return std::static_pointer_cast<T>(it->second);
} }
/** auto factoryIt = factories_.find(typeId);
* @brief if (factoryIt != factories_.end()) {
* @tparam T auto service = factoryIt->second();
* @param factory services_[typeId] = service;
*/ return std::static_pointer_cast<T>(service);
template<typename T>
void registerFactory(ServiceFactory<T> factory) {
static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T));
factories_[typeId] = [factory]() -> SharedPtr<IService> {
return std::static_pointer_cast<IService>(factory());
};
} }
/** return nullptr;
* @brief }
* @tparam T
* @return nullptr
*/
template<typename T>
SharedPtr<T> getService() const {
static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_); /**
auto typeId = std::type_index(typeid(T)); * @brief
* @tparam T
* @return nullptr
*/
template <typename T> SharedPtr<T> tryGetService() const {
static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService");
auto it = services_.find(typeId); std::lock_guard<std::mutex> lock(mutex_);
if (it != services_.end()) { auto typeId = std::type_index(typeid(T));
return std::static_pointer_cast<T>(it->second); auto it = services_.find(typeId);
} if (it != services_.end()) {
return std::static_pointer_cast<T>(it->second);
}
return nullptr;
}
auto factoryIt = factories_.find(typeId); /**
if (factoryIt != factories_.end()) { * @brief
auto service = factoryIt->second(); * @tparam T
services_[typeId] = service; * @return true
return std::static_pointer_cast<T>(service); */
} template <typename T> bool hasService() const {
std::lock_guard<std::mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T));
return services_.find(typeId) != services_.end() ||
factories_.find(typeId) != factories_.end();
}
return nullptr; /**
* @brief
* @tparam T
*/
template <typename T> void unregisterService() {
std::lock_guard<std::mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T));
auto it = services_.find(typeId);
if (it != services_.end()) {
auto service = it->second;
services_.erase(it);
auto orderIt =
std::find(orderedServices_.begin(), orderedServices_.end(), service);
if (orderIt != orderedServices_.end()) {
orderedServices_.erase(orderIt);
}
} }
/** factories_.erase(typeId);
* @brief }
* @tparam T
* @return nullptr
*/
template<typename T>
SharedPtr<T> tryGetService() const {
static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService");
std::lock_guard<std::mutex> lock(mutex_); /**
auto typeId = std::type_index(typeid(T)); * @brief
auto it = services_.find(typeId); * @return true
if (it != services_.end()) { */
return std::static_pointer_cast<T>(it->second); bool initializeAll();
}
return nullptr;
}
/** /**
* @brief * @brief
* @tparam T */
* @return true void shutdownAll();
*/
template<typename T>
bool hasService() const {
std::lock_guard<std::mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T));
return services_.find(typeId) != services_.end() ||
factories_.find(typeId) != factories_.end();
}
/** /**
* @brief * @brief
* @tparam T * @param deltaTime
*/ */
template<typename T> void updateAll(float deltaTime);
void unregisterService() {
std::lock_guard<std::mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T));
auto it = services_.find(typeId); /**
if (it != services_.end()) { * @brief
auto service = it->second; */
services_.erase(it); void pauseAll();
auto orderIt = std::find(orderedServices_.begin(), /**
orderedServices_.end(), service); * @brief
if (orderIt != orderedServices_.end()) { */
orderedServices_.erase(orderIt); void resumeAll();
}
}
factories_.erase(typeId); /**
} * @brief
* @return
*/
std::vector<SharedPtr<IService>> getAllServices() const;
/** /**
* @brief * @brief
* @return true */
*/ void clear();
bool initializeAll();
/** /**
* @brief * @brief
*/ * @return
void shutdownAll(); */
size_t size() const { return services_.size(); }
/**
* @brief
* @param deltaTime
*/
void updateAll(float deltaTime);
/**
* @brief
*/
void pauseAll();
/**
* @brief
*/
void resumeAll();
/**
* @brief
* @return
*/
std::vector<SharedPtr<IService>> getAllServices() const;
/**
* @brief
*/
void clear();
/**
* @brief
* @return
*/
size_t size() const { return services_.size(); }
private: private:
ServiceLocator() = default; ServiceLocator() = default;
~ServiceLocator() = default; ~ServiceLocator() = default;
/** /**
* @brief * @brief
*/ */
void sortServices(); void sortServices();
mutable std::unordered_map<std::type_index, SharedPtr<IService>> services_; mutable std::unordered_map<std::type_index, SharedPtr<IService>> services_;
std::unordered_map<std::type_index, std::function<SharedPtr<IService>()>> factories_; std::unordered_map<std::type_index, std::function<SharedPtr<IService>()>>
std::vector<SharedPtr<IService>> orderedServices_; factories_;
mutable std::mutex mutex_; std::vector<SharedPtr<IService>> orderedServices_;
mutable std::mutex mutex_;
}; };
/** /**
* @brief * @brief
* *
*/ */
template<typename Interface, typename Implementation> template <typename Interface, typename Implementation> class ServiceRegistrar {
class ServiceRegistrar {
public: public:
explicit ServiceRegistrar(ServiceFactory<Interface> factory = nullptr) { explicit ServiceRegistrar(ServiceFactory<Interface> factory = nullptr) {
if (factory) { if (factory) {
ServiceLocator::instance().registerFactory<Interface>(factory); ServiceLocator::instance().registerFactory<Interface>(factory);
} else { } else {
ServiceLocator::instance().registerFactory<Interface>( ServiceLocator::instance().registerFactory<Interface>(
[]() -> SharedPtr<Interface> { []() -> SharedPtr<Interface> {
return makeShared<Implementation>(); return makeShared<Implementation>();
} });
);
}
} }
}
}; };
} /**
* @brief
* 使
*
*/
template <typename Interface, typename Implementation> struct ServiceAutoReg {
/**
* @brief 访
*/
static const bool registered;
#define E2D_REGISTER_SERVICE(Interface, Implementation) \ /**
namespace { \ * @brief
static ::extra2d::ServiceRegistrar<Interface, Implementation> \ * @return true
E2D_CONCAT(service_registrar_, __LINE__); \ */
} static bool doRegister() {
::extra2d::ServiceLocator::instance().registerFactory<Interface>(
[]() -> ::extra2d::SharedPtr<Interface> {
return ::extra2d::makeShared<Implementation>();
});
return true;
}
};
#define E2D_REGISTER_SERVICE_FACTORY(Interface, Factory) \ // 静态成员定义,在此处触发注册
namespace { \ template <typename Interface, typename Implementation>
static ::extra2d::ServiceRegistrar<Interface, Interface> \ const bool ServiceAutoReg<Interface, Implementation>::registered =
E2D_CONCAT(service_factory_registrar_, __LINE__)(Factory); \ ServiceAutoReg<Interface, Implementation>::doRegister();
/**
* @brief
*/
template <typename Interface> struct ServiceAutoRegFactory {
template <typename Factory> struct Impl {
static const bool registered;
static bool doRegister(Factory factory) {
::extra2d::ServiceLocator::instance().registerFactory<Interface>(factory);
return true;
} }
};
};
template <typename Interface>
template <typename Factory>
const bool ServiceAutoRegFactory<Interface>::Impl<Factory>::registered =
ServiceAutoRegFactory<Interface>::Impl<Factory>::doRegister(Factory{});
/**
* @brief
* 使
*
*/
#define E2D_AUTO_REGISTER_SERVICE(Interface, Implementation) \
static inline const bool E2D_CONCAT(_service_reg_, __LINE__) = \
ServiceAutoReg<Interface, Implementation>::registered
/**
* @brief
*/
#define E2D_AUTO_REGISTER_SERVICE_FACTORY(Interface, Factory) \
static inline const bool E2D_CONCAT(_service_factory_reg_, __LINE__) = \
ServiceAutoRegFactory<Interface>::Impl<Factory>::registered
} // namespace extra2d

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <extra2d/core/service_interface.h> #include <extra2d/core/service_interface.h>
#include <extra2d/core/service_locator.h>
#include <extra2d/graphics/camera/camera.h> #include <extra2d/graphics/camera/camera.h>
#include <extra2d/graphics/camera/viewport_adapter.h> #include <extra2d/graphics/camera/viewport_adapter.h>
@ -106,6 +107,9 @@ public:
private: private:
Camera camera_; Camera camera_;
ViewportAdapter viewportAdapter_; ViewportAdapter viewportAdapter_;
// 服务注册元数据
E2D_AUTO_REGISTER_SERVICE(ICameraService, CameraService);
}; };
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <extra2d/core/service_interface.h> #include <extra2d/core/service_interface.h>
#include <extra2d/core/service_locator.h>
#include <extra2d/event/event_dispatcher.h> #include <extra2d/event/event_dispatcher.h>
#include <extra2d/event/event_queue.h> #include <extra2d/event/event_queue.h>
@ -68,6 +69,9 @@ public:
private: private:
EventQueue queue_; EventQueue queue_;
EventDispatcher dispatcher_; EventDispatcher dispatcher_;
// 服务注册元数据
E2D_AUTO_REGISTER_SERVICE(IEventService, EventService);
}; };
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <extra2d/core/service_interface.h> #include <extra2d/core/service_interface.h>
#include <extra2d/core/service_locator.h>
#include <extra2d/core/types.h> #include <extra2d/core/types.h>
#include <cstdarg> #include <cstdarg>
#include <string> #include <string>
@ -124,6 +125,9 @@ private:
LogLevel level_; LogLevel level_;
class Impl; class Impl;
UniquePtr<Impl> impl_; UniquePtr<Impl> impl_;
// 服务注册元数据
E2D_AUTO_REGISTER_SERVICE(ILogger, ConsoleLogger);
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <extra2d/core/service_interface.h> #include <extra2d/core/service_interface.h>
#include <extra2d/core/service_locator.h>
#include <extra2d/scene/scene_manager.h> #include <extra2d/scene/scene_manager.h>
namespace extra2d { namespace extra2d {
@ -86,6 +87,9 @@ public:
private: private:
SceneManager manager_; SceneManager manager_;
// 服务注册元数据
E2D_AUTO_REGISTER_SERVICE(ISceneService, SceneService);
}; };
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <extra2d/core/service_interface.h> #include <extra2d/core/service_interface.h>
#include <extra2d/core/service_locator.h>
#include <extra2d/utils/timer.h> #include <extra2d/utils/timer.h>
namespace extra2d { namespace extra2d {
@ -48,6 +49,9 @@ public:
private: private:
TimerManager manager_; TimerManager manager_;
// 服务注册元数据
E2D_AUTO_REGISTER_SERVICE(ITimerService, TimerService);
}; };
} }

View File

@ -14,8 +14,6 @@
#include <extra2d/services/timer_service.h> #include <extra2d/services/timer_service.h>
#include <chrono>
namespace extra2d { namespace extra2d {
static double getTimeSeconds() { static double getTimeSeconds() {
@ -57,66 +55,49 @@ bool Application::init(const AppConfig &config) {
appConfig_ = config; appConfig_ = config;
// 首先注册日志服务(模块初始化可能需要它)
auto &locator = ServiceLocator::instance();
if (!locator.hasService<ILogger>()) {
auto logger = makeShared<ConsoleLogger>();
locator.registerService(std::static_pointer_cast<ILogger>(logger));
}
// 初始化所有模块(拓扑排序) // 初始化所有模块(拓扑排序)
// 服务通过 E2D_AUTO_REGISTER_SERVICE 宏自动注册
if (!Registry::instance().init()) { if (!Registry::instance().init()) {
return false; return false;
} }
// 模块初始化完成后,注册其他核心服务 // 配置相机服务(需要窗口信息)
registerCoreServices(); configureCameraService();
// 初始化所有服务
ServiceLocator::instance().initializeAll();
initialized_ = true; initialized_ = true;
running_ = true; running_ = true;
return true; return true;
} }
void Application::registerCoreServices() { void Application::configureCameraService() {
auto &locator = ServiceLocator::instance();
if (!locator.hasService<ISceneService>()) {
auto service = makeShared<SceneService>();
locator.registerService(std::static_pointer_cast<ISceneService>(service));
}
if (!locator.hasService<ITimerService>()) {
auto service = makeShared<TimerService>();
locator.registerService(std::static_pointer_cast<ITimerService>(service));
}
if (!locator.hasService<IEventService>()) {
auto service = makeShared<EventService>();
locator.registerService(std::static_pointer_cast<IEventService>(service));
}
auto *winMod = get<WindowModule>(); auto *winMod = get<WindowModule>();
if (winMod && winMod->win() && !locator.hasService<ICameraService>()) { if (!winMod || !winMod->win()) {
auto cameraService = makeShared<CameraService>(); return;
auto *win = winMod->win();
cameraService->setViewport(0, static_cast<float>(win->width()),
static_cast<float>(win->height()), 0);
ViewportConfig vpConfig;
vpConfig.logicWidth = static_cast<float>(win->width());
vpConfig.logicHeight = static_cast<float>(win->height());
vpConfig.mode = ViewportMode::AspectRatio;
cameraService->setViewportConfig(vpConfig);
cameraService->updateViewport(win->width(), win->height());
locator.registerService(
std::static_pointer_cast<ICameraService>(cameraService));
win->onResize([cameraService](int width, int height) {
cameraService->updateViewport(width, height);
cameraService->applyViewportAdapter();
});
} }
locator.initializeAll(); auto cameraService = ServiceLocator::instance().getService<ICameraService>();
if (!cameraService) {
return;
}
auto *win = winMod->win();
cameraService->setViewport(0, static_cast<float>(win->width()),
static_cast<float>(win->height()), 0);
ViewportConfig vpConfig;
vpConfig.logicWidth = static_cast<float>(win->width());
vpConfig.logicHeight = static_cast<float>(win->height());
vpConfig.mode = ViewportMode::AspectRatio;
cameraService->setViewportConfig(vpConfig);
cameraService->updateViewport(win->width(), win->height());
win->onResize([cameraService](int width, int height) {
cameraService->updateViewport(width, height);
cameraService->applyViewportAdapter();
});
} }
void Application::shutdown() { void Application::shutdown() {
@ -125,6 +106,7 @@ void Application::shutdown() {
VRAMMgr::get().printStats(); VRAMMgr::get().printStats();
ServiceLocator::instance().shutdownAll();
ServiceLocator::instance().clear(); ServiceLocator::instance().clear();
Registry::instance().shutdown(); Registry::instance().shutdown();
Registry::instance().clear(); Registry::instance().clear();

View File

@ -3,126 +3,97 @@
namespace extra2d { namespace extra2d {
CameraService::CameraService() { CameraService::CameraService() {
info_.name = "CameraService"; info_.name = "CameraService";
info_.priority = ServicePriority::Camera; info_.priority = ServicePriority::Camera;
info_.enabled = true; info_.enabled = true;
} }
CameraService::CameraService(float left, float right, float bottom, float top) CameraService::CameraService(float left, float right, float bottom, float top)
: camera_(left, right, bottom, top) { : camera_(left, right, bottom, top) {
info_.name = "CameraService"; info_.name = "CameraService";
info_.priority = ServicePriority::Camera; info_.priority = ServicePriority::Camera;
info_.enabled = true; info_.enabled = true;
} }
ServiceInfo CameraService::getServiceInfo() const { ServiceInfo CameraService::getServiceInfo() const { return info_; }
return info_;
}
bool CameraService::initialize() { bool CameraService::initialize() {
camera_.setViewportAdapter(&viewportAdapter_); camera_.setViewportAdapter(&viewportAdapter_);
setState(ServiceState::Running); setState(ServiceState::Running);
return true; return true;
} }
void CameraService::shutdown() { void CameraService::shutdown() { setState(ServiceState::Stopped); }
setState(ServiceState::Stopped);
void CameraService::setPosition(const Vec2 &position) {
camera_.setPos(position);
} }
void CameraService::setPosition(const Vec2& position) { void CameraService::setPosition(float x, float y) { camera_.setPos(x, y); }
camera_.setPos(position);
Vec2 CameraService::getPosition() const { return camera_.getPosition(); }
void CameraService::setRotation(float degrees) { camera_.setRotation(degrees); }
float CameraService::getRotation() const { return camera_.getRotation(); }
void CameraService::setZoom(float zoom) { camera_.setZoom(zoom); }
float CameraService::getZoom() const { return camera_.getZoom(); }
void CameraService::setViewport(float left, float right, float bottom,
float top) {
camera_.setViewport(left, right, bottom, top);
} }
void CameraService::setPosition(float x, float y) { Rect CameraService::getViewport() const { return camera_.getViewport(); }
camera_.setPos(x, y);
}
Vec2 CameraService::getPosition() const {
return camera_.getPosition();
}
void CameraService::setRotation(float degrees) {
camera_.setRotation(degrees);
}
float CameraService::getRotation() const {
return camera_.getRotation();
}
void CameraService::setZoom(float zoom) {
camera_.setZoom(zoom);
}
float CameraService::getZoom() const {
return camera_.getZoom();
}
void CameraService::setViewport(float left, float right, float bottom, float top) {
camera_.setViewport(left, right, bottom, top);
}
Rect CameraService::getViewport() const {
return camera_.getViewport();
}
glm::mat4 CameraService::getViewMatrix() const { glm::mat4 CameraService::getViewMatrix() const {
return camera_.getViewMatrix(); return camera_.getViewMatrix();
} }
glm::mat4 CameraService::getProjectionMatrix() const { glm::mat4 CameraService::getProjectionMatrix() const {
return camera_.getProjectionMatrix(); return camera_.getProjectionMatrix();
} }
glm::mat4 CameraService::getViewProjectionMatrix() const { glm::mat4 CameraService::getViewProjectionMatrix() const {
return camera_.getViewProjectionMatrix(); return camera_.getViewProjectionMatrix();
} }
Vec2 CameraService::screenToWorld(const Vec2& screenPos) const { Vec2 CameraService::screenToWorld(const Vec2 &screenPos) const {
return camera_.screenToWorld(screenPos); return camera_.screenToWorld(screenPos);
} }
Vec2 CameraService::worldToScreen(const Vec2& worldPos) const { Vec2 CameraService::worldToScreen(const Vec2 &worldPos) const {
return camera_.worldToScreen(worldPos); return camera_.worldToScreen(worldPos);
} }
void CameraService::move(const Vec2& offset) { void CameraService::move(const Vec2 &offset) { camera_.move(offset); }
camera_.move(offset);
void CameraService::move(float x, float y) { camera_.move(x, y); }
void CameraService::setBounds(const Rect &bounds) { camera_.setBounds(bounds); }
void CameraService::clearBounds() { camera_.clearBounds(); }
void CameraService::lookAt(const Vec2 &target) { camera_.lookAt(target); }
void CameraService::setViewportConfig(const ViewportConfig &config) {
viewportAdapter_.setConfig(config);
} }
void CameraService::move(float x, float y) { const ViewportConfig &CameraService::getViewportConfig() const {
camera_.move(x, y); return viewportAdapter_.getConfig();
}
void CameraService::setBounds(const Rect& bounds) {
camera_.setBounds(bounds);
}
void CameraService::clearBounds() {
camera_.clearBounds();
}
void CameraService::lookAt(const Vec2& target) {
camera_.lookAt(target);
}
void CameraService::setViewportConfig(const ViewportConfig& config) {
viewportAdapter_.setConfig(config);
}
const ViewportConfig& CameraService::getViewportConfig() const {
return viewportAdapter_.getConfig();
} }
void CameraService::updateViewport(int screenWidth, int screenHeight) { void CameraService::updateViewport(int screenWidth, int screenHeight) {
viewportAdapter_.update(screenWidth, screenHeight); viewportAdapter_.update(screenWidth, screenHeight);
} }
const ViewportResult& CameraService::getViewportResult() const { const ViewportResult &CameraService::getViewportResult() const {
return viewportAdapter_.getResult(); return viewportAdapter_.getResult();
} }
void CameraService::applyViewportAdapter() { void CameraService::applyViewportAdapter() { camera_.applyViewportAdapter(); }
camera_.applyViewportAdapter();
}
} } // namespace extra2d

View File

@ -3,78 +3,63 @@
namespace extra2d { namespace extra2d {
EventService::EventService() { EventService::EventService() {
info_.name = "EventService"; info_.name = "EventService";
info_.priority = ServicePriority::Event; info_.priority = ServicePriority::Event;
info_.enabled = true; info_.enabled = true;
} }
ServiceInfo EventService::getServiceInfo() const { ServiceInfo EventService::getServiceInfo() const { return info_; }
return info_;
}
bool EventService::initialize() { bool EventService::initialize() {
setState(ServiceState::Running); setState(ServiceState::Running);
return true; return true;
} }
void EventService::shutdown() { void EventService::shutdown() {
queue_.clear(); queue_.clear();
dispatcher_.removeAllListeners(); dispatcher_.removeAllListeners();
setState(ServiceState::Stopped); setState(ServiceState::Stopped);
} }
void EventService::update(float deltaTime) { void EventService::update(float deltaTime) {
if (getState() == ServiceState::Running) { if (getState() == ServiceState::Running) {
processQueue(); processQueue();
} }
} }
void EventService::pushEvent(const Event& event) { void EventService::pushEvent(const Event &event) { queue_.push(event); }
queue_.push(event);
}
void EventService::pushEvent(Event&& event) { void EventService::pushEvent(Event &&event) { queue_.push(std::move(event)); }
queue_.push(std::move(event));
}
bool EventService::pollEvent(Event& event) { bool EventService::pollEvent(Event &event) { return queue_.poll(event); }
return queue_.poll(event);
}
ListenerId EventService::addListener(EventType type, EventDispatcher::EventCallback callback) { ListenerId EventService::addListener(EventType type,
return dispatcher_.addListener(type, callback); EventDispatcher::EventCallback callback) {
return dispatcher_.addListener(type, callback);
} }
void EventService::removeListener(ListenerId id) { void EventService::removeListener(ListenerId id) {
dispatcher_.removeListener(id); dispatcher_.removeListener(id);
} }
void EventService::removeAllListeners(EventType type) { void EventService::removeAllListeners(EventType type) {
dispatcher_.removeAllListeners(type); dispatcher_.removeAllListeners(type);
} }
void EventService::removeAllListeners() { void EventService::removeAllListeners() { dispatcher_.removeAllListeners(); }
dispatcher_.removeAllListeners();
}
void EventService::dispatch(Event& event) { void EventService::dispatch(Event &event) { dispatcher_.dispatch(event); }
dispatcher_.dispatch(event);
}
void EventService::processQueue() { void EventService::processQueue() { dispatcher_.processQueue(queue_); }
dispatcher_.processQueue(queue_);
}
size_t EventService::getListenerCount(EventType type) const { size_t EventService::getListenerCount(EventType type) const {
return dispatcher_.getListenerCount(type); return dispatcher_.getListenerCount(type);
} }
size_t EventService::getTotalListenerCount() const { size_t EventService::getTotalListenerCount() const {
return dispatcher_.getTotalListenerCount(); return dispatcher_.getTotalListenerCount();
} }
size_t EventService::getQueueSize() const { size_t EventService::getQueueSize() const { return queue_.size(); }
return queue_.size();
}
} } // namespace extra2d

View File

@ -1,10 +1,7 @@
#include <extra2d/services/logger_service.h>
#include <extra2d/core/service_locator.h>
#include <cstdio>
#include <cstdarg>
#include <chrono> #include <chrono>
#include <iomanip> #include <cstdarg>
#include <sstream> #include <cstdio>
#include <extra2d/services/logger_service.h>
#include <mutex> #include <mutex>
namespace extra2d { namespace extra2d {
@ -12,160 +9,183 @@ namespace extra2d {
// ConsoleLogger 实现 // ConsoleLogger 实现
class ConsoleLogger::Impl { class ConsoleLogger::Impl {
public: public:
std::mutex mutex_; std::mutex mutex_;
}; };
ConsoleLogger::ConsoleLogger() : level_(LogLevel::Info), impl_(std::make_unique<Impl>()) { ConsoleLogger::ConsoleLogger()
info_.name = "ConsoleLogger"; : level_(LogLevel::Info), impl_(std::make_unique<Impl>()) {
info_.priority = ServicePriority::Core; info_.name = "ConsoleLogger";
info_.priority = ServicePriority::Core;
} }
ConsoleLogger::~ConsoleLogger() = default; ConsoleLogger::~ConsoleLogger() = default;
bool ConsoleLogger::initialize() { bool ConsoleLogger::initialize() {
setState(ServiceState::Running); setState(ServiceState::Running);
return true; return true;
} }
void ConsoleLogger::shutdown() { void ConsoleLogger::shutdown() { setState(ServiceState::Stopped); }
setState(ServiceState::Stopped);
}
void ConsoleLogger::setLevel(LogLevel level) { void ConsoleLogger::setLevel(LogLevel level) { level_ = level; }
level_ = level;
}
LogLevel ConsoleLogger::getLevel() const { LogLevel ConsoleLogger::getLevel() const { return level_; }
return level_;
}
bool ConsoleLogger::isEnabled(LogLevel level) const { bool ConsoleLogger::isEnabled(LogLevel level) const {
return static_cast<int>(level) >= static_cast<int>(level_); return static_cast<int>(level) >= static_cast<int>(level_);
} }
void ConsoleLogger::log(LogLevel level, const char* fmt, ...) { void ConsoleLogger::log(LogLevel level, const char *fmt, ...) {
if (!isEnabled(level)) return; if (!isEnabled(level))
return;
char buffer[1024]; char buffer[1024];
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args); vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args); va_end(args);
output(level, buffer); output(level, buffer);
} }
void ConsoleLogger::log(LogLevel level, const std::string& msg) { void ConsoleLogger::log(LogLevel level, const std::string &msg) {
if (!isEnabled(level)) return; if (!isEnabled(level))
output(level, msg.c_str()); return;
output(level, msg.c_str());
} }
void ConsoleLogger::trace(const char* fmt, ...) { void ConsoleLogger::trace(const char *fmt, ...) {
if (!isEnabled(LogLevel::Trace)) return; if (!isEnabled(LogLevel::Trace))
char buffer[1024]; return;
va_list args; char buffer[1024];
va_start(args, fmt); va_list args;
vsnprintf(buffer, sizeof(buffer), fmt, args); va_start(args, fmt);
va_end(args); vsnprintf(buffer, sizeof(buffer), fmt, args);
output(LogLevel::Trace, buffer); va_end(args);
output(LogLevel::Trace, buffer);
} }
void ConsoleLogger::debug(const char* fmt, ...) { void ConsoleLogger::debug(const char *fmt, ...) {
if (!isEnabled(LogLevel::Debug)) return; if (!isEnabled(LogLevel::Debug))
char buffer[1024]; return;
va_list args; char buffer[1024];
va_start(args, fmt); va_list args;
vsnprintf(buffer, sizeof(buffer), fmt, args); va_start(args, fmt);
va_end(args); vsnprintf(buffer, sizeof(buffer), fmt, args);
output(LogLevel::Debug, buffer); va_end(args);
output(LogLevel::Debug, buffer);
} }
void ConsoleLogger::info(const char* fmt, ...) { void ConsoleLogger::info(const char *fmt, ...) {
if (!isEnabled(LogLevel::Info)) return; if (!isEnabled(LogLevel::Info))
char buffer[1024]; return;
va_list args; char buffer[1024];
va_start(args, fmt); va_list args;
vsnprintf(buffer, sizeof(buffer), fmt, args); va_start(args, fmt);
va_end(args); vsnprintf(buffer, sizeof(buffer), fmt, args);
output(LogLevel::Info, buffer); va_end(args);
output(LogLevel::Info, buffer);
} }
void ConsoleLogger::warn(const char* fmt, ...) { void ConsoleLogger::warn(const char *fmt, ...) {
if (!isEnabled(LogLevel::Warn)) return; if (!isEnabled(LogLevel::Warn))
char buffer[1024]; return;
va_list args; char buffer[1024];
va_start(args, fmt); va_list args;
vsnprintf(buffer, sizeof(buffer), fmt, args); va_start(args, fmt);
va_end(args); vsnprintf(buffer, sizeof(buffer), fmt, args);
output(LogLevel::Warn, buffer); va_end(args);
output(LogLevel::Warn, buffer);
} }
void ConsoleLogger::error(const char* fmt, ...) { void ConsoleLogger::error(const char *fmt, ...) {
if (!isEnabled(LogLevel::Error)) return; if (!isEnabled(LogLevel::Error))
char buffer[1024]; return;
va_list args; char buffer[1024];
va_start(args, fmt); va_list args;
vsnprintf(buffer, sizeof(buffer), fmt, args); va_start(args, fmt);
va_end(args); vsnprintf(buffer, sizeof(buffer), fmt, args);
output(LogLevel::Error, buffer); va_end(args);
output(LogLevel::Error, buffer);
} }
void ConsoleLogger::fatal(const char* fmt, ...) { void ConsoleLogger::fatal(const char *fmt, ...) {
if (!isEnabled(LogLevel::Fatal)) return; if (!isEnabled(LogLevel::Fatal))
char buffer[1024]; return;
va_list args; char buffer[1024];
va_start(args, fmt); va_list args;
vsnprintf(buffer, sizeof(buffer), fmt, args); va_start(args, fmt);
va_end(args); vsnprintf(buffer, sizeof(buffer), fmt, args);
output(LogLevel::Fatal, buffer); va_end(args);
output(LogLevel::Fatal, buffer);
} }
void ConsoleLogger::output(LogLevel level, const char* msg) { void ConsoleLogger::output(LogLevel level, const char *msg) {
std::lock_guard<std::mutex> lock(impl_->mutex_); std::lock_guard<std::mutex> lock(impl_->mutex_);
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now); auto time = std::chrono::system_clock::to_time_t(now);
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>( auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000; now.time_since_epoch()) %
1000;
std::tm tm; std::tm tm;
#ifdef _WIN32 #ifdef _WIN32
localtime_s(&tm, &time); localtime_s(&tm, &time);
#else #else
localtime_r(&time, &tm); localtime_r(&time, &tm);
#endif #endif
const char* levelStr = getLevelString(level); const char *levelStr = getLevelString(level);
// 颜色代码 // 颜色代码
const char* color = ""; const char *color = "";
const char* reset = "\033[0m"; const char *reset = "\033[0m";
switch (level) { switch (level) {
case LogLevel::Trace: color = "\033[90m"; break; case LogLevel::Trace:
case LogLevel::Debug: color = "\033[36m"; break; color = "\033[90m";
case LogLevel::Info: color = "\033[32m"; break; break;
case LogLevel::Warn: color = "\033[33m"; break; case LogLevel::Debug:
case LogLevel::Error: color = "\033[31m"; break; color = "\033[36m";
case LogLevel::Fatal: color = "\033[35m"; break; break;
default: break; case LogLevel::Info:
} color = "\033[32m";
break;
case LogLevel::Warn:
color = "\033[33m";
break;
case LogLevel::Error:
color = "\033[31m";
break;
case LogLevel::Fatal:
color = "\033[35m";
break;
default:
break;
}
printf("%s[%02d:%02d:%02d.%03d] [%s] %s%s\n", printf("%s[%02d:%02d:%02d.%03d] [%s] %s%s\n", color, tm.tm_hour, tm.tm_min,
color, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)ms.count(), tm.tm_sec, (int)ms.count(), levelStr, msg, reset);
levelStr, msg, reset);
} }
const char* ConsoleLogger::getLevelString(LogLevel level) { const char *ConsoleLogger::getLevelString(LogLevel level) {
switch (level) { switch (level) {
case LogLevel::Trace: return "TRACE"; case LogLevel::Trace:
case LogLevel::Debug: return "DEBUG"; return "TRACE";
case LogLevel::Info: return "INFO"; case LogLevel::Debug:
case LogLevel::Warn: return "WARN"; return "DEBUG";
case LogLevel::Error: return "ERROR"; case LogLevel::Info:
case LogLevel::Fatal: return "FATAL"; return "INFO";
default: return "UNKNOWN"; case LogLevel::Warn:
} return "WARN";
case LogLevel::Error:
return "ERROR";
case LogLevel::Fatal:
return "FATAL";
default:
return "UNKNOWN";
}
} }
} // namespace extra2d } // namespace extra2d

View File

@ -3,109 +3,92 @@
namespace extra2d { namespace extra2d {
SceneService::SceneService() { SceneService::SceneService() {
info_.name = "SceneService"; info_.name = "SceneService";
info_.priority = ServicePriority::Scene; info_.priority = ServicePriority::Scene;
info_.enabled = true; info_.enabled = true;
} }
ServiceInfo SceneService::getServiceInfo() const { ServiceInfo SceneService::getServiceInfo() const { return info_; }
return info_;
}
bool SceneService::initialize() { bool SceneService::initialize() {
setState(ServiceState::Running); setState(ServiceState::Running);
return true; return true;
} }
void SceneService::shutdown() { void SceneService::shutdown() {
manager_.end(); manager_.end();
setState(ServiceState::Stopped); setState(ServiceState::Stopped);
} }
void SceneService::update(float deltaTime) { void SceneService::update(float deltaTime) {
if (getState() == ServiceState::Running) { if (getState() == ServiceState::Running) {
manager_.update(deltaTime); manager_.update(deltaTime);
} }
} }
void SceneService::runWithScene(Ptr<Scene> scene) { void SceneService::runWithScene(Ptr<Scene> scene) {
manager_.runWithScene(scene); manager_.runWithScene(scene);
} }
void SceneService::replaceScene(Ptr<Scene> scene) { void SceneService::replaceScene(Ptr<Scene> scene) {
manager_.replaceScene(scene); manager_.replaceScene(scene);
} }
void SceneService::pushScene(Ptr<Scene> scene) { void SceneService::pushScene(Ptr<Scene> scene) { manager_.pushScene(scene); }
manager_.pushScene(scene);
}
void SceneService::popScene() { void SceneService::popScene() { manager_.popScene(); }
manager_.popScene();
}
void SceneService::popToRootScene() { void SceneService::popToRootScene() { manager_.popToRootScene(); }
manager_.popToRootScene();
}
void SceneService::popToScene(const std::string& name) { void SceneService::popToScene(const std::string &name) {
manager_.popToScene(name); manager_.popToScene(name);
} }
Ptr<Scene> SceneService::getCurrentScene() const { Ptr<Scene> SceneService::getCurrentScene() const {
return manager_.getCurrentScene(); return manager_.getCurrentScene();
} }
Ptr<Scene> SceneService::getPreviousScene() const { Ptr<Scene> SceneService::getPreviousScene() const {
return manager_.getPreviousScene(); return manager_.getPreviousScene();
} }
Ptr<Scene> SceneService::getRootScene() const { Ptr<Scene> SceneService::getRootScene() const {
return manager_.getRootScene(); return manager_.getRootScene();
} }
Ptr<Scene> SceneService::getSceneByName(const std::string& name) const { Ptr<Scene> SceneService::getSceneByName(const std::string &name) const {
return manager_.getSceneByName(name); return manager_.getSceneByName(name);
} }
size_t SceneService::getSceneCount() const { size_t SceneService::getSceneCount() const { return manager_.getSceneCount(); }
return manager_.getSceneCount();
bool SceneService::isEmpty() const { return manager_.isEmpty(); }
bool SceneService::hasScene(const std::string &name) const {
return manager_.hasScene(name);
} }
bool SceneService::isEmpty() const { void SceneService::render(RenderBackend &renderer) {
return manager_.isEmpty(); manager_.render(renderer);
} }
bool SceneService::hasScene(const std::string& name) const { void SceneService::collectRenderCommands(std::vector<RenderCommand> &commands) {
return manager_.hasScene(name); manager_.collectRenderCommands(commands);
}
void SceneService::render(RenderBackend& renderer) {
manager_.render(renderer);
}
void SceneService::collectRenderCommands(std::vector<RenderCommand>& commands) {
manager_.collectRenderCommands(commands);
} }
bool SceneService::isTransitioning() const { bool SceneService::isTransitioning() const {
return manager_.isTransitioning(); return manager_.isTransitioning();
} }
void SceneService::setTransitionCallback(SceneManager::TransitionCallback callback) { void SceneService::setTransitionCallback(
manager_.setTransitionCallback(callback); SceneManager::TransitionCallback callback) {
manager_.setTransitionCallback(callback);
} }
void SceneService::end() { void SceneService::end() { manager_.end(); }
manager_.end();
}
void SceneService::purgeCachedScenes() { void SceneService::purgeCachedScenes() { manager_.purgeCachedScenes(); }
manager_.purgeCachedScenes();
}
void SceneService::enterScene(Ptr<Scene> scene) { void SceneService::enterScene(Ptr<Scene> scene) { manager_.enterScene(scene); }
manager_.enterScene(scene);
}
} } // namespace extra2d

View File

@ -3,57 +3,50 @@
namespace extra2d { namespace extra2d {
TimerService::TimerService() { TimerService::TimerService() {
info_.name = "TimerService"; info_.name = "TimerService";
info_.priority = ServicePriority::Timer; info_.priority = ServicePriority::Timer;
info_.enabled = true; info_.enabled = true;
} }
ServiceInfo TimerService::getServiceInfo() const { ServiceInfo TimerService::getServiceInfo() const { return info_; }
return info_;
}
bool TimerService::initialize() { bool TimerService::initialize() {
setState(ServiceState::Running); setState(ServiceState::Running);
return true; return true;
} }
void TimerService::shutdown() { void TimerService::shutdown() {
manager_.clear(); manager_.clear();
setState(ServiceState::Stopped); setState(ServiceState::Stopped);
} }
void TimerService::update(float deltaTime) { void TimerService::update(float deltaTime) {
if (getState() == ServiceState::Running) { if (getState() == ServiceState::Running) {
manager_.update(deltaTime); manager_.update(deltaTime);
} }
} }
uint32 TimerService::addTimer(float delay, Timer::Callback callback) { uint32 TimerService::addTimer(float delay, Timer::Callback callback) {
return manager_.addTimer(delay, callback); return manager_.addTimer(delay, callback);
} }
uint32 TimerService::addRepeatingTimer(float interval, Timer::Callback callback) { uint32 TimerService::addRepeatingTimer(float interval,
return manager_.addRepeatingTimer(interval, callback); Timer::Callback callback) {
return manager_.addRepeatingTimer(interval, callback);
} }
void TimerService::cancelTimer(uint32 timerId) { void TimerService::cancelTimer(uint32 timerId) {
manager_.cancelTimer(timerId); manager_.cancelTimer(timerId);
} }
void TimerService::pauseTimer(uint32 timerId) { void TimerService::pauseTimer(uint32 timerId) { manager_.pauseTimer(timerId); }
manager_.pauseTimer(timerId);
}
void TimerService::resumeTimer(uint32 timerId) { void TimerService::resumeTimer(uint32 timerId) {
manager_.resumeTimer(timerId); manager_.resumeTimer(timerId);
} }
void TimerService::clear() { void TimerService::clear() { manager_.clear(); }
manager_.clear();
}
size_t TimerService::getTimerCount() const { size_t TimerService::getTimerCount() const { return manager_.getTimerCount(); }
return manager_.getTimerCount();
}
} } // namespace extra2d