Extra2D/src/app/application.cpp

196 lines
4.0 KiB
C++
Raw Normal View History

#include <app/application.h>
#include <context/context.h>
#include <event/events.h>
#include <platform/sdl2.h>
#include <utils/logger.h>
2026-02-11 19:40:26 +08:00
#include <chrono>
#include <thread>
#ifdef __SWITCH__
#include <switch.h>
#endif
namespace extra2d {
/**
* @brief
*/
2026-02-11 19:40:26 +08:00
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;
2026-02-11 19:40:26 +08:00
#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();
2026-02-11 19:40:26 +08:00
#endif
}
std::unique_ptr<Application> Application::create() {
return std::unique_ptr<Application>(new Application());
}
2026-02-11 19:40:26 +08:00
Application::Application() = default;
Application::~Application() {
shutdown();
}
Application::Application(Application&&) noexcept = default;
Application& Application::operator=(Application&&) noexcept = default;
2026-02-11 19:40:26 +08:00
bool Application::init(const AppConfig &config) {
if (initialized_) {
E2D_LOG_WARN("Application already initialized");
return true;
}
2026-02-11 19:40:26 +08:00
config_ = config;
2026-02-11 19:40:26 +08:00
#ifdef __SWITCH__
Result rc;
rc = romfsInit();
if (R_SUCCEEDED(rc)) {
E2D_LOG_INFO("RomFS initialized successfully");
} else {
E2D_LOG_WARN("romfsInit failed: {:#08X}", rc);
}
rc = socketInitializeDefault();
if (R_FAILED(rc)) {
E2D_LOG_WARN("socketInitializeDefault failed");
}
#endif
if (!Sdl2::initAll()) {
E2D_LOG_ERROR("Failed to initialize SDL2");
return false;
}
// 创建引擎上下文
context_ = Context::create();
if (!context_) {
E2D_LOG_ERROR("Failed to create context");
return false;
}
// 初始化引擎
if (!context_->init()) {
E2D_LOG_ERROR("Failed to initialize context");
return false;
}
initialized_ = true;
running_ = true;
events::OnInit::emit();
E2D_LOG_INFO("Application initialized successfully");
E2D_LOG_INFO("Window: {}x{}, Fullscreen: {}, VSync: {}", config_.width,
config_.height, config_.fullscreen, config_.vsync);
return true;
2026-02-11 19:40:26 +08:00
}
void Application::shutdown() {
if (!initialized_)
return;
2026-02-11 19:40:26 +08:00
events::OnShutdown::emit();
E2D_LOG_INFO("Shutting down application...");
2026-02-11 19:40:26 +08:00
// 关闭上下文(会自动关闭模块和插件)
context_.reset();
Sdl2::shutdown();
2026-02-11 19:40:26 +08:00
#ifdef __SWITCH__
romfsExit();
socketExit();
2026-02-11 19:40:26 +08:00
#endif
initialized_ = false;
running_ = false;
2026-02-11 19:40:26 +08:00
E2D_LOG_INFO("Application shutdown complete");
2026-02-11 19:40:26 +08:00
}
void Application::run() {
if (!initialized_) {
E2D_LOG_ERROR("Application not initialized");
return;
}
2026-02-11 19:40:26 +08:00
lastFrameTime_ = getTimeSeconds();
2026-02-11 19:40:26 +08:00
while (running_) {
mainLoop();
}
2026-02-11 19:40:26 +08:00
}
void Application::quit() {
shouldQuit_ = true;
running_ = false;
2026-02-11 19:40:26 +08:00
}
void Application::pause() {
if (!paused_) {
paused_ = true;
events::OnPause::emit();
E2D_LOG_INFO("Application paused");
}
2026-02-11 19:40:26 +08:00
}
void Application::resume() {
if (paused_) {
paused_ = false;
events::OnResume::emit();
lastFrameTime_ = getTimeSeconds();
E2D_LOG_INFO("Application resumed");
}
2026-02-11 19:40:26 +08:00
}
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;
}
if (!paused_) {
update();
}
// 帧率限制
if (!config_.vsync && config_.fpsLimit > 0) {
double frameEndTime = getTimeSeconds();
double frameTime = frameEndTime - currentTime;
double target = 1.0 / static_cast<double>(config_.fpsLimit);
if (frameTime < target) {
std::this_thread::sleep_for(
std::chrono::duration<double>(target - frameTime));
}
}
2026-02-11 19:40:26 +08:00
}
void Application::update() {
// 通过上下文更新引擎
if (context_) {
context_->tick(deltaTime_);
}
2026-02-11 19:40:26 +08:00
}
} // namespace extra2d