blob: d699d3c636d2c32136c04ab0a491bc927c17300b [file] [log] [blame]
Adam Snaider43516782023-06-26 15:14:18 -07001use aos_configuration as config;
2use aos_events_event_loop_runtime::{EventLoopRuntime, Sender, Watcher};
3use aos_events_shm_event_loop::ShmEventLoop;
Adam Snaider48a62f32023-10-02 15:49:23 -07004use aos_init::WithCppFlags;
5use clap::{CommandFactory, Parser};
Adam Snaider43516782023-06-26 15:14:18 -07006use core::cell::Cell;
Adam Snaider43516782023-06-26 15:14:18 -07007use core::time::Duration;
8use futures::never::Never;
9use std::path::Path;
10
11use ping_rust_fbs::aos::examples as ping;
12use pong_rust_fbs::aos::examples as pong;
13
Adam Snaider48a62f32023-10-02 15:49:23 -070014/// Ping portion of a ping/pong system.
15#[derive(Parser, Debug)]
16#[command(name = "ping")]
17struct App {
18 /// Time to sleep between pings.
19 #[arg(long, default_value_t = 10000, value_name = "MICROS")]
20 sleep: u64,
21}
22
Adam Snaider43516782023-06-26 15:14:18 -070023fn main() {
Adam Snaider48a62f32023-10-02 15:49:23 -070024 let app = App::parse_with_cpp_flags();
Adam Snaider43516782023-06-26 15:14:18 -070025 aos_init::init();
26 let config = config::read_config_from(Path::new("pingpong_config.json")).unwrap();
27 let ping = PingTask::new();
28 ShmEventLoop::new(&config).run_with(|runtime| {
Adam Snaider48a62f32023-10-02 15:49:23 -070029 runtime.spawn(ping.tasks(runtime, app.sleep));
Adam Snaider43516782023-06-26 15:14:18 -070030 });
31}
32
33#[derive(Debug)]
34struct PingTask {
35 counter: Cell<i32>,
36}
37
38impl PingTask {
39 pub fn new() -> Self {
40 Self {
41 counter: Cell::new(0),
42 }
43 }
44
45 /// Returns a future with all the tasks for the ping process
Adam Snaider48a62f32023-10-02 15:49:23 -070046 pub async fn tasks(&self, event_loop: &EventLoopRuntime<'_>, sleep: u64) -> Never {
47 futures::join!(self.ping(event_loop, sleep), self.handle_pong(event_loop));
Adam Snaiderde51c672023-09-28 21:55:43 -070048 unreachable!("Let's hope `never_type` gets stabilized soon :)");
Adam Snaider43516782023-06-26 15:14:18 -070049 }
50
Adam Snaider48a62f32023-10-02 15:49:23 -070051 async fn ping(&self, event_loop: &EventLoopRuntime<'_>, sleep: u64) -> Never {
Adam Snaider43516782023-06-26 15:14:18 -070052 // The sender is used to send messages back to the pong channel.
53 let mut ping_sender: Sender<ping::Ping> = event_loop.make_sender("/test").unwrap();
Adam Snaider48a62f32023-10-02 15:49:23 -070054 let mut interval = event_loop.add_interval(Duration::from_micros(sleep));
Adam Snaider43516782023-06-26 15:14:18 -070055
Adam Snaiderde51c672023-09-28 21:55:43 -070056 event_loop.on_run().await;
57 loop {
58 interval.tick().await;
59 self.counter.set(self.counter.get() + 1);
60 let mut builder = ping_sender.make_builder();
61 let mut ping = ping::PingBuilder::new(builder.fbb());
62 let iter = self.counter.get();
63 ping.add_value(iter);
64 ping.add_send_time(event_loop.monotonic_now().into());
65 let ping = ping.finish();
66 builder.send(ping).expect("Can't send ping");
Adam Snaider43516782023-06-26 15:14:18 -070067 }
68 }
69
Adam Snaiderde51c672023-09-28 21:55:43 -070070 async fn handle_pong(&self, event_loop: &EventLoopRuntime<'_>) -> Never {
Adam Snaider43516782023-06-26 15:14:18 -070071 // The watcher gives us incoming ping messages.
72 let mut pong_watcher: Watcher<pong::Pong> = event_loop.make_watcher("/test").unwrap();
Adam Snaider43516782023-06-26 15:14:18 -070073
Adam Snaiderde51c672023-09-28 21:55:43 -070074 event_loop.on_run().await;
75 loop {
76 let pong = dbg!(pong_watcher.next().await);
77 assert_eq!(
78 pong.message().unwrap().value(),
79 self.counter.get(),
80 "Missed a reply"
81 );
Adam Snaider43516782023-06-26 15:14:18 -070082 }
83 }
84}