Lua verbs fire their events before returning, in the reference's order (#1015)
In 1.12.1 an event a Lua verb raises runs its handlers before the verb returns: `SignalEvent` (`0x703e50`) walks the listeners in place. About 35 benilla binding sites queued theirs for a later drain instead. - Verbs now raise inside `tick::verb` steps, and the events fire as each step's model borrow drops. A step follows the reference's split wherever it signals before changing state a getter reads: the money pickup, bag pickup and place, merchant grab, repair cursor, item use, action and pet-bar pickup and drop. - The grid events fire before `CURSOR_UPDATE`, and a clear's unlock before both, as at `0x4952b3`/`0x495455`. `ITEM_LOCK_CHANGED` carries no arguments. - `pending_events` is host-only now. Tests pin handler order per family, nesting from a handler, and the order changes. Fixes #999 Fixes #582 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
24c7cab983
commit
aba120cdcb
@@ -1019,22 +1019,17 @@ pub(crate) struct Model {
|
||||
pub(crate) chat_bubbles: super::chat_bubble::ChatBubbles,
|
||||
/// The world-state readout's rows, gated and resolved by the app.
|
||||
pub(crate) worldstate: super::worldstate::WorldStateUiState,
|
||||
/// Events raised outside a dispatch, fired at the start of the next tick ahead of its `OnUpdate`
|
||||
/// pass (`UiScript::tick`). The reference queues nothing here: a fire site calls
|
||||
/// `SignalEvent` (`0x703e50`, `0x703f50`), which runs every handler before it returns, so a
|
||||
/// verb's event reaches its listeners inside the call.
|
||||
///
|
||||
/// A binding can do the same: `tick::fire_event_into` re-enters dispatch from inside Lua, as
|
||||
/// `SetCVar`'s `CVAR_UPDATE` does, once the binding holds no model borrow. So the queue is no
|
||||
/// limit, and a Lua verb that pushes here instead is a gap against the reference: the cursor
|
||||
/// verbs' `CURSOR_UPDATE`, grid, `ITEM_LOCK_CHANGED`, `DELETE_ITEM_CONFIRM` and
|
||||
/// `PLAYER_MONEY`, the send-mail verbs' events, `SetGuildRecruitmentMode`'s
|
||||
/// `UPDATE_CHAT_WINDOWS`, `SetBattlefieldScoreFaction`'s `UPDATE_BATTLEFIELD_SCORE`,
|
||||
/// `UpdateInventoryAlertStatus`'s `UPDATE_INVENTORY_ALERTS`, `CancelAreaSpiritHeal`'s
|
||||
/// `AREA_SPIRIT_HEALER_OUT_OF_RANGE` and the trainer verbs' `TRAINER_UPDATE`. The host's own
|
||||
/// setters (the world map's, the world-state rows, a dropped mail attachment) and
|
||||
/// `UiScript::queue_event` have no verb to fire inside and queue by design.
|
||||
/// The host's event queue, fired at the start of the next tick ahead of its `OnUpdate` pass
|
||||
/// (`UiScript::tick`). Host producers only: the app's setters (the world map's, the
|
||||
/// world-state rows, a dropped mail attachment), `UiScript::queue_event`, and an engine path
|
||||
/// such as a world click that clears the cursor, which has no verb to fire inside and queues
|
||||
/// so it stays behind the input already queued. A Lua verb never lands here: the reference's
|
||||
/// `SignalEvent` (`0x703e50`, `0x703f50`) runs every handler before it returns, so a verb's
|
||||
/// events fire inside the call, through [`super::tick::verb`].
|
||||
pub(crate) pending_events: Vec<(String, Vec<ScriptValue>)>,
|
||||
/// The events the running [`super::tick::verb`] segment has raised, fired in order once its
|
||||
/// model borrow drops; `None` outside a segment, where [`Model::raise`] queues instead.
|
||||
pub(crate) verb_events: Option<Vec<(String, Vec<ScriptValue>)>>,
|
||||
/// The last cursor position in UI space (logical px, y-up), behind `GetCursorPosition()`.
|
||||
pub(crate) cursor_pos: (f32, f32),
|
||||
|
||||
@@ -1543,6 +1538,7 @@ impl Model {
|
||||
chat_bubbles: super::chat_bubble::ChatBubbles::default(),
|
||||
worldstate: super::worldstate::WorldStateUiState::default(),
|
||||
pending_events: Vec::new(),
|
||||
verb_events: None,
|
||||
cursor_pos: (0.0, 0.0),
|
||||
minimap_ping_request: None,
|
||||
minimap_ping: (0.0, 0.0),
|
||||
|
||||
Reference in New Issue
Block a user