Skip to content

Commit a18027c

Browse files
authored
Merge pull request #143 from lvgl/infallible-raw
`<T as NativeObject>::raw()` infallible, `Obj` store `NonNull` pointers
2 parents b9763a4 + 0f44d76 commit a18027c

File tree

14 files changed

+101
-110
lines changed

14 files changed

+101
-110
lines changed

examples/sdl.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ fn main() -> LvResult<()> {
2828

2929
let mut screen_style = Style::default();
3030
screen_style.set_bg_color(Color::from_rgb((0, 0, 0)));
31-
screen.add_style(Part::Main, &mut screen_style)?;
31+
screen.add_style(Part::Main, &mut screen_style);
3232
// Create the button
3333
let mut button = Btn::create(&mut screen)?;
34-
button.set_align(Align::LeftMid, 30, 0)?;
35-
button.set_size(180, 80)?;
34+
button.set_align(Align::LeftMid, 30, 0);
35+
button.set_size(180, 80);
3636
let mut btn_lbl = Label::create(&mut button)?;
3737
btn_lbl.set_text(CString::new("Click me!").unwrap().as_c_str())?;
3838

lvgl-codegen/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl Rusty for LvFunc {
110110
pub fn create(parent: &mut impl crate::NativeObject) -> crate::LvResult<Self> {
111111
unsafe {
112112
let ptr = lvgl_sys::#original_func_name(
113-
parent.raw()?.as_mut(),
113+
parent.raw().as_mut(),
114114
);
115115
if let Some(raw) = core::ptr::NonNull::new(ptr) {
116116
let core = <crate::Obj as crate::Widget>::from_raw(raw).unwrap();
@@ -196,7 +196,7 @@ impl Rusty for LvFunc {
196196
.fold(quote!(), |args, (i, arg)| {
197197
// if first arg is `const`, then it should be immutable
198198
let next_arg = if i == 0 {
199-
quote!(self.core.raw()?.as_mut())
199+
quote!(self.core.raw().as_mut())
200200
} else {
201201
let var = arg.get_value_usage();
202202
quote!(#var)
@@ -557,7 +557,7 @@ mod test {
557557
let expected_code = quote! {
558558
pub fn set_bg_end_angle(&mut self, end: u16) -> crate::LvResult<()> {
559559
unsafe {
560-
lvgl_sys::lv_arc_set_bg_end_angle(self.core.raw()?.as_mut(), end);
560+
lvgl_sys::lv_arc_set_bg_end_angle(self.core.raw().as_mut(), end);
561561
}
562562
Ok(())
563563
}
@@ -590,7 +590,7 @@ mod test {
590590
pub fn set_text(&mut self, text: &cstr_core::CStr) -> crate::LvResult<()> {
591591
unsafe {
592592
lvgl_sys::lv_label_set_text(
593-
self.core.raw()?.as_mut(),
593+
self.core.raw().as_mut(),
594594
text.as_ptr()
595595
);
596596
}
@@ -649,7 +649,7 @@ mod test {
649649
pub fn create(parent: &mut impl crate::NativeObject) -> crate::LvResult<Self> {
650650
unsafe {
651651
let ptr = lvgl_sys::lv_arc_create(
652-
parent.raw()?.as_mut(),
652+
parent.raw().as_mut(),
653653
);
654654
if let Some(raw) = core::ptr::NonNull::new(ptr) {
655655
let core = <crate::Obj as crate::Widget>::from_raw(raw).unwrap();

lvgl/src/display.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::functions::CoreError;
22
use crate::Screen;
3-
use crate::{disp_drv_register, disp_get_default, get_str_act, LvResult, NativeObject};
3+
use crate::{disp_drv_register, disp_get_default, get_str_act, NativeObject};
44
use crate::{Box, Color};
55
use core::convert::TryInto;
66
#[cfg(feature = "nightly")]
@@ -77,10 +77,9 @@ impl<'a> Display {
7777
}
7878

7979
/// Sets a `Screen` as currently active.
80-
pub fn set_scr_act(&'a self, screen: &'a mut Screen) -> LvResult<()> {
81-
let scr_ptr = unsafe { screen.raw()?.as_mut() };
80+
pub fn set_scr_act(&'a self, screen: &'a mut Screen) {
81+
let scr_ptr = unsafe { screen.raw().as_mut() };
8282
unsafe { lvgl_sys::lv_disp_load_scr(scr_ptr) }
83-
Ok(())
8483
}
8584

8685
/// Registers a display from raw functions and values.
@@ -89,6 +88,7 @@ impl<'a> Display {
8988
///
9089
/// `hor_res` and `ver_res` must be nonzero, and the provided functions
9190
/// must not themselves cause undefined behavior.
91+
#[allow(clippy::too_many_arguments)]
9292
pub unsafe fn register_raw<const N: usize>(
9393
draw_buffer: DrawBuffer<N>,
9494
hor_res: u32,
@@ -230,6 +230,7 @@ impl<'a, const N: usize> DisplayDriver<N> {
230230
}))
231231
}
232232

233+
#[allow(clippy::too_many_arguments)]
233234
pub unsafe fn new_raw(
234235
mut draw_buffer: DrawBuffer<N>,
235236
flush_cb: Option<

lvgl/src/functions.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,10 @@ pub fn task_handler() {
7272
pub fn event_send<W: for<'a> Widget<'a>>(
7373
obj: &mut W,
7474
event: Event<<W as Widget<'_>>::SpecialEvent>,
75-
) -> LvResult<()> {
75+
) {
7676
unsafe {
77-
lvgl_sys::lv_event_send(obj.raw()?.as_mut(), event.into(), ptr::null_mut());
77+
lvgl_sys::lv_event_send(obj.raw().as_mut(), event.into(), ptr::null_mut());
7878
};
79-
Ok(())
8079
}
8180

8281
/// Register an input device driver to LVGL.

lvgl/src/lv_core/group.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl Group {
2727

2828
/// Adds an object to the group.
2929
pub fn add_obj(&mut self, obj: &impl NativeObject) -> LvResult<()> {
30-
unsafe { lvgl_sys::lv_group_add_obj(self.raw()?.as_mut(), obj.raw()?.as_mut()) }
30+
unsafe { lvgl_sys::lv_group_add_obj(self.raw()?.as_mut(), obj.raw().as_mut()) }
3131
Ok(())
3232
}
3333

lvgl/src/lv_core/obj.rs

+45-53
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,24 @@ use crate::lv_core::style::Style;
99
use crate::{Align, LvError, LvResult};
1010
use core::fmt::{self, Debug};
1111
use core::marker::PhantomData;
12-
use core::ptr;
12+
use core::ptr::{self, NonNull};
1313

1414
/// Represents a native LVGL object.
1515
pub trait NativeObject {
1616
/// Provide common way to access to the underlying native object pointer.
17-
fn raw(&self) -> LvResult<ptr::NonNull<lvgl_sys::lv_obj_t>>;
17+
fn raw(&self) -> NonNull<lvgl_sys::lv_obj_t>;
1818
}
1919

2020
/// Generic LVGL object.
2121
///
22-
/// This is the parent object of all widget types. It stores the native LVGL raw pointer.
22+
/// This is the parent object of all widget types. It stores the native LVGL
23+
/// raw pointer.
2324
pub struct Obj<'a> {
24-
// We use a raw pointer here because we do not control this memory address, it is controlled
25-
// by LVGL's global state.
26-
raw: *mut lvgl_sys::lv_obj_t,
27-
// This is to ensure safety for style memory; it has no runtime impact
28-
styles_used: PhantomData<&'a lvgl_sys::lv_style_t>,
25+
// We use a raw pointer here because we do not control this memory address,
26+
// it is controlled by LVGL's global state.
27+
raw: NonNull<lvgl_sys::lv_obj_t>,
28+
// This is to ensure safety for children memory; it has no runtime impact
29+
dependents: PhantomData<&'a isize>,
2930
}
3031

3132
impl Debug for Obj<'_> {
@@ -38,15 +39,15 @@ impl Debug for Obj<'_> {
3839

3940
// We need to manually impl methods on Obj since widget codegen is defined in
4041
// terms of Obj
41-
impl Obj<'_> {
42-
pub fn create(parent: &mut impl NativeObject) -> LvResult<Self> {
42+
impl<'a> Obj<'a> {
43+
pub fn create(parent: &'a mut impl NativeObject) -> LvResult<Self> {
4344
unsafe {
44-
let ptr = lvgl_sys::lv_obj_create(parent.raw()?.as_mut());
45-
if ptr::NonNull::new(ptr).is_some() {
45+
let ptr = lvgl_sys::lv_obj_create(parent.raw().as_mut());
46+
if let Some(nn_ptr) = ptr::NonNull::new(ptr) {
4647
//(*ptr).user_data = Box::new(UserDataObj::empty()).into_raw() as *mut _;
4748
Ok(Self {
48-
raw: ptr,
49-
styles_used: PhantomData,
49+
raw: nn_ptr,
50+
dependents: PhantomData::<&'a _>,
5051
})
5152
} else {
5253
Err(LvError::InvalidReference)
@@ -56,17 +57,23 @@ impl Obj<'_> {
5657

5758
pub fn new() -> crate::LvResult<Self> {
5859
let mut parent = crate::display::get_scr_act()?;
59-
Self::create(&mut parent)
60+
Self::create(unsafe { &mut *(&mut parent as *mut _) })
61+
}
62+
63+
pub fn blank() -> LvResult<Self> {
64+
match NonNull::new(unsafe { lvgl_sys::lv_obj_create(ptr::null_mut()) }) {
65+
Some(raw) => Ok(Self {
66+
raw,
67+
dependents: PhantomData,
68+
}),
69+
None => Err(LvError::LvOOMemory),
70+
}
6071
}
6172
}
6273

6374
impl NativeObject for Obj<'_> {
64-
fn raw(&self) -> LvResult<ptr::NonNull<lvgl_sys::lv_obj_t>> {
65-
if let Some(non_null_ptr) = ptr::NonNull::new(self.raw) {
66-
Ok(non_null_ptr)
67-
} else {
68-
Err(LvError::InvalidReference)
69-
}
75+
fn raw(&self) -> ptr::NonNull<lvgl_sys::lv_obj_t> {
76+
self.raw
7077
}
7178
}
7279

@@ -85,92 +92,77 @@ pub trait Widget<'a>: NativeObject + Sized + 'a {
8592
unsafe fn from_raw(raw_pointer: ptr::NonNull<lvgl_sys::lv_obj_t>) -> Option<Self>;
8693

8794
/// Adds a `Style` to a given widget.
88-
fn add_style(&mut self, part: Self::Part, style: &'a mut Style) -> LvResult<()> {
95+
fn add_style(&mut self, part: Self::Part, style: &'a mut Style) {
8996
unsafe {
9097
lvgl_sys::lv_obj_add_style(
91-
self.raw()?.as_mut(),
98+
self.raw().as_mut(),
9299
style.raw.as_mut() as *mut _,
93100
part.into(),
94101
);
95102
};
96-
Ok(())
97103
}
98104

99105
/// Sets a widget's position relative to its parent.
100-
fn set_pos(&mut self, x: i16, y: i16) -> LvResult<()> {
106+
fn set_pos(&mut self, x: i16, y: i16) {
101107
unsafe {
102108
lvgl_sys::lv_obj_set_pos(
103-
self.raw()?.as_mut(),
109+
self.raw().as_mut(),
104110
x as lvgl_sys::lv_coord_t,
105111
y as lvgl_sys::lv_coord_t,
106112
);
107113
}
108-
Ok(())
109114
}
110115

111116
/// Sets a widget's size. Alternatively, use `set_width()` and `set_height()`.
112-
fn set_size(&mut self, w: i16, h: i16) -> LvResult<()> {
117+
fn set_size(&mut self, w: i16, h: i16) {
113118
unsafe {
114119
lvgl_sys::lv_obj_set_size(
115-
self.raw()?.as_mut(),
120+
self.raw().as_mut(),
116121
w as lvgl_sys::lv_coord_t,
117122
h as lvgl_sys::lv_coord_t,
118123
);
119124
}
120-
Ok(())
121125
}
122126

123127
/// Sets a widget's width. Alternatively, use `set_size()`.
124-
fn set_width(&mut self, w: u32) -> LvResult<()> {
128+
fn set_width(&mut self, w: u32) {
125129
unsafe {
126-
lvgl_sys::lv_obj_set_width(self.raw()?.as_mut(), w as lvgl_sys::lv_coord_t);
130+
lvgl_sys::lv_obj_set_width(self.raw().as_mut(), w as lvgl_sys::lv_coord_t);
127131
}
128-
Ok(())
129132
}
130133

131134
/// Sets a widget's height. Alternatively, use `set_size()`.
132-
fn set_height(&mut self, h: u32) -> LvResult<()> {
135+
fn set_height(&mut self, h: u32) {
133136
unsafe {
134-
lvgl_sys::lv_obj_set_height(self.raw()?.as_mut(), h as lvgl_sys::lv_coord_t);
137+
lvgl_sys::lv_obj_set_height(self.raw().as_mut(), h as lvgl_sys::lv_coord_t);
135138
}
136-
Ok(())
137139
}
138140

139141
/// Sets a widget's align relative to its parent along with an offset.
140-
fn set_align(&mut self, align: Align, x_mod: i32, y_mod: i32) -> LvResult<()> {
142+
fn set_align(&mut self, align: Align, x_mod: i32, y_mod: i32) {
141143
unsafe {
142144
lvgl_sys::lv_obj_align(
143-
self.raw()?.as_mut(),
145+
self.raw().as_mut(),
144146
align.into(),
145147
x_mod as lvgl_sys::lv_coord_t,
146148
y_mod as lvgl_sys::lv_coord_t,
147149
);
148150
}
149-
Ok(())
150151
}
151152
}
152153

153154
impl<'a> Widget<'a> for Obj<'a> {
154155
type SpecialEvent = u32;
155156
type Part = Part;
156157

157-
unsafe fn from_raw(raw: ptr::NonNull<lvgl_sys::lv_obj_t>) -> Option<Self> {
158+
unsafe fn from_raw(raw: NonNull<lvgl_sys::lv_obj_t>) -> Option<Self> {
158159
Some(Self {
159-
raw: raw.as_ptr(),
160-
styles_used: PhantomData,
160+
raw,
161+
dependents: PhantomData,
161162
})
162163
}
163164
}
164165

165-
impl Default for Obj<'_> {
166-
fn default() -> Self {
167-
Self {
168-
raw: unsafe { lvgl_sys::lv_obj_create(ptr::null_mut()) },
169-
styles_used: PhantomData,
170-
}
171-
}
172-
}
173-
174166
macro_rules! define_object {
175167
($item:ident) => {
176168
define_object!($item, event = (), part = $crate::Part);
@@ -197,7 +189,7 @@ macro_rules! define_object {
197189
{
198190
use $crate::NativeObject;
199191
unsafe {
200-
let obj = self.raw()?.as_mut();
192+
let obj = self.raw().as_mut();
201193
obj.user_data = $crate::Box::into_raw($crate::Box::new(f)) as *mut _;
202194
lvgl_sys::lv_obj_add_event_cb(
203195
obj,
@@ -213,7 +205,7 @@ macro_rules! define_object {
213205
}
214206

215207
impl $crate::NativeObject for $item<'_> {
216-
fn raw(&self) -> $crate::LvResult<core::ptr::NonNull<lvgl_sys::lv_obj_t>> {
208+
fn raw(&self) -> core::ptr::NonNull<lvgl_sys::lv_obj_t> {
217209
self.core.raw()
218210
}
219211
}

lvgl/src/lv_core/screen.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
use crate::{LvError, NativeObject, Obj, Part, Widget};
1+
use crate::{LvError, LvResult, NativeObject, Obj, Part, Widget};
22

33
/// An LVGL screen.
4-
#[derive(Debug, Default)]
4+
#[derive(Debug)]
55
pub struct Screen<'a> {
66
raw: Obj<'a>,
77
}
88

9+
impl Screen<'_> {
10+
pub fn blank() -> LvResult<Self> {
11+
Ok(Self { raw: Obj::blank()? })
12+
}
13+
}
14+
915
impl NativeObject for Screen<'_> {
10-
fn raw(&self) -> crate::LvResult<core::ptr::NonNull<lvgl_sys::lv_obj_t>> {
16+
fn raw(&self) -> core::ptr::NonNull<lvgl_sys::lv_obj_t> {
1117
self.raw.raw()
1218
}
1319
}
@@ -28,13 +34,14 @@ impl<'a> TryFrom<Obj<'a>> for Screen<'a> {
2834
type Error = LvError;
2935

3036
fn try_from(value: Obj<'a>) -> Result<Self, Self::Error> {
31-
match unsafe { value.raw()?.as_mut().parent } as usize {
37+
match unsafe { value.raw().as_mut().parent } as usize {
3238
0 => Ok(Self { raw: value }),
3339
_ => Err(LvError::InvalidReference),
3440
}
3541
}
3642
}
3743

44+
#[allow(clippy::from_over_into)]
3845
impl<'a> Into<Obj<'a>> for Screen<'a> {
3946
fn into(self) -> Obj<'a> {
4047
self.raw
@@ -66,8 +73,8 @@ mod test {
6673
let buffer = DrawBuffer::<{ (HOR_RES * VER_RES) as usize }>::default();
6774
let display = Display::register(buffer, HOR_RES, VER_RES, |_| {}).unwrap();
6875
let mut screen_old = display.get_scr_act().unwrap();
69-
let mut screen_new = Screen::default();
70-
display.set_scr_act(&mut screen_new).unwrap();
71-
display.set_scr_act(&mut screen_old).unwrap();
76+
let mut screen_new = Screen::blank().unwrap();
77+
display.set_scr_act(&mut screen_new);
78+
display.set_scr_act(&mut screen_old);
7279
}
7380
}

lvgl/src/misc/anim.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ where
113113
let anim =
114114
NonNull::new(lvgl_sys::lv_anim_get(obj, None) as *mut lvgl_sys::lv_anim_t).unwrap();
115115
// yes, we have to do it this way. Casting `obj` directly to `&mut Obj` segfaults
116-
let obj = (*(obj as *mut T)).raw().unwrap();
116+
let obj = (*(obj as *mut T)).raw();
117117
if !anim.as_ref().user_data.is_null() {
118118
let callback = &mut *(obj.as_ref().user_data as *mut F);
119119
let mut obj_nondrop = Obj::from_raw(obj).unwrap();

0 commit comments

Comments
 (0)