Skip to main content

yog_event/
event.rs

1//! Events on the bus: each event type's addresses, and its payload's bytes.
2
3use yog_data::Schema;
4use yog_ids as ids;
5
6use crate::message::{Message, branch, last_segment};
7
8use crate::{block, client, container, entity, log, nanite, player, server, world};
9
10/// An event the bus carries; its payload is `Self` in `yog-data`'s binary form.
11pub trait Event: Message {
12    /// Where it's emitted after the game did it.
13    const ADDRESS: &'static str;
14    /// Where it's emitted before — a handler's cancel stops it — if it can be stopped.
15    const PRE: Option<&'static str>;
16    /// The field whose value picks the event's branch (`entity_type`: each
17    /// type's ticks go to `…/tick/<type>`), if it's keyed — see [`crate::keyed`].
18    const KEY: Option<&'static str>;
19
20    /// The key field's value, if it's keyed.
21    fn key(&self) -> Option<&str>;
22
23    /// Where this event goes after the game did it: the address, or its branch for the key.
24    fn target(&self) -> String {
25        crate::message::target(Self::ADDRESS, self.key())
26    }
27
28    /// Where it goes before, if it can be stopped.
29    fn pre_target(&self) -> Option<String> {
30        Self::PRE.map(|pre| crate::message::target(pre, self.key()))
31    }
32
33    /// [`Event::target`]'s number — the type's own address cached.
34    fn address(&self) -> crate::Address;
35
36    /// [`Event::pre_target`]'s number.
37    fn pre_address(&self) -> Option<crate::Address>;
38}
39
40/// An event type's descriptor: its plane and name, addresses and payload shape.
41pub struct EventInfo {
42    /// Its place in the tree: `player/session`, `block`, `client/ui`…
43    pub plane: &'static str,
44    pub name: &'static str,
45    pub address: &'static str,
46    pub pre: Option<&'static str>,
47    pub key: Option<&'static str>,
48    pub shape: yog_data::Shape,
49}
50
51macro_rules! events {
52    ($($ty:path => $post:expr, $pre:expr $(, key = $key:ident)?;)*) => {
53        $(impl Event for $ty {
54            const ADDRESS: &'static str = $post;
55            const PRE: Option<&'static str> = $pre;
56            const KEY: Option<&'static str> = key!($($key)?);
57
58            fn key(&self) -> Option<&str> {
59                key_value!(self, $($key)?)
60            }
61
62            fn address(&self) -> crate::Address {
63                static AT: crate::Cached = crate::Cached::new();
64                crate::address::of(&AT, $post, self.key())
65            }
66
67            fn pre_address(&self) -> Option<crate::Address> {
68                static PRE: crate::Cached = crate::Cached::new();
69                $pre.map(|pre: &'static str| crate::address::of(&PRE, pre, self.key()))
70            }
71        })*
72
73        /// Every event type, plane by plane.
74        pub fn all() -> Vec<EventInfo> {
75            vec![$(EventInfo {
76                plane: branch($post, ids::event::PREFIX),
77                name: last_segment(stringify!($ty)),
78                address: $post,
79                pre: $pre,
80                key: key!($($key)?),
81                shape: <$ty as Schema>::shape(),
82            }),*]
83        }
84    };
85}
86
87events! {
88    log::Record => ids::event_log::RECORD, None;
89    player::session::Join => ids::event_player_session::JOIN, None;
90    player::session::Leave => ids::event_player_session::LEAVE, None;
91    player::life::Death => ids::event_player_life::DEATH, Some(ids::event_player_life::DEATH_PRE);
92    player::life::Respawn => ids::event_player_life::RESPAWN, None;
93    player::chat::Message => ids::event_player_chat::MESSAGE, Some(ids::event_player_chat::MESSAGE_PRE);
94    player::action::Move => ids::event_player_action::MOVE, None;
95    player::action::UseItem => ids::event_player_action::USE_ITEM, Some(ids::event_player_action::USE_ITEM_PRE);
96    player::action::Attack => ids::event_player_action::ATTACK, None;
97    player::action::Interact => ids::event_player_action::INTERACT, Some(ids::event_player_action::INTERACT_PRE);
98    player::action::Craft => ids::event_player_action::CRAFT, None;
99    player::action::Pickup => ids::event_player_action::PICKUP, Some(ids::event_player_action::PICKUP_PRE);
100    player::progress::Advancement => ids::event_player_progress::ADVANCEMENT, None;
101    block::Break => ids::event_block::BREAK, Some(ids::event_block::BREAK_PRE);
102    block::Place => ids::event_block::PLACE, Some(ids::event_block::PLACE_PRE);
103    block::Use => ids::event_block::USE, Some(ids::event_block::USE_PRE);
104    entity::life::Spawn => ids::event_entity_life::SPAWN, Some(ids::event_entity_life::SPAWN_PRE);
105    entity::life::Death => ids::event_entity_life::DEATH, None;
106    entity::combat::Damage => ids::event_entity_combat::DAMAGE, Some(ids::event_entity_combat::DAMAGE_PRE);
107    entity::combat::ProjectileHit => ids::event_entity_combat::PROJECTILE_HIT, Some(ids::event_entity_combat::PROJECTILE_HIT_PRE);
108    entity::game::Tick => ids::event_entity_game::TICK, None, key = entity_type;
109    world::Explosion => ids::event_world::EXPLOSION, Some(ids::event_world::EXPLOSION_PRE);
110    world::generation::Chunk => ids::event_world_generation::CHUNK, None, key = generator;
111    world::loot::Roll => ids::event_world_loot::ROLL, None;
112    container::Open => ids::event_container::OPEN, Some(ids::event_container::OPEN_PRE);
113    container::Close => ids::event_container::CLOSE, None;
114    container::machine::Craft => ids::event_container_machine::CRAFT, Some(ids::event_container_machine::CRAFT_PRE);
115    server::game::Tick => ids::event_server_game::TICK, None;
116    server::life::Started => ids::event_server_life::STARTED, None;
117    server::life::Stopping => ids::event_server_life::STOPPING, None;
118    server::life::Saving => ids::event_server_life::SAVING, None;
119    server::command::Run => ids::event_server_command::RUN, None, key = name;
120    server::net::Packet => ids::event_server_net::PACKET, None, key = channel;
121    nanite::Injected => ids::event_nanite::INJECT, None, key = point;
122    client::game::Tick => ids::event_client_game::TICK, None;
123    client::game::Travel => ids::event_client_game::TRAVEL, None;
124    client::input::Key => ids::event_client_input::KEY, Some(ids::event_client_input::KEY_PRE);
125    client::input::Binding => ids::event_client_input::BINDING, None, key = id;
126    client::input::Scroll => ids::event_client_input::SCROLL, Some(ids::event_client_input::SCROLL_PRE);
127    client::chat::Send => ids::event_client_chat::SEND, Some(ids::event_client_chat::SEND_PRE);
128    client::ui::Open => ids::event_client_ui::OPEN, None;
129    client::ui::Close => ids::event_client_ui::CLOSE, None;
130    client::ui::Input => ids::event_client_ui::INPUT, Some(ids::event_client_ui::INPUT_PRE), key = ui_id;
131    client::render::Hud => ids::event_client_render::HUD, None;
132    client::render::World => ids::event_client_render::WORLD, None;
133    client::render::Ui => ids::event_client_render::UI, None, key = ui_id;
134    client::render::Tooltip => ids::event_client_render::TOOLTIP, None, key = item;
135    client::render::Page => ids::event_client_render::PAGE, None, key = drawer;
136    client::render::Camera => ids::event_client_render::CAMERA, None;
137    client::render::Body => ids::event_client_render::BODY, None;
138    client::net::Packet => ids::event_client_net::PACKET, None, key = channel;
139}