Skip to main content

memlink_msdk/
dispatch.rs

1//! Method dispatch table for routing method calls to their handlers.
2
3use std::collections::HashMap;
4use std::sync::{LazyLock, Mutex};
5
6use crate::context::CallContext;
7use crate::error::{ModuleError, Result};
8
9pub type MethodHandler = fn(&CallContext<'_>, &[u8]) -> Result<Vec<u8>>;
10
11static METHOD_TABLE: LazyLock<Mutex<HashMap<u32, MethodHandler>>> =
12    LazyLock::new(|| Mutex::new(HashMap::new()));
13
14pub fn register_method(hash: u32, handler: MethodHandler) {
15    let mut table = METHOD_TABLE.lock().unwrap();
16    table.insert(hash, handler);
17}
18
19pub fn dispatch_with_context(ctx: &CallContext<'_>, method_hash: u32, args: &[u8]) -> Result<Vec<u8>> {
20    let table = METHOD_TABLE.lock().unwrap();
21
22    match table.get(&method_hash) {
23        Some(handler) => handler(ctx, args),
24        None => Err(ModuleError::InvalidMethod),
25    }
26}
27
28pub fn dispatch(method_hash: u32, args: &[u8]) -> Result<Vec<u8>> {
29    use crate::exports::get_arena;
30
31    let arena_guard = get_arena();
32    if let Some(arena) = arena_guard.as_ref() {
33        let ctx = CallContext::new(arena, 0.0, 0, 0, None, None);
34        dispatch_with_context(&ctx, method_hash, args)
35    } else {
36        Err(ModuleError::ServiceUnavailable)
37    }
38}
39
40pub fn unregister_method(hash: u32) -> bool {
41    let mut table = METHOD_TABLE.lock().unwrap();
42    table.remove(&hash).is_some()
43}
44
45pub fn method_count() -> usize {
46    let table = METHOD_TABLE.lock().unwrap();
47    table.len()
48}
49
50pub fn clear_methods() {
51    let mut table = METHOD_TABLE.lock().unwrap();
52    table.clear();
53}