Skip to content

Commit

Permalink
fix: animation crash
Browse files Browse the repository at this point in the history
  • Loading branch information
richerfu committed Nov 29, 2024
1 parent 6382f5c commit e1d54d5
Show file tree
Hide file tree
Showing 18 changed files with 219 additions and 90 deletions.
25 changes: 9 additions & 16 deletions crates/arkui/src/animate/animate_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,8 @@ impl Animation {
let ret = unsafe { OH_ArkUI_AnimateOption_Create() };
Animation {
raw: Rc::new(RefCell::new(ret)),
update_ctx: Rc::new(RefCell::new(AnimationUpdateContext {
callback: Rc::new(RefCell::new(None)),
data: Rc::new(RefCell::new(None)),
})),
finish_ctx: Rc::new(RefCell::new(AnimationFinishContext {
callback: Rc::new(RefCell::new(None)),
data: Rc::new(RefCell::new(None)),
callback_type: Rc::new(RefCell::new(AnimationFinishCallbackType::Removed)),
})),
update_ctx: Default::default(),
finish_ctx: Default::default(),
}
}

Expand Down Expand Up @@ -75,9 +68,9 @@ impl Animation {
}

pub fn update<T: Fn(*mut c_void) -> () + 'static>(&self, data: *mut c_void, callback: T) {
let mut ctx = self.update_ctx.borrow_mut();
ctx.data = Rc::new(RefCell::new(Some(data)));
ctx.callback = Rc::new(RefCell::new(Some(Box::new(callback))));
let ctx = self.update_ctx.borrow_mut();
ctx.data(data);
ctx.callback(callback);
}

pub fn finish<T: Fn(*mut c_void) -> () + 'static>(
Expand All @@ -86,10 +79,10 @@ impl Animation {
data: *mut c_void,
callback: T,
) {
let mut ctx = self.finish_ctx.borrow_mut();
ctx.data = Rc::new(RefCell::new(Some(data)));
ctx.callback = Rc::new(RefCell::new(Some(Box::new(callback))));
ctx.callback_type = Rc::new(RefCell::new(callback_type));
let ctx = self.finish_ctx.borrow_mut();
ctx.data(data);
ctx.callback(callback);
ctx.callback_type(callback_type);
}

#[cfg(feature = "napi")]
Expand Down
65 changes: 48 additions & 17 deletions crates/arkui/src/animate/finish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,78 @@ use ohos_arkui_sys::ArkUI_AnimateCompleteCallback;

use crate::AnimationFinishCallbackType;

pub struct AnimationFinishContext {
struct CallbackContext {
pub(crate) callback: Rc<RefCell<Option<Box<dyn Fn(*mut c_void) -> ()>>>>,
pub(crate) data: Rc<RefCell<Option<*mut c_void>>>,
pub(crate) callback_type: Rc<RefCell<AnimationFinishCallbackType>>,
}

pub struct AnimationFinishContext {
inner: Rc<RefCell<CallbackContext>>,
}

impl AnimationFinishContext {
pub fn callback<T: Fn(*mut c_void) + 'static>(&self, callback: T) {
let inner = self.inner.borrow();
let mut cb = inner.callback.borrow_mut();
*cb = Some(Box::new(callback));
}
pub fn data(&self, data: *mut c_void) {
let inner = self.inner.borrow();
let mut d = inner.data.borrow_mut();
*d = Some(data);
}

pub fn callback_type(&self, callback_type: AnimationFinishCallbackType) {
let inner = self.inner.borrow();
let mut t = inner.callback_type.borrow_mut();
*t = callback_type;
}
}

impl Default for AnimationFinishContext {
fn default() -> Self {
AnimationFinishContext {
callback: Rc::new(RefCell::new(None)),
data: Rc::new(RefCell::new(None)),
callback_type: Rc::new(RefCell::new(AnimationFinishCallbackType::Removed)),
inner: Rc::new(RefCell::new(CallbackContext {
callback: Rc::new(RefCell::new(None)),
data: Rc::new(RefCell::new(None)),
callback_type: Rc::new(RefCell::new(AnimationFinishCallbackType::Logically)),
})),
}
}
}

impl AnimationFinishContext {
pub fn raw(&self) -> *mut ArkUI_AnimateCompleteCallback {
let t = self.callback_type.borrow();
let inner_raw = self.inner.borrow();
let t = inner_raw.callback_type.borrow();
let inner = self.inner.clone();

let ctx = Box::new(ArkUI_AnimateCompleteCallback {
callback: Some(finish),
userData: self as *const AnimationFinishContext as *mut AnimationFinishContext
as *mut c_void,
userData: Box::into_raw(Box::new(inner)) as *mut c_void,
type_: (*t).into(),
});

Box::into_raw(ctx)
}
}

