Extra2D/src/app/application.cpp

180 lines
3.8 KiB
C++
Raw Normal View History

#include <app/application.h>
#include <core/director.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 {
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
}
Application& Application::instance() {
static Application instance;
return instance;
2026-02-11 19:40:26 +08:00
}
Application::~Application() {
shutdown();
}
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
PlatformType platform = config_.platform;
if (platform == PlatformType::Auto) {
2026-02-11 19:40:26 +08:00
#ifdef __SWITCH__
platform = PlatformType::Switch;
2026-02-11 19:40:26 +08:00
#else
platform = PlatformType::PC;
2026-02-11 19:40:26 +08:00
#endif
}
2026-02-11 19:40:26 +08:00
if (platform == PlatformType::Switch) {
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
2026-02-11 19:40:26 +08:00
}
if (!DIRECTOR.init()) {
E2D_LOG_ERROR("Failed to initialize Director");
return false;
2026-02-11 19:40:26 +08:00
}
initialized_ = true;
running_ = true;
E2D_LOG_INFO("Application initialized successfully");
return true;
2026-02-11 19:40:26 +08:00
}
void Application::shutdown() {
if (!initialized_) return;
2026-02-11 19:40:26 +08:00
E2D_LOG_INFO("Shutting down application...");
2026-02-11 19:40:26 +08:00
DIRECTOR.shutdown();
2026-02-11 19:40:26 +08:00
PlatformType platform = config_.platform;
if (platform == PlatformType::Auto) {
2026-02-11 19:40:26 +08:00
#ifdef __SWITCH__
platform = PlatformType::Switch;
2026-02-11 19:40:26 +08:00
#else
platform = PlatformType::PC;
2026-02-11 19:40:26 +08:00
#endif
}
if (platform == PlatformType::Switch) {
2026-02-11 19:40:26 +08:00
#ifdef __SWITCH__
romfsExit();
socketExit();
2026-02-11 19:40:26 +08:00
#endif
}
2026-02-11 19:40:26 +08:00
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;
DIRECTOR.pause();
E2D_LOG_INFO("Application paused");
}
2026-02-11 19:40:26 +08:00
}
void Application::resume() {
if (paused_) {
paused_ = false;
DIRECTOR.resume();
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() {
DIRECTOR.mainLoop(deltaTime_);
2026-02-11 19:40:26 +08:00
}
} // namespace extra2d