2026-02-11 19:40:26 +08:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
2026-02-28 23:35:34 +08:00
|
|
|
|
#include <config/app_config.h>
|
|
|
|
|
|
#include <module/module.h>
|
2026-02-28 20:56:11 +08:00
|
|
|
|
#include <memory>
|
2026-02-28 23:35:34 +08:00
|
|
|
|
#include <vector>
|
2026-02-26 00:59:16 +08:00
|
|
|
|
|
2026-02-11 19:40:26 +08:00
|
|
|
|
namespace extra2d {
|
|
|
|
|
|
|
2026-02-28 20:56:11 +08:00
|
|
|
|
// 前向声明
|
|
|
|
|
|
class Context;
|
2026-02-28 22:30:48 +08:00
|
|
|
|
class WindowModule;
|
|
|
|
|
|
class InputModule;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
2026-02-28 23:35:34 +08:00
|
|
|
|
* @brief 应用程序主控类 - 简化版
|
2026-02-28 20:56:11 +08:00
|
|
|
|
*
|
2026-02-27 20:46:16 +08:00
|
|
|
|
* 管理应用程序生命周期、窗口和主循环
|
2026-02-28 23:35:34 +08:00
|
|
|
|
* 自动管理模块的创建和销毁
|
2026-02-27 20:46:16 +08:00
|
|
|
|
*/
|
2026-02-11 19:40:26 +08:00
|
|
|
|
class Application {
|
|
|
|
|
|
public:
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
2026-02-28 20:56:11 +08:00
|
|
|
|
* @brief 创建应用程序实例
|
2026-02-27 22:59:17 +08:00
|
|
|
|
*/
|
2026-02-28 20:56:11 +08:00
|
|
|
|
static std::unique_ptr<Application> create();
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-27 20:46:16 +08:00
|
|
|
|
Application(const Application&) = delete;
|
|
|
|
|
|
Application& operator=(const Application&) = delete;
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-28 20:56:11 +08:00
|
|
|
|
Application(Application&&) noexcept;
|
|
|
|
|
|
Application& operator=(Application&&) noexcept;
|
|
|
|
|
|
|
|
|
|
|
|
~Application();
|
|
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 初始化应用程序
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
bool init(const AppConfig& config);
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 关闭应用程序
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
void shutdown();
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 运行主循环
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
void run();
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 请求退出
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
void quit();
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 暂停应用
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
void pause();
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 恢复应用
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
void resume();
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 是否暂停
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
bool isPaused() const { return paused_; }
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 是否运行中
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
bool isRunning() const { return running_; }
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取帧时间
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
float deltaTime() const { return deltaTime_; }
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取总运行时间
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
float totalTime() const { return totalTime_; }
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取当前 FPS
|
|
|
|
|
|
*/
|
2026-02-28 23:35:34 +08:00
|
|
|
|
int32 fps() const { return 0; } // TODO: 使用 SDL 计算 FPS
|
2026-02-27 22:59:17 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取配置
|
|
|
|
|
|
*/
|
2026-02-27 20:46:16 +08:00
|
|
|
|
const AppConfig& getConfig() const { return config_; }
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-28 20:56:11 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取引擎上下文
|
|
|
|
|
|
*/
|
|
|
|
|
|
Context* getContext() const { return context_.get(); }
|
|
|
|
|
|
|
2026-02-28 22:30:48 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取窗口模块
|
|
|
|
|
|
*/
|
2026-02-28 23:35:34 +08:00
|
|
|
|
WindowModule* getWindow() const;
|
2026-02-28 22:30:48 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取输入模块
|
|
|
|
|
|
*/
|
2026-02-28 23:35:34 +08:00
|
|
|
|
InputModule* getInput() const;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取指定类型的模块
|
|
|
|
|
|
* @tparam T 模块类型
|
|
|
|
|
|
* @return 模块指针,未找到返回 nullptr
|
|
|
|
|
|
*/
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
|
T* getModule() const {
|
|
|
|
|
|
for (const auto& module : modules_) {
|
|
|
|
|
|
if (auto* ptr = dynamic_cast<T*>(module.get())) {
|
|
|
|
|
|
return ptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
}
|
2026-02-28 22:30:48 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取窗口宽度
|
|
|
|
|
|
*/
|
|
|
|
|
|
int32 getWindowWidth() const;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取窗口高度
|
|
|
|
|
|
*/
|
|
|
|
|
|
int32 getWindowHeight() const;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取窗口标题
|
|
|
|
|
|
*/
|
|
|
|
|
|
const char* getWindowTitle() const;
|
|
|
|
|
|
|
2026-02-11 19:40:26 +08:00
|
|
|
|
private:
|
2026-02-28 20:56:11 +08:00
|
|
|
|
Application();
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-27 20:46:16 +08:00
|
|
|
|
void update();
|
2026-02-28 23:35:34 +08:00
|
|
|
|
void initModules();
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-28 20:56:11 +08:00
|
|
|
|
std::unique_ptr<Context> context_;
|
2026-02-28 23:35:34 +08:00
|
|
|
|
std::vector<std::unique_ptr<Module>> modules_;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 20:46:16 +08:00
|
|
|
|
AppConfig config_;
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-27 20:46:16 +08:00
|
|
|
|
bool initialized_ = false;
|
|
|
|
|
|
bool running_ = false;
|
|
|
|
|
|
bool paused_ = false;
|
|
|
|
|
|
bool shouldQuit_ = false;
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
2026-02-27 20:46:16 +08:00
|
|
|
|
float deltaTime_ = 0.0f;
|
|
|
|
|
|
float totalTime_ = 0.0f;
|
2026-02-11 19:40:26 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace extra2d
|