Rust::com Field APIs design and example of usage - #700
Conversation
* Created field interface APIs * Updated SampleMut to use in field as well
* Added field related files on build target
* Created impl block in Lola Runtime for field Producer and Consumer trait
* Mock Runtime impl block added for field APIs
* Updated Interface macro to generate field related types and APIs
* Create proc macro for field init and set handler validation before offer call
* Updated Runtime GATs for field public types * Updated Runtime implementation
* Updated example file with Field APIs usage
70fbb6e to
f7cd859
Compare
| /// "left_tire" and "exhaust" events. | ||
| /// - `VehicleOfferedProducer<R>` struct that implements `OfferedProducer` trait for offering | ||
| /// "left_tire" and "exhaust" events. | ||
| // TODO: We need to enable the support for mixed types (Event, Method, Field) in the same interface definition. |
* Updated the TODOs and documentation
6921668 to
6faaa6c
Compare
* Clone bound removed from fieldPublisher trait and impl block
6faaa6c to
21d958d
Compare
* Producer trait offer API limitation added to avoid direct use
30e0af1 to
8589c65
Compare
| // Below function just demonstrate the field APIs usage | ||
| // This build fine but it can not run because we have not implemented the field APIs in Lola runtime yet. | ||
|
|
||
| // Producer creation and intialization of fields with initial values and set handlers for the fields | ||
| // It will return the offered producer instance which can be used to update the fields. |
There was a problem hiding this comment.
| // Below function just demonstrate the field APIs usage | |
| // This build fine but it can not run because we have not implemented the field APIs in Lola runtime yet. | |
| // Producer creation and intialization of fields with initial values and set handlers for the fields | |
| // It will return the offered producer instance which can be used to update the fields. | |
| // Below function demonstrate the field APIs usage | |
| // This builds fine, but it cannot run as the field APIs in Lola runtime are not implemented yet. | |
| // Producer creation and intialization of fields with initial values and set handlers for the fields | |
| // It will return the offered producer instance which can be used to update the fields. |
| // TODO: in working example add that logic to demonstrate the set handler usage. | ||
| // Note: I think producer may be need clone ? | ||
| }) | ||
| .expect("Failed to register set handlers") |
There was a problem hiding this comment.
Why would register_* ever fail? As discussed for Method, it shouldn't return Result.
| .register_set_handler_left_tire(move |val: &Tire| { | ||
| println!("Received tire pressure update: {:?}", val); | ||
| // Additional logic to handle the tire pressure update can be added here | ||
| // For example, we can increment value or conver unit and update the field again. |
There was a problem hiding this comment.
| // For example, we can increment value or conver unit and update the field again. | |
| // For example, we can increment value or convert unit and update the field again. |
darkwisebear
left a comment
There was a problem hiding this comment.
I mainly reviewed the concept part; I think we need to nail that part before it makes sense to look at the rest.
| * SPDX-License-Identifier: Apache-2.0 | ||
| ********************************************************************************/ | ||
|
|
||
| #![allow(unused)] |
There was a problem hiding this comment.
Please put this to the specific places and do not globally turn it on for the module.
| // Must register handlers and initialize all fields before offer() is available | ||
| let offered = producer | ||
| .init_field() | ||
| .register_set_handler_left_tire(move |val: &Tire| { |
There was a problem hiding this comment.
I wonder whether &Tire is correct. Why not hand over ownership to the callable? This way, the implementer wouldn't have to clone the value in the likely case the value is written somewhere.
| println!("Received exhaust update"); | ||
| }) | ||
| .expect("Failed to register set handlers") | ||
| .update_left_tire(&initial_tire_value) |
There was a problem hiding this comment.
Why by-reference? This forces cloning as the implementation most likely has to clone the value to send it across the network. It might be a corner case, though.
| use std::fmt::Debug; | ||
| use std::future::Future; | ||
|
|
||
| #[allow(dead_code)] |
There was a problem hiding this comment.
Why is this dead code?
| #[allow(dead_code)] | ||
| // Temp for build test | ||
| // We will remove this once memory layout of same created in rust side like SamplePtr. | ||
| #[repr(C)] |
There was a problem hiding this comment.
Doesn't this trigger an "improper_ctypes" lint? Result isn't #[repr(C)], so it cannot be used here properly.
| // or by default we will enable for user, | ||
| // -> we can keep it default enable as of now, | ||
| // and later we can add tag based mechanism if required because Interface side we need to check how we can do this | ||
| // 2. We are offering get method after subscrption async but before subscription it is sync, |
There was a problem hiding this comment.
Just turn the one before subscription into async. Or is there anything that prevents you from doing so?
| // we will create a module which will have common trait for event and field which will be used by both event and field as a super trait and | ||
| // for this we need to create marker trait for event. | ||
|
|
||
| use crate::*; |
There was a problem hiding this comment.
Please import specific types. Yes, it's tedious, but being explicit here also saves some headaches.
| /// # Returns | ||
| /// Return the result of `Result<()>` which contains the status of the register operation. | ||
| // TODO: Do we need to make callback lifetime 'static or we keep same as field publisher lifetime. | ||
| fn register_set_handler<'a>(&self, callback: impl Fn(&T) + Send + 'a) -> Result<()>; |
There was a problem hiding this comment.
There is no equivalent method for registering the get handler. It may sound weird, but the C++ counterpart has that, since mw::com treats set and get as ordinary methods.
| /// # Returns | ||
| /// Return the result of `Result<()>` which contains the status of the register operation. | ||
| // TODO: Do we need to make callback lifetime 'static or we keep same as field publisher lifetime. | ||
| fn register_set_handler<'a>(&self, callback: impl Fn(&T) + Send + 'a) -> Result<()>; |
There was a problem hiding this comment.
TO me this feels as if we're treating ordinary methods and field methods in a distinct way. Maybe we should think about getting methods ready first and then incorporate them as the foundation of set and get here.
| @@ -329,18 +342,10 @@ where | |||
| /// | |||
| /// # Type Parameters | |||
| /// * `T` - The relocatable event data type | |||
| pub trait SampleMut<T>: DerefMut<Target = T> + Debug | |||
| pub trait EventSampleMut<T>: SampleMut<T> | |||
There was a problem hiding this comment.
Is this just because of update vs send (aka naming)?
#579