Skip to main content

ironsbe_server/
dispatcher.rs

1//! Message dispatcher for routing messages to handlers.
2
3use crate::handler::{MessageHandler, Responder, TypedHandler};
4use ironsbe_core::header::MessageHeader;
5use std::collections::HashMap;
6use std::sync::Arc;
7
8/// Dispatcher that routes messages to specific handlers based on template ID.
9pub struct MessageDispatcher {
10    handlers: HashMap<u16, Arc<dyn TypedHandler>>,
11    default_handler: Option<Arc<dyn MessageHandler>>,
12}
13
14impl MessageDispatcher {
15    /// Creates a new empty dispatcher.
16    #[must_use]
17    pub fn new() -> Self {
18        Self {
19            handlers: HashMap::new(),
20            default_handler: None,
21        }
22    }
23
24    /// Registers a handler for a specific template ID.
25    pub fn register<H: TypedHandler + 'static>(&mut self, template_id: u16, handler: H) {
26        self.handlers.insert(template_id, Arc::new(handler));
27    }
28
29    /// Sets the default handler for unregistered template IDs.
30    pub fn set_default<H: MessageHandler + 'static>(&mut self, handler: H) {
31        self.default_handler = Some(Arc::new(handler));
32    }
33
34    /// Returns true if a handler is registered for the given template ID.
35    #[must_use]
36    pub fn has_handler(&self, template_id: u16) -> bool {
37        self.handlers.contains_key(&template_id)
38    }
39}
40
41impl Default for MessageDispatcher {
42    fn default() -> Self {
43        Self::new()
44    }
45}
46
47impl MessageHandler for MessageDispatcher {
48    fn on_message(
49        &self,
50        session_id: u64,
51        header: &MessageHeader,
52        buffer: &[u8],
53        responder: &dyn Responder,
54    ) {
55        let template_id = { header.template_id };
56        if let Some(handler) = self.handlers.get(&template_id) {
57            handler.handle(session_id, buffer, responder);
58        } else if let Some(default) = &self.default_handler {
59            default.on_message(session_id, header, buffer, responder);
60        } else {
61            tracing::warn!(
62                "No handler for template_id={} from session={}",
63                template_id,
64                session_id
65            );
66        }
67    }
68
69    fn on_session_start(&self, session_id: u64) {
70        if let Some(default) = &self.default_handler {
71            default.on_session_start(session_id);
72        }
73    }
74
75    fn on_session_end(&self, session_id: u64) {
76        if let Some(default) = &self.default_handler {
77            default.on_session_end(session_id);
78        }
79    }
80
81    fn on_error(&self, session_id: u64, error: &str) {
82        if let Some(default) = &self.default_handler {
83            default.on_error(session_id, error);
84        }
85    }
86}