From 5aa54d875f37b823c5c1d1c18ed0e12d4c7eb094 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Thu, 5 Jun 2025 01:23:52 -0400 Subject: [PATCH] Initial first steps in pulling the SFML event processing out of the gui::fsm so that I can handle more complex things like drag and drop. --- event_router.cpp | 86 ------------------------------ event_router.hpp | 33 ------------ events.hpp | 23 ++++++++ gui/event_router.cpp | 116 +++++++++++++++++++++++++++++++++++++++++ gui/event_router.hpp | 43 +++++++++++++++ gui/fsm.cpp | 6 ++- gui/fsm.hpp | 24 ++------- meson.build | 2 +- tests/event_router.cpp | 7 +-- 9 files changed, 194 insertions(+), 146 deletions(-) delete mode 100644 event_router.cpp delete mode 100644 event_router.hpp create mode 100644 gui/event_router.cpp create mode 100644 gui/event_router.hpp diff --git a/event_router.cpp b/event_router.cpp deleted file mode 100644 index 49b182d..0000000 --- a/event_router.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#define FSM_DEBUG 1 -#include "event_router.hpp" -#include "dbc.hpp" - -namespace routing { - using enum Event; - using enum State; - - void Router::process_window(sf::RenderWindow& window) { - (void)window; - } - - void Router::event(Event ev) { - switch($state) { - FSM_STATE(State, START, ev); - FSM_STATE(State, IDLE, ev); - FSM_STATE(State, MOUSE_ACTIVE, ev); - FSM_STATE(State, MOUSE_MOVING, ev); - } - } - - void Router::START(Event ) { - state(State::IDLE); - } - - void Router::IDLE(Event ev) { - switch(ev) { - case MOUSE_DOWN: - state(State::MOUSE_ACTIVE); - break; - case MOUSE_UP: - dbc::log("mouse up in IDLE"); - break; - case MOUSE_MOVE: - dbc::log("mouse move, send moved event"); - break; - case KEY_PRESS: - dbc::log("key pressed"); - break; - default: - dbc::sentinel("invalid event"); - } - } - - void Router::MOUSE_ACTIVE(Event ev) { - switch(ev) { - case MOUSE_DOWN: - dbc::log("mouse down in MOUSE_ACTIVE"); - break; - case MOUSE_UP: - dbc::log("mouse up, send click event"); - state(State::IDLE); - break; - case MOUSE_MOVE: - state(State::MOUSE_MOVING); - break; - case KEY_PRESS: - dbc::log("send the key but cancel"); - state(State::IDLE); - break; - default: - dbc::sentinel("invalid event"); - } - } - - void Router::MOUSE_MOVING(Event ev) { - switch(ev) { - case MOUSE_DOWN: - dbc::log("mouse down in MOUSE_MOVING state"); - break; - case MOUSE_UP: - dbc::log("mouse up, send drop event"); - state(State::IDLE); - break; - case MOUSE_MOVE: - dbc::log("mouse move, send drag event"); - break; - case KEY_PRESS: - dbc::log("send the key but cancel"); - state(State::IDLE); - break; - default: - dbc::sentinel("invalid event"); - } - } -} diff --git a/event_router.hpp b/event_router.hpp deleted file mode 100644 index 4d20665..0000000 --- a/event_router.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include "events.hpp" -#include "simplefsm.hpp" -#include - -namespace routing { - enum class State { - START, - IDLE, - MOUSE_ACTIVE, - MOUSE_MOVING, - }; - - enum class Event { - STARTED=0, - MOUSE_DOWN=1, - MOUSE_UP=2, - MOUSE_MOVE=3, - KEY_PRESS=4 - }; - - class Router : public DeadSimpleFSM { - public: - void event(Event ev); - - void START(Event ev); - void IDLE(Event ev); - void MOUSE_ACTIVE(Event ev); - void MOUSE_MOVING(Event ev); - - void process_window(sf::RenderWindow& window); - }; -} diff --git a/events.hpp b/events.hpp index 5de8e2a..4e6b5fe 100644 --- a/events.hpp +++ b/events.hpp @@ -14,3 +14,26 @@ namespace Events { int enemy_did; }; } + +namespace gui { + enum class Event { + STARTED=0, + TICK=1, + MOVE_FORWARD = 2, + MOVE_BACK = 3, + MOVE_LEFT = 4, + MOVE_RIGHT = 5, + MAP_OPEN = 6, + CLOSE = 7, + ROTATE_LEFT = 8, + ROTATE_RIGHT = 9, + ATTACK = 10, + START_COMBAT = 11, + STOP_COMBAT = 12, + STAIRS_DOWN = 13, + LOOT_OPEN=14, + LOOT_SELECT=15, + LOOT_PLACE=16, + QUIT = 17 + }; +} diff --git a/gui/event_router.cpp b/gui/event_router.cpp new file mode 100644 index 0000000..a7f3782 --- /dev/null +++ b/gui/event_router.cpp @@ -0,0 +1,116 @@ +#define FSM_DEBUG 1 +#include "event_router.hpp" +#include "dbc.hpp" +#include "events.hpp" + +namespace gui { + namespace routing { + using enum Event; + using enum State; + + gui::Event Router::process_event(std::optional ev) { + $next_event = gui::Event::TICK; + + if(ev->is()) { + return gui::Event::QUIT; + } + + if(const auto* mouse = ev->getIf()) { + if(mouse->button == sf::Mouse::Button::Left) { + position = mouse->position; + event(MOUSE_DOWN); + } + } else if(const auto* mouse = ev->getIf()) { + if(mouse->button == sf::Mouse::Button::Left) { + position = mouse->position; + event(MOUSE_UP); + } + } else if(const auto* mouse = ev->getIf()) { + position = mouse->position; + event(MOUSE_MOVE); + } + + if(const auto* key = ev->getIf()) { + scancode = key->scancode; + event(KEY_PRESS); + } + + return $next_event; + } + + void Router::event(Event ev) { + switch($state) { + FSM_STATE(State, START, ev); + FSM_STATE(State, IDLE, ev); + FSM_STATE(State, MOUSE_ACTIVE, ev); + FSM_STATE(State, MOUSE_MOVING, ev); + } + } + + void Router::START(Event ) { + state(State::IDLE); + } + + void Router::IDLE(Event ev) { + switch(ev) { + case MOUSE_DOWN: + set_event(gui::Event::TICK); + state(State::MOUSE_ACTIVE); + break; + case MOUSE_UP: + dbc::log("mouse up in IDLE"); + break; + case MOUSE_MOVE: + dbc::log("mouse move, send moved event"); + break; + case KEY_PRESS: + dbc::log("key pressed"); + break; + default: + dbc::sentinel("invalid event"); + } + } + + void Router::MOUSE_ACTIVE(Event ev) { + switch(ev) { + case MOUSE_DOWN: + dbc::log("mouse down in MOUSE_ACTIVE"); + break; + case MOUSE_UP: + dbc::log("mouse up, send click event"); + state(State::IDLE); + break; + case MOUSE_MOVE: + state(State::MOUSE_MOVING); + break; + case KEY_PRESS: + dbc::log("send the key but cancel"); + state(State::IDLE); + break; + default: + dbc::sentinel("invalid event"); + } + } + + void Router::MOUSE_MOVING(Event ev) { + switch(ev) { + case MOUSE_DOWN: + dbc::log("mouse down in MOUSE_MOVING state"); + break; + case MOUSE_UP: + dbc::log("mouse up, send drop event"); + state(State::IDLE); + break; + case MOUSE_MOVE: + dbc::log("mouse move, send drag event"); + break; + case KEY_PRESS: + dbc::log("send the key but cancel"); + state(State::IDLE); + break; + default: + dbc::sentinel("invalid event"); + } + } + } +} diff --git a/gui/event_router.hpp b/gui/event_router.hpp new file mode 100644 index 0000000..40cebdf --- /dev/null +++ b/gui/event_router.hpp @@ -0,0 +1,43 @@ +#pragma once +#include "events.hpp" +#include "simplefsm.hpp" +#include + +namespace gui { + namespace routing { + enum class State { + START, + IDLE, + MOUSE_ACTIVE, + MOUSE_MOVING, + }; + + enum class Event { + STARTED=0, + MOUSE_DOWN=1, + MOUSE_UP=2, + MOUSE_MOVE=3, + KEY_PRESS=4 + }; + + class Router : public DeadSimpleFSM { + public: + sf::Vector2i position; + sf::Keyboard::Scancode scancode; + gui::Event $next_event = gui::Event::TICK; + + void event(Event ev); + + void START(Event ev); + void IDLE(Event ev); + void MOUSE_ACTIVE(Event ev); + void MOUSE_MOVING(Event ev); + + gui::Event process_event(std::optional ev); + + void set_event(gui::Event ev) { + $next_event = ev; + } + }; + } +} diff --git a/gui/fsm.cpp b/gui/fsm.cpp index 809d5b9..3be2dbd 100644 --- a/gui/fsm.cpp +++ b/gui/fsm.cpp @@ -282,9 +282,11 @@ namespace gui { void FSM::handle_keyboard_mouse() { while(const auto ev = $window.pollEvent()) { + auto gui_ev = $router.process_event(ev); - if(ev->is()) { - event(Event::QUIT); + if(gui_ev != gui::Event::TICK) { + event(gui_ev); + continue; } if(const auto* mouse = ev->getIf()) { diff --git a/gui/fsm.hpp b/gui/fsm.hpp index 4d2ae6a..d2417d4 100644 --- a/gui/fsm.hpp +++ b/gui/fsm.hpp @@ -10,6 +10,8 @@ #include "gui/boss_fight_ui.hpp" #include "gui/map_view.hpp" #include "gui/mini_map.hpp" +#include "events.hpp" +#include "gui/event_router.hpp" namespace gui { enum class State { @@ -25,27 +27,6 @@ namespace gui { END }; - enum class Event { - STARTED=0, - TICK=1, - MOVE_FORWARD = 2, - MOVE_BACK = 3, - MOVE_LEFT = 4, - MOVE_RIGHT = 5, - MAP_OPEN = 6, - CLOSE = 7, - ROTATE_LEFT = 8, - ROTATE_RIGHT = 9, - ATTACK = 10, - START_COMBAT = 11, - STOP_COMBAT = 12, - STAIRS_DOWN = 13, - LOOT_OPEN=14, - LOOT_SELECT=15, - LOOT_PLACE=16, - QUIT = 17 - }; - class FSM : public DeadSimpleFSM { public: sf::RenderWindow $window; @@ -64,6 +45,7 @@ namespace gui { MiniMapUI $mini_map; LootUI $loot_ui; sf::Font $font; + gui::routing::Router $router; FSM(); diff --git a/meson.build b/meson.build index c47762e..c276eb1 100644 --- a/meson.build +++ b/meson.build @@ -92,8 +92,8 @@ sources = [ 'config.cpp', 'dbc.cpp', 'devices.cpp', - 'event_router.cpp', 'goap.cpp', + 'gui/event_router.cpp', 'gui/boss_fight_ui.cpp', 'gui/combat_ui.cpp', 'gui/debug_ui.cpp', diff --git a/tests/event_router.cpp b/tests/event_router.cpp index c05fe27..588ad35 100644 --- a/tests/event_router.cpp +++ b/tests/event_router.cpp @@ -1,11 +1,12 @@ #include #include #include -#include "event_router.hpp" +#include "gui/event_router.hpp" using namespace fmt; -using enum routing::Event; -using enum routing::State; +using namespace gui; +using enum gui::routing::Event; +using enum gui::routing::State; using EventScript = std::vector;