refactor(platform): 移除PlatformType枚举并调整OpenGL配置

移除不再使用的PlatformType枚举及相关平台判断逻辑,简化代码结构。同时将默认OpenGL配置从3.3 Core改为3.2 ES,以支持更多平台。调整了窗口服务初始化方式,使用lambda表达式创建配置对象。
This commit is contained in:
ChestnutYueyue 2026-02-27 23:08:49 +08:00
parent 8abf58e3d5
commit 0761b55864
3 changed files with 281 additions and 312 deletions

View File

@ -5,15 +5,6 @@
namespace extra2d { namespace extra2d {
/**
* @brief
*/
enum class PlatformType {
Auto = 0,
PC,
Switch
};
/** /**
* @brief * @brief
*/ */
@ -27,7 +18,6 @@ struct AppConfig {
int32 fpsLimit = 0; int32 fpsLimit = 0;
int32 glMajor = 3; int32 glMajor = 3;
int32 glMinor = 3; int32 glMinor = 3;
PlatformType platform = PlatformType::Auto;
bool enableCursors = true; bool enableCursors = true;
bool enableDpiScale = false; bool enableDpiScale = false;
}; };

View File

@ -1,11 +1,11 @@
#include <app/application.h> #include <app/application.h>
#include <core/director.h> #include <core/director.h>
#include <core/service.h>
#include <core/event/events.h> #include <core/event/events.h>
#include <core/service.h>
#include <platform/file.h>
#include <platform/input.h>
#include <platform/sdl2.h> #include <platform/sdl2.h>
#include <platform/window.h> #include <platform/window.h>
#include <platform/input.h>
#include <platform/file.h>
#include <utils/logger.h> #include <utils/logger.h>
#include <chrono> #include <chrono>
@ -22,222 +22,200 @@ namespace extra2d {
*/ */
static double getTimeSeconds() { static double getTimeSeconds() {
#ifdef __SWITCH__ #ifdef __SWITCH__
struct timespec ts; struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
return static_cast<double>(ts.tv_sec) + static_cast<double>(ts.tv_nsec) / 1000000000.0; return static_cast<double>(ts.tv_sec) +
static_cast<double>(ts.tv_nsec) / 1000000000.0;
#else #else
using namespace std::chrono; using namespace std::chrono;
auto now = steady_clock::now(); auto now = steady_clock::now();
auto duration = now.time_since_epoch(); auto duration = now.time_since_epoch();
return duration_cast<std::chrono::duration<double>>(duration).count(); return duration_cast<std::chrono::duration<double>>(duration).count();
#endif #endif
} }
Application& Application::instance() { Application &Application::instance() {
static Application instance; static Application instance;
return instance; return instance;
} }
Application::~Application() { Application::~Application() { shutdown(); }
shutdown();
}
bool Application::init(const AppConfig& config) { bool Application::init(const AppConfig &config) {
if (initialized_) { if (initialized_) {
E2D_LOG_WARN("Application already initialized"); E2D_LOG_WARN("Application already initialized");
return true;
}
config_ = config;
PlatformType platform = config_.platform;
if (platform == PlatformType::Auto) {
#ifdef __SWITCH__
platform = PlatformType::Switch;
#else
platform = PlatformType::PC;
#endif
}
if (platform == PlatformType::Switch) {
#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;
}
SVC_MGR.reg(&WINDOW);
SVC_MGR.reg(&INPUT_SVC);
SVC_MGR.reg(&FILE_SVC);
if (!SVC_MGR.initAll()) {
E2D_LOG_ERROR("Failed to initialize services");
return false;
}
WindowCfg winCfg;
winCfg.title = config_.title;
winCfg.width = config_.width;
winCfg.height = config_.height;
winCfg.fullscreen = config_.fullscreen;
winCfg.resizable = config_.resizable;
winCfg.vsync = config_.vsync;
winCfg.glMajor = config_.glMajor;
winCfg.glMinor = config_.glMinor;
if (!WINDOW.create(winCfg)) {
E2D_LOG_ERROR("Failed to create window");
return false;
}
if (!DIRECTOR.init()) {
E2D_LOG_ERROR("Failed to initialize Director");
return false;
}
WINDOW.setOnClose([this]() {
quit();
});
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; return true;
}
config_ = config;
#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;
}
SVC_MGR.reg(&WINDOW);
SVC_MGR.reg(&INPUT_SVC);
SVC_MGR.reg(&FILE_SVC);
if (!SVC_MGR.initAll()) {
E2D_LOG_ERROR("Failed to initialize services");
return false;
}
if (!WINDOW.create([&] {
WindowCfg cfg;
cfg.title = config_.title;
cfg.width = config_.width;
cfg.height = config_.height;
cfg.fullscreen = config_.fullscreen;
cfg.resizable = config_.resizable;
cfg.vsync = config_.vsync;
cfg.glMajor = config_.glMajor;
cfg.glMinor = config_.glMinor;
return cfg;
}())) {
E2D_LOG_ERROR("Failed to create window");
return false;
}
if (!DIRECTOR.init()) {
E2D_LOG_ERROR("Failed to initialize Director");
return false;
}
WINDOW.setOnClose([this]() { quit(); });
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;
} }
void Application::shutdown() { void Application::shutdown() {
if (!initialized_) return; if (!initialized_)
return;
events::OnShutdown::emit(); events::OnShutdown::emit();
E2D_LOG_INFO("Shutting down application..."); E2D_LOG_INFO("Shutting down application...");
DIRECTOR.shutdown(); DIRECTOR.shutdown();
SVC_MGR.shutdownAll(); SVC_MGR.shutdownAll();
Sdl2::shutdown(); Sdl2::shutdown();
PlatformType platform = config_.platform;
if (platform == PlatformType::Auto) {
#ifdef __SWITCH__ #ifdef __SWITCH__
platform = PlatformType::Switch; romfsExit();
#else socketExit();
platform = PlatformType::PC;
#endif #endif
}
if (platform == PlatformType::Switch) { initialized_ = false;
#ifdef __SWITCH__ running_ = false;
romfsExit();
socketExit();
#endif
}
initialized_ = false; E2D_LOG_INFO("Application shutdown complete");
running_ = false;
E2D_LOG_INFO("Application shutdown complete");
} }
void Application::run() { void Application::run() {
if (!initialized_) { if (!initialized_) {
E2D_LOG_ERROR("Application not initialized"); E2D_LOG_ERROR("Application not initialized");
return; return;
} }
lastFrameTime_ = getTimeSeconds(); lastFrameTime_ = getTimeSeconds();
while (running_ && !WINDOW.shouldClose()) { while (running_ && !WINDOW.shouldClose()) {
mainLoop(); mainLoop();
} }
} }
void Application::quit() { void Application::quit() {
shouldQuit_ = true; shouldQuit_ = true;
running_ = false; running_ = false;
WINDOW.requestClose(); WINDOW.requestClose();
} }
void Application::pause() { void Application::pause() {
if (!paused_) { if (!paused_) {
paused_ = true; paused_ = true;
SVC_MGR.pauseAll(); SVC_MGR.pauseAll();
DIRECTOR.pause(); DIRECTOR.pause();
events::OnPause::emit(); events::OnPause::emit();
E2D_LOG_INFO("Application paused"); E2D_LOG_INFO("Application paused");
} }
} }
void Application::resume() { void Application::resume() {
if (paused_) { if (paused_) {
paused_ = false; paused_ = false;
SVC_MGR.resumeAll(); SVC_MGR.resumeAll();
DIRECTOR.resume(); DIRECTOR.resume();
lastFrameTime_ = getTimeSeconds(); lastFrameTime_ = getTimeSeconds();
events::OnResume::emit(); events::OnResume::emit();
E2D_LOG_INFO("Application resumed"); E2D_LOG_INFO("Application resumed");
} }
} }
void Application::mainLoop() { void Application::mainLoop() {
if (!WINDOW.pollEvents()) { if (!WINDOW.pollEvents()) {
running_ = false; running_ = false;
return; return;
} }
double currentTime = getTimeSeconds(); double currentTime = getTimeSeconds();
deltaTime_ = static_cast<float>(currentTime - lastFrameTime_); deltaTime_ = static_cast<float>(currentTime - lastFrameTime_);
lastFrameTime_ = currentTime; lastFrameTime_ = currentTime;
totalTime_ += deltaTime_; totalTime_ += deltaTime_;
frameCount_++; frameCount_++;
fpsTimer_ += deltaTime_; fpsTimer_ += deltaTime_;
if (fpsTimer_ >= 1.0f) { if (fpsTimer_ >= 1.0f) {
currentFps_ = frameCount_; currentFps_ = frameCount_;
frameCount_ = 0; frameCount_ = 0;
fpsTimer_ -= 1.0f; fpsTimer_ -= 1.0f;
} }
if (!paused_) { if (!paused_) {
update(); update();
} }
WINDOW.swapBuffers(); WINDOW.swapBuffers();
if (!config_.vsync && config_.fpsLimit > 0) { if (!config_.vsync && config_.fpsLimit > 0) {
double frameEndTime = getTimeSeconds(); double frameEndTime = getTimeSeconds();
double frameTime = frameEndTime - currentTime; double frameTime = frameEndTime - currentTime;
double target = 1.0 / static_cast<double>(config_.fpsLimit); double target = 1.0 / static_cast<double>(config_.fpsLimit);
if (frameTime < target) { if (frameTime < target) {
std::this_thread::sleep_for(std::chrono::duration<double>(target - frameTime)); std::this_thread::sleep_for(
} std::chrono::duration<double>(target - frameTime));
} }
}
} }
void Application::update() { void Application::update() {
SVC_MGR.updateAll(deltaTime_); SVC_MGR.updateAll(deltaTime_);
events::OnUpdate::emit(deltaTime_); events::OnUpdate::emit(deltaTime_);
DIRECTOR.mainLoop(deltaTime_); DIRECTOR.mainLoop(deltaTime_);
} }
} // namespace extra2d } // namespace extra2d

