Refactor fase 4 (parcial): Crear estructura básica de StateManager

Crea la infraestructura del StateManager para gestionar estados DEMO/LOGO
con patrón de callbacks al Engine. Estructura lista para migración de lógica.

## Archivos Nuevos

**source/state/state_manager.h:**
- Declaración de clase StateManager
- Forward declaration de Engine (patrón callback)
- Métodos públicos: initialize(), update(), setState()
- Métodos toggle: toggleDemoMode(), toggleDemoLiteMode(), toggleLogoMode()
- Getters: getCurrentMode(), getPreviousMode(), is*ModeActive()
- Métodos privados: performDemoAction(), randomizeOnDemoStart(), etc.
- Miembros para timers, convergencia, flip detection, estado previo

**source/state/state_manager.cpp:**
- Implementación de constructor/destructor
- initialize() con callback al Engine
- Stubs de todos los métodos (TODO: migrar lógica completa)
- Preparado para recibir ~600 líneas de lógica DEMO/LOGO

## Archivos Modificados

**CMakeLists.txt:**
- Agregado: source/state/*.cpp al glob de archivos fuente

**source/engine.h:**
- Agregado: #include "state/state_manager.h"
- Agregado: std::unique_ptr<StateManager> state_manager_
- NOTA: Miembros de estado aún no removidos (pendiente migración)

**source/engine.cpp:**
- initialize(): Crea state_manager_ con `this` como callback
- NOTA: Métodos DEMO/LOGO aún no migrados (pendiente)

## Estado Actual

-  Estructura del StateManager creada y compila
-  Patrón de callbacks al Engine configurado
-  CMakeLists actualizado
-  Migración de lógica DEMO/LOGO: PENDIENTE (~600 líneas)
-  Remoción de miembros duplicados en Engine: PENDIENTE

## Próximos Pasos (Fase 4b)

1. Migrar updateDemoMode() → StateManager::update()
2. Migrar performDemoAction() → StateManager (privado)
3. Migrar randomizeOnDemoStart() → StateManager (privado)
4. Migrar enterLogoMode() → StateManager (privado)
5. Migrar exitLogoMode() → StateManager (privado)
6. Migrar toggleGravityOnOff() → StateManager (privado)
7. Migrar setState() completo
8. Delegar toggle*Mode() desde Engine a StateManager
9. Remover miembros de estado duplicados en Engine
10. Commit final de Fase 4

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-10 12:21:39 +02:00
parent e655c643a5
commit e2a60e4f87
5 changed files with 280 additions and 1 deletions

View File

@@ -0,0 +1,191 @@
#pragma once
#include <SDL3/SDL_stdinc.h> // for Uint64
#include <cstddef> // for size_t
#include "../defines.h" // for AppMode, ShapeType, GravityDirection
// Forward declarations
class Engine;
class Shape;
class PNGShape;
/**
* @class StateManager
* @brief Gestiona los estados de aplicación (SANDBOX/DEMO/DEMO_LITE/LOGO)
*
* Responsabilidad única: Máquina de estados y lógica de modos automáticos
*
* Características:
* - Control de modo DEMO (auto-play completo)
* - Control de modo DEMO_LITE (solo física/figuras)
* - Control de modo LOGO (easter egg con convergencia)
* - Timers y triggers automáticos
* - Sistema de convergencia y espera de flips
* - Callbacks al Engine para ejecutar acciones
*/
class StateManager {
public:
/**
* @brief Constructor
*/
StateManager();
/**
* @brief Destructor
*/
~StateManager();
/**
* @brief Inicializa el StateManager con referencia al Engine
* @param engine Puntero al Engine (para callbacks)
*/
void initialize(Engine* engine);
/**
* @brief Actualiza la máquina de estados (timers, triggers, acciones)
* @param delta_time Delta time para timers
* @param shape_convergence Convergencia actual de la forma (0.0-1.0)
* @param active_shape Puntero a la forma activa (para flip detection)
*/
void update(float delta_time, float shape_convergence, Shape* active_shape);
/**
* @brief Cambia el estado de aplicación
* @param new_mode Nuevo modo (SANDBOX/DEMO/DEMO_LITE/LOGO)
* @param current_screen_width Ancho de pantalla (para escalar tiempos)
* @param current_screen_height Alto de pantalla (para escalar tiempos)
*/
void setState(AppMode new_mode, int current_screen_width, int current_screen_height);
/**
* @brief Toggle del modo DEMO completo (tecla L)
* @param current_screen_width Ancho de pantalla
* @param current_screen_height Alto de pantalla
*/
void toggleDemoMode(int current_screen_width, int current_screen_height);
/**
* @brief Toggle del modo DEMO_LITE (tecla L x2)
* @param current_screen_width Ancho de pantalla
* @param current_screen_height Alto de pantalla
*/
void toggleDemoLiteMode(int current_screen_width, int current_screen_height);
/**
* @brief Toggle del modo LOGO (tecla K)
* @param current_screen_width Ancho de pantalla
* @param current_screen_height Alto de pantalla
* @param ball_count Número de bolas actual
*/
void toggleLogoMode(int current_screen_width, int current_screen_height, size_t ball_count);
// === Getters ===
/**
* @brief Obtiene el modo actual
*/
AppMode getCurrentMode() const { return current_app_mode_; }
/**
* @brief Obtiene el modo previo (antes de LOGO)
*/
AppMode getPreviousMode() const { return previous_app_mode_; }
/**
* @brief Verifica si LOGO está activo
*/
bool isLogoModeActive() const { return current_app_mode_ == AppMode::LOGO; }
/**
* @brief Verifica si DEMO (completo o lite) está activo
*/
bool isDemoModeActive() const {
return current_app_mode_ == AppMode::DEMO || current_app_mode_ == AppMode::DEMO_LITE;
}
/**
* @brief Obtiene índice de tema guardado (para restaurar al salir de LOGO)
*/
int getLogoPreviousTheme() const { return logo_previous_theme_; }
/**
* @brief Obtiene índice de textura guardada (para restaurar al salir de LOGO)
*/
size_t getLogoPreviousTextureIndex() const { return logo_previous_texture_index_; }
/**
* @brief Obtiene escala de forma guardada (para restaurar al salir de LOGO)
*/
float getLogoPreviousShapeScale() const { return logo_previous_shape_scale_; }
/**
* @brief Establece valores previos de LOGO (llamado por Engine antes de entrar)
*/
void setLogoPreviousState(int theme, size_t texture_index, float shape_scale);
private:
// === Referencia al Engine (callback) ===
Engine* engine_;
// === Estado de aplicación ===
AppMode current_app_mode_;
AppMode previous_app_mode_;
// === Sistema DEMO (timers) ===
float demo_timer_;
float demo_next_action_time_;
// === Sistema LOGO (convergencia) ===
float logo_convergence_threshold_;
float logo_min_time_;
float logo_max_time_;
// === Sistema LOGO (espera de flips) ===
bool logo_waiting_for_flip_;
int logo_target_flip_number_;
float logo_target_flip_percentage_;
int logo_current_flip_count_;
// === Control de entrada LOGO ===
bool logo_entered_manually_;
// === Estado previo LOGO (restauración) ===
int logo_previous_theme_;
size_t logo_previous_texture_index_;
float logo_previous_shape_scale_;
// === Métodos privados ===
/**
* @brief Ejecuta una acción del modo DEMO
* @param is_lite true si es DEMO_LITE, false si es DEMO completo
*/
void performDemoAction(bool is_lite);
/**
* @brief Randomiza estado al entrar a modo DEMO
* @param is_lite true si es DEMO_LITE, false si es DEMO completo
*/
void randomizeOnDemoStart(bool is_lite);
/**
* @brief Toggle de gravedad ON/OFF (para DEMO)
*/
void toggleGravityOnOff();
/**
* @brief Entra al modo LOGO
* @param from_demo true si viene desde DEMO, false si es manual
* @param current_screen_width Ancho de pantalla
* @param current_screen_height Alto de pantalla
* @param ball_count Número de bolas
*/
void enterLogoMode(bool from_demo, int current_screen_width, int current_screen_height, size_t ball_count);
/**
* @brief Sale del modo LOGO
* @param return_to_demo true si debe volver a DEMO/DEMO_LITE
*/
void exitLogoMode(bool return_to_demo);
};