use crate::memory::Value;
use std::collections::HashMap;
use std::sync::{OnceLock, RwLock};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SharedObjectId(pub u32);
pub type RustCallback = Box<dyn Fn(&[Value]) -> Result<Value, String> + Send + Sync>;
fn rust_callbacks() -> &'static RwLock<HashMap<String, RustCallback>> {
static RUST_CALLBACKS: OnceLock<RwLock<HashMap<String, RustCallback>>> = OnceLock::new();
RUST_CALLBACKS.get_or_init(|| RwLock::new(HashMap::new()))
}
pub fn register_rust_callback(name: &str, callback: RustCallback) {
rust_callbacks()
.write()
.expect("Rust callbacks lock poisoned")
.insert(name.to_string(), callback);
}
pub fn unregister_rust_callback(name: &str) -> bool {
rust_callbacks()
.write()
.expect("Rust callbacks lock poisoned")
.remove(name)
.is_some()
}
pub fn has_rust_callback(name: &str) -> bool {
rust_callbacks()
.read()
.expect("Rust callbacks lock poisoned")
.contains_key(name)
}
pub fn invoke_rust_callback(name: &str, args: &[Value]) -> Result<Value, String> {
let callbacks = rust_callbacks()
.read()
.expect("Rust callbacks lock poisoned");
callbacks
.get(name)
.ok_or_else(|| format!("Rust callback not found: {}", name))?(args)
}
#[derive(Debug, Clone)]
pub struct JavaObjectBridge {
pub heap_ref: u32,
pub class_name: String,
}
fn java_object_bridge() -> &'static RwLock<HashMap<SharedObjectId, JavaObjectBridge>> {
static JAVA_OBJECT_BRIDGE: OnceLock<RwLock<HashMap<SharedObjectId, JavaObjectBridge>>> =
OnceLock::new();
JAVA_OBJECT_BRIDGE.get_or_init(|| RwLock::new(HashMap::new()))
}
pub fn expose_java_object(heap_ref: u32, class_name: String) -> SharedObjectId {
let id = SharedObjectId(heap_ref);
java_object_bridge()
.write()
.expect("Java object bridge lock poisoned")
.insert(
id,
JavaObjectBridge {
heap_ref,
class_name,
},
);
id
}
pub fn get_java_object(id: SharedObjectId) -> Option<JavaObjectBridge> {
java_object_bridge()
.read()
.expect("Java object bridge lock poisoned")
.get(&id)
.cloned()
}
pub fn release_java_object(id: SharedObjectId) {
java_object_bridge()
.write()
.expect("Java object bridge lock poisoned")
.remove(&id);
}