hypen_engine/dispatch/
event.rs

1use serde::{Deserialize, Serialize};
2
3/// A UI event from a platform renderer (e.g., click, input change)
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct Event {
6    /// Node ID that generated the event
7    pub node_id: String,
8
9    /// Event name (e.g., "click", "change", "submit")
10    pub event_name: String,
11
12    /// Optional event payload (varies by event type)
13    pub payload: Option<serde_json::Value>,
14}
15
16impl Event {
17    pub fn new(node_id: impl Into<String>, event_name: impl Into<String>) -> Self {
18        Self {
19            node_id: node_id.into(),
20            event_name: event_name.into(),
21            payload: None,
22        }
23    }
24
25    pub fn with_payload(mut self, payload: serde_json::Value) -> Self {
26        self.payload = Some(payload);
27        self
28    }
29}
30
31/// Callback type for event handlers
32pub type EventHandler = Box<dyn Fn(&Event) + Send + Sync>;
33
34/// Routes UI events to the appropriate action handlers
35pub struct EventRouter {
36    /// Map of (node_id, event_name) -> action_name
37    event_actions: indexmap::IndexMap<(String, String), String>,
38}
39
40impl EventRouter {
41    pub fn new() -> Self {
42        Self {
43            event_actions: indexmap::IndexMap::new(),
44        }
45    }
46
47    /// Register that a node's event should trigger an action
48    pub fn register(
49        &mut self,
50        node_id: impl Into<String>,
51        event_name: impl Into<String>,
52        action_name: impl Into<String>,
53    ) {
54        let key = (node_id.into(), event_name.into());
55        self.event_actions.insert(key, action_name.into());
56    }
57
58    /// Get the action name for a given node event
59    pub fn get_action(&self, node_id: &str, event_name: &str) -> Option<&str> {
60        self.event_actions
61            .get(&(node_id.to_string(), event_name.to_string()))
62            .map(|s| s.as_str())
63    }
64
65    /// Unregister an event
66    pub fn unregister(&mut self, node_id: &str, event_name: &str) {
67        self.event_actions
68            .shift_remove(&(node_id.to_string(), event_name.to_string()));
69    }
70
71    /// Clear all event mappings
72    pub fn clear(&mut self) {
73        self.event_actions.clear();
74    }
75}
76
77impl Default for EventRouter {
78    fn default() -> Self {
79        Self::new()
80    }
81}