use pyo3::prelude::*; use std::collections::HashMap; use std::ffi::CString; use std::sync::{Arc, LazyLock, RwLock}; pub struct PythonManager { functions: Arc>>, } static INSTANCE: LazyLock = LazyLock::new(PythonManager::new); impl PythonManager { pub fn new() -> Self { Self { functions: Arc::new(RwLock::new(HashMap::new())), } } pub fn instance() -> &'static Self { &INSTANCE } fn register_fn(&self, key: &str, function: PyObject) -> PyResult<()> { let mut functions = self.functions.write().unwrap(); functions.insert(key.to_string(), function); Ok(()) } fn unregister_fn(&self, key: &str) -> PyResult<()> { let mut functions = self.functions.write().unwrap(); functions.remove(key); Ok(()) } pub fn call_fn(&self, key: &str, arg: Option) -> PyResult { let functions = self.functions.read().unwrap(); if let Some(function) = functions.get(key) { Python::with_gil(|py| match arg { None => function.call0(py), Some(arg) => function.call1(py, (arg,)), }) } else { Err(pyo3::exceptions::PyKeyError::new_err(format!( "未找到函数: {}", key ))) } } pub fn log(&self, text: String) { let _ = self.eval(&format!("print('{}')", text)); } pub fn eval(&self, script: &str) -> PyResult<()> { Python::with_gil(|py| { let c_script = CString::new(script)?; py.run(&c_script, None, None)?; Ok(()) }) } } #[pyfunction] fn register_fn(key: &str, function: PyObject) -> PyResult<()> { PythonManager::instance().register_fn(key, function) } #[pyfunction] fn unregister_fn(key: &str) -> PyResult<()> { PythonManager::instance().unregister_fn(key) } pub fn init_module(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(register_fn, m)?)?; m.add_function(wrap_pyfunction!(unregister_fn, m)?)?; Ok(()) }