Use the new lel-geucs update process.

This commit is contained in:
Zed A. Shaw 2026-04-20 16:53:09 -04:00
parent 8f65e882ac
commit cd475f8e02
14 changed files with 66 additions and 176 deletions

View file

@ -140,11 +140,3 @@ executable('fragviewer',
include_directories: inc_dirs, include_directories: inc_dirs,
override_options: exe_defaults, override_options: exe_defaults,
dependencies: dependencies) dependencies: dependencies)
executable('multiscreen',
[ 'tools/multiscreen.cpp' ],
cpp_args: cpp_args,
link_args: link_args,
include_directories: inc_dirs,
override_options: exe_defaults,
dependencies: dependencies)

View file

@ -6,7 +6,7 @@
#define FSM_STATE(C, S, E, ...) case C::S: S(E, ##__VA_ARGS__); break #define FSM_STATE(C, S, E, ...) case C::S: S(E, ##__VA_ARGS__); break
#else #else
static int last_event=-1; static int last_event=-1;
#define FSM_STATE(C, S, E, ...) case C::S: if(last_event != int(E)) { last_event = int(E); fmt::println(">> " #C " " #S " event={}, state={}", int(E), int($state));}; S(E, ##__VA_ARGS__); break #define FSM_STATE(C, S, E, ...) case C::S: if(last_event != int(E)) { last_event = int(E); fmt::println(">> [{}] " #C " " #S " event={}, state={}", __FILE__, int(E), int($state));}; S(E, ##__VA_ARGS__); break
#endif #endif
template<typename S, typename E> template<typename S, typename E>

View file