pub unsafe extern "C" fn finish(data: *mut c_void) {
if !data.is_null() {
let context = &*(data as *const AnimationFinishContext);

let ctx_callback = context.callback.borrow_mut();
let user_data = context.data.borrow_mut();
unsafe extern "C" fn finish(data: *mut c_void) {
if data.is_null() {
return;
}
let context_ptr = Box::from_raw(data as *mut Rc<RefCell<Option<CallbackContext>>>);
let context = context_ptr.borrow();

if let Some(callback) = &*ctx_callback {
if let Some(d) = *user_data {
callback(d);
if let Some(ctx) = context.as_ref() {
let cb = ctx.callback.borrow();
if let Some(f) = cb.as_ref() {
let d = ctx.data.borrow();
if let Some(data) = *d {
f(data);
} else {
callback(std::ptr::null_mut())
f(std::ptr::null_mut());
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/arkui/src/animate/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
mod animate_option;
mod finish;
mod frame_rate_range;
mod update;
mod finish;

pub use animate_option::*;
pub use finish::*;
pub use frame_rate_range::*;
pub use update::*;
pub use finish::*;
47 changes: 37 additions & 10 deletions crates/arkui/src/animate/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,26 @@ use std::{cell::RefCell, os::raw::c_void, rc::Rc};

use ohos_arkui_sys::ArkUI_ContextCallback;

pub struct AnimationUpdateContext {
struct CallbackContext {
pub(crate) callback: Rc<RefCell<Option<Box<dyn Fn(*mut c_void) -> ()>>>>,
pub(crate) data: Rc<RefCell<Option<*mut c_void>>>,
}

pub struct AnimationUpdateContext {
inner: Rc<RefCell<CallbackContext>>,
}

impl Default for AnimationUpdateContext {
fn default() -> Self {
AnimationUpdateContext {
inner: Rc::new(RefCell::new(CallbackContext {
callback: Rc::new(RefCell::new(None)),
data: Rc::new(RefCell::new(None)),
})),
}
}
}

impl AnimationUpdateContext {
pub fn raw(&self) -> *mut ArkUI_ContextCallback {
let ctx = Box::new(ArkUI_ContextCallback {
Expand All @@ -16,20 +31,32 @@ impl AnimationUpdateContext {
});
Box::into_raw(ctx)
}

pub fn callback<T: Fn(*mut c_void) + 'static>(&self, callback: T) {
let inner = self.inner.borrow();
let mut cb = inner.callback.borrow_mut();
*cb = Some(Box::new(callback));
}

pub fn data(&self, data: *mut c_void) {
let inner = self.inner.borrow();
let mut d = inner.data.borrow_mut();
*d = Some(data);
}
}

pub unsafe extern "C" fn update(data: *mut c_void) {
if !data.is_null() {
let context = &*(data as *const AnimationUpdateContext);

let ctx_callback = context.callback.borrow_mut();
let user_data = context.data.borrow_mut();
let context_ptr = Box::from_raw(data as *mut Rc<RefCell<Option<CallbackContext>>>);
let context = context_ptr.borrow();

if let Some(callback) = &*ctx_callback {
if let Some(d) = *user_data {
callback(d);
if let Some(ctx) = context.as_ref() {
let cb = ctx.callback.borrow();
if let Some(f) = cb.as_ref() {
let d = ctx.data.borrow();
if let Some(data) = *d {
f(data);
} else {
callback(std::ptr::null_mut())
f(std::ptr::null_mut());
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/arkui/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
mod animate;
mod dialog;
mod gesture;
mod node;
mod animate;

pub use animate::*;
pub use dialog::*;
pub use gesture::*;
pub use node::*;
pub use animate::*;
10 changes: 5 additions & 5 deletions crates/arkui/src/component/attribute/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub trait ArkUIAttributeBasic {
/// Every node should implement this trait, include the custom node.
pub trait ArkUICommonAttribute: ArkUIAttributeBasic {
/// Set node height
fn set_width(&self, width: f32) -> ArkUIResult<()> {
fn width(&self, width: f32) -> ArkUIResult<()> {
let width_property: ArkUINodeAttributeItem =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Float(width)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
Expand All @@ -28,7 +28,7 @@ pub trait ArkUICommonAttribute: ArkUIAttributeBasic {
}

/// Set node height
fn set_height(&self, height: f32) -> ArkUIResult<()> {
fn height(&self, height: f32) -> ArkUIResult<()> {
let height_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Float(height)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
Expand All @@ -40,7 +40,7 @@ pub trait ArkUICommonAttribute: ArkUIAttributeBasic {
}

/// Set percent width
fn set_percent_width(&self, width: f32) -> ArkUIResult<()> {
fn percent_width(&self, width: f32) -> ArkUIResult<()> {
let percent_width_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Float(width)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
Expand All @@ -52,7 +52,7 @@ pub trait ArkUICommonAttribute: ArkUIAttributeBasic {
}

/// Set percent height
fn set_percent_height(&self, height: f32) -> ArkUIResult<()> {
fn percent_height(&self, height: f32) -> ArkUIResult<()> {
let percent_height_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Float(height)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
Expand All @@ -64,7 +64,7 @@ pub trait ArkUICommonAttribute: ArkUIAttributeBasic {
}

/// Set background-color
fn set_background_color(&self, color: u32) -> ArkUIResult<()> {
fn background_color(&self, color: u32) -> ArkUIResult<()> {
let background_color_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Uint(color)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
Expand Down
4 changes: 2 additions & 2 deletions crates/arkui/src/component/attribute/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use super::ArkUIAttributeBasic;

pub trait ArkUICommonFontAttribute: ArkUIAttributeBasic {
fn set_font_size(&self, font_size: f32) -> ArkUIResult<()> {
fn font_size(&self, font_size: f32) -> ArkUIResult<()> {
let font_size_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Float(font_size)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
Expand All @@ -16,7 +16,7 @@ pub trait ArkUICommonFontAttribute: ArkUIAttributeBasic {
Ok(())
}

fn set_font_color(&self, font_color: u32) -> ArkUIResult<()> {
fn font_color(&self, font_color: u32) -> ArkUIResult<()> {
let font_color_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Uint(font_color)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
Expand Down
2 changes: 1 addition & 1 deletion crates/arkui/src/component/built_in_component/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl List {
}))
}

pub fn set_scroll_bar_state(&mut self, mode: ScrollBarDisplayMode) -> ArkUIResult<()> {
pub fn scroll_bar_state(&mut self, mode: ScrollBarDisplayMode) -> ArkUIResult<()> {
let scroll_bar_display_mode_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Int(mode.into())]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
Expand Down
2 changes: 2 additions & 0 deletions crates/arkui/src/component/built_in_component/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod list;
mod list_item;
mod text;
mod text_input;
mod xcomponent;

pub use list::*;
pub use list_item::*;
pub use text::*;
pub use text_input::*;
pub use xcomponent::*;
4 changes: 2 additions & 2 deletions crates/arkui/src/component/built_in_component/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Text {
}))
}

pub fn set_content<T: Into<String>>(&self, content: T) -> ArkUIResult<()> {
pub fn content<T: Into<String>>(&self, content: T) -> ArkUIResult<()> {
let content_property = ArkUINodeAttributeItem::String(content.into());
ARK_UI_NATIVE_NODE_API_1.set_attribute(
&self.0,
Expand All @@ -28,7 +28,7 @@ impl Text {
Ok(())
}

pub fn set_alignment(&self, alignment: TextAlignment) -> ArkUIResult<()> {
pub fn alignment(&self, alignment: TextAlignment) -> ArkUIResult<()> {
let alignment_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Int(
alignment.into(),
Expand Down
38 changes: 38 additions & 0 deletions crates/arkui/src/component/built_in_component/text_input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::{
ArkUIAttributeBasic, ArkUICommonAttribute, ArkUIEvent, ArkUIGesture, ArkUINode, ArkUINodeType,
ArkUIResult, ARK_UI_NATIVE_NODE_API_1,
};

#[derive(Clone)]
pub struct TextInput(ArkUINode);

impl TextInput {
pub fn new() -> ArkUIResult<Self> {
let list_item = ARK_UI_NATIVE_NODE_API_1.create_node(ArkUINodeType::TextInput)?;
Ok(Self(ArkUINode {
raw: list_item,
tag: ArkUINodeType::TextInput,
..Default::default()
}))
}
}

impl From<TextInput> for ArkUINode {
fn from(list_item: TextInput) -> Self {
list_item.0
}
}

impl ArkUIAttributeBasic for TextInput {
fn raw(&self) -> &ArkUINode {
&self.0
}

fn borrow_mut(&mut self) -> &mut ArkUINode {
&mut self.0
}
}

impl ArkUICommonAttribute for TextInput {}
impl ArkUIEvent for TextInput {}
impl ArkUIGesture for TextInput {}
Loading

0 comments on commit e1d54d5

Please sign in to comment.