diff --git a/CMakeLists.txt b/CMakeLists.txt index e53c09f8..c142702b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ FetchContent_MakeAvailable(googletest) add_executable(pizzeria src/main.cpp + src/controlador_clicks.cpp src/datos_niveles.cpp src/debug_sfml.cpp src/globales.cpp diff --git a/src/controlador_clicks.cpp b/src/controlador_clicks.cpp new file mode 100644 index 00000000..4f346435 --- /dev/null +++ b/src/controlador_clicks.cpp @@ -0,0 +1,95 @@ +#include "controlador_clicks.h" +#include "comandos.h" +#include "estado_nivel.h" +#include "globales.h" +#include "realizador_base.h" +#include "vista/botones_app.h" + +std::optional ControladorClicks::genera_comando( + const std::function &pulsado, // + const BotonesApp &botones, // + const FaseNivel fase_actual // +) { + // Fijos + if (pulsado(botones.generales.salir)) { + return Comando::Salir{}; + } else if (pulsado(botones.generales.reiniciar)) { + return Comando::Reiniciar{}; + } else if (pulsado(botones.generales.alternar_grid)) { + return Comando::AlternarGrid{}; + } + // Dependientes de la fase + switch (fase_actual) { + case FaseNivel::MostrandoInstrucciones: + if (pulsado(botones.empezar)) { + return Comando::Empezar{}; + } + break; + case FaseNivel::Activa: + for (const auto &[tp, boton] : botones.encargar) { + if (pulsado(boton)) { + return Comando::Encargar{tp}; + } + } + for (const auto &[tp, boton] : botones.despachar) { + if (pulsado(boton)) { + return Comando::Despachar{tp}; + } + } + break; + default: + break; + } + return std::nullopt; +} + +#define SWITCH(variante) \ + using T = std::decay_t; \ + if (false) { /* Para inicializar los bloques if else */ \ + } +#define CASE(comando, accion) \ + else if constexpr (std::is_same_v) { \ + return accion; \ + } +/* Aplica un comando y devuelve la nueva fase, si correspondiera cambiar */ +std::optional ControladorClicks::aplica_comando( // + RealizadorBase &realizador, // + const Comando &comando // + +) { + return std::visit( + [&realizador](auto &&variante) -> std::optional { + SWITCH(variante) + CASE(Empezar, realizador.empezar()) + CASE(Salir, FaseNivel::Saliendo) + CASE(Reiniciar, FaseNivel::Reiniciando) + CASE(AlternarGrid, realizador.alternar_grid()) + CASE(Encargar, realizador.encargar_pizza(variante.tp)) + CASE(Despachar, realizador.despachar_pizza(variante.tp)) + return std::nullopt; + }, + comando.variante + ); +} +#undef SWITCH +#undef CASE + +std::optional ControladorClicks::procesa_click( + Globales &globales, // + const BotonesApp &botones, // + const Estado &estado, // + RealizadorBase &realizador, // + const sf::Vector2i &mouse_pos // + +) { + const auto pulsado = [&globales, &mouse_pos](const BotonConTexto &boton) { + return globales.detecta_colision(boton, mouse_pos); + }; + std::optional comando = genera_comando( // + pulsado, botones, estado.fase_actual + ); + if (!comando) { + return std::nullopt; + } + return aplica_comando(realizador, comando.value()); +} diff --git a/src/controlador_clicks.h b/src/controlador_clicks.h new file mode 100644 index 00000000..56252acb --- /dev/null +++ b/src/controlador_clicks.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +struct BotonConTexto; +struct BotonesApp; +struct Estado; +struct Globales; +class RealizadorBase; +class Comando; +enum class FaseNivel; + +struct ControladorClicks { + private: + std::optional ControladorClicks::genera_comando( + const std::function &pulsado, // + const BotonesApp &, // + const FaseNivel fase_actual // + ); + std::optional aplica_comando( + RealizadorBase &, // + const Comando & // + ); + + public: + std::optional procesa_click( + Globales &, // + const BotonesApp &, // + const Estado &, // + RealizadorBase &, // + const sf::Vector2i &mouse_pos // + ); +}; diff --git a/src/nivel.cpp b/src/nivel.cpp index 3e131d55..988c8bdb 100644 --- a/src/nivel.cpp +++ b/src/nivel.cpp @@ -1,28 +1,15 @@ #include "nivel.h" -#include "comandos.h" +#include "controlador_clicks.h" #include "estado_nivel.h" +#include "realizador_base.h" #include "tiempo.h" #include "vista/enlace_vista.h" #include "vista/vista.h" -#include #include #include #include #include -class RealizadorBase { - public: - using NuevaFase = std::optional; - - virtual ~RealizadorBase() = default; // Destructor virtual - - // Métodos virtuales puros - virtual NuevaFase encargar_pizza(const modelo::TipoPizza tp) = 0; - virtual NuevaFase despachar_pizza(const modelo::TipoPizza tp) = 0; - virtual NuevaFase alternar_grid() = 0; - virtual NuevaFase empezar() = 0; -}; - class Realizador : public RealizadorBase { private: Estado &estado; @@ -67,28 +54,6 @@ class Realizador : public RealizadorBase { } }; -struct ControladorClicks { - private: - std::optional ControladorClicks::genera_comando( - const std::function &pulsado, // - const BotonesApp &, // - const FaseNivel fase_actual // - ); - std::optional aplica_comando( - RealizadorBase &realizador, // - const Comando &comando // - ); - - public: - std::optional procesa_click( - Globales &, // - const BotonesApp &, // - const Estado &, // - RealizadorBase &, // - const sf::Vector2i &mouse_pos // - ); -}; - Nivel::Nivel( Globales &globales, // const DatosNivel &datos_nivel, // @@ -140,95 +105,6 @@ std::optional Nivel::procesarEvento( return siguiente_fase; }; -std::optional ControladorClicks::genera_comando( - const std::function &pulsado, // - const BotonesApp &botones, // - const FaseNivel fase_actual // -) { - // Fijos - if (pulsado(botones.generales.salir)) { - return Comando::Salir{}; - } else if (pulsado(botones.generales.reiniciar)) { - return Comando::Reiniciar{}; - } else if (pulsado(botones.generales.alternar_grid)) { - return Comando::AlternarGrid{}; - } - // Dependientes de la fase - switch (fase_actual) { - case FaseNivel::MostrandoInstrucciones: - if (pulsado(botones.empezar)) { - return Comando::Empezar{}; - } - break; - case FaseNivel::Activa: - for (const auto &[tp, boton] : botones.encargar) { - if (pulsado(boton)) { - return Comando::Encargar{tp}; - } - } - for (const auto &[tp, boton] : botones.despachar) { - if (pulsado(boton)) { - return Comando::Despachar{tp}; - } - } - break; - default: - break; - } - return std::nullopt; -} - -#define SWITCH(variante) \ - using T = std::decay_t; \ - if (false) { /* Para inicializar los bloques if else */ \ - } -#define CASE(comando, accion) \ - else if constexpr (std::is_same_v) { \ - return accion; \ - } -/* Aplica un comando y devuelve la nueva fase, si correspondiera cambiar */ -std::optional ControladorClicks::aplica_comando( // - RealizadorBase &realizador, // - const Comando &comando // - -) { - return std::visit( - [&realizador](auto &&variante) -> std::optional { - SWITCH(variante) - CASE(Empezar, realizador.empezar()) - CASE(Salir, FaseNivel::Saliendo) - CASE(Reiniciar, FaseNivel::Reiniciando) - CASE(AlternarGrid, realizador.alternar_grid()) - CASE(Encargar, realizador.encargar_pizza(variante.tp)) - CASE(Despachar, realizador.despachar_pizza(variante.tp)) - return std::nullopt; - }, - comando.variante - ); -} -#undef SWITCH -#undef CASE - -std::optional ControladorClicks::procesa_click( - Globales &globales, // - const BotonesApp &botones, // - const Estado &estado, // - RealizadorBase &realizador, // - const sf::Vector2i &mouse_pos // - -) { - const auto pulsado = [&globales, &mouse_pos](const BotonConTexto &boton) { - return globales.detecta_colision(boton, mouse_pos); - }; - std::optional comando = genera_comando( // - pulsado, botones, estado.fase_actual - ); - if (!comando) { - return std::nullopt; - } - return aplica_comando(realizador, comando.value()); -} - /* Procesa un cambio de fase reciente */ std::optional Nivel::procesa_cambio_de_fase( FaseNivel nueva_fase, // diff --git a/src/realizador_base.h b/src/realizador_base.h new file mode 100644 index 00000000..d4f22149 --- /dev/null +++ b/src/realizador_base.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +enum class FaseNivel; + +class RealizadorBase { + public: + using NuevaFase = std::optional; + + virtual ~RealizadorBase() = default; // Destructor virtual + + // Métodos virtuales puros + virtual NuevaFase encargar_pizza(const modelo::TipoPizza tp) = 0; + virtual NuevaFase despachar_pizza(const modelo::TipoPizza tp) = 0; + virtual NuevaFase alternar_grid() = 0; + virtual NuevaFase empezar() = 0; +};