View File

@ -1,177 +1,178 @@
#include <platform/window.h> #include <SDL.h>
#include <platform/input.h> #include <platform/input.h>
#include <platform/sdl2.h> #include <platform/sdl2.h>
#include <SDL.h> #include <platform/window.h>
namespace extra2d { namespace extra2d {
WindowSvc& WindowSvc::inst() { WindowSvc &WindowSvc::inst() {
static WindowSvc instance; static WindowSvc instance;
return instance; return instance;
} }
bool WindowSvc::init() { bool WindowSvc::init() {
if (isInited()) return true; if (isInited())
if (!Sdl2::initVideo()) {
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
state_ = SvcState::Inited;
return true; return true;
if (!Sdl2::initVideo()) {
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
state_ = SvcState::Inited;
return true;
} }
void WindowSvc::shutdown() { void WindowSvc::shutdown() {
if (glCtx_) { if (glCtx_) {
SDL_GL_DeleteContext(glCtx_); SDL_GL_DeleteContext(glCtx_);
glCtx_ = nullptr; glCtx_ = nullptr;
} }
if (window_) { if (window_) {
SDL_DestroyWindow(window_); SDL_DestroyWindow(window_);
window_ = nullptr; window_ = nullptr;
} }
state_ = SvcState::Shutdown; state_ = SvcState::Shutdown;
} }
bool WindowSvc::create(const WindowCfg& cfg) { bool WindowSvc::create(const WindowCfg &cfg) {
if (window_) return true; if (window_)
uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
if (cfg.resizable) {
flags |= SDL_WINDOW_RESIZABLE;
}
if (cfg.fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, cfg.glMajor);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, cfg.glMinor);
window_ = SDL_CreateWindow(
cfg.title.c_str(),
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
cfg.width,
cfg.height,
flags
);
if (!window_) {
return false;
}
glCtx_ = SDL_GL_CreateContext(window_);
if (!glCtx_) {
SDL_DestroyWindow(window_);
window_ = nullptr;
return false;
}
setVsync(cfg.vsync);
vsync_ = cfg.vsync;
return true; return true;
uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
if (cfg.resizable) {
flags |= SDL_WINDOW_RESIZABLE;
}
if (cfg.fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, cfg.glMajor);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, cfg.glMinor);
window_ =
SDL_CreateWindow(cfg.title.c_str(), SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, cfg.width, cfg.height, flags);
if (!window_) {
return false;
}
glCtx_ = SDL_GL_CreateContext(window_);
if (!glCtx_) {
SDL_DestroyWindow(window_);
window_ = nullptr;
return false;
}
setVsync(cfg.vsync);
vsync_ = cfg.vsync;
return true;
} }
bool WindowSvc::pollEvents() { bool WindowSvc::pollEvents() {
SDL_Event evt; SDL_Event evt;
while (SDL_PollEvent(&evt)) { while (SDL_PollEvent(&evt)) {
switch (evt.type) { switch (evt.type) {
case SDL_QUIT: case SDL_QUIT:
shouldClose_ = true; shouldClose_ = true;
if (onClose_) onClose_(); if (onClose_)
break; onClose_();
case SDL_WINDOWEVENT: break;
if (evt.window.event == SDL_WINDOWEVENT_RESIZED) { case SDL_WINDOWEVENT:
if (onResize_) { if (evt.window.event == SDL_WINDOWEVENT_RESIZED) {
onResize_(evt.window.data1, evt.window.data2); if (onResize_) {
} onResize_(evt.window.data1, evt.window.data2);
}
break;
default:
if (INPUT_SVC.isInited()) {
INPUT_SVC.processEvent(evt);
}
break;
} }
}
break;
default:
if (INPUT_SVC.isInited()) {
INPUT_SVC.processEvent(evt);
}
break;
} }
return !shouldClose_; }
return !shouldClose_;
} }
void WindowSvc::swapBuffers() { void WindowSvc::swapBuffers() {
if (window_ && glCtx_) { if (window_ && glCtx_) {
SDL_GL_SwapWindow(window_); SDL_GL_SwapWindow(window_);
} }
} }
Size WindowSvc::getSize() const { Size WindowSvc::getSize() const {
if (!window_) return Size(0, 0); if (!window_)
int w, h; return Size(0, 0);
SDL_GetWindowSize(window_, &w, &h); int w, h;
return Size(w, h); SDL_GetWindowSize(window_, &w, &h);
return Size(w, h);
} }
Vec2 WindowSvc::getPosition() const { Vec2 WindowSvc::getPosition() const {
if (!window_) return Vec2(0, 0); if (!window_)
int x, y; return Vec2(0, 0);
SDL_GetWindowPosition(window_, &x, &y); int x, y;
return Vec2(static_cast<float>(x), static_cast<float>(y)); SDL_GetWindowPosition(window_, &x, &y);
return Vec2(static_cast<float>(x), static_cast<float>(y));
} }
void WindowSvc::setSize(int32 w, int32 h) { void WindowSvc::setSize(int32 w, int32 h) {
if (window_) { if (window_) {
SDL_SetWindowSize(window_, w, h); SDL_SetWindowSize(window_, w, h);
} }
} }
void WindowSvc::setTitle(const std::string& title) { void WindowSvc::setTitle(const std::string &title) {
if (window_) { if (window_) {
SDL_SetWindowTitle(window_, title.c_str()); SDL_SetWindowTitle(window_, title.c_str());
} }
} }
void WindowSvc::setFullscreen(bool fullscreen) { void WindowSvc::setFullscreen(bool fullscreen) {
if (window_) { if (window_) {
SDL_SetWindowFullscreen(window_, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); SDL_SetWindowFullscreen(window_,
} fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
}
} }
bool WindowSvc::isFullscreen() const { bool WindowSvc::isFullscreen() const {
if (!window_) return false; if (!window_)
uint32 flags = SDL_GetWindowFlags(window_); return false;
return (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; uint32 flags = SDL_GetWindowFlags(window_);
return (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
} }
void WindowSvc::setVsync(bool vsync) { void WindowSvc::setVsync(bool vsync) {
SDL_GL_SetSwapInterval(vsync ? 1 : 0); SDL_GL_SetSwapInterval(vsync ? 1 : 0);
vsync_ = vsync; vsync_ = vsync;
} }
bool WindowSvc::isVsync() const { bool WindowSvc::isVsync() const { return vsync_; }
return vsync_;
}
void WindowSvc::setVisible(bool visible) { void WindowSvc::setVisible(bool visible) {
if (window_) { if (window_) {
if (visible) { if (visible) {
SDL_ShowWindow(window_); SDL_ShowWindow(window_);
} else { } else {
SDL_HideWindow(window_); SDL_HideWindow(window_);
}
} }
}
} }
bool WindowSvc::isVisible() const { bool WindowSvc::isVisible() const {
if (!window_) return false; if (!window_)
uint32 flags = SDL_GetWindowFlags(window_); return false;
return (flags & SDL_WINDOW_SHOWN) != 0; uint32 flags = SDL_GetWindowFlags(window_);
return (flags & SDL_WINDOW_SHOWN) != 0;
} }
} // namespace extra2d } // namespace extra2d