feat: 实现服务定位器模式并重构核心服务架构
重构应用程序架构,引入服务定位器模式解耦模块依赖 新增服务注册表和服务定位器核心组件 实现核心服务接口及实现类(场景、计时器、事件、相机服务) 重构Application类使用服务定位器管理服务 添加服务自动注册宏和类型安全服务获取机制
This commit is contained in:
parent
f8ecf7e03a
commit
453a057c7d
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <extra2d/core/types.h>
|
#include <extra2d/core/types.h>
|
||||||
|
#include <extra2d/core/service_locator.h>
|
||||||
#include <extra2d/config/app_config.h>
|
#include <extra2d/config/app_config.h>
|
||||||
#include <extra2d/config/config_manager.h>
|
#include <extra2d/config/config_manager.h>
|
||||||
#include <extra2d/config/module_config.h>
|
#include <extra2d/config/module_config.h>
|
||||||
|
|
@ -10,70 +11,209 @@
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
class IInput;
|
class IInput;
|
||||||
class SceneManager;
|
|
||||||
class TimerManager;
|
|
||||||
class EventQueue;
|
|
||||||
class EventDispatcher;
|
|
||||||
class Camera;
|
|
||||||
class ViewportAdapter;
|
|
||||||
class RenderBackend;
|
class RenderBackend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 应用程序类
|
||||||
|
* 使用服务定位器模式管理模块依赖,支持依赖注入和测试Mock
|
||||||
|
*/
|
||||||
class Application {
|
class Application {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief 获取单例实例
|
||||||
|
* @return 应用程序实例引用
|
||||||
|
*/
|
||||||
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 使用默认配置初始化
|
||||||
|
* @return 初始化成功返回 true
|
||||||
|
*/
|
||||||
bool init();
|
bool init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 使用指定配置初始化
|
||||||
|
* @param config 应用配置
|
||||||
|
* @return 初始化成功返回 true
|
||||||
|
*/
|
||||||
bool init(const AppConfig& config);
|
bool init(const AppConfig& config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 使用配置文件初始化
|
||||||
|
* @param configPath 配置文件路径
|
||||||
|
* @return 初始化成功返回 true
|
||||||
|
*/
|
||||||
bool init(const std::string& configPath);
|
bool init(const std::string& configPath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 关闭应用程序
|
||||||
|
*/
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 运行主循环
|
||||||
|
*/
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 请求退出
|
||||||
|
*/
|
||||||
void quit();
|
void quit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 暂停应用程序
|
||||||
|
*/
|
||||||
void pause();
|
void pause();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 恢复应用程序
|
||||||
|
*/
|
||||||
void resume();
|
void resume();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查是否暂停
|
||||||
|
* @return 暂停状态返回 true
|
||||||
|
*/
|
||||||
bool isPaused() const { return paused_; }
|
bool isPaused() const { return paused_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查是否运行中
|
||||||
|
* @return 运行中返回 true
|
||||||
|
*/
|
||||||
bool isRunning() const { return running_; }
|
bool isRunning() const { return running_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取窗口
|
||||||
|
* @return 窗口引用
|
||||||
|
*/
|
||||||
IWindow& window() { return *window_; }
|
IWindow& window() { return *window_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取渲染器
|
||||||
|
* @return 渲染器引用
|
||||||
|
*/
|
||||||
RenderBackend& renderer();
|
RenderBackend& renderer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取输入接口
|
||||||
|
* @return 输入接口引用
|
||||||
|
*/
|
||||||
IInput& input();
|
IInput& input();
|
||||||
|
|
||||||
SceneManager& scenes();
|
/**
|
||||||
TimerManager& timers();
|
* @brief 获取场景服务
|
||||||
EventQueue& eventQueue();
|
* @return 场景服务共享指针
|
||||||
EventDispatcher& eventDispatcher();
|
*/
|
||||||
Camera& camera();
|
SharedPtr<class ISceneService> scenes();
|
||||||
ViewportAdapter& viewportAdapter();
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取计时器服务
|
||||||
|
* @return 计时器服务共享指针
|
||||||
|
*/
|
||||||
|
SharedPtr<class ITimerService> timers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取事件服务
|
||||||
|
* @return 事件服务共享指针
|
||||||
|
*/
|
||||||
|
SharedPtr<class IEventService> events();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取相机服务
|
||||||
|
* @return 相机服务共享指针
|
||||||
|
*/
|
||||||
|
SharedPtr<class ICameraService> camera();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 进入场景
|
||||||
|
* @param scene 场景指针
|
||||||
|
*/
|
||||||
void enterScene(Ptr<class Scene> scene);
|
void enterScene(Ptr<class Scene> scene);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取帧间隔时间
|
||||||
|
* @return 帧间隔时间(秒)
|
||||||
|
*/
|
||||||
float deltaTime() const { return deltaTime_; }
|
float deltaTime() const { return deltaTime_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取总运行时间
|
||||||
|
* @return 总运行时间(秒)
|
||||||
|
*/
|
||||||
float totalTime() const { return totalTime_; }
|
float totalTime() const { return totalTime_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取当前帧率
|
||||||
|
* @return 帧率
|
||||||
|
*/
|
||||||
int fps() const { return currentFps_; }
|
int fps() const { return currentFps_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取配置管理器
|
||||||
|
* @return 配置管理器引用
|
||||||
|
*/
|
||||||
ConfigManager& config();
|
ConfigManager& config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取应用配置
|
||||||
|
* @return 应用配置常量引用
|
||||||
|
*/
|
||||||
const AppConfig& getConfig() const;
|
const AppConfig& getConfig() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 注册自定义服务
|
||||||
|
* @tparam T 服务接口类型
|
||||||
|
* @param service 服务实例
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
void registerService(SharedPtr<T> service) {
|
||||||
|
ServiceLocator::instance().registerService(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取服务
|
||||||
|
* @tparam T 服务接口类型
|
||||||
|
* @return 服务共享指针
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
SharedPtr<T> getService() {
|
||||||
|
return ServiceLocator::instance().getService<T>();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application() = default;
|
Application() = default;
|
||||||
~Application();
|
~Application();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化模块
|
||||||
|
* @return 初始化成功返回 true
|
||||||
|
*/
|
||||||
bool initModules();
|
bool initModules();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 注册核心服务
|
||||||
|
*/
|
||||||
|
void registerCoreServices();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 主循环
|
||||||
|
*/
|
||||||
void mainLoop();
|
void mainLoop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 更新
|
||||||
|
*/
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 渲染
|
||||||
|
*/
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
IWindow* window_ = nullptr;
|
IWindow* window_ = nullptr;
|
||||||
UniquePtr<SceneManager> sceneManager_;
|
|
||||||
UniquePtr<TimerManager> timerManager_;
|
|
||||||
UniquePtr<EventQueue> eventQueue_;
|
|
||||||
UniquePtr<EventDispatcher> eventDispatcher_;
|
|
||||||
UniquePtr<Camera> camera_;
|
|
||||||
UniquePtr<ViewportAdapter> viewportAdapter_;
|
|
||||||
|
|
||||||
bool initialized_ = false;
|
bool initialized_ = false;
|
||||||
bool running_ = false;
|
bool running_ = false;
|
||||||
|
|
@ -88,4 +228,4 @@ private:
|
||||||
int currentFps_ = 0;
|
int currentFps_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace extra2d
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <extra2d/core/types.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务优先级枚举
|
||||||
|
* 定义服务的初始化顺序,数值越小越先初始化
|
||||||
|
*/
|
||||||
|
enum class ServicePriority : int {
|
||||||
|
Core = 0,
|
||||||
|
Event = 100,
|
||||||
|
Timer = 200,
|
||||||
|
Scene = 300,
|
||||||
|
Camera = 400,
|
||||||
|
Resource = 500,
|
||||||
|
Audio = 600,
|
||||||
|
User = 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务状态枚举
|
||||||
|
*/
|
||||||
|
enum class ServiceState {
|
||||||
|
Uninitialized,
|
||||||
|
Initializing,
|
||||||
|
Running,
|
||||||
|
Paused,
|
||||||
|
Stopping,
|
||||||
|
Stopped
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务信息结构体
|
||||||
|
*/
|
||||||
|
struct ServiceInfo {
|
||||||
|
std::string name;
|
||||||
|
ServicePriority priority = ServicePriority::User;
|
||||||
|
ServiceState state = ServiceState::Uninitialized;
|
||||||
|
bool enabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务接口基类
|
||||||
|
* 所有服务必须实现此接口,支持依赖注入和生命周期管理
|
||||||
|
*/
|
||||||
|
class IService {
|
||||||
|
friend class ServiceLocator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~IService() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取服务信息
|
||||||
|
* @return 服务信息结构体
|
||||||
|
*/
|
||||||
|
virtual ServiceInfo getServiceInfo() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化服务
|
||||||
|
* @return 初始化成功返回 true
|
||||||
|
*/
|
||||||
|
virtual bool initialize() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 关闭服务
|
||||||
|
*/
|
||||||
|
virtual void shutdown() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 暂停服务
|
||||||
|
*/
|
||||||
|
virtual void pause() {
|
||||||
|
info_.state = ServiceState::Paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 恢复服务
|
||||||
|
*/
|
||||||
|
virtual void resume() {
|
||||||
|
if (info_.state == ServiceState::Paused) {
|
||||||
|
info_.state = ServiceState::Running;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 更新服务
|
||||||
|
* @param deltaTime 帧间隔时间
|
||||||
|
*/
|
||||||
|
virtual void update(float deltaTime) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查服务是否已初始化
|
||||||
|
* @return 已初始化返回 true
|
||||||
|
*/
|
||||||
|
virtual bool isInitialized() const {
|
||||||
|
return info_.state == ServiceState::Running ||
|
||||||
|
info_.state == ServiceState::Paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取服务状态
|
||||||
|
* @return 当前服务状态
|
||||||
|
*/
|
||||||
|
ServiceState getState() const { return info_.state; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取服务名称
|
||||||
|
* @return 服务名称
|
||||||
|
*/
|
||||||
|
const std::string& getName() const { return info_.name; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ServiceInfo info_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置服务状态
|
||||||
|
* @param state 新状态
|
||||||
|
*/
|
||||||
|
void setState(ServiceState state) { info_.state = state; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 类型ID生成器
|
||||||
|
* 用于为每种服务类型生成唯一ID
|
||||||
|
*/
|
||||||
|
using ServiceTypeId = size_t;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
inline ServiceTypeId nextServiceTypeId() {
|
||||||
|
static ServiceTypeId id = 0;
|
||||||
|
return ++id;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ServiceTypeId getServiceTypeId() {
|
||||||
|
static ServiceTypeId id = nextServiceTypeId();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <extra2d/core/service_interface.h>
|
||||||
|
#include <extra2d/core/types.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
#include <functional>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务工厂函数类型
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
using ServiceFactory = std::function<SharedPtr<T>()>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务定位器
|
||||||
|
* 实现依赖注入和服务发现模式,解耦模块间依赖
|
||||||
|
*
|
||||||
|
* 特性:
|
||||||
|
* - 类型安全的服务注册和获取
|
||||||
|
* - 支持服务工厂延迟创建
|
||||||
|
* - 支持服务依赖声明
|
||||||
|
* - 线程安全
|
||||||
|
* - 支持 Mock 测试
|
||||||
|
*/
|
||||||
|
class ServiceLocator {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief 获取单例实例
|
||||||
|
* @return 服务定位器实例引用
|
||||||
|
*/
|
||||||
|
static ServiceLocator& instance();
|
||||||
|
|
||||||
|
ServiceLocator(const ServiceLocator&) = delete;
|
||||||
|
ServiceLocator& operator=(const ServiceLocator&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 注册服务实例
|
||||||
|
* @tparam T 服务接口类型
|
||||||
|
* @param service 服务实例
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
void registerService(SharedPtr<T> service) {
|
||||||
|
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));
|
||||||
|
services_[typeId] = std::static_pointer_cast<IService>(service);
|
||||||
|
orderedServices_.push_back(service);
|
||||||
|
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());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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);
|
||||||
|
if (factoryIt != factories_.end()) {
|
||||||
|
auto service = factoryIt->second();
|
||||||
|
services_[typeId] = service;
|
||||||
|
return std::static_pointer_cast<T>(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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));
|
||||||
|
auto it = services_.find(typeId);
|
||||||
|
if (it != services_.end()) {
|
||||||
|
return std::static_pointer_cast<T>(it->second);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查服务是否已注册
|
||||||
|
* @tparam T 服务接口类型
|
||||||
|
* @return 已注册返回 true
|
||||||
|
*/
|
||||||
|
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 注销服务
|
||||||
|
* @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 初始化所有已注册的服务
|
||||||
|
* @return 所有服务初始化成功返回 true
|
||||||
|
*/
|
||||||
|
bool initializeAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 关闭所有服务
|
||||||
|
*/
|
||||||
|
void shutdownAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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:
|
||||||
|
ServiceLocator() = default;
|
||||||
|
~ServiceLocator() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 按优先级排序服务
|
||||||
|
*/
|
||||||
|
void sortServices();
|
||||||
|
|
||||||
|
mutable std::unordered_map<std::type_index, SharedPtr<IService>> services_;
|
||||||
|
std::unordered_map<std::type_index, std::function<SharedPtr<IService>()>> factories_;
|
||||||
|
std::vector<SharedPtr<IService>> orderedServices_;
|
||||||
|
mutable std::mutex mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务注册器
|
||||||
|
* 用于静态注册服务
|
||||||
|
*/
|
||||||
|
template<typename Interface, typename Implementation>
|
||||||
|
class ServiceRegistrar {
|
||||||
|
public:
|
||||||
|
explicit ServiceRegistrar(ServiceFactory<Interface> factory = nullptr) {
|
||||||
|
if (factory) {
|
||||||
|
ServiceLocator::instance().registerFactory<Interface>(factory);
|
||||||
|
} else {
|
||||||
|
ServiceLocator::instance().registerFactory<Interface>(
|
||||||
|
[]() -> SharedPtr<Interface> {
|
||||||
|
return makeShared<Implementation>();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define E2D_REGISTER_SERVICE(Interface, Implementation) \
|
||||||
|
namespace { \
|
||||||
|
static ::extra2d::ServiceRegistrar<Interface, Implementation> \
|
||||||
|
E2D_CONCAT(service_registrar_, __LINE__); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define E2D_REGISTER_SERVICE_FACTORY(Interface, Factory) \
|
||||||
|
namespace { \
|
||||||
|
static ::extra2d::ServiceRegistrar<Interface, Interface> \
|
||||||
|
E2D_CONCAT(service_factory_registrar_, __LINE__)(Factory); \
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <extra2d/core/service_interface.h>
|
||||||
|
#include <extra2d/core/service_locator.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务注册信息
|
||||||
|
*/
|
||||||
|
struct ServiceRegistration {
|
||||||
|
std::string name;
|
||||||
|
ServicePriority priority;
|
||||||
|
std::function<SharedPtr<IService>()> factory;
|
||||||
|
bool enabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 服务注册表
|
||||||
|
* 管理服务的注册信息,支持延迟创建和配置
|
||||||
|
*/
|
||||||
|
class ServiceRegistry {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief 获取单例实例
|
||||||
|
* @return 服务注册表实例引用
|
||||||
|
*/
|
||||||
|
static ServiceRegistry& instance();
|
||||||
|
|
||||||
|
ServiceRegistry(const ServiceRegistry&) = delete;
|
||||||
|
ServiceRegistry& operator=(const ServiceRegistry&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 注册服务
|
||||||
|
* @tparam T 服务接口类型
|
||||||
|
* @tparam Impl 服务实现类型
|
||||||
|
* @param name 服务名称
|
||||||
|
* @param priority 服务优先级
|
||||||
|
*/
|
||||||
|
template<typename T, typename Impl>
|
||||||
|
void registerService(const std::string& name, ServicePriority priority) {
|
||||||
|
static_assert(std::is_base_of_v<IService, T>,
|
||||||
|
"T must derive from IService");
|
||||||
|
static_assert(std::is_base_of_v<T, Impl>,
|
||||||
|
"Impl must derive from T");
|
||||||
|
|
||||||
|
ServiceRegistration reg;
|
||||||
|
reg.name = name;
|
||||||
|
reg.priority = priority;
|
||||||
|
reg.factory = []() -> SharedPtr<IService> {
|
||||||
|
return std::static_pointer_cast<IService>(makeShared<Impl>());
|
||||||
|
};
|
||||||
|
registrations_.push_back(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 注册服务(带工厂函数)
|
||||||
|
* @tparam T 服务接口类型
|
||||||
|
* @param name 服务名称
|
||||||
|
* @param priority 服务优先级
|
||||||
|
* @param factory 工厂函数
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
void registerServiceWithFactory(
|
||||||
|
const std::string& name,
|
||||||
|
ServicePriority priority,
|
||||||
|
std::function<SharedPtr<T>()> factory) {
|
||||||
|
static_assert(std::is_base_of_v<IService, T>,
|
||||||
|
"T must derive from IService");
|
||||||
|
|
||||||
|
ServiceRegistration reg;
|
||||||
|
reg.name = name;
|
||||||
|
reg.priority = priority;
|
||||||
|
reg.factory = [factory]() -> SharedPtr<IService> {
|
||||||
|
return std::static_pointer_cast<IService>(factory());
|
||||||
|
};
|
||||||
|
registrations_.push_back(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启用/禁用服务
|
||||||
|
* @param name 服务名称
|
||||||
|
* @param enabled 是否启用
|
||||||
|
*/
|
||||||
|
void setServiceEnabled(const std::string& name, bool enabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建所有已注册的服务
|
||||||
|
* 并注册到 ServiceLocator
|
||||||
|
*/
|
||||||
|
void createAllServices();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取所有注册信息
|
||||||
|
* @return 注册信息列表
|
||||||
|
*/
|
||||||
|
const std::vector<ServiceRegistration>& getRegistrations() const {
|
||||||
|
return registrations_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 清空所有注册
|
||||||
|
*/
|
||||||
|
void clear() {
|
||||||
|
registrations_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ServiceRegistry() = default;
|
||||||
|
~ServiceRegistry() = default;
|
||||||
|
|
||||||
|
std::vector<ServiceRegistration> registrations_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 自动服务注册器
|
||||||
|
* 在全局作用域使用,自动注册服务
|
||||||
|
*/
|
||||||
|
template<typename Interface, typename Implementation>
|
||||||
|
class AutoServiceRegistrar {
|
||||||
|
public:
|
||||||
|
AutoServiceRegistrar(const std::string& name, ServicePriority priority) {
|
||||||
|
ServiceRegistry::instance().registerService<Interface, Implementation>(
|
||||||
|
name, priority);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define E2D_REGISTER_SERVICE_AUTO(Interface, Implementation, Name, Priority) \
|
||||||
|
namespace { \
|
||||||
|
static ::extra2d::AutoServiceRegistrar<Interface, Implementation> \
|
||||||
|
E2D_CONCAT(auto_service_registrar_, __LINE__)(Name, Priority); \
|
||||||
|
}
|
||||||
|
|
@ -7,10 +7,17 @@
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// 宏定义
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
#define E2D_CONCAT_IMPL(a, b) a##b
|
||||||
|
#define E2D_CONCAT(a, b) E2D_CONCAT_IMPL(a, b)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// 智能指针别名
|
// 智能指针别名
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <typename T> using Ptr = std::shared_ptr<T>;
|
template <typename T> using Ptr = std::shared_ptr<T>;
|
||||||
|
template <typename T> using SharedPtr = std::shared_ptr<T>;
|
||||||
|
|
||||||
template <typename T> using UniquePtr = std::unique_ptr<T>;
|
template <typename T> using UniquePtr = std::unique_ptr<T>;
|
||||||
|
|
||||||
|
|
@ -21,6 +28,10 @@ template <typename T, typename... Args> inline Ptr<T> makePtr(Args &&...args) {
|
||||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args> inline SharedPtr<T> makeShared(Args &&...args) {
|
||||||
|
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
/// 创建 unique_ptr 的便捷函数
|
/// 创建 unique_ptr 的便捷函数
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
inline UniquePtr<T> makeUnique(Args &&...args) {
|
inline UniquePtr<T> makeUnique(Args &&...args) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <extra2d/core/service_interface.h>
|
||||||
|
#include <extra2d/graphics/camera.h>
|
||||||
|
#include <extra2d/graphics/viewport_adapter.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 相机服务接口
|
||||||
|
*/
|
||||||
|
class ICameraService : public IService {
|
||||||
|
public:
|
||||||
|
virtual ~ICameraService() = default;
|
||||||
|
|
||||||
|
virtual void setPosition(const Vec2& position) = 0;
|
||||||
|
virtual void setPosition(float x, float y) = 0;
|
||||||
|
virtual Vec2 getPosition() const = 0;
|
||||||
|
|
||||||
|
virtual void setRotation(float degrees) = 0;
|
||||||
|
virtual float getRotation() const = 0;
|
||||||
|
|
||||||
|
virtual void setZoom(float zoom) = 0;
|
||||||
|
virtual float getZoom() const = 0;
|
||||||
|
|
||||||
|
virtual void setViewport(float left, float right, float bottom, float top) = 0;
|
||||||
|
virtual Rect getViewport() const = 0;
|
||||||
|
|
||||||
|
virtual glm::mat4 getViewMatrix() const = 0;
|
||||||
|
virtual glm::mat4 getProjectionMatrix() const = 0;
|
||||||
|
virtual glm::mat4 getViewProjectionMatrix() const = 0;
|
||||||
|
|
||||||
|
virtual Vec2 screenToWorld(const Vec2& screenPos) const = 0;
|
||||||
|
virtual Vec2 worldToScreen(const Vec2& worldPos) const = 0;
|
||||||
|
|
||||||
|
virtual void move(const Vec2& offset) = 0;
|
||||||
|
virtual void move(float x, float y) = 0;
|
||||||
|
|
||||||
|
virtual void setBounds(const Rect& bounds) = 0;
|
||||||
|
virtual void clearBounds() = 0;
|
||||||
|
|
||||||
|
virtual void lookAt(const Vec2& target) = 0;
|
||||||
|
|
||||||
|
virtual void setViewportConfig(const ViewportConfig& config) = 0;
|
||||||
|
virtual const ViewportConfig& getViewportConfig() const = 0;
|
||||||
|
virtual void updateViewport(int screenWidth, int screenHeight) = 0;
|
||||||
|
virtual const ViewportResult& getViewportResult() const = 0;
|
||||||
|
|
||||||
|
virtual void applyViewportAdapter() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 相机服务实现
|
||||||
|
*/
|
||||||
|
class CameraService : public ICameraService {
|
||||||
|
public:
|
||||||
|
CameraService();
|
||||||
|
explicit CameraService(float left, float right, float bottom, float top);
|
||||||
|
~CameraService() override = default;
|
||||||
|
|
||||||
|
ServiceInfo getServiceInfo() const override;
|
||||||
|
|
||||||
|
bool initialize() override;
|
||||||
|
void shutdown() override;
|
||||||
|
|
||||||
|
void setPosition(const Vec2& position) override;
|
||||||
|
void setPosition(float x, float y) override;
|
||||||
|
Vec2 getPosition() const override;
|
||||||
|
|
||||||
|
void setRotation(float degrees) override;
|
||||||
|
float getRotation() const override;
|
||||||
|
|
||||||
|
void setZoom(float zoom) override;
|
||||||
|
float getZoom() const override;
|
||||||
|
|
||||||
|
void setViewport(float left, float right, float bottom, float top) override;
|
||||||
|
Rect getViewport() const override;
|
||||||
|
|
||||||
|
glm::mat4 getViewMatrix() const override;
|
||||||
|
glm::mat4 getProjectionMatrix() const override;
|
||||||
|
glm::mat4 getViewProjectionMatrix() const override;
|
||||||
|
|
||||||
|
Vec2 screenToWorld(const Vec2& screenPos) const override;
|
||||||
|
Vec2 worldToScreen(const Vec2& worldPos) const override;
|
||||||
|
|
||||||
|
void move(const Vec2& offset) override;
|
||||||
|
void move(float x, float y) override;
|
||||||
|
|
||||||
|
void setBounds(const Rect& bounds) override;
|
||||||
|
void clearBounds() override;
|
||||||
|
|
||||||
|
void lookAt(const Vec2& target) override;
|
||||||
|
|
||||||
|
void setViewportConfig(const ViewportConfig& config) override;
|
||||||
|
const ViewportConfig& getViewportConfig() const override;
|
||||||
|
void updateViewport(int screenWidth, int screenHeight) override;
|
||||||
|
const ViewportResult& getViewportResult() const override;
|
||||||
|
|
||||||
|
void applyViewportAdapter() override;
|
||||||
|
|
||||||
|
Camera& getCamera() { return camera_; }
|
||||||
|
const Camera& getCamera() const { return camera_; }
|
||||||
|
ViewportAdapter& getViewportAdapter() { return viewportAdapter_; }
|
||||||
|
const ViewportAdapter& getViewportAdapter() const { return viewportAdapter_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Camera camera_;
|
||||||
|
ViewportAdapter viewportAdapter_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <extra2d/core/service_interface.h>
|
||||||
|
#include <extra2d/event/event_dispatcher.h>
|
||||||
|
#include <extra2d/event/event_queue.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 事件服务接口
|
||||||
|
*/
|
||||||
|
class IEventService : public IService {
|
||||||
|
public:
|
||||||
|
virtual ~IEventService() = default;
|
||||||
|
|
||||||
|
virtual void pushEvent(const Event& event) = 0;
|
||||||
|
virtual void pushEvent(Event&& event) = 0;
|
||||||
|
virtual bool pollEvent(Event& event) = 0;
|
||||||
|
|
||||||
|
virtual ListenerId addListener(EventType type, EventDispatcher::EventCallback callback) = 0;
|
||||||
|
virtual void removeListener(ListenerId id) = 0;
|
||||||
|
virtual void removeAllListeners(EventType type) = 0;
|
||||||
|
virtual void removeAllListeners() = 0;
|
||||||
|
|
||||||
|
virtual void dispatch(Event& event) = 0;
|
||||||
|
virtual void processQueue() = 0;
|
||||||
|
|
||||||
|
virtual size_t getListenerCount(EventType type) const = 0;
|
||||||
|
virtual size_t getTotalListenerCount() const = 0;
|
||||||
|
virtual size_t getQueueSize() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 事件服务实现
|
||||||
|
*/
|
||||||
|
class EventService : public IEventService {
|
||||||
|
public:
|
||||||
|
EventService();
|
||||||
|
~EventService() override = default;
|
||||||
|
|
||||||
|
ServiceInfo getServiceInfo() const override;
|
||||||
|
|
||||||
|
bool initialize() override;
|
||||||
|
void shutdown() override;
|
||||||
|
void update(float deltaTime) override;
|
||||||
|
|
||||||
|
void pushEvent(const Event& event) override;
|
||||||
|
void pushEvent(Event&& event) override;
|
||||||
|
bool pollEvent(Event& event) override;
|
||||||
|
|
||||||
|
ListenerId addListener(EventType type, EventDispatcher::EventCallback callback) override;
|
||||||
|
void removeListener(ListenerId id) override;
|
||||||
|
void removeAllListeners(EventType type) override;
|
||||||
|
void removeAllListeners() override;
|
||||||
|
|
||||||
|
void dispatch(Event& event) override;
|
||||||
|
void processQueue() override;
|
||||||
|
|
||||||
|
size_t getListenerCount(EventType type) const override;
|
||||||
|
size_t getTotalListenerCount() const override;
|
||||||
|
size_t getQueueSize() const override;
|
||||||
|
|
||||||
|
EventQueue& getQueue() { return queue_; }
|
||||||
|
const EventQueue& getQueue() const { return queue_; }
|
||||||
|
EventDispatcher& getDispatcher() { return dispatcher_; }
|
||||||
|
const EventDispatcher& getDispatcher() const { return dispatcher_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
EventQueue queue_;
|
||||||
|
EventDispatcher dispatcher_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <extra2d/core/service_interface.h>
|
||||||
|
#include <extra2d/scene/scene_manager.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 场景服务接口
|
||||||
|
* 定义场景管理的抽象接口,便于测试和Mock
|
||||||
|
*/
|
||||||
|
class ISceneService : public IService {
|
||||||
|
public:
|
||||||
|
virtual ~ISceneService() = default;
|
||||||
|
|
||||||
|
virtual void runWithScene(Ptr<Scene> scene) = 0;
|
||||||
|
virtual void replaceScene(Ptr<Scene> scene) = 0;
|
||||||
|
virtual void pushScene(Ptr<Scene> scene) = 0;
|
||||||
|
virtual void popScene() = 0;
|
||||||
|
virtual void popToRootScene() = 0;
|
||||||
|
virtual void popToScene(const std::string& name) = 0;
|
||||||
|
|
||||||
|
virtual Ptr<Scene> getCurrentScene() const = 0;
|
||||||
|
virtual Ptr<Scene> getPreviousScene() const = 0;
|
||||||
|
virtual Ptr<Scene> getRootScene() const = 0;
|
||||||
|
virtual Ptr<Scene> getSceneByName(const std::string& name) const = 0;
|
||||||
|
|
||||||
|
virtual size_t getSceneCount() const = 0;
|
||||||
|
virtual bool isEmpty() const = 0;
|
||||||
|
virtual bool hasScene(const std::string& name) const = 0;
|
||||||
|
|
||||||
|
virtual void render(RenderBackend& renderer) = 0;
|
||||||
|
virtual void collectRenderCommands(std::vector<RenderCommand>& commands) = 0;
|
||||||
|
|
||||||
|
virtual bool isTransitioning() const = 0;
|
||||||
|
virtual void setTransitionCallback(SceneManager::TransitionCallback callback) = 0;
|
||||||
|
|
||||||
|
virtual void end() = 0;
|
||||||
|
virtual void purgeCachedScenes() = 0;
|
||||||
|
virtual void enterScene(Ptr<Scene> scene) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 场景服务实现
|
||||||
|
* 包装 SceneManager,实现 IService 接口
|
||||||
|
*/
|
||||||
|
class SceneService : public ISceneService {
|
||||||
|
public:
|
||||||
|
SceneService();
|
||||||
|
~SceneService() override = default;
|
||||||
|
|
||||||
|
ServiceInfo getServiceInfo() const override;
|
||||||
|
|
||||||
|
bool initialize() override;
|
||||||
|
void shutdown() override;
|
||||||
|
void update(float deltaTime) override;
|
||||||
|
|
||||||
|
void runWithScene(Ptr<Scene> scene) override;
|
||||||
|
void replaceScene(Ptr<Scene> scene) override;
|
||||||
|
void pushScene(Ptr<Scene> scene) override;
|
||||||
|
void popScene() override;
|
||||||
|
void popToRootScene() override;
|
||||||
|
void popToScene(const std::string& name) override;
|
||||||
|
|
||||||
|
Ptr<Scene> getCurrentScene() const override;
|
||||||
|
Ptr<Scene> getPreviousScene() const override;
|
||||||
|
Ptr<Scene> getRootScene() const override;
|
||||||
|
Ptr<Scene> getSceneByName(const std::string& name) const override;
|
||||||
|
|
||||||
|
size_t getSceneCount() const override;
|
||||||
|
bool isEmpty() const override;
|
||||||
|
bool hasScene(const std::string& name) const override;
|
||||||
|
|
||||||
|
void render(RenderBackend& renderer) override;
|
||||||
|
void collectRenderCommands(std::vector<RenderCommand>& commands) override;
|
||||||
|
|
||||||
|
bool isTransitioning() const override;
|
||||||
|
void setTransitionCallback(SceneManager::TransitionCallback callback) override;
|
||||||
|
|
||||||
|
void end() override;
|
||||||
|
void purgeCachedScenes() override;
|
||||||
|
void enterScene(Ptr<Scene> scene) override;
|
||||||
|
|
||||||
|
SceneManager& getManager() { return manager_; }
|
||||||
|
const SceneManager& getManager() const { return manager_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SceneManager manager_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <extra2d/core/service_interface.h>
|
||||||
|
#include <extra2d/utils/timer.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 计时器服务接口
|
||||||
|
*/
|
||||||
|
class ITimerService : public IService {
|
||||||
|
public:
|
||||||
|
virtual ~ITimerService() = default;
|
||||||
|
|
||||||
|
virtual uint32 addTimer(float delay, Timer::Callback callback) = 0;
|
||||||
|
virtual uint32 addRepeatingTimer(float interval, Timer::Callback callback) = 0;
|
||||||
|
virtual void cancelTimer(uint32 timerId) = 0;
|
||||||
|
virtual void pauseTimer(uint32 timerId) = 0;
|
||||||
|
virtual void resumeTimer(uint32 timerId) = 0;
|
||||||
|
virtual void clear() = 0;
|
||||||
|
virtual size_t getTimerCount() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 计时器服务实现
|
||||||
|
*/
|
||||||
|
class TimerService : public ITimerService {
|
||||||
|
public:
|
||||||
|
TimerService();
|
||||||
|
~TimerService() override = default;
|
||||||
|
|
||||||
|
ServiceInfo getServiceInfo() const override;
|
||||||
|
|
||||||
|
bool initialize() override;
|
||||||
|
void shutdown() override;
|
||||||
|
void update(float deltaTime) override;
|
||||||
|
|
||||||
|
uint32 addTimer(float delay, Timer::Callback callback) override;
|
||||||
|
uint32 addRepeatingTimer(float interval, Timer::Callback callback) override;
|
||||||
|
void cancelTimer(uint32 timerId) override;
|
||||||
|
void pauseTimer(uint32 timerId) override;
|
||||||
|
void resumeTimer(uint32 timerId) override;
|
||||||
|
void clear() override;
|
||||||
|
size_t getTimerCount() const override;
|
||||||
|
|
||||||
|
TimerManager& getManager() { return manager_; }
|
||||||
|
const TimerManager& getManager() const { return manager_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
TimerManager manager_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
#include <extra2d/app/application.h>
|
#include <extra2d/app/application.h>
|
||||||
#include <extra2d/config/config_module.h>
|
#include <extra2d/config/config_module.h>
|
||||||
#include <extra2d/config/module_registry.h>
|
#include <extra2d/config/module_registry.h>
|
||||||
#include <extra2d/event/event_dispatcher.h>
|
|
||||||
#include <extra2d/event/event_queue.h>
|
|
||||||
#include <extra2d/graphics/camera.h>
|
|
||||||
#include <extra2d/graphics/render_module.h>
|
#include <extra2d/graphics/render_module.h>
|
||||||
#include <extra2d/graphics/viewport_adapter.h>
|
|
||||||
#include <extra2d/graphics/vram_manager.h>
|
#include <extra2d/graphics/vram_manager.h>
|
||||||
#include <extra2d/platform/iinput.h>
|
#include <extra2d/platform/iinput.h>
|
||||||
#include <extra2d/platform/platform_init_module.h>
|
#include <extra2d/platform/platform_init_module.h>
|
||||||
#include <extra2d/platform/window_module.h>
|
#include <extra2d/platform/window_module.h>
|
||||||
#include <extra2d/scene/scene_manager.h>
|
#include <extra2d/services/scene_service.h>
|
||||||
#include <extra2d/utils/timer.h>
|
#include <extra2d/services/timer_service.h>
|
||||||
|
#include <extra2d/services/event_service.h>
|
||||||
|
#include <extra2d/services/camera_service.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
@ -88,6 +86,37 @@ bool Application::init(const std::string& configPath) {
|
||||||
return initModules();
|
return initModules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::registerCoreServices() {
|
||||||
|
auto& locator = ServiceLocator::instance();
|
||||||
|
|
||||||
|
if (!locator.hasService<IEventService>()) {
|
||||||
|
locator.registerService<ISceneService>(makeShared<SceneService>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locator.hasService<ITimerService>()) {
|
||||||
|
locator.registerService<ITimerService>(makeShared<TimerService>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locator.hasService<IEventService>()) {
|
||||||
|
locator.registerService<IEventService>(makeShared<EventService>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locator.hasService<ICameraService>()) {
|
||||||
|
auto cameraService = makeShared<CameraService>();
|
||||||
|
if (window_) {
|
||||||
|
cameraService->setViewport(0, static_cast<float>(window_->width()),
|
||||||
|
static_cast<float>(window_->height()), 0);
|
||||||
|
ViewportConfig vpConfig;
|
||||||
|
vpConfig.logicWidth = static_cast<float>(window_->width());
|
||||||
|
vpConfig.logicHeight = static_cast<float>(window_->height());
|
||||||
|
vpConfig.mode = ViewportMode::AspectRatio;
|
||||||
|
cameraService->setViewportConfig(vpConfig);
|
||||||
|
cameraService->updateViewport(window_->width(), window_->height());
|
||||||
|
}
|
||||||
|
locator.registerService<ICameraService>(cameraService);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Application::initModules() {
|
bool Application::initModules() {
|
||||||
auto initOrder = ModuleRegistry::instance().getInitializationOrder();
|
auto initOrder = ModuleRegistry::instance().getInitializationOrder();
|
||||||
|
|
||||||
|
|
@ -144,40 +173,28 @@ bool Application::initModules() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sceneManager_ = makeUnique<SceneManager>();
|
registerCoreServices();
|
||||||
timerManager_ = makeUnique<TimerManager>();
|
|
||||||
eventQueue_ = makeUnique<EventQueue>();
|
|
||||||
eventDispatcher_ = makeUnique<EventDispatcher>();
|
|
||||||
camera_ = makeUnique<Camera>(0, static_cast<float>(window_->width()),
|
|
||||||
static_cast<float>(window_->height()), 0);
|
|
||||||
|
|
||||||
viewportAdapter_ = makeUnique<ViewportAdapter>();
|
if (!ServiceLocator::instance().initializeAll()) {
|
||||||
ViewportConfig vpConfig;
|
return false;
|
||||||
vpConfig.logicWidth = static_cast<float>(window_->width());
|
}
|
||||||
vpConfig.logicHeight = static_cast<float>(window_->height());
|
|
||||||
vpConfig.mode = ViewportMode::AspectRatio;
|
|
||||||
viewportAdapter_->setConfig(vpConfig);
|
|
||||||
|
|
||||||
camera_->setViewportAdapter(viewportAdapter_.get());
|
auto cameraService = ServiceLocator::instance().getService<ICameraService>();
|
||||||
viewportAdapter_->update(window_->width(), window_->height());
|
if (cameraService && window_) {
|
||||||
|
window_->onResize([this, cameraService](int width, int height) {
|
||||||
|
cameraService->updateViewport(width, height);
|
||||||
|
cameraService->applyViewportAdapter();
|
||||||
|
|
||||||
window_->onResize([this](int width, int height) {
|
auto sceneService = ServiceLocator::instance().getService<ISceneService>();
|
||||||
if (viewportAdapter_) {
|
if (sceneService) {
|
||||||
viewportAdapter_->update(width, height);
|
auto currentScene = sceneService->getCurrentScene();
|
||||||
}
|
if (currentScene) {
|
||||||
|
currentScene->setViewportSize(static_cast<float>(width),
|
||||||
if (camera_) {
|
static_cast<float>(height));
|
||||||
camera_->applyViewportAdapter();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (sceneManager_) {
|
|
||||||
auto currentScene = sceneManager_->getCurrentScene();
|
|
||||||
if (currentScene) {
|
|
||||||
currentScene->setViewportSize(static_cast<float>(width),
|
|
||||||
static_cast<float>(height));
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
initialized_ = true;
|
initialized_ = true;
|
||||||
running_ = true;
|
running_ = true;
|
||||||
|
|
@ -191,17 +208,7 @@ void Application::shutdown() {
|
||||||
|
|
||||||
VRAMMgr::get().printStats();
|
VRAMMgr::get().printStats();
|
||||||
|
|
||||||
if (sceneManager_) {
|
ServiceLocator::instance().clear();
|
||||||
sceneManager_->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
sceneManager_.reset();
|
|
||||||
viewportAdapter_.reset();
|
|
||||||
camera_.reset();
|
|
||||||
|
|
||||||
timerManager_.reset();
|
|
||||||
eventQueue_.reset();
|
|
||||||
eventDispatcher_.reset();
|
|
||||||
|
|
||||||
window_ = nullptr;
|
window_ = nullptr;
|
||||||
|
|
||||||
|
|
@ -239,12 +246,14 @@ void Application::quit() {
|
||||||
void Application::pause() {
|
void Application::pause() {
|
||||||
if (!paused_) {
|
if (!paused_) {
|
||||||
paused_ = true;
|
paused_ = true;
|
||||||
|
ServiceLocator::instance().pauseAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::resume() {
|
void Application::resume() {
|
||||||
if (paused_) {
|
if (paused_) {
|
||||||
paused_ = false;
|
paused_ = false;
|
||||||
|
ServiceLocator::instance().resumeAll();
|
||||||
lastFrameTime_ = getTimeSeconds();
|
lastFrameTime_ = getTimeSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -266,8 +275,9 @@ void Application::mainLoop() {
|
||||||
|
|
||||||
window_->poll();
|
window_->poll();
|
||||||
|
|
||||||
if (eventDispatcher_ && eventQueue_) {
|
auto eventService = ServiceLocator::instance().getService<IEventService>();
|
||||||
eventDispatcher_->processQueue(*eventQueue_);
|
if (eventService) {
|
||||||
|
eventService->processQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!paused_) {
|
if (!paused_) {
|
||||||
|
|
@ -291,13 +301,7 @@ void Application::mainLoop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::update() {
|
void Application::update() {
|
||||||
if (timerManager_) {
|
ServiceLocator::instance().updateAll(deltaTime_);
|
||||||
timerManager_->update(deltaTime_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sceneManager_) {
|
|
||||||
sceneManager_->update(deltaTime_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::render() {
|
void Application::render() {
|
||||||
|
|
@ -314,8 +318,9 @@ void Application::render() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewportAdapter_) {
|
auto cameraService = ServiceLocator::instance().getService<ICameraService>();
|
||||||
const auto& vp = viewportAdapter_->getViewport();
|
if (cameraService) {
|
||||||
|
const auto& vp = cameraService->getViewportResult().viewport;
|
||||||
renderer->setViewport(
|
renderer->setViewport(
|
||||||
static_cast<int>(vp.origin.x), static_cast<int>(vp.origin.y),
|
static_cast<int>(vp.origin.x), static_cast<int>(vp.origin.y),
|
||||||
static_cast<int>(vp.size.width), static_cast<int>(vp.size.height));
|
static_cast<int>(vp.size.width), static_cast<int>(vp.size.height));
|
||||||
|
|
@ -323,8 +328,9 @@ void Application::render() {
|
||||||
renderer->setViewport(0, 0, window_->width(), window_->height());
|
renderer->setViewport(0, 0, window_->width(), window_->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneManager_) {
|
auto sceneService = ServiceLocator::instance().getService<ISceneService>();
|
||||||
sceneManager_->render(*renderer);
|
if (sceneService) {
|
||||||
|
sceneService->render(*renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
window_->swap();
|
window_->swap();
|
||||||
|
|
@ -349,35 +355,28 @@ RenderBackend& Application::renderer() {
|
||||||
return *dummy;
|
return *dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneManager& Application::scenes() {
|
SharedPtr<ISceneService> Application::scenes() {
|
||||||
return *sceneManager_;
|
return ServiceLocator::instance().getService<ISceneService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TimerManager& Application::timers() {
|
SharedPtr<ITimerService> Application::timers() {
|
||||||
return *timerManager_;
|
return ServiceLocator::instance().getService<ITimerService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
EventQueue& Application::eventQueue() {
|
SharedPtr<IEventService> Application::events() {
|
||||||
return *eventQueue_;
|
return ServiceLocator::instance().getService<IEventService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
EventDispatcher& Application::eventDispatcher() {
|
SharedPtr<ICameraService> Application::camera() {
|
||||||
return *eventDispatcher_;
|
return ServiceLocator::instance().getService<ICameraService>();
|
||||||
}
|
|
||||||
|
|
||||||
Camera& Application::camera() {
|
|
||||||
return *camera_;
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewportAdapter& Application::viewportAdapter() {
|
|
||||||
return *viewportAdapter_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::enterScene(Ptr<Scene> scene) {
|
void Application::enterScene(Ptr<Scene> scene) {
|
||||||
if (sceneManager_ && scene) {
|
auto sceneService = ServiceLocator::instance().getService<ISceneService>();
|
||||||
|
if (sceneService && scene) {
|
||||||
scene->setViewportSize(static_cast<float>(window_->width()),
|
scene->setViewportSize(static_cast<float>(window_->width()),
|
||||||
static_cast<float>(window_->height()));
|
static_cast<float>(window_->height()));
|
||||||
sceneManager_->enterScene(scene);
|
sceneService->enterScene(scene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -389,4 +388,4 @@ const AppConfig& Application::getConfig() const {
|
||||||
return ConfigManager::instance().appConfig();
|
return ConfigManager::instance().appConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace extra2d
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
#include <extra2d/core/service_locator.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
ServiceLocator& ServiceLocator::instance() {
|
||||||
|
static ServiceLocator instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServiceLocator::initializeAll() {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& service : orderedServices_) {
|
||||||
|
if (!service) continue;
|
||||||
|
|
||||||
|
auto info = service->getServiceInfo();
|
||||||
|
if (!info.enabled) continue;
|
||||||
|
|
||||||
|
if (!service->isInitialized()) {
|
||||||
|
service->setState(ServiceState::Initializing);
|
||||||
|
if (!service->initialize()) {
|
||||||
|
service->setState(ServiceState::Stopped);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
service->setState(ServiceState::Running);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceLocator::shutdownAll() {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto it = orderedServices_.rbegin();
|
||||||
|
it != orderedServices_.rend(); ++it) {
|
||||||
|
if (*it && (*it)->isInitialized()) {
|
||||||
|
(*it)->setState(ServiceState::Stopping);
|
||||||
|
(*it)->shutdown();
|
||||||
|
(*it)->setState(ServiceState::Stopped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceLocator::updateAll(float deltaTime) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& service : orderedServices_) {
|
||||||
|
if (service && service->isInitialized()) {
|
||||||
|
auto state = service->getState();
|
||||||
|
if (state == ServiceState::Running) {
|
||||||
|
service->update(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceLocator::pauseAll() {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& service : orderedServices_) {
|
||||||
|
if (service && service->isInitialized()) {
|
||||||
|
service->pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceLocator::resumeAll() {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& service : orderedServices_) {
|
||||||
|
if (service && service->isInitialized()) {
|
||||||
|
service->resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SharedPtr<IService>> ServiceLocator::getAllServices() const {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
return orderedServices_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceLocator::clear() {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto it = orderedServices_.rbegin();
|
||||||
|
it != orderedServices_.rend(); ++it) {
|
||||||
|
if (*it && (*it)->isInitialized()) {
|
||||||
|
(*it)->setState(ServiceState::Stopping);
|
||||||
|
(*it)->shutdown();
|
||||||
|
(*it)->setState(ServiceState::Stopped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
services_.clear();
|
||||||
|
factories_.clear();
|
||||||
|
orderedServices_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceLocator::sortServices() {
|
||||||
|
std::stable_sort(orderedServices_.begin(), orderedServices_.end(),
|
||||||
|
[](const SharedPtr<IService>& a, const SharedPtr<IService>& b) {
|
||||||
|
if (!a || !b) return false;
|
||||||
|
return static_cast<int>(a->getServiceInfo().priority) <
|
||||||
|
static_cast<int>(b->getServiceInfo().priority);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include <extra2d/core/service_registry.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
ServiceRegistry& ServiceRegistry::instance() {
|
||||||
|
static ServiceRegistry instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceRegistry::setServiceEnabled(const std::string& name, bool enabled) {
|
||||||
|
for (auto& reg : registrations_) {
|
||||||
|
if (reg.name == name) {
|
||||||
|
reg.enabled = enabled;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceRegistry::createAllServices() {
|
||||||
|
std::sort(registrations_.begin(), registrations_.end(),
|
||||||
|
[](const ServiceRegistration& a, const ServiceRegistration& b) {
|
||||||
|
return static_cast<int>(a.priority) < static_cast<int>(b.priority);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto& reg : registrations_) {
|
||||||
|
if (!reg.enabled) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto service = reg.factory();
|
||||||
|
if (service) {
|
||||||
|
ServiceLocator::instance().registerService<IService>(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
#include <extra2d/services/camera_service.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
CameraService::CameraService() {
|
||||||
|
info_.name = "CameraService";
|
||||||
|
info_.priority = ServicePriority::Camera;
|
||||||
|
info_.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraService::CameraService(float left, float right, float bottom, float top)
|
||||||
|
: camera_(left, right, bottom, top) {
|
||||||
|
info_.name = "CameraService";
|
||||||
|
info_.priority = ServicePriority::Camera;
|
||||||
|
info_.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceInfo CameraService::getServiceInfo() const {
|
||||||
|
return info_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraService::initialize() {
|
||||||
|
camera_.setViewportAdapter(&viewportAdapter_);
|
||||||
|
setState(ServiceState::Running);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraService::shutdown() {
|
||||||
|
setState(ServiceState::Stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraService::setPosition(const Vec2& position) {
|
||||||
|
camera_.setPos(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraService::setPosition(float x, float y) {
|
||||||
|
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 {
|
||||||
|
return camera_.getViewMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 CameraService::getProjectionMatrix() const {
|
||||||
|
return camera_.getProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 CameraService::getViewProjectionMatrix() const {
|
||||||
|
return camera_.getViewProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2 CameraService::screenToWorld(const Vec2& screenPos) const {
|
||||||
|
return camera_.screenToWorld(screenPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2 CameraService::worldToScreen(const Vec2& worldPos) const {
|
||||||
|
return camera_.worldToScreen(worldPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraService::move(const Vec2& 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ViewportConfig& CameraService::getViewportConfig() const {
|
||||||
|
return viewportAdapter_.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraService::updateViewport(int screenWidth, int screenHeight) {
|
||||||
|
viewportAdapter_.update(screenWidth, screenHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ViewportResult& CameraService::getViewportResult() const {
|
||||||
|
return viewportAdapter_.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraService::applyViewportAdapter() {
|
||||||
|
camera_.applyViewportAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
#include <extra2d/services/event_service.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
EventService::EventService() {
|
||||||
|
info_.name = "EventService";
|
||||||
|
info_.priority = ServicePriority::Event;
|
||||||
|
info_.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceInfo EventService::getServiceInfo() const {
|
||||||
|
return info_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventService::initialize() {
|
||||||
|
setState(ServiceState::Running);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::shutdown() {
|
||||||
|
queue_.clear();
|
||||||
|
dispatcher_.removeAllListeners();
|
||||||
|
setState(ServiceState::Stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::update(float deltaTime) {
|
||||||
|
if (getState() == ServiceState::Running) {
|
||||||
|
processQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::pushEvent(const Event& event) {
|
||||||
|
queue_.push(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::pushEvent(Event&& event) {
|
||||||
|
queue_.push(std::move(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventService::pollEvent(Event& event) {
|
||||||
|
return queue_.poll(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListenerId EventService::addListener(EventType type, EventDispatcher::EventCallback callback) {
|
||||||
|
return dispatcher_.addListener(type, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::removeListener(ListenerId id) {
|
||||||
|
dispatcher_.removeListener(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::removeAllListeners(EventType type) {
|
||||||
|
dispatcher_.removeAllListeners(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::removeAllListeners() {
|
||||||
|
dispatcher_.removeAllListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::dispatch(Event& event) {
|
||||||
|
dispatcher_.dispatch(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventService::processQueue() {
|
||||||
|
dispatcher_.processQueue(queue_);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t EventService::getListenerCount(EventType type) const {
|
||||||
|
return dispatcher_.getListenerCount(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t EventService::getTotalListenerCount() const {
|
||||||
|
return dispatcher_.getTotalListenerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t EventService::getQueueSize() const {
|
||||||
|
return queue_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
#include <extra2d/services/scene_service.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
SceneService::SceneService() {
|
||||||
|
info_.name = "SceneService";
|
||||||
|
info_.priority = ServicePriority::Scene;
|
||||||
|
info_.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceInfo SceneService::getServiceInfo() const {
|
||||||
|
return info_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneService::initialize() {
|
||||||
|
setState(ServiceState::Running);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::shutdown() {
|
||||||
|
manager_.end();
|
||||||
|
setState(ServiceState::Stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::update(float deltaTime) {
|
||||||
|
if (getState() == ServiceState::Running) {
|
||||||
|
manager_.update(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::runWithScene(Ptr<Scene> scene) {
|
||||||
|
manager_.runWithScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::replaceScene(Ptr<Scene> scene) {
|
||||||
|
manager_.replaceScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::pushScene(Ptr<Scene> scene) {
|
||||||
|
manager_.pushScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::popScene() {
|
||||||
|
manager_.popScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::popToRootScene() {
|
||||||
|
manager_.popToRootScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::popToScene(const std::string& name) {
|
||||||
|
manager_.popToScene(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr<Scene> SceneService::getCurrentScene() const {
|
||||||
|
return manager_.getCurrentScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr<Scene> SceneService::getPreviousScene() const {
|
||||||
|
return manager_.getPreviousScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr<Scene> SceneService::getRootScene() const {
|
||||||
|
return manager_.getRootScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr<Scene> SceneService::getSceneByName(const std::string& name) const {
|
||||||
|
return manager_.getSceneByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SceneService::getSceneCount() const {
|
||||||
|
return manager_.getSceneCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneService::isEmpty() const {
|
||||||
|
return manager_.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneService::hasScene(const std::string& name) const {
|
||||||
|
return manager_.hasScene(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::render(RenderBackend& renderer) {
|
||||||
|
manager_.render(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::collectRenderCommands(std::vector<RenderCommand>& commands) {
|
||||||
|
manager_.collectRenderCommands(commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneService::isTransitioning() const {
|
||||||
|
return manager_.isTransitioning();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::setTransitionCallback(SceneManager::TransitionCallback callback) {
|
||||||
|
manager_.setTransitionCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::end() {
|
||||||
|
manager_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::purgeCachedScenes() {
|
||||||
|
manager_.purgeCachedScenes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneService::enterScene(Ptr<Scene> scene) {
|
||||||
|
manager_.enterScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include <extra2d/services/timer_service.h>
|
||||||
|
|
||||||
|
namespace extra2d {
|
||||||
|
|
||||||
|
TimerService::TimerService() {
|
||||||
|
info_.name = "TimerService";
|
||||||
|
info_.priority = ServicePriority::Timer;
|
||||||
|
info_.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceInfo TimerService::getServiceInfo() const {
|
||||||
|
return info_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimerService::initialize() {
|
||||||
|
setState(ServiceState::Running);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerService::shutdown() {
|
||||||
|
manager_.clear();
|
||||||
|
setState(ServiceState::Stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerService::update(float deltaTime) {
|
||||||
|
if (getState() == ServiceState::Running) {
|
||||||
|
manager_.update(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 TimerService::addTimer(float delay, Timer::Callback callback) {
|
||||||
|
return manager_.addTimer(delay, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 TimerService::addRepeatingTimer(float interval, Timer::Callback callback) {
|
||||||
|
return manager_.addRepeatingTimer(interval, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerService::cancelTimer(uint32 timerId) {
|
||||||
|
manager_.cancelTimer(timerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerService::pauseTimer(uint32 timerId) {
|
||||||
|
manager_.pauseTimer(timerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerService::resumeTimer(uint32 timerId) {
|
||||||
|
manager_.resumeTimer(timerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerService::clear() {
|
||||||
|
manager_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t TimerService::getTimerCount() const {
|
||||||
|
return manager_.getTimerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue