From 0674908e493a6164100917708ad935551aa845ba Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Wed, 4 Jun 2025 12:19:24 -0400 Subject: [PATCH] Implemented an initial cut at the event router. Its job is to take the random events from SFML and translate them into nice clean orderly events to the Gui::FSM. --- Makefile | 4 +- event_router.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++ event_router.hpp | 33 ++++++++++++++++ gui/fsm.cpp | 3 +- gui/fsm.hpp | 2 +- main.cpp | 2 +- meson.build | 4 +- tests/event_router.cpp | 56 +++++++++++++++++++++++++++ 8 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 event_router.cpp create mode 100644 event_router.hpp create mode 100644 tests/event_router.cpp diff --git a/Makefile b/Makefile index 6b74d7b..e6ad107 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ tracy_build: meson compile -j 10 -C builddir test: build - ./builddir/runtests + ./builddir/runtests "[event_router]" run: build test ifeq '$(OS)' 'Windows_NT' @@ -49,7 +49,7 @@ clean: meson compile --clean -C builddir debug_test: build - gdb --nx -x .gdbinit --ex run --args builddir/runtests -e + gdb --nx -x .gdbinit --ex run --args builddir/runtests -e "[event_router]" win_installer: powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp' diff --git a/event_router.cpp b/event_router.cpp new file mode 100644 index 0000000..49b182d --- /dev/null +++ b/event_router.cpp @@ -0,0 +1,86 @@ +#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 new file mode 100644 index 0000000..4d20665 --- /dev/null +++ b/event_router.hpp @@ -0,0 +1,33 @@ +#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/gui/fsm.cpp b/gui/fsm.cpp index 6f1bd80..809d5b9 100644 --- a/gui/fsm.cpp +++ b/gui/fsm.cpp @@ -280,7 +280,7 @@ namespace gui { dbc::log(fmt::format("END: received event after done: {}", int(ev))); } - void FSM::keyboard_mouse() { + void FSM::handle_keyboard_mouse() { while(const auto ev = $window.pollEvent()) { if(ev->is()) { @@ -290,6 +290,7 @@ namespace gui { if(const auto* mouse = ev->getIf()) { if(mouse->button == sf::Mouse::Button::Left) { sf::Vector2f pos = $window.mapPixelToCoords(mouse->position); + if(in_state(State::NEXT_LEVEL)) { $boss_fight_ui->mouse(pos.x, pos.y, false); diff --git a/gui/fsm.hpp b/gui/fsm.hpp index 43019e7..4d2ae6a 100644 --- a/gui/fsm.hpp +++ b/gui/fsm.hpp @@ -85,7 +85,7 @@ namespace gui { void END(Event ev); void try_move(int dir, bool strafe); - void keyboard_mouse(); + void handle_keyboard_mouse(); void draw_gui(); void render(); bool active(); diff --git a/main.cpp b/main.cpp index 24fab23..559a8e1 100644 --- a/main.cpp +++ b/main.cpp @@ -40,7 +40,7 @@ int main(int argc, char* argv[]) { if(main.autowalking) { walker.autowalk(); } else { - main.keyboard_mouse(); + main.handle_keyboard_mouse(); } } else{ main.event(gui::Event::TICK); diff --git a/meson.build b/meson.build index 027fbb4..c47762e 100644 --- a/meson.build +++ b/meson.build @@ -92,6 +92,7 @@ sources = [ 'config.cpp', 'dbc.cpp', 'devices.cpp', + 'event_router.cpp', 'goap.cpp', 'gui/boss_fight_ui.cpp', 'gui/combat_ui.cpp', @@ -109,6 +110,7 @@ sources = [ 'lights.cpp', 'map.cpp', 'matrix.cpp', + 'maze.cpp', 'pathing.cpp', 'rand.cpp', 'raycaster.cpp', @@ -122,7 +124,6 @@ sources = [ 'systems.cpp', 'textures.cpp', 'worldbuilder.cpp', - 'maze.cpp' ] executable('runtests', sources + [ @@ -135,6 +136,7 @@ executable('runtests', sources + [ 'tests/dbc.cpp', 'tests/dinkyecs.cpp', 'tests/easings.cpp', + 'tests/event_router.cpp', 'tests/fsm.cpp', 'tests/levelmanager.cpp', 'tests/lighting.cpp', diff --git a/tests/event_router.cpp b/tests/event_router.cpp new file mode 100644 index 0000000..c05fe27 --- /dev/null +++ b/tests/event_router.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include "event_router.hpp" + +using namespace fmt; +using enum routing::Event; +using enum routing::State; + +using EventScript = std::vector; + +void run_script(routing::Router& router, routing::State expected, EventScript script) { + for(auto ev : script) { + router.event(ev); + } + + REQUIRE(router.in_state(expected)); +} + +TEST_CASE("basic router operations test", "[event_router]") { + routing::Router router; + + // start goes to idle + run_script(router, IDLE, { + STARTED + }); + + // simulate drag and drop + run_script(router, IDLE, { + MOUSE_DOWN, + MOUSE_MOVE, + MOUSE_UP, + KEY_PRESS + }); + + // moving the mouse outside dnd + run_script(router, IDLE, { + MOUSE_MOVE, + KEY_PRESS, + MOUSE_MOVE + }); + + // regular mouse click + run_script(router, IDLE, { + MOUSE_DOWN, + MOUSE_UP + }); + + // possible bad key press in a move? + run_script(router, IDLE, { + MOUSE_DOWN, + MOUSE_MOVE, + KEY_PRESS, + MOUSE_UP, + }); +}