Tried to use Ragel to create state machines but its lacking an incremental mode and doesn't do any logging of state activity so debugging is harder. Put it in scratchpad for reference though.

This commit is contained in:
Zed A. Shaw 2025-06-14 12:34:27 -04:00
parent 7fc32b0248
commit d99d9a68c8
10 changed files with 541 additions and 313 deletions

175
scratchpad/dnd_loot_2.rl Normal file
View file

@ -0,0 +1,175 @@
#include "gui/dnd_loot_2.hpp"
#include "gui/guecstra.hpp"
#include "gui/uisystems.hpp"
#include <guecs/ui.hpp>
#include <fmt/core.h>
#include "dbc.hpp"
#define _log(M, F) {$cur_state = F; fmt::println("| {}:{} action={}, fcurs={}", __FILE_NAME__, __LINE__, #M, F);}
%%{
machine DNDLoot;
alphtype int;
import "gui/fsm_events.hpp";
action error {
$cur_state = fcurs;
fmt::println("!!! ERROR fcurs={}", fcurs);
}
action started {
_log(started, fcurs);
fbreak;
}
action loot_close {
_log(loot_close, fcurs);
$loot_ui.active = false;
fbreak;
}
action loot_grab {
_log(loot_grab, fcurs);
// NOTE: when grab_source could work to do the if that was here
$grab_source = UISystem::loot_grab($loot_ui.$gui, data);
fbreak;
}
action inv_grab {
_log(inv_grab, fcurs);
$grab_source = UISystem::loot_grab($status_ui.$gui, data);
fbreak;
}
action loot_drop {
_log(loot_drop, fcurs);
if(UISystem::loot_drop($status_ui.$gui,
$loot_ui.$gui, $grab_source, data))
{
fnext looting;
}
fbreak;
}
action inv_drop {
_log(inv_drop, fcurs);
if(UISystem::loot_drop($loot_ui.$gui,
$status_ui.$gui, $grab_source, data))
{
fnext looting;
}
fbreak;
}
action at_end {
_log(at_end, fcurs);
fmt::println("> AT END");
$grab_source = std::nullopt;
$at_end = true;
fbreak;
}
action not_end {
_log(not_end, fcurs);
fmt::println("% NOT_END");
$at_end = false;
fbreak;
}
action mouse_click {
_log(mouse_click, fcurs);
mouse_action(false);
fbreak;
}
action mouse_move {
_log(mouse_move, fcurs);
if($grab_source) {
auto& source = $loot_ui.$gui.get<guecs::GrabSource>(*$grab_source);
source.move($window.mapPixelToCoords($router.position));
}
mouse_action(true);
fbreak;
}
mouse_click = (MOUSE_DRAG_START | MOUSE_CLICK | MOUSE_DROP);
mouse_move = (MOUSE_MOVE | MOUSE_DRAG);
main := start: (
STARTED @started -> looting
),
looting: (
LOOT_OPEN @loot_close -> looting |
LOOT_ITEM @loot_grab -> loot_grab |
LOOT_SELECT @loot_grab -> loot_grab |
INV_SELECT @inv_grab -> inv_grab |
mouse_click @mouse_click -> looting |
mouse_move @mouse_move -> looting
),
loot_grab: (
LOOT_OPEN @loot_grab -> end |
LOOT_SELECT @loot_grab -> looting |
INV_SELECT @inv_drop -> looting |
mouse_click @mouse_click -> loot_grab |
mouse_move @mouse_move -> loot_grab
),
inv_grab: (
LOOT_OPEN @loot_close -> end |
LOOT_SELECT @loot_drop -> looting |
INV_SELECT @inv_grab -> looting |
mouse_click @mouse_click -> inv_grab |
mouse_move @mouse_move -> inv_grab
),
end: (
LOOT_ITEM @loot_grab -> loot_grab |
LOOT_OPEN -> looting
) >at_end %not_end %err(error);
}%%
%% write data;
namespace gui {
sf::Vector2f DNDLoot2::mouse_position() {
return $window.mapPixelToCoords($router.position);
}
void DNDLoot2::mouse_action(bool hover) {
sf::Vector2f pos = mouse_position();
$status_ui.mouse(pos.x, pos.y, hover);
if($loot_ui.active) $loot_ui.mouse(pos.x, pos.y, hover);
}
DNDLoot2::DNDLoot2(StatusUI& status_ui, LootUI& loot_ui, sf::RenderWindow &window, routing::Router& router) :
$status_ui(status_ui),
$loot_ui(loot_ui),
$window(window),
$router(router)
{
%%write init;
dbc::log("====================================");
event(Event::STARTED);
dbc::log("---------------- END CONSTRICT ------");
}
bool DNDLoot2::event(Event event, std::any data) {
if(event == Event::TICK) return true;
int *p = (int *)&event;
int *pe = p+1;
int *eof = pe;
dbc::log(fmt::format(">>>> DND EVENT {}, state={}, cs={}, end={}",
int(event), $cur_state, cs, $at_end));
%%write exec noend;
dbc::log(fmt::format("<<<< DND EVENT {}, state={}, cs={}, end={}",
int(event), $cur_state, cs, $at_end));
return $at_end;
}
}