callbacks de merda

This commit is contained in:
2026-04-06 15:45:28 +02:00
parent fccc27fca0
commit a52e6c709e
10 changed files with 154 additions and 110 deletions

View File

@@ -20,6 +20,7 @@
#include "core/resources/resource_helper.hpp" // Para ResourceHelper #include "core/resources/resource_helper.hpp" // Para ResourceHelper
#include "core/resources/resource_list.hpp" // Para Asset, AssetType #include "core/resources/resource_list.hpp" // Para Asset, AssetType
#include "core/resources/resource_loader.hpp" // Para ResourceLoader #include "core/resources/resource_loader.hpp" // Para ResourceLoader
#include "core/system/event_buffer.hpp" // Para EventBuffer
#include "game/gameplay/cheevos.hpp" // Para Cheevos #include "game/gameplay/cheevos.hpp" // Para Cheevos
#include "game/options.hpp" // Para Options, options, OptionsVideo #include "game/options.hpp" // Para Options, options, OptionsVideo
#include "game/scene_manager.hpp" // Para SceneManager #include "game/scene_manager.hpp" // Para SceneManager
@@ -319,58 +320,80 @@ void Director::setFileList() { // NOLINT(readability-convert-member-functions-t
Resource::List::get()->loadFromFile(config_path, PREFIX, system_folder_); Resource::List::get()->loadFromFile(config_path, PREFIX, system_folder_);
} }
// Ejecuta la seccion de juego con el logo // Destruye la escena activa
void Director::runLogo() { void Director::destroyCurrentScene() {
auto logo = std::make_unique<Logo>(); logo_.reset();
logo->run(); title_.reset();
game_.reset();
active_scene_ = SceneManager::Scene::QUIT;
} }
// Ejecuta la seccion de juego con el titulo y los menus // Crea la escena indicada
void Director::runTitle() { void Director::createScene(SceneManager::Scene scene) {
auto title = std::make_unique<Title>(); destroyCurrentScene();
title->run();
}
// Ejecuta la seccion de juego donde se juega switch (scene) {
void Director::runGame() { case SceneManager::Scene::LOGO:
Audio::get()->stopMusic(); logo_ = std::make_unique<Logo>();
auto game = std::make_unique<Game>(Game::Mode::GAME); break;
game->run();
}
auto Director::run() -> int { case SceneManager::Scene::TITLE:
// Bucle principal title_ = std::make_unique<Title>();
while (SceneManager::current != SceneManager::Scene::QUIT) { break;
const SceneManager::Scene ACTIVE = SceneManager::current;
switch (SceneManager::current) { case SceneManager::Scene::GAME:
case SceneManager::Scene::LOGO: Audio::get()->stopMusic();
runLogo(); game_ = std::make_unique<Game>(Game::Mode::GAME);
break; break;
case SceneManager::Scene::TITLE: default:
runTitle(); break;
break;
case SceneManager::Scene::GAME:
runGame();
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;
}
} }
return 0; active_scene_ = scene;
}
// Una iteración del bucle principal (callback model)
auto Director::iterate() -> SDL_AppResult {
// Resolver RESTART_CURRENT antes de comprobar escena
if (SceneManager::current == SceneManager::Scene::RESTART_CURRENT) {
SceneManager::current = SceneManager::scene_before_restart;
}
// Salir si se ha pedido QUIT
if (SceneManager::current == SceneManager::Scene::QUIT) {
EventBuffer::events.clear();
return SDL_APP_SUCCESS;
}
// Si la escena solicitada no coincide con la activa, crear la nueva
if (SceneManager::current != active_scene_) {
createScene(SceneManager::current);
}
// Ejecutar un frame de la escena activa
switch (active_scene_) {
case SceneManager::Scene::LOGO:
logo_->update();
logo_->render();
break;
case SceneManager::Scene::TITLE:
title_->update();
title_->render();
break;
case SceneManager::Scene::GAME:
game_->update();
game_->render();
break;
default:
break;
}
// Limpiar el buffer de eventos tras cada frame
EventBuffer::events.clear();
return SDL_APP_CONTINUE;
} }

View File

@@ -2,23 +2,35 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <memory> // Para unique_ptr
#include <string> // Para string #include <string> // Para string
#include "game/scene_manager.hpp" // Para SceneManager::Scene
class Logo;
class Title;
class Game;
class Director { class Director {
public: public:
Director(); // Constructor Director(); // Constructor
~Director(); // Destructor ~Director(); // Destructor
static auto run() -> int; // Bucle principal auto iterate() -> SDL_AppResult; // Una iteración del bucle principal (callback model)
private: private:
// --- Variables --- // --- Variables ---
std::string executable_path_; // Path del ejecutable std::string executable_path_; // Path del ejecutable
std::string system_folder_; // Carpeta del sistema donde guardar datos std::string system_folder_; // Carpeta del sistema donde guardar datos
// --- Gestión de escenas ---
SceneManager::Scene active_scene_{SceneManager::Scene::QUIT}; // Escena activa (la que tiene objeto creado)
std::unique_ptr<Logo> logo_;
std::unique_ptr<Title> title_;
std::unique_ptr<Game> game_;
// --- Funciones --- // --- Funciones ---
void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema donde guardar datos void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema donde guardar datos
void setFileList(); // Carga la configuración de assets desde assets.yaml void setFileList(); // Carga la configuración de assets desde assets.yaml
static void runLogo(); // Ejecuta la seccion de juego con el logo void destroyCurrentScene(); // Destruye la escena activa
static void runTitle(); // Ejecuta la seccion de juego con el titulo y los menus void createScene(SceneManager::Scene scene); // Crea la escena indicada
static void runGame(); // Ejecuta la seccion de juego donde se juega
}; };

View File

@@ -0,0 +1,12 @@
#pragma once
#include <SDL3/SDL.h>
#include <vector>
// Buffer global de eventos SDL para el modelo de callbacks (SDL_MAIN_USE_CALLBACKS).
// SDL_AppEvent() almacena los eventos aquí; las escenas los consumen en su handleEvents().
// El buffer se limpia al final de cada iteración en Director::iterate().
namespace EventBuffer {
inline std::vector<SDL_Event> events;
} // namespace EventBuffer

View File

@@ -15,6 +15,7 @@
#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG #include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG
#include "core/resources/resource_cache.hpp" // Para ResourceRoom, Resource #include "core/resources/resource_cache.hpp" // Para ResourceRoom, Resource
#include "core/resources/resource_list.hpp" // Para Asset #include "core/resources/resource_list.hpp" // Para Asset
#include "core/system/event_buffer.hpp" // Para EventBuffer
#include "core/system/global_events.hpp" // Para check #include "core/system/global_events.hpp" // Para check
#include "game/defaults.hpp" // Para Defaults::Game #include "game/defaults.hpp" // Para Defaults::Game
#include "game/game_control.hpp" // Para GameControl #include "game/game_control.hpp" // Para GameControl
@@ -158,9 +159,20 @@ Game::Game(Mode mode)
SceneManager::current = SceneManager::Scene::GAME; SceneManager::current = SceneManager::Scene::GAME;
SceneManager::options = SceneManager::Options::NONE; SceneManager::options = SceneManager::Options::NONE;
// Inicialización de música (antes estaba al principio de run())
keepMusicPlaying();
if (!scoreboard_data_->music && mode_ == Mode::GAME) {
Audio::get()->pauseMusic();
}
} }
Game::~Game() { Game::~Game() {
// Parar música al destruir la escena (antes estaba al final de run())
if (mode_ == Mode::GAME) {
Audio::get()->stopMusic();
}
ItemTracker::destroy(); ItemTracker::destroy();
GameControl::change_player_skin = nullptr; GameControl::change_player_skin = nullptr;
@@ -185,8 +197,7 @@ Game::~Game() {
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
void Game::handleEvents() { void Game::handleEvents() {
SDL_Event event; for (const auto& event : EventBuffer::events) {
while (SDL_PollEvent(&event)) {
GlobalEvents::handle(event); GlobalEvents::handle(event);
#ifdef _DEBUG #ifdef _DEBUG
// En modo editor: click del ratón cierra la consola // En modo editor: click del ratón cierra la consola
@@ -257,23 +268,6 @@ void Game::handleInput() {
GlobalInputs::handle(); GlobalInputs::handle();
} }
// Bucle para el juego
void Game::run() {
keepMusicPlaying();
if (!scoreboard_data_->music && mode_ == Mode::GAME) {
Audio::get()->pauseMusic();
}
while (SceneManager::current == SceneManager::Scene::GAME) {
update();
render();
}
if (mode_ == Mode::GAME) {
Audio::get()->stopMusic();
}
}
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void Game::update() { void Game::update() {
const float DELTA_TIME = delta_timer_.tick(); const float DELTA_TIME = delta_timer_.tick();

View File

@@ -34,8 +34,9 @@ class Game {
explicit Game(Mode mode); explicit Game(Mode mode);
~Game(); ~Game();
// --- Bucle para el juego --- // --- Frame (llamados desde Director::iterate) ---
void run(); void update();
void render();
private: private:
// --- Constantes de tiempo --- // --- Constantes de tiempo ---
@@ -53,8 +54,6 @@ class Game {
}; };
// --- Métodos --- // --- Métodos ---
void update(); // Actualiza el juego, las variables, comprueba la entrada, etc.
void render(); // Pinta los objetos en pantalla
void handleEvents(); // Comprueba los eventos de la cola void handleEvents(); // Comprueba los eventos de la cola
void transitionToState(State new_state); // Cambia al estado especificado y resetea los timers void transitionToState(State new_state); // Cambia al estado especificado y resetea los timers
void updatePlaying(float delta_time); // Actualiza el juego en estado PLAYING void updatePlaying(float delta_time); // Actualiza el juego en estado PLAYING

View File

@@ -13,6 +13,7 @@
#include "core/rendering/sprite/sprite.hpp" // Para SSprite #include "core/rendering/sprite/sprite.hpp" // Para SSprite
#include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface.hpp" // Para Surface
#include "core/resources/resource_cache.hpp" // Para Resource #include "core/resources/resource_cache.hpp" // Para Resource
#include "core/system/event_buffer.hpp" // Para EventBuffer
#include "core/system/global_events.hpp" // Para check #include "core/system/global_events.hpp" // Para check
#include "game/options.hpp" // Para Options, SectionState, options, Section #include "game/options.hpp" // Para Options, SectionState, options, Section
#include "game/scene_manager.hpp" // Para SceneManager #include "game/scene_manager.hpp" // Para SceneManager
@@ -56,8 +57,7 @@ Logo::Logo()
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
void Logo::handleEvents() { void Logo::handleEvents() {
SDL_Event event; for (const auto& event : EventBuffer::events) {
while (SDL_PollEvent(&event)) {
GlobalEvents::handle(event); GlobalEvents::handle(event);
} }
} }
@@ -228,14 +228,6 @@ void Logo::render() { // NOLINT(readability-convert-member-functions-to-static)
Screen::get()->render(); Screen::get()->render();
} }
// Bucle para el logo del juego
void Logo::run() {
while (SceneManager::current == SceneManager::Scene::LOGO) {
update();
render();
}
}
// Termina la sección // Termina la sección
void Logo::endSection() { void Logo::endSection() {
SceneManager::current = SceneManager::Scene::TITLE; SceneManager::current = SceneManager::Scene::TITLE;

View File

@@ -30,8 +30,9 @@ class Logo {
Logo(); Logo();
~Logo() = default; ~Logo() = default;
// --- Bucle principal --- // --- Frame (llamados desde Director::iterate) ---
void run(); void update();
void render();
private: private:
// --- Constantes de tiempo (en segundos) --- // --- Constantes de tiempo (en segundos) ---
@@ -46,8 +47,6 @@ class Logo {
static constexpr int JAILGAMES_DEST_X = 37; // Posición X de destino para JAILGAMES static constexpr int JAILGAMES_DEST_X = 37; // Posición X de destino para JAILGAMES
// --- Métodos --- // --- Métodos ---
void update(); // Actualiza las variables
void render(); // Dibuja en pantalla
static void handleEvents(); // Comprueba el manejador de eventos static void handleEvents(); // Comprueba el manejador de eventos
static void handleInput(); // Comprueba las entradas static void handleInput(); // Comprueba las entradas
void updateJAILGAMES(float delta_time); // Gestiona el logo de JAILGAME (time-based) void updateJAILGAMES(float delta_time); // Gestiona el logo de JAILGAME (time-based)

View File

@@ -14,6 +14,7 @@
#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG #include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG
#include "core/resources/resource_cache.hpp" // Para Resource #include "core/resources/resource_cache.hpp" // Para Resource
#include "core/resources/resource_list.hpp" // Para Asset #include "core/resources/resource_list.hpp" // Para Asset
#include "core/system/event_buffer.hpp" // Para EventBuffer
#include "core/system/global_events.hpp" // Para check #include "core/system/global_events.hpp" // Para check
#include "game/gameplay/cheevos.hpp" // Para Cheevos, Achievement #include "game/gameplay/cheevos.hpp" // Para Cheevos, Achievement
#include "game/options.hpp" // Para Options, options, SectionState, Section #include "game/options.hpp" // Para Options, options, SectionState, Section
@@ -53,8 +54,7 @@ Title::~Title() { // NOLINT(modernize-use-equals-default)
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
void Title::handleEvents() { void Title::handleEvents() {
SDL_Event event; for (const auto& event : EventBuffer::events) {
while (SDL_PollEvent(&event)) {
GlobalEvents::handle(event); GlobalEvents::handle(event);
// Manejo especial para captura de botones de gamepad // Manejo especial para captura de botones de gamepad
@@ -311,14 +311,6 @@ void Title::render() {
Screen::get()->render(); Screen::get()->render();
} }
// Bucle para el logo del juego
void Title::run() {
while (SceneManager::current == SceneManager::Scene::TITLE) {
update();
render();
}
}
// Crea y rellena la textura para mostrar los logros // Crea y rellena la textura para mostrar los logros
void Title::createCheevosTexture() { // NOLINT(readability-convert-member-functions-to-static) void Title::createCheevosTexture() { // NOLINT(readability-convert-member-functions-to-static)
// Define la zona central del menu (entre el logo y la marquesina) // Define la zona central del menu (entre el logo y la marquesina)

View File

@@ -17,8 +17,9 @@ class Title {
Title(); Title();
~Title(); ~Title();
// --- Bucle principal --- // --- Frame (llamados desde Director::iterate) ---
void run(); void update();
void render();
private: private:
// --- Estructuras y enumeraciones --- // --- Estructuras y enumeraciones ---
@@ -38,8 +39,6 @@ class Title {
static constexpr float CHEEVOS_SCROLL_DECELERATION = 800.0F; // Desaceleración del scroll (pixels/segundo²) static constexpr float CHEEVOS_SCROLL_DECELERATION = 800.0F; // Desaceleración del scroll (pixels/segundo²)
// --- Métodos --- // --- Métodos ---
void update(); // Actualiza las variables
void render(); // Dibuja en pantalla
void handleEvents(); // Comprueba el manejador de eventos void handleEvents(); // Comprueba el manejador de eventos
void handleMainMenuKeyPress(SDL_Keycode key); // Maneja las teclas del menu principal void handleMainMenuKeyPress(SDL_Keycode key); // Maneja las teclas del menu principal
void handleInput(float delta_time); // Comprueba las entradas void handleInput(float delta_time); // Comprueba las entradas

View File

@@ -5,14 +5,36 @@ Empezado en Castalla el 01/07/2022.
*/ */
#include <memory> #define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include "core/system/director.hpp" #include "core/system/director.hpp"
#include "core/system/event_buffer.hpp"
auto main() -> int { SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) {
// Crea el objeto Director (void)argc;
auto director = std::make_unique<Director>(); (void)argv;
// Bucle principal auto* director = new Director();
return Director::run(); *appstate = director;
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
(void)appstate;
EventBuffer::events.push_back(*event);
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppIterate(void* appstate) {
auto* director = static_cast<Director*>(appstate);
return director->iterate();
}
void SDL_AppQuit(void* appstate, SDL_AppResult result) {
(void)result;
auto* director = static_cast<Director*>(appstate);
delete director;
} }