@ -59,7 +59,7 @@ namespace gui {
auto gui_id = $gui.entity(key); auto gui_id = $gui.entity(key);
if(auto meter = $gui.get_if<Meter>(gui_id)) { if(auto meter = $gui.get_if<Meter>(gui_id)) {
meter->update_percent(float(value) / float(player_combat.max_hp)); meter->percent = float(value) / float(player_combat.max_hp);
if(meter->percent < 0.2) { if(meter->percent < 0.2) {
meter->color = sf::Color(220, 10, 10, 255); meter->color = sf::Color(220, 10, 10, 255);
@ -67,8 +67,7 @@ namespace gui {
meter->color = THEME.DARK_MID; meter->color = THEME.DARK_MID;
} }
// BUG: gross, make it stop meter->update();
meter->bar.shape->setFillColor(meter->color);
} }
$gui.show_text(key, fmt::format(L"{}", guecs::to_wstring(key), value)); $gui.show_text(key, fmt::format(L"{}", guecs::to_wstring(key), value));

View file

@ -1,3 +1,4 @@
#define FSM_DEBUG 1
#include "gui/guecstra.hpp" #include "gui/guecstra.hpp"
#include "gui/dnd_loot.hpp" #include "gui/dnd_loot.hpp"

View file

@ -7,17 +7,22 @@ namespace gui {
using enum Event; using enum Event;
using enum State; using enum State;
game::Event Router::process_event(std::optional<sf::Event> ev) { std::pair<game::Event, guecs::Modifiers> Router::process_event(std::optional<sf::Event> ev) {
$next_event = game::Event::TICK; $next_event = game::Event::TICK;
if(ev->is<sf::Event::Closed>()) { if(ev->is<sf::Event::Closed>()) {
return game::Event::QUIT; return {game::Event::QUIT, guecs::NO_MODS};
} }
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 || mouse->button == sf::Mouse::Button::Right) { if(mouse->button == sf::Mouse::Button::Left || mouse->button == sf::Mouse::Button::Right) {
left_button = mouse->button == sf::Mouse::Button::Left; left_button = mouse->button == sf::Mouse::Button::Left;
position = mouse->position; position = mouse->position;
if(left_button) {
mouse_mods = {1 << guecs::ModBit::left};
} else {
mouse_mods = {1 << guecs::ModBit::right};
}
event(MOUSE_DOWN); event(MOUSE_DOWN);
} }
} else if(const auto* mouse = ev->getIf<sf::Event::MouseButtonReleased>()) { } else if(const auto* mouse = ev->getIf<sf::Event::MouseButtonReleased>()) {
@ -25,10 +30,12 @@ namespace gui {
if(mouse->button == sf::Mouse::Button::Left || mouse->button == sf::Mouse::Button::Right) { if(mouse->button == sf::Mouse::Button::Left || mouse->button == sf::Mouse::Button::Right) {
left_button = mouse->button == sf::Mouse::Button::Left; left_button = mouse->button == sf::Mouse::Button::Left;
position = mouse->position; position = mouse->position;
mouse_mods = guecs::NO_MODS;
event(MOUSE_UP); event(MOUSE_UP);
} }
} else if(const auto* mouse = ev->getIf<sf::Event::MouseMoved>()) { } else if(const auto* mouse = ev->getIf<sf::Event::MouseMoved>()) {
position = mouse->position; position = mouse->position;
mouse_mods = {1 << guecs::ModBit::hover};
event(MOUSE_MOVE); event(MOUSE_MOVE);
} }
@ -37,7 +44,7 @@ namespace gui {
event(KEY_PRESS); event(KEY_PRESS);
} }
return $next_event; return {$next_event, mouse_mods};
} }
void Router::event(Event ev) { void Router::event(Event ev) {

View file

@ -3,6 +3,7 @@
#include "events.hpp" #include "events.hpp"
#include "algos/simplefsm.hpp" #include "algos/simplefsm.hpp"
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include <guecs/ui.hpp>
namespace gui { namespace gui {
namespace routing { namespace routing {
@ -25,6 +26,7 @@ namespace gui {
class Router : public DeadSimpleFSM<State, Event> { class Router : public DeadSimpleFSM<State, Event> {
public: public:
sf::Vector2i position; sf::Vector2i position;
guecs::Modifiers mouse_mods = guecs::NO_MODS;
sf::Keyboard::Scancode scancode; sf::Keyboard::Scancode scancode;
game::Event $next_event = game::Event::TICK; game::Event $next_event = game::Event::TICK;
int move_count = 0; int move_count = 0;
@ -39,7 +41,7 @@ namespace gui {
void MOUSE_MOVING(Event ev); void MOUSE_MOVING(Event ev);
void MOUSE_DRAGGING(Event ev); void MOUSE_DRAGGING(Event ev);
game::Event process_event(std::optional<sf::Event> ev); std::pair<game::Event, guecs::Modifiers> process_event(std::optional<sf::Event> ev);
void set_event(game::Event ev) { void set_event(game::Event ev) {
$next_event = ev; $next_event = ev;

View file

@ -1,3 +1,4 @@
#define FSM_DEBUG 1
#include "gui/fsm.hpp" #include "gui/fsm.hpp"
#include <iostream> #include <iostream>
#include <chrono> #include <chrono>
@ -27,20 +28,20 @@ namespace gui {
void FSM::event(Event ev, std::any data) { void FSM::event(Event ev, std::any data) {
switch($state) { switch($state) {
FSM_STATE(State, START, ev); FSM_STATE(State, START, ev, data);
FSM_STATE(State, INTRO, ev); FSM_STATE(State, INTRO, ev, data);
FSM_STATE(State, SHOW_SCREEN, ev); FSM_STATE(State, SHOW_SCREEN, ev, data);
FSM_STATE(State, MOVING, ev); FSM_STATE(State, MOVING, ev, data);
FSM_STATE(State, ATTACKING, ev, data); FSM_STATE(State, ATTACKING, ev, data);
FSM_STATE(State, ROTATING, ev); FSM_STATE(State, ROTATING, ev, data);
FSM_STATE(State, IDLE, ev, data); FSM_STATE(State, IDLE, ev, data);
FSM_STATE(State, LOOTING, ev, data); FSM_STATE(State, LOOTING, ev, data);
FSM_STATE(State, END_QUIT, ev); FSM_STATE(State, END_QUIT, ev, data);
FSM_STATE(State, END_NEW_GAME, ev); FSM_STATE(State, END_NEW_GAME, ev, data);
} }
} }
void FSM::START(Event ) { void FSM::START(Event ev, std::any data) {
$main_ui.update_level(); $main_ui.update_level();
$main_ui.init(); $main_ui.init();
$loot_ui.init(); $loot_ui.init();
@ -58,7 +59,7 @@ namespace gui {
show_scene("STARTING"); show_scene("STARTING");
} }
void FSM::INTRO(Event ev) { void FSM::INTRO(Event ev, std::any data) {
dbc::check($story != nullptr, "you forgot the stroy"); dbc::check($story != nullptr, "you forgot the stroy");
if(ev == game::Event::MOUSE_CLICK) { if(ev == game::Event::MOUSE_CLICK) {
@ -71,21 +72,16 @@ namespace gui {
} }
} }
void FSM::SHOW_SCREEN(Event ev) { void FSM::SHOW_SCREEN(Event ev, std::any data) {
using enum Event; using enum Event;
switch(ev) { switch(ev) {
case MOUSE_CLICK:
mouse_action(guecs::NO_MODS);
break;
case MOUSE_MOVE: {
mouse_action({1 << guecs::ModBit::hover});
} break;
case START: case START:
close_scene(); close_scene();
$story = std::make_shared<storyboard::UI>("intro_story"); state(State::IDLE);
$story->init(); //$story = std::make_shared<storyboard::UI>("intro_story");
state(State::INTRO); //$story->init();
//state(State::INTRO);
break; break;
case NEW_GAME: case NEW_GAME:
close_scene(); close_scene();
@ -97,7 +93,7 @@ namespace gui {
state(State::IDLE); state(State::IDLE);
break; break;
case QUIT: case QUIT:
FSM::IDLE(ev, {}); FSM::IDLE(ev, data);
break; break;
case TICK: case TICK:
break; break;
@ -107,7 +103,7 @@ namespace gui {
} }
} }
void FSM::MOVING(Event ) { void FSM::MOVING(Event ev, std::any data) {
// this should be an optional that returns a point // this should be an optional that returns a point
if(auto move_to = $main_ui.play_move()) { if(auto move_to = $main_ui.play_move()) {
$systems.runMoving(*move_to); $systems.runMoving(*move_to);
@ -125,7 +121,7 @@ namespace gui {
} }
} }
void FSM::ROTATING(Event) { void FSM::ROTATING(Event ev, std::any data) {
if(auto aim = $main_ui.play_rotate()) { if(auto aim = $main_ui.play_rotate()) {
auto& player_pos = GameDB::player_position(); auto& player_pos = GameDB::player_position();
player_pos.aiming_at = *aim; player_pos.aiming_at = *aim;
@ -136,18 +132,11 @@ namespace gui {
void FSM::LOOTING(Event ev, std::any data) { void FSM::LOOTING(Event ev, std::any data) {
using enum Event; using enum Event;
switch(ev) {
case MOUSE_DRAG_START:
case MOUSE_CLICK:
case MOUSE_DROP:
mouse_action(guecs::NO_MODS);
break;
default:
if(!$dnd_loot.event(ev, data)) { if(!$dnd_loot.event(ev, data)) {
dbc::log("!!!!!!!!!!!!!!!!!!!! dnd_lot said end");
state(State::IDLE); state(State::IDLE);
} }
} }
}
void FSM::IDLE(Event ev, std::any data) { void FSM::IDLE(Event ev, std::any data) {
using enum Event; using enum Event;
@ -209,12 +198,6 @@ namespace gui {
$systems.runUseItem(slot_name); $systems.runUseItem(slot_name);
$status_ui.update(); $status_ui.update();
} break; } break;
case MOUSE_CLICK:
mouse_action(guecs::NO_MODS);
break;
case MOUSE_MOVE: {
mouse_action({1 << guecs::ModBit::hover});
} break;
case AIM_CLICK: case AIM_CLICK:
$systems.runPickup(); $systems.runPickup();
break; break;
@ -244,11 +227,11 @@ namespace gui {
} }
} }
void FSM::END_QUIT(Event ev) { void FSM::END_QUIT(Event ev, std::any data) {
dbc::log($F("END_QUIT: received event after done: {}", int(ev))); dbc::log($F("END_QUIT: received event after done: {}", int(ev)));
} }
void FSM::END_NEW_GAME(Event ev) { void FSM::END_NEW_GAME(Event ev, std::any data) {
dbc::log($F("END_PLAYER_DIED: received event after done: {}", int(ev))); dbc::log($F("END_PLAYER_DIED: received event after done: {}", int(ev)));
} }
@ -256,27 +239,30 @@ namespace gui {
return $window.mapPixelToCoords($router.position); return $window.mapPixelToCoords($router.position);
} }
void FSM::mouse_action(guecs::Modifiers mods) { void FSM::mouse_action() {
sf::Vector2f pos = mouse_position(); sf::Vector2f pos = mouse_position();
if($screens.is_visible()) { if($screens.is_visible()) {
$screens.mouse(pos.x, pos.y, mods); $screens.mouse(pos.x, pos.y, $router.mouse_mods);
return; return;
} }
if($debug_ui.active) $debug_ui.mouse(pos.x, pos.y, mods); if($debug_ui.active) {
$status_ui.mouse(pos.x, pos.y, mods); $debug_ui.mouse(pos.x, pos.y, $router.mouse_mods);
}
$status_ui.mouse(pos.x, pos.y, $router.mouse_mods);
if($loot_ui.active) { if($loot_ui.active) {
$loot_ui.mouse(pos.x, pos.y, mods); $loot_ui.mouse(pos.x, pos.y, $router.mouse_mods);
} else { } else {
$main_ui.mouse(pos.x, pos.y, mods); $main_ui.mouse(pos.x, pos.y, $router.mouse_mods);
} }
} }
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, mouse_mods] = $router.process_event(ev);
if(gui_ev == Event::KEY_PRESS) { if(gui_ev == Event::KEY_PRESS) {
using KEY = sf::Keyboard::Scan; using KEY = sf::Keyboard::Scan;
@ -335,7 +321,8 @@ namespace gui {
break; // ignored break; // ignored
} }
} else { } else {
event(gui_ev); // event(gui_ev, {mouse_mods});
mouse_action();
} }
} }
} }

View file

@ -13,7 +13,7 @@
#include "events.hpp" #include "events.hpp"
#include "gui/scene_ui.hpp" #include "gui/scene_ui.hpp"
#include "gui/storyboard.hpp" #include "gui/storyboard.hpp"
#include "gui/uistack.hpp" #include <guecs/uistack.hpp>
namespace gui { namespace gui {
enum class State { enum class State {
@ -55,21 +55,21 @@ namespace gui {
void event(game::Event ev, std::any data={}); void event(game::Event ev, std::any data={});
void START(game::Event ev); void START(game::Event ev, std::any data);
void INTRO(game::Event ev); void INTRO(game::Event ev, std::any data);
void SHOW_SCREEN(game::Event ev); void SHOW_SCREEN(game::Event ev, std::any data);
void IDLE(game::Event ev, std::any data); void IDLE(game::Event ev, std::any data);
void MOVING(game::Event ev); void MOVING(game::Event ev, std::any data);
void ATTACKING(game::Event ev, std::any data); void ATTACKING(game::Event ev, std::any data);
void MAPPING(game::Event ev); void MAPPING(game::Event ev, std::any data);
void ROTATING(game::Event ev); void ROTATING(game::Event ev, std::any data);
void LOOTING(game::Event ev, std::any data); void LOOTING(game::Event ev, std::any data);
void END_QUIT(game::Event ev); void END_QUIT(game::Event ev, std::any data);
void END_NEW_GAME(game::Event ev); void END_NEW_GAME(game::Event ev, std::any data);
void try_move(int dir, bool strafe); void try_move(int dir, bool strafe);
sf::Vector2f mouse_position(); sf::Vector2f mouse_position();
void mouse_action(guecs::Modifiers mods); void mouse_action();
void handle_keyboard_mouse(); void handle_keyboard_mouse();
void draw_gui(); void draw_gui();
void update(); void update();

View file

@ -80,7 +80,6 @@ namespace gui {
dbc::check(world->has<components::Sprite>(item), dbc::check(world->has<components::Sprite>(item),
"item in inventory UI doesn't exist in world. New level?"); "item in inventory UI doesn't exist in world. New level?");
auto& sprite = world->get<components::Sprite>(item); auto& sprite = world->get<components::Sprite>(item);
fmt::println("!!!!!!!!!!! trying to load {}", sprite.name);
$gui.set_init<guecs::Icon>(id, {sprite.name}); $gui.set_init<guecs::Icon>(id, {sprite.name});
guecs::GrabSource grabber{ guecs::GrabSource grabber{

View file

@ -24,7 +24,6 @@ namespace gui {
gui.set<Clickable>(area, { gui.set<Clickable>(area, {
[=](auto) { [=](auto) {
auto world = GameDB::current_world(); auto world = GameDB::current_world();
fmt::println("CLICK {}", name);
world->send<game::Event>(game::Event::AIM_CLICK, area, {}); world->send<game::Event>(game::Event::AIM_CLICK, area, {});
} }
}); });

View file

@ -1,98 +0,0 @@
#include <guecs/ui.hpp>
#include "dbc.hpp"
#include "constants.hpp"
#include <flat_map>
namespace gui {
template<typename SCREEN_TYPE>
struct UIStack {
using UIStackMap = std::flat_map<std::string, std::shared_ptr<SCREEN_TYPE>>;
UIStackMap screens{};
bool visible = false;
UIStackMap::iterator $current{screens.begin()};
SCREEN_TYPE* $active = nullptr;
void add(const std::string& name, std::shared_ptr<SCREEN_TYPE> screen) {
screens.insert_or_assign(name, screen);
update_active(screens.begin());
}
void update_active(const UIStackMap::iterator& itr) {
$current = itr;
$active = (*$current).second.get();
}
void set_active(const std::string& name) {
dbc::check(screens.contains(name), $F("screen {} not in stack", name));
update_active(screens.find(name));
}
void set_visible(bool new_value) {
visible = new_value;
}
bool is_visible() {
return visible;
}
void render(sf::RenderTarget& target) {
dbc::check($active != nullptr, "you didn't set active");
$active->render(target);
}
void update() {
dbc::check($active != nullptr, "you didn't set active");
$active->update();
}
bool mouse(float x, float y, guecs::Modifiers mods = guecs::NO_MODS) {
dbc::check($active != nullptr, "you didn't set active");
return $active->mouse(x, y, mods);
}
bool move(const UIStackMap::iterator& itr, const UIStackMap::iterator& avoid, const UIStackMap::iterator& result) {
if(itr != avoid) {
update_active(result);
return true;
} else {
return false;
}
}
bool next() {
return move($current + 1, screens.end(), $current + 1);
}
bool prev() {
return move($current, screens.begin(), $current - 1);
}
void first() {
update_active(screens.begin());
}
void last() {
update_active(screens.end() - 1);
}
const std::string& active_name() {
dbc::check($active != nullptr, "you didn't set active");
return (*$current).first;
}
std::shared_ptr<SCREEN_TYPE> active_ui() {
dbc::check($active != nullptr, "you didn't set active");
return (*$current).second;
}
std::shared_ptr<SCREEN_TYPE> at(const std::string& name) {
return screens.at(name);
}
const UIStackMap::key_container_type& names() {
return screens.keys();
}
};
}

View file

@ -12,6 +12,7 @@
void play_game(std::shared_ptr<gui::FSM> main) { void play_game(std::shared_ptr<gui::FSM> main) {
sound::play("ambient_1", true); sound::play("ambient_1", true);
sound::mute(false);
main->event(game::Event::START); main->event(game::Event::START);
while(main->active()) { while(main->active()) {

View file

@ -174,7 +174,7 @@ namespace animator {
while(const auto ev = $window.pollEvent()) { while(const auto ev = $window.pollEvent()) {
using enum game::Event; using enum game::Event;
using KEY = sf::Keyboard::Scan; using KEY = sf::Keyboard::Scan;
auto gui_ev = $router.process_event(ev); auto [gui_ev, mouse_mods] = $router.process_event(ev);
auto mouse_pos = $window.mapPixelToCoords($router.position); auto mouse_pos = $window.mapPixelToCoords($router.position);
switch(gui_ev) { switch(gui_ev) {
@ -227,6 +227,7 @@ namespace animator {
} }
auto viewer = $ui.entity("viewer"); auto viewer = $ui.entity("viewer");
// BUG: this is some jank bullshit but it works // BUG: this is some jank bullshit but it works
$ui.set<guecs::Sprite>(viewer, {sprite_name, 0, false}); $ui.set<guecs::Sprite>(viewer, {sprite_name, 0, false});
$ui.init(); $ui.init();

View file

@ -1,5 +1,5 @@
[wrap-git] [wrap-git]
directory=lel-guecs-0.7.1 directory=lel-guecs-0.7.3
url=https://git.zedshaw.games/games/lel-guecs.git url=https://git.zedshaw.games/games/lel-guecs.git
revision=HEAD revision=HEAD
depth=1 depth=1