First step in removing dependency on alloc crate

This commit is contained in:
Rafael Caricio 2020-06-15 20:56:44 +02:00 committed by Rafael Carício
parent b85226aada
commit 657640d206
6 changed files with 43 additions and 27 deletions

View file

@ -10,6 +10,9 @@ lvgl = { path = "../lvgl" }
lvgl-sys = { path = "../lvgl-sys" } lvgl-sys = { path = "../lvgl-sys" }
embedded-graphics = "0.6" embedded-graphics = "0.6"
embedded-graphics-simulator = "0.2.0" embedded-graphics-simulator = "0.2.0"
heapless = "0.5.5"
cstr_core = { version = "0.2.0" }
typenum = "1.12.0"
[[example]] [[example]]
name = "demo" name = "demo"

View file

@ -1,3 +1,4 @@
use cstr_core::{CStr, CString};
use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::prelude::*; use embedded_graphics::prelude::*;
use embedded_graphics_simulator::{ use embedded_graphics_simulator::{
@ -44,7 +45,7 @@ fn main() -> Result<(), LvError> {
style_time.set_text_color(State::DEFAULT, Color::from_rgb((255, 255, 255))); style_time.set_text_color(State::DEFAULT, Color::from_rgb((255, 255, 255)));
time.add_style(Part::Main, style_time)?; time.add_style(Part::Main, style_time)?;
time.set_align(&mut screen, Align::Center, 0, 0)?; time.set_align(&mut screen, Align::Center, 0, 0)?;
time.set_text("20:46")?; time.set_text(CString::new("20:46").unwrap().as_c_str())?;
time.set_width(240)?; time.set_width(240)?;
time.set_height(240)?; time.set_height(240)?;
@ -52,15 +53,29 @@ fn main() -> Result<(), LvError> {
bt.set_width(50)?; bt.set_width(50)?;
bt.set_height(80)?; bt.set_height(80)?;
bt.set_recolor(true)?; bt.set_recolor(true)?;
bt.set_text("#5794f2 \u{F293}#")?; bt.set_text(CString::new("#5794f2 \u{F293}#").unwrap().as_c_str())?;
bt.set_label_align(LabelAlign::Left)?; bt.set_label_align(LabelAlign::Left)?;
bt.set_align(&mut screen, Align::InTopLeft, 0, 0)?; bt.set_align(&mut screen, Align::InTopLeft, 0, 0)?;
fn set_text<S>(text: S) -> Result<(), ()>
where
S: AsRef<cstr_core::CStr>,
{
let _v: *const i8 = text.as_ref().as_ptr();
Ok(())
}
let mut t: heapless::String<heapless::consts::U8> = heapless::String::from("test");
t.push('\0').unwrap();
set_text(CStr::from_bytes_with_nul(t.as_bytes()).unwrap()).unwrap();
set_text(CStr::from_bytes_with_nul("test\0".as_bytes()).unwrap()).unwrap();
set_text(cstr_core::CString::new("test").unwrap().as_c_str()).unwrap();
let mut power = Label::new(&mut screen)?; let mut power = Label::new(&mut screen)?;
power.set_recolor(true)?; power.set_recolor(true)?;
power.set_width(80)?; power.set_width(80)?;
power.set_height(20)?; power.set_height(20)?;
power.set_text("#fade2a 20%#")?; power.set_text(CString::new("#fade2a 20%#").unwrap().as_c_str())?;
power.set_label_align(LabelAlign::Right)?; power.set_label_align(LabelAlign::Right)?;
power.set_align(&mut screen, Align::InTopRight, 0, 0)?; power.set_align(&mut screen, Align::InTopRight, 0, 0)?;
@ -83,7 +98,8 @@ fn main() -> Result<(), LvError> {
if i > 59 { if i > 59 {
i = 0; i = 0;
} }
time.set_text(format!("21:{:02}", i).as_str())?; let val = format!("21:{:02}", i);
time.set_text(CString::new(val.as_str()).unwrap().as_c_str())?;
i = 1 + i; i = 1 + i;
sleep(Duration::from_secs(1)); sleep(Duration::from_secs(1));

View file

@ -19,7 +19,7 @@ lazy_static! {
("i32", "i32"), ("i32", "i32"),
("u8", "u8"), ("u8", "u8"),
("bool", "bool"), ("bool", "bool"),
("* const cty :: c_char", "&str"), ("* const cty :: c_char", "_"),
] ]
.iter() .iter()
.cloned() .cloned()
@ -259,18 +259,12 @@ impl LvArg {
} }
pub fn get_processing(&self) -> TokenStream { pub fn get_processing(&self) -> TokenStream {
let ident = self.get_name_ident();
// TODO: A better way to handle this, instead of `is_sometype()`, is using the Rust // TODO: A better way to handle this, instead of `is_sometype()`, is using the Rust
// type system itself. // type system itself.
if self.typ.is_str() {
quote! {
let #ident = cstr_core::CString::new(#ident)?;
}
} else {
// No need to pre-process this type of argument // No need to pre-process this type of argument
quote! {} quote! {}
} }
}
pub fn get_value_usage(&self) -> TokenStream { pub fn get_value_usage(&self) -> TokenStream {
let ident = self.get_name_ident(); let ident = self.get_name_ident();
@ -339,7 +333,7 @@ impl Rusty for LvType {
match TYPE_MAPPINGS.get(self.literal_name.as_str()) { match TYPE_MAPPINGS.get(self.literal_name.as_str()) {
Some(name) => { Some(name) => {
let val = if self.is_str() { let val = if self.is_str() {
quote!(&str) quote!(&cstr_core::CStr)
} else { } else {
let ident = format_ident!("{}", name); let ident = format_ident!("{}", name);
quote!(#ident) quote!(#ident)
@ -573,8 +567,8 @@ mod test {
let code = label_set_text.code(&parent_widget).unwrap(); let code = label_set_text.code(&parent_widget).unwrap();
let expected_code = quote! { let expected_code = quote! {
pub fn set_text(&mut self, text: &str) -> crate::LvResult<()> {
let text = cstr_core::CString::new(text)?; pub fn set_text(&mut self, text: &cstr_core::CStr) -> crate::LvResult<()> {
unsafe { unsafe {
lvgl_sys::lv_label_set_text( lvgl_sys::lv_label_set_text(
self.core.raw()?.as_mut(), self.core.raw()?.as_mut(),
@ -583,6 +577,7 @@ mod test {
} }
Ok(()) Ok(())
} }
}; };
assert_eq!(code.to_string(), expected_code.to_string()); assert_eq!(code.to_string(), expected_code.to_string());

View file

@ -17,6 +17,8 @@ cty = "0.2.1"
embedded-graphics = "0.6.2" embedded-graphics = "0.6.2"
cstr_core = { version = "0.2.0", default-features = false, features = ["alloc"] } cstr_core = { version = "0.2.0", default-features = false, features = ["alloc"] }
bitflags = "1.2.1" bitflags = "1.2.1"
heapless = "0.5.5"
typenum = "1.12.0"
[build-dependencies] [build-dependencies]
quote = "1.0.7" quote = "1.0.7"

View file

@ -19,23 +19,21 @@ impl DisplayDriver {
// Declare a buffer for the refresh rate // Declare a buffer for the refresh rate
// TODO: Make this an external configuration // TODO: Make this an external configuration
const REFRESH_BUFFER_LEN: usize = 2; const REFRESH_BUFFER_LEN: usize = 2;
let refresh_buffer1 = vec![ const BUF_SIZE: usize = lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN;
Color::from_rgb((0, 0, 0)).raw;
lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN
];
let refresh_buffer2 = vec![ let refresh_buffer1: [lvgl_sys::lv_color_t; BUF_SIZE] =
Color::from_rgb((0, 0, 0)).raw; [Color::from_rgb((0, 0, 0)).raw; BUF_SIZE];
lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN
]; let refresh_buffer2: [lvgl_sys::lv_color_t; BUF_SIZE] =
[Color::from_rgb((0, 0, 0)).raw; BUF_SIZE];
// Create a display buffer for LittlevGL // Create a display buffer for LittlevGL
let mut display_buffer = MaybeUninit::<lvgl_sys::lv_disp_buf_t>::uninit(); let mut display_buffer = MaybeUninit::<lvgl_sys::lv_disp_buf_t>::uninit();
// Initialize the display buffer // Initialize the display buffer
lvgl_sys::lv_disp_buf_init( lvgl_sys::lv_disp_buf_init(
display_buffer.as_mut_ptr(), display_buffer.as_mut_ptr(),
Box::into_raw(refresh_buffer1.into_boxed_slice()) as *mut cty::c_void, Box::into_raw(Box::new(refresh_buffer1)) as *mut cty::c_void,
Box::into_raw(refresh_buffer2.into_boxed_slice()) as *mut cty::c_void, Box::into_raw(Box::new(refresh_buffer2)) as *mut cty::c_void,
lvgl_sys::LV_HOR_RES_MAX * REFRESH_BUFFER_LEN as u32, lvgl_sys::LV_HOR_RES_MAX * REFRESH_BUFFER_LEN as u32,
); );
let display_buffer = Box::new(display_buffer.assume_init()); let display_buffer = Box::new(display_buffer.assume_init());

View file

@ -12,6 +12,8 @@ pub enum LvError {
InvalidReference, InvalidReference,
Uninitialized, Uninitialized,
InvalidNulByteString, InvalidNulByteString,
StringSizeTooShort,
StringCannotAppendNulByte,
AlreadyInUse, AlreadyInUse,
} }