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.

master
Zed A. Shaw 3 days ago
parent 5c47a0151c
commit 0674908e49
  1. 4
      Makefile
  2. 86
      event_router.cpp
  3. 33
      event_router.hpp
  4. 3
      gui/fsm.cpp
  5. 2
      gui/fsm.hpp
  6. 2
      main.cpp
  7. 4
      meson.build
  8. 56
      tests/event_router.cpp

@ -26,7 +26,7 @@ tracy_build:
meson compile -j 10 -C builddir meson compile -j 10 -C builddir
test: build test: build
./builddir/runtests ./builddir/runtests "[event_router]"
run: build test run: build test
ifeq '$(OS)' 'Windows_NT' ifeq '$(OS)' 'Windows_NT'
@ -49,7 +49,7 @@ clean:
meson compile --clean -C builddir meson compile --clean -C builddir
debug_test: build 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: win_installer:
powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp' powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp'

@ -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");
}
}
}

@ -0,0 +1,33 @@
#pragma once
#include "events.hpp"
#include "simplefsm.hpp"
#include <SFML/Graphics.hpp>
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<State, Event> {
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);
};
}

@ -280,7 +280,7 @@ namespace gui {
dbc::log(fmt::format("END: received event after done: {}", int(ev))); 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()) { while(const auto ev = $window.pollEvent()) {
if(ev->is<sf::Event::Closed>()) { if(ev->is<sf::Event::Closed>()) {
@ -290,6 +290,7 @@ namespace gui {
if(const auto* mouse = ev->getIf<sf::Event::MouseButtonPressed>()) { if(const auto* mouse = ev->getIf<sf::Event::MouseButtonPressed>()) {
if(mouse->button == sf::Mouse::Button::Left) { if(mouse->button == sf::Mouse::Button::Left) {
sf::Vector2f pos = $window.mapPixelToCoords(mouse->position); sf::Vector2f pos = $window.mapPixelToCoords(mouse->position);
if(in_state(State::NEXT_LEVEL)) { if(in_state(State::NEXT_LEVEL)) {
$boss_fight_ui->mouse(pos.x, pos.y, false); $boss_fight_ui->mouse(pos.x, pos.y, false);

@ -85,7 +85,7 @@ namespace gui {
void END(Event ev); void END(Event ev);
void try_move(int dir, bool strafe); void try_move(int dir, bool strafe);
void keyboard_mouse(); void handle_keyboard_mouse();
void draw_gui(); void draw_gui();
void render(); void render();
bool active(); bool active();

@ -40,7 +40,7 @@ int main(int argc, char* argv[]) {
if(main.autowalking) { if(main.autowalking) {
walker.autowalk(); walker.autowalk();
} else { } else {
main.keyboard_mouse(); main.handle_keyboard_mouse();
} }
} else{ } else{
main.event(gui::Event::TICK); main.event(gui::Event::TICK);

@ -92,6 +92,7 @@ sources = [
'config.cpp', 'config.cpp',
'dbc.cpp', 'dbc.cpp',
'devices.cpp', 'devices.cpp',
'event_router.cpp',
'goap.cpp', 'goap.cpp',
'gui/boss_fight_ui.cpp', 'gui/boss_fight_ui.cpp',
'gui/combat_ui.cpp', 'gui/combat_ui.cpp',
@ -109,6 +110,7 @@ sources = [
'lights.cpp', 'lights.cpp',
'map.cpp', 'map.cpp',
'matrix.cpp', 'matrix.cpp',
'maze.cpp',
'pathing.cpp', 'pathing.cpp',
'rand.cpp', 'rand.cpp',
'raycaster.cpp', 'raycaster.cpp',
@ -122,7 +124,6 @@ sources = [
'systems.cpp', 'systems.cpp',
'textures.cpp', 'textures.cpp',
'worldbuilder.cpp', 'worldbuilder.cpp',
'maze.cpp'
] ]
executable('runtests', sources + [ executable('runtests', sources + [
@ -135,6 +136,7 @@ executable('runtests', sources + [
'tests/dbc.cpp', 'tests/dbc.cpp',
'tests/dinkyecs.cpp', 'tests/dinkyecs.cpp',
'tests/easings.cpp', 'tests/easings.cpp',
'tests/event_router.cpp',
'tests/fsm.cpp', 'tests/fsm.cpp',
'tests/levelmanager.cpp', 'tests/levelmanager.cpp',
'tests/lighting.cpp', 'tests/lighting.cpp',

@ -0,0 +1,56 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#include "event_router.hpp"
using namespace fmt;
using enum routing::Event;
using enum routing::State;
using EventScript = std::vector<routing::Event>;
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,
});
}
Loading…
Cancel
Save