From bc32bfadede7023c4aa8fd1b0d73c76b4acca403 Mon Sep 17 00:00:00 2001 From: Nia Espera Date: Wed, 21 Jun 2023 13:15:57 +0200 Subject: [PATCH] more infallible methods, work to autodrop --- examples/sdl.rs | 6 +-- lvgl-codegen/src/lib.rs | 10 ++-- lvgl/src/display.rs | 7 ++- lvgl/src/functions.rs | 5 +- lvgl/src/lv_core/group.rs | 2 +- lvgl/src/lv_core/obj.rs | 98 +++++++++++++++++------------------- lvgl/src/lv_core/screen.rs | 20 +++++--- lvgl/src/misc/anim.rs | 2 +- lvgl/src/widgets/arc.rs | 5 +- lvgl/src/widgets/bar.rs | 11 ++-- lvgl/src/widgets/keyboard.rs | 8 ++- lvgl/src/widgets/label.rs | 11 ++-- lvgl/src/widgets/slider.rs | 11 ++-- lvgl/src/widgets/table.rs | 12 ++--- 14 files changed, 98 insertions(+), 110 deletions(-) diff --git a/examples/sdl.rs b/examples/sdl.rs index c27d58b1..1c14f1a6 100644 --- a/examples/sdl.rs +++ b/examples/sdl.rs @@ -28,11 +28,11 @@ fn main() -> LvResult<()> { let mut screen_style = Style::default(); screen_style.set_bg_color(Color::from_rgb((0, 0, 0))); - screen.add_style(Part::Main, &mut screen_style)?; + screen.add_style(Part::Main, &mut screen_style); // Create the button let mut button = Btn::create(&mut screen)?; - button.set_align(Align::LeftMid, 30, 0)?; - button.set_size(180, 80)?; + button.set_align(Align::LeftMid, 30, 0); + button.set_size(180, 80); let mut btn_lbl = Label::create(&mut button)?; btn_lbl.set_text(CString::new("Click me!").unwrap().as_c_str())?; diff --git a/lvgl-codegen/src/lib.rs b/lvgl-codegen/src/lib.rs index 75a02432..ca97a8c6 100644 --- a/lvgl-codegen/src/lib.rs +++ b/lvgl-codegen/src/lib.rs @@ -110,7 +110,7 @@ impl Rusty for LvFunc { pub fn create(parent: &mut impl crate::NativeObject) -> crate::LvResult { unsafe { let ptr = lvgl_sys::#original_func_name( - parent.raw()?.as_mut(), + parent.raw().as_mut(), ); if let Some(raw) = core::ptr::NonNull::new(ptr) { let core = ::from_raw(raw).unwrap(); @@ -196,7 +196,7 @@ impl Rusty for LvFunc { .fold(quote!(), |args, (i, arg)| { // if first arg is `const`, then it should be immutable let next_arg = if i == 0 { - quote!(self.core.raw()?.as_mut()) + quote!(self.core.raw().as_mut()) } else { let var = arg.get_value_usage(); quote!(#var) @@ -557,7 +557,7 @@ mod test { let expected_code = quote! { pub fn set_bg_end_angle(&mut self, end: u16) -> crate::LvResult<()> { unsafe { - lvgl_sys::lv_arc_set_bg_end_angle(self.core.raw()?.as_mut(), end); + lvgl_sys::lv_arc_set_bg_end_angle(self.core.raw().as_mut(), end); } Ok(()) } @@ -590,7 +590,7 @@ mod test { pub fn set_text(&mut self, text: &cstr_core::CStr) -> crate::LvResult<()> { unsafe { lvgl_sys::lv_label_set_text( - self.core.raw()?.as_mut(), + self.core.raw().as_mut(), text.as_ptr() ); } @@ -649,7 +649,7 @@ mod test { pub fn create(parent: &mut impl crate::NativeObject) -> crate::LvResult { unsafe { let ptr = lvgl_sys::lv_arc_create( - parent.raw()?.as_mut(), + parent.raw().as_mut(), ); if let Some(raw) = core::ptr::NonNull::new(ptr) { let core = ::from_raw(raw).unwrap(); diff --git a/lvgl/src/display.rs b/lvgl/src/display.rs index a574702e..61eae1c6 100644 --- a/lvgl/src/display.rs +++ b/lvgl/src/display.rs @@ -1,6 +1,6 @@ use crate::functions::CoreError; use crate::Screen; -use crate::{disp_drv_register, disp_get_default, get_str_act, LvResult, NativeObject}; +use crate::{disp_drv_register, disp_get_default, get_str_act, NativeObject}; use crate::{Box, Color}; use core::convert::TryInto; #[cfg(feature = "nightly")] @@ -77,10 +77,9 @@ impl<'a> Display { } /// Sets a `Screen` as currently active. - pub fn set_scr_act(&'a self, screen: &'a mut Screen) -> LvResult<()> { - let scr_ptr = unsafe { screen.raw()?.as_mut() }; + pub fn set_scr_act(&'a self, screen: &'a mut Screen) { + let scr_ptr = unsafe { screen.raw().as_mut() }; unsafe { lvgl_sys::lv_disp_load_scr(scr_ptr) } - Ok(()) } /// Registers a display from raw functions and values. diff --git a/lvgl/src/functions.rs b/lvgl/src/functions.rs index feb6250f..ca19e2c2 100644 --- a/lvgl/src/functions.rs +++ b/lvgl/src/functions.rs @@ -72,11 +72,10 @@ pub fn task_handler() { pub fn event_send Widget<'a>>( obj: &mut W, event: Event<>::SpecialEvent>, -) -> LvResult<()> { +) { unsafe { - lvgl_sys::lv_event_send(obj.raw()?.as_mut(), event.into(), ptr::null_mut()); + lvgl_sys::lv_event_send(obj.raw().as_mut(), event.into(), ptr::null_mut()); }; - Ok(()) } /// Register an input device driver to LVGL. diff --git a/lvgl/src/lv_core/group.rs b/lvgl/src/lv_core/group.rs index aa1d7295..53053def 100644 --- a/lvgl/src/lv_core/group.rs +++ b/lvgl/src/lv_core/group.rs @@ -27,7 +27,7 @@ impl Group { /// Adds an object to the group. pub fn add_obj(&mut self, obj: &impl NativeObject) -> LvResult<()> { - unsafe { lvgl_sys::lv_group_add_obj(self.raw()?.as_mut(), obj.raw()?.as_mut()) } + unsafe { lvgl_sys::lv_group_add_obj(self.raw()?.as_mut(), obj.raw().as_mut()) } Ok(()) } diff --git a/lvgl/src/lv_core/obj.rs b/lvgl/src/lv_core/obj.rs index 26797e87..433ca537 100644 --- a/lvgl/src/lv_core/obj.rs +++ b/lvgl/src/lv_core/obj.rs @@ -9,23 +9,24 @@ use crate::lv_core::style::Style; use crate::{Align, LvError, LvResult}; use core::fmt::{self, Debug}; use core::marker::PhantomData; -use core::ptr; +use core::ptr::{self, NonNull}; /// Represents a native LVGL object. pub trait NativeObject { /// Provide common way to access to the underlying native object pointer. - fn raw(&self) -> LvResult>; + fn raw(&self) -> NonNull; } /// Generic LVGL object. /// -/// This is the parent object of all widget types. It stores the native LVGL raw pointer. +/// This is the parent object of all widget types. It stores the native LVGL +/// raw pointer. pub struct Obj<'a> { - // We use a raw pointer here because we do not control this memory address, it is controlled - // by LVGL's global state. - raw: *mut lvgl_sys::lv_obj_t, - // This is to ensure safety for style memory; it has no runtime impact - styles_used: PhantomData<&'a lvgl_sys::lv_style_t>, + // We use a raw pointer here because we do not control this memory address, + // it is controlled by LVGL's global state. + raw: NonNull, + // This is to ensure safety for children memory; it has no runtime impact + dependents: PhantomData<&'a isize>, } impl Debug for Obj<'_> { @@ -38,15 +39,15 @@ impl Debug for Obj<'_> { // We need to manually impl methods on Obj since widget codegen is defined in // terms of Obj -impl Obj<'_> { - pub fn create(parent: &mut impl NativeObject) -> LvResult { +impl<'a> Obj<'a> { + pub fn create(parent: &'a mut impl NativeObject) -> LvResult { unsafe { - let ptr = lvgl_sys::lv_obj_create(parent.raw()?.as_mut()); - if ptr::NonNull::new(ptr).is_some() { + let ptr = lvgl_sys::lv_obj_create(parent.raw().as_mut()); + if let Some(nn_ptr) = ptr::NonNull::new(ptr) { //(*ptr).user_data = Box::new(UserDataObj::empty()).into_raw() as *mut _; Ok(Self { - raw: ptr, - styles_used: PhantomData, + raw: nn_ptr, + dependents: PhantomData::<&'a _>, }) } else { Err(LvError::InvalidReference) @@ -56,17 +57,23 @@ impl Obj<'_> { pub fn new() -> crate::LvResult { let mut parent = crate::display::get_scr_act()?; - Self::create(&mut parent) + Self::create(unsafe { &mut *(&mut parent as *mut _) }) + } + + pub fn blank() -> LvResult { + match NonNull::new(unsafe { lvgl_sys::lv_obj_create(ptr::null_mut()) }) { + Some(raw) => Ok(Self { + raw, + dependents: PhantomData, + }), + None => Err(LvError::LvOOMemory), + } } } impl NativeObject for Obj<'_> { - fn raw(&self) -> LvResult> { - if let Some(non_null_ptr) = ptr::NonNull::new(self.raw) { - Ok(non_null_ptr) - } else { - Err(LvError::InvalidReference) - } + fn raw(&self) -> ptr::NonNull { + self.raw } } @@ -85,68 +92,62 @@ pub trait Widget<'a>: NativeObject + Sized + 'a { unsafe fn from_raw(raw_pointer: ptr::NonNull) -> Option; /// Adds a `Style` to a given widget. - fn add_style(&mut self, part: Self::Part, style: &'a mut Style) -> LvResult<()> { + fn add_style(&mut self, part: Self::Part, style: &'a mut Style) { unsafe { lvgl_sys::lv_obj_add_style( - self.raw()?.as_mut(), + self.raw().as_mut(), style.raw.as_mut() as *mut _, part.into(), ); }; - Ok(()) } /// Sets a widget's position relative to its parent. - fn set_pos(&mut self, x: i16, y: i16) -> LvResult<()> { + fn set_pos(&mut self, x: i16, y: i16) { unsafe { lvgl_sys::lv_obj_set_pos( - self.raw()?.as_mut(), + self.raw().as_mut(), x as lvgl_sys::lv_coord_t, y as lvgl_sys::lv_coord_t, ); } - Ok(()) } /// Sets a widget's size. Alternatively, use `set_width()` and `set_height()`. - fn set_size(&mut self, w: i16, h: i16) -> LvResult<()> { + fn set_size(&mut self, w: i16, h: i16) { unsafe { lvgl_sys::lv_obj_set_size( - self.raw()?.as_mut(), + self.raw().as_mut(), w as lvgl_sys::lv_coord_t, h as lvgl_sys::lv_coord_t, ); } - Ok(()) } /// Sets a widget's width. Alternatively, use `set_size()`. - fn set_width(&mut self, w: u32) -> LvResult<()> { + fn set_width(&mut self, w: u32) { unsafe { - lvgl_sys::lv_obj_set_width(self.raw()?.as_mut(), w as lvgl_sys::lv_coord_t); + lvgl_sys::lv_obj_set_width(self.raw().as_mut(), w as lvgl_sys::lv_coord_t); } - Ok(()) } /// Sets a widget's height. Alternatively, use `set_size()`. - fn set_height(&mut self, h: u32) -> LvResult<()> { + fn set_height(&mut self, h: u32) { unsafe { - lvgl_sys::lv_obj_set_height(self.raw()?.as_mut(), h as lvgl_sys::lv_coord_t); + lvgl_sys::lv_obj_set_height(self.raw().as_mut(), h as lvgl_sys::lv_coord_t); } - Ok(()) } /// Sets a widget's align relative to its parent along with an offset. - fn set_align(&mut self, align: Align, x_mod: i32, y_mod: i32) -> LvResult<()> { + fn set_align(&mut self, align: Align, x_mod: i32, y_mod: i32) { unsafe { lvgl_sys::lv_obj_align( - self.raw()?.as_mut(), + self.raw().as_mut(), align.into(), x_mod as lvgl_sys::lv_coord_t, y_mod as lvgl_sys::lv_coord_t, ); } - Ok(()) } } @@ -154,23 +155,14 @@ impl<'a> Widget<'a> for Obj<'a> { type SpecialEvent = u32; type Part = Part; - unsafe fn from_raw(raw: ptr::NonNull) -> Option { + unsafe fn from_raw(raw: NonNull) -> Option { Some(Self { - raw: raw.as_ptr(), - styles_used: PhantomData, + raw, + dependents: PhantomData, }) } } -impl Default for Obj<'_> { - fn default() -> Self { - Self { - raw: unsafe { lvgl_sys::lv_obj_create(ptr::null_mut()) }, - styles_used: PhantomData, - } - } -} - macro_rules! define_object { ($item:ident) => { define_object!($item, event = (), part = $crate::Part); @@ -197,7 +189,7 @@ macro_rules! define_object { { use $crate::NativeObject; unsafe { - let obj = self.raw()?.as_mut(); + let obj = self.raw().as_mut(); obj.user_data = $crate::Box::into_raw($crate::Box::new(f)) as *mut _; lvgl_sys::lv_obj_add_event_cb( obj, @@ -213,7 +205,7 @@ macro_rules! define_object { } impl $crate::NativeObject for $item<'_> { - fn raw(&self) -> $crate::LvResult> { + fn raw(&self) -> core::ptr::NonNull { self.core.raw() } } diff --git a/lvgl/src/lv_core/screen.rs b/lvgl/src/lv_core/screen.rs index 55b2005a..f67bacfc 100644 --- a/lvgl/src/lv_core/screen.rs +++ b/lvgl/src/lv_core/screen.rs @@ -1,13 +1,19 @@ -use crate::{LvError, NativeObject, Obj, Part, Widget}; +use crate::{LvError, LvResult, NativeObject, Obj, Part, Widget}; /// An LVGL screen. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct Screen<'a> { raw: Obj<'a>, } +impl Screen<'_> { + pub fn blank() -> LvResult { + Ok(Self { raw: Obj::blank()? }) + } +} + impl NativeObject for Screen<'_> { - fn raw(&self) -> crate::LvResult> { + fn raw(&self) -> core::ptr::NonNull { self.raw.raw() } } @@ -28,7 +34,7 @@ impl<'a> TryFrom> for Screen<'a> { type Error = LvError; fn try_from(value: Obj<'a>) -> Result { - match unsafe { value.raw()?.as_mut().parent } as usize { + match unsafe { value.raw().as_mut().parent } as usize { 0 => Ok(Self { raw: value }), _ => Err(LvError::InvalidReference), } @@ -66,8 +72,8 @@ mod test { let buffer = DrawBuffer::<{ (HOR_RES * VER_RES) as usize }>::default(); let display = Display::register(buffer, HOR_RES, VER_RES, |_| {}).unwrap(); let mut screen_old = display.get_scr_act().unwrap(); - let mut screen_new = Screen::default(); - display.set_scr_act(&mut screen_new).unwrap(); - display.set_scr_act(&mut screen_old).unwrap(); + let mut screen_new = Screen::blank().unwrap(); + display.set_scr_act(&mut screen_new); + display.set_scr_act(&mut screen_old); } } diff --git a/lvgl/src/misc/anim.rs b/lvgl/src/misc/anim.rs index b8a2263a..206e9a93 100644 --- a/lvgl/src/misc/anim.rs +++ b/lvgl/src/misc/anim.rs @@ -113,7 +113,7 @@ where let anim = NonNull::new(lvgl_sys::lv_anim_get(obj, None) as *mut lvgl_sys::lv_anim_t).unwrap(); // yes, we have to do it this way. Casting `obj` directly to `&mut Obj` segfaults - let obj = (*(obj as *mut T)).raw().unwrap(); + let obj = (*(obj as *mut T)).raw(); if !anim.as_ref().user_data.is_null() { let callback = &mut *(obj.as_ref().user_data as *mut F); let mut obj_nondrop = Obj::from_raw(obj).unwrap(); diff --git a/lvgl/src/widgets/arc.rs b/lvgl/src/widgets/arc.rs index 17bcdb6a..5fd94a0c 100644 --- a/lvgl/src/widgets/arc.rs +++ b/lvgl/src/widgets/arc.rs @@ -1,6 +1,5 @@ use crate::lv_core::obj::NativeObject; use crate::widgets::Arc; -use crate::LvResult; impl Arc<'_> { // /// Set the start angle, for the given arc part. @@ -40,8 +39,8 @@ impl Arc<'_> { // } /// Gets the current value of the arc - pub fn get_value(&self) -> LvResult { - unsafe { Ok(lvgl_sys::lv_bar_get_value(self.core.raw()?.as_ptr())) } + pub fn get_value(&self) -> i32 { + unsafe { lvgl_sys::lv_bar_get_value(self.core.raw().as_ptr()) } } } /* diff --git a/lvgl/src/widgets/bar.rs b/lvgl/src/widgets/bar.rs index c6aaeb87..4a50d6b1 100644 --- a/lvgl/src/widgets/bar.rs +++ b/lvgl/src/widgets/bar.rs @@ -1,6 +1,6 @@ use crate::support::AnimationState; use crate::widgets::Bar; -use crate::{LvResult, NativeObject}; +use crate::NativeObject; impl Bar<'_> { /// Set minimum and the maximum values of the bar @@ -12,16 +12,15 @@ impl Bar<'_> { //} /// Set a new value on the bar - pub fn set_value(&mut self, value: i32, anim: AnimationState) -> LvResult<()> { + pub fn set_value(&mut self, value: i32, anim: AnimationState) { unsafe { - lvgl_sys::lv_bar_set_value(self.core.raw()?.as_mut(), value, anim.into()); + lvgl_sys::lv_bar_set_value(self.core.raw().as_mut(), value, anim.into()); } - Ok(()) } /// Gets the current value of the bar - pub fn get_value(&self) -> LvResult { - unsafe { Ok(lvgl_sys::lv_bar_get_value(self.core.raw()?.as_ptr())) } + pub fn get_value(&self) -> i32 { + unsafe { lvgl_sys::lv_bar_get_value(self.core.raw().as_ptr()) } } } /* diff --git a/lvgl/src/widgets/keyboard.rs b/lvgl/src/widgets/keyboard.rs index da1f5669..ebdaf050 100644 --- a/lvgl/src/widgets/keyboard.rs +++ b/lvgl/src/widgets/keyboard.rs @@ -1,16 +1,14 @@ use crate::widgets::{Keyboard, Textarea}; -use crate::LvResult; use crate::NativeObject; impl Keyboard<'_> { /// Associates a given `Textarea` to the keyboard. - pub fn set_textarea(&mut self, textarea: &mut Textarea) -> LvResult<()> { + pub fn set_textarea(&mut self, textarea: &mut Textarea) { unsafe { lvgl_sys::lv_keyboard_set_textarea( - self.raw()?.as_mut() as *mut lvgl_sys::lv_obj_t, - textarea.raw()?.as_mut() as *mut lvgl_sys::lv_obj_t, + self.raw().as_mut() as *mut lvgl_sys::lv_obj_t, + textarea.raw().as_mut() as *mut lvgl_sys::lv_obj_t, ) } - Ok(()) } } diff --git a/lvgl/src/widgets/label.rs b/lvgl/src/widgets/label.rs index 1ff3363e..691ffb8d 100644 --- a/lvgl/src/widgets/label.rs +++ b/lvgl/src/widgets/label.rs @@ -1,5 +1,5 @@ use crate::widgets::Label; -use crate::{LabelLongMode, LvResult, NativeObject}; +use crate::{LabelLongMode, NativeObject}; #[cfg(feature = "alloc")] mod alloc_imp { @@ -32,14 +32,13 @@ mod alloc_imp { } impl Label<'_> { - pub fn set_long_mode(&mut self, long_mode: LabelLongMode) -> LvResult<()> { + pub fn set_long_mode(&mut self, long_mode: LabelLongMode) { unsafe { - lvgl_sys::lv_label_set_long_mode(self.raw()?.as_mut(), long_mode.into()); - Ok(()) + lvgl_sys::lv_label_set_long_mode(self.raw().as_mut(), long_mode.into()); } } - pub fn get_long_mode(&self) -> LvResult { - unsafe { Ok(lvgl_sys::lv_label_get_long_mode(self.raw()?.as_ref())) } + pub fn get_long_mode(&self) -> u8 { + unsafe { lvgl_sys::lv_label_get_long_mode(self.raw().as_ref()) } } } diff --git a/lvgl/src/widgets/slider.rs b/lvgl/src/widgets/slider.rs index bb8d0dda..f2d69519 100644 --- a/lvgl/src/widgets/slider.rs +++ b/lvgl/src/widgets/slider.rs @@ -1,16 +1,15 @@ use crate::lv_core::obj::NativeObject; use crate::widgets::Slider; -use crate::{AnimationState, LvResult}; +use crate::AnimationState; impl Slider<'_> { /// Set a new value on the slider - pub fn set_value(&self, value: i32, anim: AnimationState) -> LvResult<()> { - unsafe { lvgl_sys::lv_bar_set_value(self.core.raw()?.as_ptr(), value, anim.into()) } - Ok(()) + pub fn set_value(&self, value: i32, anim: AnimationState) { + unsafe { lvgl_sys::lv_bar_set_value(self.core.raw().as_ptr(), value, anim.into()) } } /// Gets the current value of the slider - pub fn get_value(&self) -> LvResult { - unsafe { Ok(lvgl_sys::lv_bar_get_value(self.core.raw()?.as_ptr())) } + pub fn get_value(&self) -> i32 { + unsafe { lvgl_sys::lv_bar_get_value(self.core.raw().as_ptr()) } } } diff --git a/lvgl/src/widgets/table.rs b/lvgl/src/widgets/table.rs index 28947888..cda81588 100644 --- a/lvgl/src/widgets/table.rs +++ b/lvgl/src/widgets/table.rs @@ -1,28 +1,26 @@ use crate::lv_core::obj::NativeObject; use crate::widgets::Table; -use crate::LvResult; use core::mem::MaybeUninit; impl Table<'_> { /// Sets the column width. Row height cannot be set manually and is /// calculated by LVGL based on styling parameters. - pub fn set_col_width(&mut self, column: u16, width: i16) -> LvResult<()> { - unsafe { lvgl_sys::lv_table_set_col_width(self.core.raw()?.as_ptr(), column, width) } - Ok(()) + pub fn set_col_width(&mut self, column: u16, width: i16) { + unsafe { lvgl_sys::lv_table_set_col_width(self.core.raw().as_ptr(), column, width) } } /// Returns the selected cell as a tuple of (row, column). - pub fn get_selected_cell(&self) -> LvResult<(u16, u16)> { + pub fn get_selected_cell(&self) -> (u16, u16) { let mut row = MaybeUninit::::uninit(); let mut col = MaybeUninit::::uninit(); unsafe { lvgl_sys::lv_table_get_selected_cell( - self.core.raw()?.as_ptr(), + self.core.raw().as_ptr(), row.as_mut_ptr(), col.as_mut_ptr(), ); // The values get initialised by LVGL - Ok((row.assume_init(), col.assume_init())) + (row.assume_init(), col.assume_init()) } } }