ohos-arkui-binding 0.2.0

OpenHarmony's arkui binding for rust
Documentation
//! Module animate::context::update wrappers and related types.

use std::{cell::RefCell, os::raw::c_void};

use ohos_arkui_sys::ArkUI_ContextCallback;

struct UpdateCallbackContext {
    callback: Option<Box<dyn Fn()>>,
}

/// Callback context used for animation update execution.
pub struct AnimationUpdateContext {
    callback_context: Box<RefCell<UpdateCallbackContext>>,
    raw: RefCell<ArkUI_ContextCallback>,
}

impl Default for AnimationUpdateContext {
    fn default() -> Self {
        let callback_context = Box::new(RefCell::new(UpdateCallbackContext { callback: None }));
        let user_data =
            callback_context.as_ref() as *const RefCell<UpdateCallbackContext> as *mut c_void;
        let raw = RefCell::new(ArkUI_ContextCallback {
            callback: Some(update_callback_trampoline),
            userData: user_data,
        });
        Self {
            callback_context,
            raw,
        }
    }
}

impl AnimationUpdateContext {
    pub(crate) fn raw(&self) -> *mut ArkUI_ContextCallback {
        self.raw.as_ptr()
    }

    /// Registers update callback closure.
    pub fn callback<T: Fn() + 'static>(&self, callback: T) {
        self.callback_context.borrow_mut().callback = Some(Box::new(callback));
    }

    /// Clears previously registered update callback.
    pub fn clear_callback(&self) {
        self.callback_context.borrow_mut().callback = None;
    }
}

unsafe extern "C" fn update_callback_trampoline(user_data: *mut c_void) {
    if user_data.is_null() {
        return;
    }
    let context = unsafe { &*(user_data as *const RefCell<UpdateCallbackContext>) };
    if let Some(callback) = context.borrow().callback.as_ref() {
        callback();
    }
}