1use 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}