use crate::WebViewError;
use napi_ohos::Status;
use napi_ohos::bindgen_prelude::Function;
use napi_ohos::threadsafe_function::{ThreadsafeCallContext, ThreadsafeFunctionCallMode};
use std::sync::OnceLock;
type TsfnType = napi_ohos::threadsafe_function::ThreadsafeFunction<
String,
napi_ohos::Unknown<'static>,
String,
napi_ohos::Status,
false,
false,
200,
>;
static CALLBACK_TSFN: OnceLock<TsfnType> = OnceLock::new();
pub fn init(callback_function: Function<'static>) -> Result<(), String> {
let tsfn = callback_function
.build_threadsafe_function::<String>()
.callee_handled::<false>()
.max_queue_size::<200>()
.build_callback(|ctx: ThreadsafeCallContext<String>| {
let data = ctx.value;
log::info!("ThreadSafe callback called with data: {}", data);
Ok(data)
});
let tsfn = match tsfn {
Ok(tsfn) => {
log::info!("ThreadSafe Function created successfully");
tsfn
}
Err(e) => {
log::error!("Failed to create threadsafe function: {:?}", e);
return Err(format!("Failed to create threadsafe function: {:?}", e));
}
};
if CALLBACK_TSFN.set(tsfn).is_err() {
log::error!("ThreadSafe Function already set");
return Err("ThreadSafe Function already set".to_string());
}
Ok(())
}
pub fn call_arkts(name: &str, args: &[&str]) -> Result<(), WebViewError> {
let tsfn = CALLBACK_TSFN.get().ok_or_else(|| {
log::error!("TSFN not initialized");
WebViewError::WebView("No callback".to_string())
})?;
let data = format!("{}|{}", name, args.join("|"));
match tsfn.call(data, ThreadsafeFunctionCallMode::NonBlocking) {
Status::Ok => Ok(()),
status => {
log::error!("TSFN call failed for {}: {:?}", name, status);
Err(WebViewError::WebView("TSFN call failed".to_string()))
}
}
}