The event router is working well and I can do drag-n-drop but I'll have to rethink where to use it.
This commit is contained in:
parent
5aa54d875f
commit
c509162be1
8 changed files with 126 additions and 63 deletions
4
Makefile
4
Makefile
|
@ -26,7 +26,7 @@ tracy_build:
|
||||||
meson compile -j 10 -C builddir
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
test: build
|
test: build
|
||||||
./builddir/runtests "[event_router]"
|
./builddir/runtests
|
||||||
|
|
||||||
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 "[event_router]"
|
gdb --nx -x .gdbinit --ex run --args builddir/runtests -e
|
||||||
|
|
||||||
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'
|
||||||
|
|
|
@ -34,6 +34,12 @@ namespace gui {
|
||||||
LOOT_OPEN=14,
|
LOOT_OPEN=14,
|
||||||
LOOT_SELECT=15,
|
LOOT_SELECT=15,
|
||||||
LOOT_PLACE=16,
|
LOOT_PLACE=16,
|
||||||
QUIT = 17
|
QUIT = 17,
|
||||||
|
MOUSE_CLICK=18,
|
||||||
|
MOUSE_MOVE=19,
|
||||||
|
MOUSE_DRAG=20,
|
||||||
|
MOUSE_DRAG_START=21,
|
||||||
|
MOUSE_DROP=22,
|
||||||
|
KEY_PRESS=23
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#define FSM_DEBUG 1
|
|
||||||
#include "event_router.hpp"
|
#include "event_router.hpp"
|
||||||
#include "dbc.hpp"
|
#include "dbc.hpp"
|
||||||
#include "events.hpp"
|
#include "events.hpp"
|
||||||
|
@ -44,6 +43,7 @@ namespace gui {
|
||||||
FSM_STATE(State, IDLE, ev);
|
FSM_STATE(State, IDLE, ev);
|
||||||
FSM_STATE(State, MOUSE_ACTIVE, ev);
|
FSM_STATE(State, MOUSE_ACTIVE, ev);
|
||||||
FSM_STATE(State, MOUSE_MOVING, ev);
|
FSM_STATE(State, MOUSE_MOVING, ev);
|
||||||
|
FSM_STATE(State, MOUSE_DRAGGING, ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,17 +54,15 @@ namespace gui {
|
||||||
void Router::IDLE(Event ev) {
|
void Router::IDLE(Event ev) {
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case MOUSE_DOWN:
|
case MOUSE_DOWN:
|
||||||
|
move_count=0;
|
||||||
set_event(gui::Event::TICK);
|
set_event(gui::Event::TICK);
|
||||||
state(State::MOUSE_ACTIVE);
|
state(State::MOUSE_ACTIVE);
|
||||||
break;
|
break;
|
||||||
case MOUSE_UP:
|
|
||||||
dbc::log("mouse up in IDLE");
|
|
||||||
break;
|
|
||||||
case MOUSE_MOVE:
|
case MOUSE_MOVE:
|
||||||
dbc::log("mouse move, send moved event");
|
set_event(gui::Event::MOUSE_MOVE);
|
||||||
break;
|
break;
|
||||||
case KEY_PRESS:
|
case KEY_PRESS:
|
||||||
dbc::log("key pressed");
|
set_event(gui::Event::KEY_PRESS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dbc::sentinel("invalid event");
|
dbc::sentinel("invalid event");
|
||||||
|
@ -73,18 +71,17 @@ namespace gui {
|
||||||
|
|
||||||
void Router::MOUSE_ACTIVE(Event ev) {
|
void Router::MOUSE_ACTIVE(Event ev) {
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case MOUSE_DOWN:
|
|
||||||
dbc::log("mouse down in MOUSE_ACTIVE");
|
|
||||||
break;
|
|
||||||
case MOUSE_UP:
|
case MOUSE_UP:
|
||||||
dbc::log("mouse up, send click event");
|
set_event(gui::Event::MOUSE_CLICK);
|
||||||
state(State::IDLE);
|
state(State::IDLE);
|
||||||
break;
|
break;
|
||||||
case MOUSE_MOVE:
|
case MOUSE_MOVE:
|
||||||
|
move_count++;
|
||||||
|
set_event(gui::Event::MOUSE_DRAG);
|
||||||
state(State::MOUSE_MOVING);
|
state(State::MOUSE_MOVING);
|
||||||
break;
|
break;
|
||||||
case KEY_PRESS:
|
case KEY_PRESS:
|
||||||
dbc::log("send the key but cancel");
|
set_event(gui::Event::KEY_PRESS);
|
||||||
state(State::IDLE);
|
state(State::IDLE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -94,23 +91,46 @@ namespace gui {
|
||||||
|
|
||||||
void Router::MOUSE_MOVING(Event ev) {
|
void Router::MOUSE_MOVING(Event ev) {
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case MOUSE_DOWN:
|
case MOUSE_UP: {
|
||||||
dbc::log("mouse down in MOUSE_MOVING state");
|
dbc::check(move_count < $drag_tolerance, "mouse up but not in dragging state");
|
||||||
break;
|
set_event(gui::Event::MOUSE_CLICK);
|
||||||
case MOUSE_UP:
|
|
||||||
dbc::log("mouse up, send drop event");
|
|
||||||
state(State::IDLE);
|
state(State::IDLE);
|
||||||
break;
|
} break;
|
||||||
case MOUSE_MOVE:
|
case MOUSE_MOVE:
|
||||||
dbc::log("mouse move, send drag event");
|
move_count++;
|
||||||
|
|
||||||
|
if(move_count < $drag_tolerance) {
|
||||||
|
set_event(gui::Event::MOUSE_DRAG);
|
||||||
|
} else {
|
||||||
|
set_event(gui::Event::MOUSE_DRAG_START);
|
||||||
|
state(State::MOUSE_DRAGGING);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case KEY_PRESS:
|
case KEY_PRESS:
|
||||||
dbc::log("send the key but cancel");
|
set_event(gui::Event::KEY_PRESS);
|
||||||
state(State::IDLE);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dbc::sentinel("invalid event");
|
dbc::sentinel("invalid event");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Router::MOUSE_DRAGGING(Event ev) {
|
||||||
|
switch(ev) {
|
||||||
|
case MOUSE_UP:
|
||||||
|
set_event(gui::Event::MOUSE_DROP);
|
||||||
|
state(State::IDLE);
|
||||||
|
break;
|
||||||
|
case MOUSE_MOVE:
|
||||||
|
move_count++;
|
||||||
|
set_event(gui::Event::MOUSE_DRAG);
|
||||||
|
break;
|
||||||
|
case KEY_PRESS:
|
||||||
|
set_event(gui::Event::KEY_PRESS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dbc::sentinel("invalid events");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace gui {
|
||||||
IDLE,
|
IDLE,
|
||||||
MOUSE_ACTIVE,
|
MOUSE_ACTIVE,
|
||||||
MOUSE_MOVING,
|
MOUSE_MOVING,
|
||||||
|
MOUSE_DRAGGING
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Event {
|
enum class Event {
|
||||||
|
@ -25,6 +26,8 @@ namespace gui {
|
||||||
sf::Vector2i position;
|
sf::Vector2i position;
|
||||||
sf::Keyboard::Scancode scancode;
|
sf::Keyboard::Scancode scancode;
|
||||||
gui::Event $next_event = gui::Event::TICK;
|
gui::Event $next_event = gui::Event::TICK;
|
||||||
|
int move_count = 0;
|
||||||
|
int $drag_tolerance = 4;
|
||||||
|
|
||||||
void event(Event ev);
|
void event(Event ev);
|
||||||
|
|
||||||
|
@ -32,6 +35,7 @@ namespace gui {
|
||||||
void IDLE(Event ev);
|
void IDLE(Event ev);
|
||||||
void MOUSE_ACTIVE(Event ev);
|
void MOUSE_ACTIVE(Event ev);
|
||||||
void MOUSE_MOVING(Event ev);
|
void MOUSE_MOVING(Event ev);
|
||||||
|
void MOUSE_DRAGGING(Event ev);
|
||||||
|
|
||||||
gui::Event process_event(std::optional<sf::Event> ev);
|
gui::Event process_event(std::optional<sf::Event> ev);
|
||||||
|
|
||||||
|
|
97
gui/fsm.cpp
97
gui/fsm.cpp
|
@ -127,6 +127,7 @@ namespace gui {
|
||||||
state(State::IDLE);
|
state(State::IDLE);
|
||||||
break;
|
break;
|
||||||
case LOOT_SELECT: {
|
case LOOT_SELECT: {
|
||||||
|
fmt::println("loot is selected");
|
||||||
int slot_id = std::any_cast<int>(data);
|
int slot_id = std::any_cast<int>(data);
|
||||||
|
|
||||||
if(auto entity = $loot_ui.select_slot(slot_id)) {
|
if(auto entity = $loot_ui.select_slot(slot_id)) {
|
||||||
|
@ -137,8 +138,26 @@ namespace gui {
|
||||||
case LOOT_PLACE: {
|
case LOOT_PLACE: {
|
||||||
std::string slot_name = std::any_cast<std::string>(data);
|
std::string slot_name = std::any_cast<std::string>(data);
|
||||||
int slot_id = $status_ui.place_slot(slot_name);
|
int slot_id = $status_ui.place_slot(slot_name);
|
||||||
$loot_ui.remove_slot(slot_id);
|
// BUG: fix this bullshit
|
||||||
|
if(slot_id != -1) {
|
||||||
|
$loot_ui.remove_slot(slot_id);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case MOUSE_CLICK:
|
||||||
|
mouse_action(false);
|
||||||
|
break;
|
||||||
|
case MOUSE_MOVE:
|
||||||
|
mouse_action(true);
|
||||||
|
break;
|
||||||
|
case MOUSE_DRAG_START:
|
||||||
|
mouse_action(false);
|
||||||
|
break;
|
||||||
|
case MOUSE_DRAG:
|
||||||
|
mouse_action(true);
|
||||||
|
break;
|
||||||
|
case MOUSE_DROP:
|
||||||
|
mouse_action(false);
|
||||||
|
break;
|
||||||
case TICK:
|
case TICK:
|
||||||
// do nothing
|
// do nothing
|
||||||
break;
|
break;
|
||||||
|
@ -214,6 +233,17 @@ namespace gui {
|
||||||
case LOOT_PLACE:
|
case LOOT_PLACE:
|
||||||
// ignored
|
// ignored
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MOUSE_CLICK:
|
||||||
|
mouse_action(false);
|
||||||
|
break;
|
||||||
|
case MOUSE_MOVE:
|
||||||
|
mouse_action(true);
|
||||||
|
break;
|
||||||
|
case MOUSE_DRAG: // ignored
|
||||||
|
case MOUSE_DRAG_START: // ignored
|
||||||
|
case MOUSE_DROP: // ignored
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dbc::sentinel("unhandled event in IDLE");
|
dbc::sentinel("unhandled event in IDLE");
|
||||||
}
|
}
|
||||||
|
@ -227,6 +257,15 @@ namespace gui {
|
||||||
sound::play("ambient");
|
sound::play("ambient");
|
||||||
next_level();
|
next_level();
|
||||||
state(State::IDLE);
|
state(State::IDLE);
|
||||||
|
break;
|
||||||
|
case MOUSE_CLICK: {
|
||||||
|
sf::Vector2f pos = mouse_position();
|
||||||
|
$boss_fight_ui->mouse(pos.x, pos.y, false);
|
||||||
|
|
||||||
|
if($boss_fight_ui->boss_dead()) {
|
||||||
|
event(Event::STAIRS_DOWN);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
break; // do nothing for now
|
break; // do nothing for now
|
||||||
}
|
}
|
||||||
|
@ -236,6 +275,12 @@ namespace gui {
|
||||||
using enum Event;
|
using enum Event;
|
||||||
|
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
|
case MOUSE_CLICK:
|
||||||
|
mouse_action(false);
|
||||||
|
break;
|
||||||
|
case MOUSE_MOVE:
|
||||||
|
mouse_action(true);
|
||||||
|
break;
|
||||||
case ATTACK:
|
case ATTACK:
|
||||||
$main_ui.dirty();
|
$main_ui.dirty();
|
||||||
sound::play("Sword_Hit_1");
|
sound::play("Sword_Hit_1");
|
||||||
|
@ -280,45 +325,27 @@ namespace gui {
|
||||||
dbc::log(fmt::format("END: received event after done: {}", int(ev)));
|
dbc::log(fmt::format("END: received event after done: {}", int(ev)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::Vector2f FSM::mouse_position() {
|
||||||
|
return $window.mapPixelToCoords($router.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSM::mouse_action(bool hover) {
|
||||||
|
sf::Vector2f pos = mouse_position();
|
||||||
|
if($debug_ui.active) $debug_ui.mouse(pos.x, pos.y, hover);
|
||||||
|
$combat_ui.mouse(pos.x, pos.y, hover);
|
||||||
|
$status_ui.mouse(pos.x, pos.y, hover);
|
||||||
|
$main_ui.mouse(pos.x, pos.y, hover);
|
||||||
|
if($loot_ui.active) $loot_ui.mouse(pos.x, pos.y, hover);
|
||||||
|
}
|
||||||
|
|
||||||
void FSM::handle_keyboard_mouse() {
|
void FSM::handle_keyboard_mouse() {
|
||||||
while(const auto ev = $window.pollEvent()) {
|
while(const auto ev = $window.pollEvent()) {
|
||||||
auto gui_ev = $router.process_event(ev);
|
auto gui_ev = $router.process_event(ev);
|
||||||
|
|
||||||
if(gui_ev != gui::Event::TICK) {
|
if(gui_ev == Event::KEY_PRESS) {
|
||||||
event(gui_ev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(const auto* mouse = ev->getIf<sf::Event::MouseButtonPressed>()) {
|
|
||||||
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);
|
|
||||||
|
|
||||||
if($boss_fight_ui->boss_dead()) {
|
|
||||||
event(Event::STAIRS_DOWN);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if($debug_ui.active) $debug_ui.mouse(pos.x, pos.y, false);
|
|
||||||
$combat_ui.mouse(pos.x, pos.y, false);
|
|
||||||
$status_ui.mouse(pos.x, pos.y, false);
|
|
||||||
$main_ui.mouse(pos.x, pos.y, false);
|
|
||||||
if($loot_ui.active) $loot_ui.mouse(pos.x, pos.y, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if(const auto* mouse = ev->getIf<sf::Event::MouseMoved>()) {
|
|
||||||
sf::Vector2f pos = $window.mapPixelToCoords(mouse->position);
|
|
||||||
if($debug_ui.active) $debug_ui.mouse(pos.x, pos.y, true);
|
|
||||||
$combat_ui.mouse(pos.x, pos.y, true);
|
|
||||||
$status_ui.mouse(pos.x, pos.y, true);
|
|
||||||
$main_ui.mouse(pos.x, pos.y, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(const auto* key = ev->getIf<sf::Event::KeyPressed>()) {
|
|
||||||
using KEY = sf::Keyboard::Scan;
|
using KEY = sf::Keyboard::Scan;
|
||||||
|
|
||||||
switch(key->scancode) {
|
switch($router.scancode) {
|
||||||
case KEY::W:
|
case KEY::W:
|
||||||
event(Event::MOVE_FORWARD);
|
event(Event::MOVE_FORWARD);
|
||||||
break;
|
break;
|
||||||
|
@ -368,6 +395,8 @@ namespace gui {
|
||||||
default:
|
default:
|
||||||
break; // ignored
|
break; // ignored
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
event(gui_ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace gui {
|
||||||
LootUI $loot_ui;
|
LootUI $loot_ui;
|
||||||
sf::Font $font;
|
sf::Font $font;
|
||||||
gui::routing::Router $router;
|
gui::routing::Router $router;
|
||||||
|
shared_ptr<sf::Sprite> $dumb_sprite = nullptr;
|
||||||
|
|
||||||
FSM();
|
FSM();
|
||||||
|
|
||||||
|
@ -67,6 +68,8 @@ namespace gui {
|
||||||
void END(Event ev);
|
void END(Event ev);
|
||||||
|
|
||||||
void try_move(int dir, bool strafe);
|
void try_move(int dir, bool strafe);
|
||||||
|
sf::Vector2f mouse_position();
|
||||||
|
void mouse_action(bool hover);
|
||||||
void handle_keyboard_mouse();
|
void handle_keyboard_mouse();
|
||||||
void draw_gui();
|
void draw_gui();
|
||||||
void render();
|
void render();
|
||||||
|
|
|
@ -89,11 +89,12 @@ namespace gui {
|
||||||
fmt::println("LOOT slot={}, entity={} PLACE into slot={}",
|
fmt::println("LOOT slot={}, entity={} PLACE into slot={}",
|
||||||
$selected_slot, $selected_entity, name);
|
$selected_slot, $selected_entity, name);
|
||||||
|
|
||||||
auto& sprite = $level.world->get<components::Sprite>($selected_entity);
|
if($level.world->has<components::Sprite>($selected_entity)) {
|
||||||
auto gui_id = $gui.entity(name);
|
auto& sprite = $level.world->get<components::Sprite>($selected_entity);
|
||||||
$gui.set_init<guecs::Sprite>(gui_id, {sprite.name});
|
auto gui_id = $gui.entity(name);
|
||||||
|
$gui.set_init<guecs::Sprite>(gui_id, {sprite.name});
|
||||||
$slots.insert_or_assign(name, $selected_entity);
|
$slots.insert_or_assign(name, $selected_entity);
|
||||||
|
}
|
||||||
|
|
||||||
return $selected_slot;
|
return $selected_slot;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace gui {
|
||||||
std::unordered_map<std::string, DinkyECS::Entity> $slots;
|
std::unordered_map<std::string, DinkyECS::Entity> $slots;
|
||||||
GameLevel $level;
|
GameLevel $level;
|
||||||
ritual::UI $ritual_ui;
|
ritual::UI $ritual_ui;
|
||||||
int $selected_slot;
|
int $selected_slot = -1;
|
||||||
DinkyECS::Entity $selected_entity;
|
DinkyECS::Entity $selected_entity;
|
||||||
|
|
||||||
StatusUI(GameLevel level);
|
StatusUI(GameLevel level);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue