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
|
||||
|
||||
test: build
|
||||
./builddir/runtests "[event_router]"
|
||||
./builddir/runtests
|
||||
|
||||
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 "[event_router]"
|
||||
gdb --nx -x .gdbinit --ex run --args builddir/runtests -e
|
||||
|
||||
win_installer:
|
||||
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_SELECT=15,
|
||||
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 "dbc.hpp"
|
||||
#include "events.hpp"
|
||||
|
@ -44,6 +43,7 @@ namespace gui {
|
|||
FSM_STATE(State, IDLE, ev);
|
||||
FSM_STATE(State, MOUSE_ACTIVE, ev);
|
||||
FSM_STATE(State, MOUSE_MOVING, ev);
|
||||
FSM_STATE(State, MOUSE_DRAGGING, ev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,17 +54,15 @@ namespace gui {
|
|||
void Router::IDLE(Event ev) {
|
||||
switch(ev) {
|
||||
case MOUSE_DOWN:
|
||||
move_count=0;
|
||||
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");
|
||||
set_event(gui::Event::MOUSE_MOVE);
|
||||
break;
|
||||
case KEY_PRESS:
|
||||
dbc::log("key pressed");
|
||||
set_event(gui::Event::KEY_PRESS);
|
||||
break;
|
||||
default:
|
||||
dbc::sentinel("invalid event");
|
||||
|
@ -73,18 +71,17 @@ namespace gui {
|
|||
|
||||
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");
|
||||
set_event(gui::Event::MOUSE_CLICK);
|
||||
state(State::IDLE);
|
||||
break;
|
||||
case MOUSE_MOVE:
|
||||
move_count++;
|
||||
set_event(gui::Event::MOUSE_DRAG);
|
||||
state(State::MOUSE_MOVING);
|
||||
break;
|
||||
case KEY_PRESS:
|
||||
dbc::log("send the key but cancel");
|
||||
set_event(gui::Event::KEY_PRESS);
|
||||
state(State::IDLE);
|
||||
break;
|
||||
default:
|
||||
|
@ -94,23 +91,46 @@ namespace gui {
|
|||
|
||||
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");
|
||||
case MOUSE_UP: {
|
||||
dbc::check(move_count < $drag_tolerance, "mouse up but not in dragging state");
|
||||
set_event(gui::Event::MOUSE_CLICK);
|
||||
state(State::IDLE);
|
||||
break;
|
||||
} break;
|
||||
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;
|
||||
case KEY_PRESS:
|
||||
dbc::log("send the key but cancel");
|
||||
state(State::IDLE);
|
||||
set_event(gui::Event::KEY_PRESS);
|
||||
break;
|
||||
default:
|
||||
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,
|
||||
MOUSE_ACTIVE,
|
||||
MOUSE_MOVING,
|
||||
MOUSE_DRAGGING
|
||||
};
|
||||
|
||||
enum class Event {
|
||||
|
@ -25,6 +26,8 @@ namespace gui {
|
|||
sf::Vector2i position;
|
||||
sf::Keyboard::Scancode scancode;
|
||||
gui::Event $next_event = gui::Event::TICK;
|
||||
int move_count = 0;
|
||||
int $drag_tolerance = 4;
|
||||
|
||||
void event(Event ev);
|
||||
|
||||
|
@ -32,6 +35,7 @@ namespace gui {
|
|||
void IDLE(Event ev);
|
||||
void MOUSE_ACTIVE(Event ev);
|
||||
void MOUSE_MOVING(Event ev);
|
||||
void MOUSE_DRAGGING(Event ev);
|
||||
|
||||
gui::Event process_event(std::optional<sf::Event> ev);
|
||||
|
||||
|
|
95
gui/fsm.cpp
95
gui/fsm.cpp
|
@ -127,6 +127,7 @@ namespace gui {
|
|||
state(State::IDLE);
|
||||
break;
|
||||
case LOOT_SELECT: {
|
||||
fmt::println("loot is selected");
|
||||
int slot_id = std::any_cast<int>(data);
|
||||
|
||||
if(auto entity = $loot_ui.select_slot(slot_id)) {
|
||||
|
@ -137,8 +138,26 @@ namespace gui {
|
|||
case LOOT_PLACE: {
|
||||
std::string slot_name = std::any_cast<std::string>(data);
|
||||
int slot_id = $status_ui.place_slot(slot_name);
|
||||
// BUG: fix this bullshit
|
||||
if(slot_id != -1) {
|
||||
$loot_ui.remove_slot(slot_id);
|
||||
}
|
||||
} 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:
|
||||
// do nothing
|
||||
break;
|
||||
|
@ -214,6 +233,17 @@ namespace gui {
|
|||
case LOOT_PLACE:
|
||||
// ignored
|
||||
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:
|
||||
dbc::sentinel("unhandled event in IDLE");
|
||||
}
|
||||
|
@ -227,6 +257,15 @@ namespace gui {
|
|||
sound::play("ambient");
|
||||
next_level();
|
||||
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:
|
||||
break; // do nothing for now
|
||||
}
|
||||
|
@ -236,6 +275,12 @@ namespace gui {
|
|||
using enum Event;
|
||||
|
||||
switch(ev) {
|
||||
case MOUSE_CLICK:
|
||||
mouse_action(false);
|
||||
break;
|
||||
case MOUSE_MOVE:
|
||||
mouse_action(true);
|
||||
break;
|
||||
case ATTACK:
|
||||
$main_ui.dirty();
|
||||
sound::play("Sword_Hit_1");
|
||||
|
@ -280,45 +325,27 @@ namespace gui {
|
|||
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() {
|
||||
while(const auto ev = $window.pollEvent()) {
|
||||
auto gui_ev = $router.process_event(ev);
|
||||
|
||||
if(gui_ev != gui::Event::TICK) {
|
||||
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>()) {
|
||||
if(gui_ev == Event::KEY_PRESS) {
|
||||
using KEY = sf::Keyboard::Scan;
|
||||
|
||||
switch(key->scancode) {
|
||||
switch($router.scancode) {
|
||||
case KEY::W:
|
||||
event(Event::MOVE_FORWARD);
|
||||
break;
|
||||
|
@ -368,6 +395,8 @@ namespace gui {
|
|||
default:
|
||||
break; // ignored
|
||||
}
|
||||
} else {
|
||||
event(gui_ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace gui {
|
|||
LootUI $loot_ui;
|
||||
sf::Font $font;
|
||||
gui::routing::Router $router;
|
||||
shared_ptr<sf::Sprite> $dumb_sprite = nullptr;
|
||||
|
||||
FSM();
|
||||
|
||||
|
@ -67,6 +68,8 @@ namespace gui {
|
|||
void END(Event ev);
|
||||
|
||||
void try_move(int dir, bool strafe);
|
||||
sf::Vector2f mouse_position();
|
||||
void mouse_action(bool hover);
|
||||
void handle_keyboard_mouse();
|
||||
void draw_gui();
|
||||
void render();
|
||||
|
|
|
@ -89,11 +89,12 @@ namespace gui {
|
|||
fmt::println("LOOT slot={}, entity={} PLACE into slot={}",
|
||||
$selected_slot, $selected_entity, name);
|
||||
|
||||
if($level.world->has<components::Sprite>($selected_entity)) {
|
||||
auto& sprite = $level.world->get<components::Sprite>($selected_entity);
|
||||
auto gui_id = $gui.entity(name);
|
||||
$gui.set_init<guecs::Sprite>(gui_id, {sprite.name});
|
||||
|
||||
$slots.insert_or_assign(name, $selected_entity);
|
||||
}
|
||||
|
||||
return $selected_slot;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace gui {
|
|||
std::unordered_map<std::string, DinkyECS::Entity> $slots;
|
||||
GameLevel $level;
|
||||
ritual::UI $ritual_ui;
|
||||
int $selected_slot;
|
||||
int $selected_slot = -1;
|
||||
DinkyECS::Entity $selected_entity;
|
||||
|
||||
StatusUI(GameLevel level);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue