refactor: migració a l'arquitectura SDL3 Callback API
Substitueix el bucle blocant main() → Director::run() → escena::run() per SDL_AppInit/Iterate/Event/Quit. Cada escena implementa ara iterate() (un frame) i handleEvent() (un event) sota una interfície base Scene. - Director gestiona l'escena activa i les transicions via switchToActiveScene() - Setup/cleanup que estava al voltant del while de run() mogut a ctor/dtor (música de Game/Ending/Ending2, volum de LoadingScreen) - GlobalEvents ja no processa SDL_EVENT_QUIT (ho fa Director::handleEvent) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+87
-112
@@ -211,6 +211,9 @@ Director::Director() {
|
||||
#else
|
||||
Cheevos::init(Resource::List::get()->get("cheevos.bin"));
|
||||
#endif
|
||||
|
||||
// Construeix la primera escena (LOGO per defecte, o la que digui Debug)
|
||||
switchToActiveScene();
|
||||
}
|
||||
|
||||
Director::~Director() {
|
||||
@@ -311,118 +314,90 @@ void Director::setFileList() { // NOLINT(readability-convert-member-functions-t
|
||||
Resource::List::get()->loadFromFile(config_path, PREFIX, system_folder_);
|
||||
}
|
||||
|
||||
// Ejecuta la seccion de juego con el logo
|
||||
void Director::runLogo() {
|
||||
auto logo = std::make_unique<Logo>();
|
||||
logo->run();
|
||||
}
|
||||
|
||||
// Ejecuta la seccion de juego de la pantalla de carga
|
||||
void Director::runLoadingScreen() {
|
||||
auto loading_screen = std::make_unique<LoadingScreen>();
|
||||
loading_screen->run();
|
||||
}
|
||||
|
||||
// Ejecuta la seccion de juego con el titulo y los menus
|
||||
void Director::runTitle() {
|
||||
auto title = std::make_unique<Title>();
|
||||
title->run();
|
||||
}
|
||||
|
||||
// Ejecuta la seccion de los creditos del juego
|
||||
void Director::runCredits() {
|
||||
auto credits = std::make_unique<Credits>();
|
||||
credits->run();
|
||||
}
|
||||
|
||||
// Ejecuta la seccion de la demo, donde se ven pantallas del juego
|
||||
void Director::runDemo() {
|
||||
auto game = std::make_unique<Game>(Game::Mode::DEMO);
|
||||
game->run();
|
||||
}
|
||||
|
||||
// Ejecuta la seccion del final del juego
|
||||
void Director::runEnding() {
|
||||
auto ending = std::make_unique<Ending>();
|
||||
ending->run();
|
||||
}
|
||||
|
||||
// Ejecuta la seccion del final del juego
|
||||
void Director::runEnding2() {
|
||||
auto ending2 = std::make_unique<Ending2>();
|
||||
ending2->run();
|
||||
}
|
||||
|
||||
// Ejecuta la seccion del final de la partida
|
||||
void Director::runGameOver() {
|
||||
auto game_over = std::make_unique<GameOver>();
|
||||
game_over->run();
|
||||
}
|
||||
|
||||
// Ejecuta la seccion de juego donde se juega
|
||||
void Director::runGame() {
|
||||
Audio::get()->stopMusic();
|
||||
auto game = std::make_unique<Game>(Game::Mode::GAME);
|
||||
game->run();
|
||||
}
|
||||
|
||||
auto Director::run() -> int {
|
||||
// Bucle principal
|
||||
while (SceneManager::current != SceneManager::Scene::QUIT) {
|
||||
const SceneManager::Scene ACTIVE = SceneManager::current;
|
||||
|
||||
switch (SceneManager::current) {
|
||||
case SceneManager::Scene::LOGO:
|
||||
runLogo();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::LOADING_SCREEN:
|
||||
runLoadingScreen();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::TITLE:
|
||||
runTitle();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::CREDITS:
|
||||
runCredits();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::DEMO:
|
||||
runDemo();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::GAME:
|
||||
runGame();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::GAME_OVER:
|
||||
runGameOver();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::ENDING:
|
||||
runEnding();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::ENDING2:
|
||||
runEnding2();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::RESTART_CURRENT:
|
||||
// La escena salió por RESTART_CURRENT → relanzar la escena guardada
|
||||
SceneManager::current = SceneManager::scene_before_restart;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Si la escena que acaba de correr dejó RESTART_CURRENT pendiente,
|
||||
// restaurar la escena que estaba activa para relanzarla en la próxima iteración
|
||||
if (SceneManager::current == SceneManager::Scene::RESTART_CURRENT) {
|
||||
SceneManager::current = ACTIVE;
|
||||
}
|
||||
// Construeix l'escena segons SceneManager::current i la deixa en active_scene_.
|
||||
// Substitueix els vells runLogo(), runTitle(), runGame(), etc.
|
||||
void Director::switchToActiveScene() {
|
||||
// Si la escena anterior va demanar RESTART_CURRENT, restaurem la que estava activa
|
||||
if (SceneManager::current == SceneManager::Scene::RESTART_CURRENT) {
|
||||
SceneManager::current = SceneManager::scene_before_restart;
|
||||
}
|
||||
|
||||
return 0;
|
||||
// Destrueix l'escena anterior (pot parar música, etc. al seu destructor)
|
||||
active_scene_.reset();
|
||||
|
||||
switch (SceneManager::current) {
|
||||
case SceneManager::Scene::LOGO:
|
||||
active_scene_ = std::make_unique<Logo>();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::LOADING_SCREEN:
|
||||
active_scene_ = std::make_unique<LoadingScreen>();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::TITLE:
|
||||
active_scene_ = std::make_unique<Title>();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::CREDITS:
|
||||
active_scene_ = std::make_unique<Credits>();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::DEMO:
|
||||
active_scene_ = std::make_unique<Game>(Game::Mode::DEMO);
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::GAME:
|
||||
Audio::get()->stopMusic();
|
||||
active_scene_ = std::make_unique<Game>(Game::Mode::GAME);
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::GAME_OVER:
|
||||
active_scene_ = std::make_unique<GameOver>();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::ENDING:
|
||||
active_scene_ = std::make_unique<Ending>();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::ENDING2:
|
||||
active_scene_ = std::make_unique<Ending2>();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
current_scene_ = SceneManager::current;
|
||||
}
|
||||
|
||||
// SDL_AppIterate: executa un frame de l'escena activa
|
||||
auto Director::iterate() -> SDL_AppResult {
|
||||
if (SceneManager::current == SceneManager::Scene::QUIT) {
|
||||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
|
||||
// Si l'escena ha canviat (o s'ha demanat RESTART_CURRENT), canviar-la abans del frame
|
||||
if (SceneManager::current != current_scene_ || SceneManager::current == SceneManager::Scene::RESTART_CURRENT) {
|
||||
switchToActiveScene();
|
||||
}
|
||||
|
||||
if (active_scene_) {
|
||||
active_scene_->iterate();
|
||||
}
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
// SDL_AppEvent: despatxa un event a l'escena activa
|
||||
auto Director::handleEvent(const SDL_Event& event) -> SDL_AppResult {
|
||||
if (event.type == SDL_EVENT_QUIT) {
|
||||
SceneManager::current = SceneManager::Scene::QUIT;
|
||||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
|
||||
if (active_scene_) {
|
||||
active_scene_->handleEvent(event);
|
||||
}
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
Reference in New Issue
Block a user