Skip to content

Commit

Permalink
Extrae ControladorClicks y RealizadorBase TODO: estructura
Browse files Browse the repository at this point in the history
  • Loading branch information
autosquash committed Oct 26, 2023
1 parent 6f027cd commit fb2ba4e
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 126 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
95 changes: 95 additions & 0 deletions src/controlador_clicks.cpp
Original file line number Diff line number Diff line change
@@ -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<Comando> ControladorClicks::genera_comando(
const std::function<bool(const BotonConTexto &boton)> &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<decltype(variante)>; \
if (false) { /* Para inicializar los bloques if else */ \
}
#define CASE(comando, accion) \
else if constexpr (std::is_same_v<T, Comando::comando>) { \
return accion; \
}
/* Aplica un comando y devuelve la nueva fase, si correspondiera cambiar */
std::optional<FaseNivel> ControladorClicks::aplica_comando( //
RealizadorBase &realizador, //
const Comando &comando //

) {
return std::visit(
[&realizador](auto &&variante) -> std::optional<FaseNivel> {
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<FaseNivel> 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> comando = genera_comando( //
pulsado, botones, estado.fase_actual
);
if (!comando) {
return std::nullopt;
}
return aplica_comando(realizador, comando.value());
}
35 changes: 35 additions & 0 deletions src/controlador_clicks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include <SFML/Graphics.hpp>
#include <functional>
#include <optional>

struct BotonConTexto;
struct BotonesApp;
struct Estado;
struct Globales;
class RealizadorBase;
class Comando;
enum class FaseNivel;

struct ControladorClicks {
private:
std::optional<Comando> ControladorClicks::genera_comando(
const std::function<bool(const BotonConTexto &boton)> &pulsado, //
const BotonesApp &, //
const FaseNivel fase_actual //
);
std::optional<FaseNivel> aplica_comando(
RealizadorBase &, //
const Comando & //
);

public:
std::optional<FaseNivel> procesa_click(
Globales &, //
const BotonesApp &, //
const Estado &, //
RealizadorBase &, //
const sf::Vector2i &mouse_pos //
);
};
128 changes: 2 additions & 126 deletions src/nivel.cpp
Original file line number Diff line number Diff line change
@@ -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 <SFML/Window.hpp>
#include <cassert>
#include <functional>
#include <memory>
#include <optional>

class RealizadorBase {
public:
using NuevaFase = std::optional<FaseNivel>;

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;
Expand Down Expand Up @@ -67,28 +54,6 @@ class Realizador : public RealizadorBase {
}
};

struct ControladorClicks {
private:
std::optional<Comando> ControladorClicks::genera_comando(
const std::function<bool(const BotonConTexto &boton)> &pulsado, //
const BotonesApp &, //
const FaseNivel fase_actual //
);
std::optional<FaseNivel> aplica_comando(
RealizadorBase &realizador, //
const Comando &comando //
);

public:
std::optional<FaseNivel> procesa_click(
Globales &, //
const BotonesApp &, //
const Estado &, //
RealizadorBase &, //
const sf::Vector2i &mouse_pos //
);
};

Nivel::Nivel(
Globales &globales, //
const DatosNivel &datos_nivel, //
Expand Down Expand Up @@ -140,95 +105,6 @@ std::optional<FaseNivel> Nivel::procesarEvento(
return siguiente_fase;
};

std::optional<Comando> ControladorClicks::genera_comando(
const std::function<bool(const BotonConTexto &boton)> &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<decltype(variante)>; \
if (false) { /* Para inicializar los bloques if else */ \
}
#define CASE(comando, accion) \
else if constexpr (std::is_same_v<T, Comando::comando>) { \
return accion; \
}
/* Aplica un comando y devuelve la nueva fase, si correspondiera cambiar */
std::optional<FaseNivel> ControladorClicks::aplica_comando( //
RealizadorBase &realizador, //
const Comando &comando //

) {
return std::visit(
[&realizador](auto &&variante) -> std::optional<FaseNivel> {
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<FaseNivel> 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> 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<AccionGeneral> Nivel::procesa_cambio_de_fase(
FaseNivel nueva_fase, //
Expand Down
18 changes: 18 additions & 0 deletions src/realizador_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <optional>

enum class FaseNivel;

class RealizadorBase {
public:
using NuevaFase = std::optional<FaseNivel>;

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;
};

0 comments on commit fb2ba4e

Please sign in to comment.