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.

master
Zed A. Shaw 3 days ago
parent 0674908e49
commit 5aa54d875f
  1. 86
      event_router.cpp
  2. 33
      event_router.hpp
  3. 23
      events.hpp
  4. 116
      gui/event_router.cpp
  5. 43
      gui/event_router.hpp
  6. 6
      gui/fsm.cpp
  7. 24
      gui/fsm.hpp
  8. 2
      meson.build
  9. 7
      tests/event_router.cpp

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

@ -1,33 +0,0 @@
#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);
};
}

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

@ -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<sf::Event> ev) {
$next_event = gui::Event::TICK;
if(ev->is<sf::Event::Closed>()) {
return gui::Event::QUIT;
}
if(const auto* mouse = ev->getIf<sf::Event::MouseButtonPressed>()) {
if(mouse->button == sf::Mouse::Button::Left) {
position = mouse->position;
event(MOUSE_DOWN);
}
} else if(const auto* mouse = ev->getIf<sf::Event::MouseButtonReleased>()) {
if(mouse->button == sf::Mouse::Button::Left) {
position = mouse->position;
event(MOUSE_UP);
}
} else if(const auto* mouse = ev->getIf<sf::Event::MouseMoved>()) {
position = mouse->position;
event(MOUSE_MOVE);
}
if(const auto* key = ev->getIf<sf::Event::KeyPressed>()) {
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");
}
}
}
}

@ -0,0 +1,43 @@
#pragma once
#include "events.hpp"
#include "simplefsm.hpp"
#include <SFML/Graphics.hpp>
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<State, Event> {
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<sf::Event> ev);
void set_event(gui::Event ev) {
$next_event = ev;
}
};
}
}

@ -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<sf::Event::Closed>()) {
event(Event::QUIT);
if(gui_ev != gui::Event::TICK) {
event(gui_ev);
continue;
}
if(const auto* mouse = ev->getIf<sf::Event::MouseButtonPressed>()) {

@ -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<State, Event> {
public:
sf::RenderWindow $window;
@ -64,6 +45,7 @@ namespace gui {
MiniMapUI $mini_map;
LootUI $loot_ui;
sf::Font $font;
gui::routing::Router $router;
FSM();

@ -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',

@ -1,11 +1,12 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#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<routing::Event>;

Loading…
Cancel
Save