parent
9f83b8fde5
commit
4b1de5e36a
|
|
@ -1,268 +1,273 @@
|
|||
#include <extra2d/app/application.h>
|
||||
#include <extra2d/core/registry.h>
|
||||
#include <extra2d/platform/window_module.h>
|
||||
#include <extra2d/platform/input_module.h>
|
||||
#include <extra2d/graphics/core/render_module.h>
|
||||
#include <extra2d/platform/iwindow.h>
|
||||
#include <extra2d/platform/iinput.h>
|
||||
#include <extra2d/graphics/core/render_backend.h>
|
||||
#include <extra2d/graphics/core/render_module.h>
|
||||
#include <extra2d/graphics/memory/vram_manager.h>
|
||||
#include <extra2d/platform/iinput.h>
|
||||
#include <extra2d/platform/input_module.h>
|
||||
#include <extra2d/platform/iwindow.h>
|
||||
#include <extra2d/platform/window_module.h>
|
||||
#include <extra2d/services/camera_service.h>
|
||||
#include <extra2d/services/event_service.h>
|
||||
#include <extra2d/services/logger_service.h>
|
||||
#include <extra2d/services/scene_service.h>
|
||||
#include <extra2d/services/timer_service.h>
|
||||
#include <extra2d/services/event_service.h>
|
||||
#include <extra2d/services/camera_service.h>
|
||||
#include <extra2d/services/logger_service.h>
|
||||
#include <extra2d/graphics/memory/vram_manager.h>
|
||||
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
static double getTimeSeconds() {
|
||||
#ifdef __SWITCH__
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return static_cast<double>(ts.tv_sec) +
|
||||
static_cast<double>(ts.tv_nsec) / 1000000000.0;
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return static_cast<double>(ts.tv_sec) +
|
||||
static_cast<double>(ts.tv_nsec) / 1000000000.0;
|
||||
#else
|
||||
using namespace std::chrono;
|
||||
auto now = steady_clock::now();
|
||||
auto duration = now.time_since_epoch();
|
||||
return duration_cast<std::chrono::duration<double>>(duration).count();
|
||||
using namespace std::chrono;
|
||||
auto now = steady_clock::now();
|
||||
auto duration = now.time_since_epoch();
|
||||
return duration_cast<std::chrono::duration<double>>(duration).count();
|
||||
#endif
|
||||
}
|
||||
|
||||
Application& Application::get() {
|
||||
static Application instance;
|
||||
return instance;
|
||||
Application &Application::get() {
|
||||
static Application instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
Application::Application() {
|
||||
Registry::instance().setApp(this);
|
||||
}
|
||||
Application::Application() { Registry::instance().setApp(this); }
|
||||
|
||||
Application::~Application() {
|
||||
if (initialized_) {
|
||||
shutdown();
|
||||
}
|
||||
if (initialized_) {
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::init() {
|
||||
AppConfig cfg;
|
||||
return init(cfg);
|
||||
AppConfig cfg;
|
||||
return init(cfg);
|
||||
}
|
||||
|
||||
bool Application::init(const AppConfig& config) {
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
appConfig_ = config;
|
||||
|
||||
// 首先注册日志服务(模块初始化可能需要它)
|
||||
auto& locator = ServiceLocator::instance();
|
||||
if (!locator.hasService<ILogger>()) {
|
||||
auto logger = makeShared<ConsoleLogger>();
|
||||
locator.registerService(std::static_pointer_cast<ILogger>(logger));
|
||||
}
|
||||
|
||||
// 初始化所有模块(拓扑排序)
|
||||
if (!Registry::instance().init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 模块初始化完成后,注册其他核心服务
|
||||
registerCoreServices();
|
||||
|
||||
initialized_ = true;
|
||||
running_ = true;
|
||||
bool Application::init(const AppConfig &config) {
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
appConfig_ = config;
|
||||
|
||||
// 首先注册日志服务(模块初始化可能需要它)
|
||||
auto &locator = ServiceLocator::instance();
|
||||
if (!locator.hasService<ILogger>()) {
|
||||
auto logger = makeShared<ConsoleLogger>();
|
||||
locator.registerService(std::static_pointer_cast<ILogger>(logger));
|
||||
}
|
||||
|
||||
// 初始化所有模块(拓扑排序)
|
||||
if (!Registry::instance().init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 模块初始化完成后,注册其他核心服务
|
||||
registerCoreServices();
|
||||
|
||||
initialized_ = true;
|
||||
running_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Application::registerCoreServices() {
|
||||
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>();
|
||||
if (winMod && winMod->win() && !locator.hasService<ICameraService>()) {
|
||||
auto cameraService = makeShared<CameraService>();
|
||||
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 &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>();
|
||||
if (winMod && winMod->win() && !locator.hasService<ICameraService>()) {
|
||||
auto cameraService = makeShared<CameraService>();
|
||||
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();
|
||||
}
|
||||
|
||||
void Application::shutdown() {
|
||||
if (!initialized_) return;
|
||||
|
||||
VRAMMgr::get().printStats();
|
||||
|
||||
ServiceLocator::instance().clear();
|
||||
Registry::instance().shutdown();
|
||||
Registry::instance().clear();
|
||||
|
||||
initialized_ = false;
|
||||
running_ = false;
|
||||
if (!initialized_)
|
||||
return;
|
||||
|
||||
VRAMMgr::get().printStats();
|
||||
|
||||
ServiceLocator::instance().clear();
|
||||
Registry::instance().shutdown();
|
||||
Registry::instance().clear();
|
||||
|
||||
initialized_ = false;
|
||||
running_ = false;
|
||||
}
|
||||
|
||||
void Application::run() {
|
||||
if (!initialized_) return;
|
||||
|
||||
auto* winMod = get<WindowModule>();
|
||||
if (!winMod || !winMod->win()) return;
|
||||
|
||||
lastFrameTime_ = getTimeSeconds();
|
||||
|
||||
while (running_ && !winMod->win()->shouldClose()) {
|
||||
mainLoop();
|
||||
}
|
||||
if (!initialized_)
|
||||
return;
|
||||
|
||||
auto *winMod = get<WindowModule>();
|
||||
if (!winMod || !winMod->win())
|
||||
return;
|
||||
|
||||
lastFrameTime_ = getTimeSeconds();
|
||||
|
||||
while (running_ && !winMod->win()->shouldClose()) {
|
||||
mainLoop();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::quit() {
|
||||
shouldQuit_ = true;
|
||||
running_ = false;
|
||||
shouldQuit_ = true;
|
||||
running_ = false;
|
||||
}
|
||||
|
||||
void Application::pause() {
|
||||
if (!paused_) {
|
||||
paused_ = true;
|
||||
ServiceLocator::instance().pauseAll();
|
||||
}
|
||||
if (!paused_) {
|
||||
paused_ = true;
|
||||
ServiceLocator::instance().pauseAll();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::resume() {
|
||||
if (paused_) {
|
||||
paused_ = false;
|
||||
ServiceLocator::instance().resumeAll();
|
||||
lastFrameTime_ = getTimeSeconds();
|
||||
}
|
||||
if (paused_) {
|
||||
paused_ = false;
|
||||
ServiceLocator::instance().resumeAll();
|
||||
lastFrameTime_ = getTimeSeconds();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::mainLoop() {
|
||||
double currentTime = getTimeSeconds();
|
||||
deltaTime_ = static_cast<float>(currentTime - lastFrameTime_);
|
||||
lastFrameTime_ = currentTime;
|
||||
|
||||
totalTime_ += deltaTime_;
|
||||
|
||||
frameCount_++;
|
||||
fpsTimer_ += deltaTime_;
|
||||
if (fpsTimer_ >= 1.0f) {
|
||||
currentFps_ = frameCount_;
|
||||
frameCount_ = 0;
|
||||
fpsTimer_ -= 1.0f;
|
||||
}
|
||||
|
||||
auto* winMod = get<WindowModule>();
|
||||
if (winMod && winMod->win()) {
|
||||
winMod->win()->poll();
|
||||
}
|
||||
|
||||
auto eventService = ServiceLocator::instance().getService<IEventService>();
|
||||
if (eventService) {
|
||||
eventService->processQueue();
|
||||
}
|
||||
|
||||
if (!paused_) {
|
||||
update();
|
||||
}
|
||||
|
||||
render();
|
||||
|
||||
// 帧率限制
|
||||
auto* renderMod = get<RenderModule>();
|
||||
if (renderMod && renderMod->renderer()) {
|
||||
// 这里可以添加帧率限制逻辑
|
||||
}
|
||||
double currentTime = getTimeSeconds();
|
||||
deltaTime_ = static_cast<float>(currentTime - lastFrameTime_);
|
||||
lastFrameTime_ = currentTime;
|
||||
|
||||
totalTime_ += deltaTime_;
|
||||
|
||||
frameCount_++;
|
||||
fpsTimer_ += deltaTime_;
|
||||
if (fpsTimer_ >= 1.0f) {
|
||||
currentFps_ = frameCount_;
|
||||
frameCount_ = 0;
|
||||
fpsTimer_ -= 1.0f;
|
||||
}
|
||||
|
||||
auto *winMod = get<WindowModule>();
|
||||
if (winMod && winMod->win()) {
|
||||
winMod->win()->poll();
|
||||
}
|
||||
|
||||
auto eventService = ServiceLocator::instance().getService<IEventService>();
|
||||
if (eventService) {
|
||||
eventService->processQueue();
|
||||
}
|
||||
|
||||
if (!paused_) {
|
||||
update();
|
||||
}
|
||||
|
||||
render();
|
||||
|
||||
// 帧率限制
|
||||
auto *renderMod = get<RenderModule>();
|
||||
if (renderMod && renderMod->renderer()) {
|
||||
// 这里可以添加帧率限制逻辑
|
||||
}
|
||||
}
|
||||
|
||||
void Application::update() {
|
||||
ServiceLocator::instance().updateAll(deltaTime_);
|
||||
|
||||
auto* inputMod = get<InputModule>();
|
||||
if (inputMod) {
|
||||
inputMod->update();
|
||||
}
|
||||
ServiceLocator::instance().updateAll(deltaTime_);
|
||||
|
||||
auto *inputMod = get<InputModule>();
|
||||
if (inputMod) {
|
||||
inputMod->update();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::render() {
|
||||
auto* renderMod = get<RenderModule>();
|
||||
if (!renderMod || !renderMod->renderer()) return;
|
||||
|
||||
auto* renderer = renderMod->renderer();
|
||||
auto* winMod = get<WindowModule>();
|
||||
if (!winMod || !winMod->win()) return;
|
||||
|
||||
auto cameraService = ServiceLocator::instance().getService<ICameraService>();
|
||||
if (cameraService) {
|
||||
const auto& vp = cameraService->getViewportResult().viewport;
|
||||
renderer->setViewport(
|
||||
static_cast<int>(vp.origin.x), static_cast<int>(vp.origin.y),
|
||||
static_cast<int>(vp.size.width), static_cast<int>(vp.size.height));
|
||||
renderer->setViewProjection(cameraService->getViewProjectionMatrix());
|
||||
} else {
|
||||
renderer->setViewport(0, 0, winMod->win()->width(), winMod->win()->height());
|
||||
}
|
||||
|
||||
auto sceneService = ServiceLocator::instance().getService<ISceneService>();
|
||||
if (sceneService) {
|
||||
sceneService->render(*renderer);
|
||||
}
|
||||
|
||||
winMod->win()->swap();
|
||||
auto *renderMod = get<RenderModule>();
|
||||
if (!renderMod || !renderMod->renderer())
|
||||
return;
|
||||
|
||||
auto *renderer = renderMod->renderer();
|
||||
auto *winMod = get<WindowModule>();
|
||||
if (!winMod || !winMod->win())
|
||||
return;
|
||||
|
||||
auto cameraService = ServiceLocator::instance().getService<ICameraService>();
|
||||
if (cameraService) {
|
||||
const auto &vp = cameraService->getViewportResult().viewport;
|
||||
renderer->setViewport(
|
||||
static_cast<int>(vp.origin.x), static_cast<int>(vp.origin.y),
|
||||
static_cast<int>(vp.size.width), static_cast<int>(vp.size.height));
|
||||
renderer->setViewProjection(cameraService->getViewProjectionMatrix());
|
||||
} else {
|
||||
renderer->setViewport(0, 0, winMod->win()->width(),
|
||||
winMod->win()->height());
|
||||
}
|
||||
|
||||
auto sceneService = ServiceLocator::instance().getService<ISceneService>();
|
||||
if (sceneService) {
|
||||
sceneService->render(*renderer);
|
||||
}
|
||||
|
||||
winMod->win()->swap();
|
||||
}
|
||||
|
||||
IWindow* Application::window() {
|
||||
auto* winMod = get<WindowModule>();
|
||||
return winMod ? winMod->win() : nullptr;
|
||||
IWindow *Application::window() {
|
||||
auto *winMod = get<WindowModule>();
|
||||
return winMod ? winMod->win() : nullptr;
|
||||
}
|
||||
|
||||
RenderBackend* Application::renderer() {
|
||||
auto* renderMod = get<RenderModule>();
|
||||
return renderMod ? renderMod->renderer() : nullptr;
|
||||
RenderBackend *Application::renderer() {
|
||||
auto *renderMod = get<RenderModule>();
|
||||
return renderMod ? renderMod->renderer() : nullptr;
|
||||
}
|
||||
|
||||
IInput* Application::input() {
|
||||
auto* winMod = get<WindowModule>();
|
||||
return (winMod && winMod->win()) ? winMod->win()->input() : nullptr;
|
||||
IInput *Application::input() {
|
||||
auto *winMod = get<WindowModule>();
|
||||
return (winMod && winMod->win()) ? winMod->win()->input() : nullptr;
|
||||
}
|
||||
|
||||
void Application::enterScene(Ptr<Scene> scene) {
|
||||
auto sceneService = ServiceLocator::instance().getService<ISceneService>();
|
||||
auto* winMod = get<WindowModule>();
|
||||
if (sceneService && scene && winMod && winMod->win()) {
|
||||
scene->setViewportSize(static_cast<float>(winMod->win()->width()),
|
||||
static_cast<float>(winMod->win()->height()));
|
||||
sceneService->enterScene(scene);
|
||||
}
|
||||
auto sceneService = ServiceLocator::instance().getService<ISceneService>();
|
||||
auto *winMod = get<WindowModule>();
|
||||
if (sceneService && scene && winMod && winMod->win()) {
|
||||
scene->setViewportSize(static_cast<float>(winMod->win()->width()),
|
||||
static_cast<float>(winMod->win()->height()));
|
||||
sceneService->enterScene(scene);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
|
|||
|
|
@ -3,15 +3,16 @@
|
|||
* @brief Extra2D 场景图测试示例
|
||||
*/
|
||||
|
||||
#include <extra2d/extra2d.h>
|
||||
#include <extra2d/platform/window_module.h>
|
||||
#include <extra2d/platform/input_module.h>
|
||||
#include <extra2d/graphics/core/render_module.h>
|
||||
#include <extra2d/core/service_locator.h>
|
||||
#include <extra2d/services/event_service.h>
|
||||
#include <extra2d/extra2d.h>
|
||||
#include <extra2d/graphics/core/render_module.h>
|
||||
#include <extra2d/platform/input_module.h>
|
||||
#include <extra2d/platform/window_module.h>
|
||||
#include <extra2d/services/camera_service.h>
|
||||
#include <extra2d/services/event_service.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace extra2d;
|
||||
|
||||
void createSceneGraph(Scene *scene) {
|
||||
|
|
@ -106,12 +107,13 @@ int main(int argc, char *argv[]) {
|
|||
winCfg.w = 1280;
|
||||
winCfg.h = 720;
|
||||
winCfg.priority = 0;
|
||||
winCfg.backend = "glfw";
|
||||
app.use<WindowModule>(winCfg);
|
||||
|
||||
|
||||
RenderModule::Cfg renderCfg;
|
||||
renderCfg.priority = 10;
|
||||
app.use<RenderModule>(renderCfg);
|
||||
|
||||
|
||||
InputModule::Cfg inputCfg;
|
||||
inputCfg.priority = 20;
|
||||
app.use<InputModule>(inputCfg);
|
||||
|
|
@ -123,10 +125,11 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
std::cout << "Application initialized successfully!" << std::endl;
|
||||
|
||||
auto* win = app.window();
|
||||
|
||||
auto *win = app.window();
|
||||
if (win) {
|
||||
std::cout << "Window: " << win->width() << "x" << win->height() << std::endl;
|
||||
std::cout << "Window: " << win->width() << "x" << win->height()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
auto eventService = ServiceLocator::instance().getService<IEventService>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue