EVerest / everest-framework

Apache License 2.0
21 stars 19 forks source link

Rust: add slots support #176

Closed dorezyuk closed 7 months ago

dorezyuk commented 7 months ago

Adds Rust support for multiple slots.

Summary

The proposed interface is

Examples

# in the manifest.yaml
# ...
requires
  example_interface:
    interface: example
    min_connections: 0
    max_connections: 10
// In the main.rs
include!(concat!(env!("OUT_DIR"), "/generated.rs"));
use generated::{ExampleClientSubscriber, Context};

struct MyModule;

impl ExampleClientSubscriber for MyModule {
    fn on_max_current(&self, context: &Context, value: f64) {
       println!("Received a connection from the slot {}.. replying to it by using something", context.index);
       context.publisher.example_interface_slots[context.index].uses_something(format!("value {value}"));
    }
}

For disambiguating the slots at the ClientSubscriber we change the interface for multiple slots (if these is only one stot, nothing changes) for the Module to be a FnMut similar to the core::array::from_fn in the Rusts standard library. It allows the user to decide if they want to use different instances of ClientPublisher or the same for every slot.

struct MyModuleWithSomeData{
   index: usize,
};

impl ExampleClientSubscriber for MyModuleWithSomeData {
    fn on_max_current(&self, context: &Context, value: f64) {
         assert_eq!(self.index, context.index);
    }
}

// ...

fn main() {
      let my_module = Arc::new(MyModule);
      let _module = Module::new(
            |_index: usize| {
              // Below we just return the same instance for every slot.
              // We could also return Arc::new(MyModuleWithSomeData{index: _index}) here if
              // we want every slot to be handled by a dedicated instance
               my_module.clone() 
            }
      );
}

Addresses https://github.com/EVerest/everest-framework/issues/174

dorezyuk commented 7 months ago

@SirVer can you check it

SirVer commented 7 months ago

Will do early this week.