use std::os::raw::c_char;
use std::{cell::RefCell, mem::MaybeUninit, os::raw::c_coid, ptr::null_mut, sync::Once};
use crate::xcomponent::{OH_NativeXComponent, OH_NATIVE_XCOMPONENT_OBJ};
use create::napi::*;
#[derive(Default)]
pub struct Scheduler {
callback: RefCell<Vec<Box<dyn FnMut(*mut OH_NativeXComponent)>>>,
}
impl Scheduler {
fn instance() -> &'static Self {
static mut INSTANCE: MaybeUninit<Scheduler> = MaybeUninit::uninit();
static ONCE: Once = Once::new();
unsafe {
ONCE.call_once(|| {
INSTANCE.write(Scheduler::default());
});
INSTANCE.assume_init_ref()
}
}
pub fn scheduler(callback: impl FnMut(*mut OH_NativeXComponent) + 'static) {
Self::instance()
.callback
.borrow_mut()
.push(Box::new(callback));
}
fn execute(component: *mut OH_NativeXComponent) {
for mut c in Self::instance().callback.borrow_mut().drain(..) {
(*c)(component);
}
}
}
unsafe extern "C" fn execute(env: napi_env, info: napi_callback_info) -> napi_value {
if env == null_mut() || info == null_mut() {
return null_mut();
}
let mut this: napi_value = null_mut();
if napi_get_cb_info(env, info, null_mut(), null_mut(), &mut this, null_mut())
!= napi_status::napi_ok
{
return null_mut();
}
let mut instance: napi_value = null_mut();
if napi_get_named_property(
env,
this,
OH_NATIVE_XCOMPONENT_OBJ.as_ptr() as *const c_char,
&mut instance,
) != napi_status::napi_ok
{
return null_mut();
}
let mut component: *mut c_void = null_mut();
if napi_unwrap(env, instance, &mut component) != napi_status::napi_ok {
return null_mut();
}
let component = component as *mut OH_NativeXComponent;
Scheduler::execute(component);
null_mut()
}
pub fn export_execute(env: napi_env, exports: napi_value) {
if env == null_mut() || exports == null_mut() {
return;
}
const NAME: &[u8; 8] = b"execute\0";
let desc = [napi_property_descriptor {
utf8name: NAME.as_ptr() as *const c_char,
name: null_mut(),
method: Some(execute),
getter: None,
setter: None,
value: null_mut(),
attributes: napi_property_attributes::napi_default,
data: null_mut(),
}];
unsafe {
if napi_define_properties(env, exports, 1, desc.as_ptr()) != napi_status::napi_ok {
panic!("Failed to export execute\n");
}
}
}