Consider moving boilerplate into its own module/crate? #24
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: rafaelcaricio/lvgl-rs#24
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I'm reading the examples to gain an understanding of how this works and I notice that the boilerplate for calling
lv_task_handler
andlv_tick_inc
is duplicated across many of the examples. It might be worth moving this to a common crate where it can be reused.b85226aada/examples/gauge.rs (L60-L107)
@embeddedt True, that is a valid concern. I just think we need to focus on showing how to use the library. If we start designing too much the examples, it will be difficult for people to understand what is going on.
Do you have an example in C that uses LVGL without threads? I was thinking we could remove this
Mutex
from the examples and thus simplify all the examples.None of the example code itself uses threads (as the library is not threaded), however, most of the platform implementations run
lv_tick_inc
using a thread or an interrupt, to make sure it doesn't blocklv_task_handler
.For nearly all the platforms,
lv_task_handler
gets run in awhile(1)
loop insidemain
.Does Rust have a function that returns the number of milliseconds since system startup? If so, we can use that, and not even bother calling
lv_tick_inc
. That way, the Rust examples can work identically to the C examples.Exactly. I know that the code is really just calling
lv_task_handler
andlv_tick_inc
, but there is lots happening in order to do that that I don't really understand yet.OT: Can you explain why you need to create an arc to call
lv_task_handler
? Is this some type of syntactic sugar?I just updated the one example to remove the
Mutex
andArc
completely (7466815586
). I think I wrote that way initially due to my lack of experience using the LVGL library before. 🤦An
Arc
in Rust meansAtomic Reference Counter
, it is a way to share a reference to a variable with multiple threads. Better described at https://doc.rust-lang.org/std/sync/struct.Arc.htmlThat definition of
Arc
makes a lot more sense. I thought it was this type of arc. 🙂I've installed Rust on my computer so hopefully I can give this a try at some point and see how it compares to using C directly.
I just have two more suggestions.
Instant::now
with theLV_TICK_CUSTOM
options directly. That way, we don't need to deal withlv_tick_inc
at all in the code.I've updated all examples removing the threads. 👍
On the other suggestions, it's complicated...
std
and from other crates ( https://docs.rs/cstr_core/0.2.0/cstr_core/struct.CStr.html , https://japaric.github.io/heapless/heapless/struct.String.html ). Each have their perks and use cases. In case of embedded Rust, we cannot use anything understd
, since it is built upon the OS abstractions. We work here in#[no_std]
Rust universe, so we are restricted to the Rustcore
. I'm thinking of ways to improve this part. Maybe creating our ownString
type that uses thelv_mem_*
mechanism to manipulate the string bytes. All we need is to append\0
character at the end of the string, Ruststr
don't contain\0
at the end.std
in embedded Rust. What I can think of here is a way to enable users oflvgl-rs
to register themselves a pure Rust function to be called to calculate time. I think it's a valid feature to add. Do you mind opening a new ticket just for this one?Thanks for your comments! This helps a lot. 😃
In my opinion, the best thing to do here is to make sure that a string literal "just works" (TM) without needing any extra wrapper around it in the user's code.
Yes, that is what I meant. Rust "string literals" are static strings, so to append a nul byte at the end I need to, internally, have a sort of dynamic array and copy the static string data from Rust in there and add a
\0
at the end so it is a valid C string. Thus the internalCStr
type just for that, it wouldn't be exposed by the crate to external users.I see. This is an unfortunate limitation, because it makes passing strings to C quite inefficient. It would be nice if the Rust compiler had a flag that would make it generate the strings with
\0
on the end automatically.Yeah, that doesn't exist. Best thing is to let users pass a instance of
cstr_core::CStr
so no need to copy as it already contains the nul byte at the end.Now see a better way to deal with this. If the users the the lib enable
alloc
we can support native Rust strings (&str
andString
, and others) by generating a method that acceptsimpl AsRef<str>
object. We would have always a method that accepts a readyCStr
and another would be available if the user enablesalloc
feature of LVGL-rs.If the
alloc
feature is enabled, then the LVGL-rs API would be much nicer to call with strings.