Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 1 | use aos_configuration as config; |
| 2 | use aos_events_event_loop_runtime::{EventLoopRuntime, Sender, Watcher}; |
| 3 | use aos_events_shm_event_loop::ShmEventLoop; |
Adam Snaider | 48a62f3 | 2023-10-02 15:49:23 -0700 | [diff] [blame] | 4 | use aos_init::WithCppFlags; |
| 5 | use clap::{CommandFactory, Parser}; |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 6 | use core::cell::Cell; |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 7 | use core::time::Duration; |
| 8 | use futures::never::Never; |
Adam Snaider | a3317c8 | 2023-10-02 16:02:36 -0700 | [diff] [blame] | 9 | use std::borrow::Borrow; |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 10 | use std::path::Path; |
| 11 | |
| 12 | use ping_rust_fbs::aos::examples as ping; |
| 13 | use pong_rust_fbs::aos::examples as pong; |
| 14 | |
Adam Snaider | 48a62f3 | 2023-10-02 15:49:23 -0700 | [diff] [blame] | 15 | /// Ping portion of a ping/pong system. |
| 16 | #[derive(Parser, Debug)] |
| 17 | #[command(name = "ping")] |
| 18 | struct App { |
| 19 | /// Time to sleep between pings. |
| 20 | #[arg(long, default_value_t = 10000, value_name = "MICROS")] |
| 21 | sleep: u64, |
| 22 | } |
| 23 | |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 24 | fn main() { |
Adam Snaider | 48a62f3 | 2023-10-02 15:49:23 -0700 | [diff] [blame] | 25 | let app = App::parse_with_cpp_flags(); |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 26 | aos_init::init(); |
| 27 | let config = config::read_config_from(Path::new("pingpong_config.json")).unwrap(); |
| 28 | let ping = PingTask::new(); |
| 29 | ShmEventLoop::new(&config).run_with(|runtime| { |
Adam Snaider | a3317c8 | 2023-10-02 16:02:36 -0700 | [diff] [blame] | 30 | runtime.set_realtime_priority(5); |
Adam Snaider | e4367cb | 2023-10-20 15:14:31 -0400 | [diff] [blame^] | 31 | runtime.spawn(ping.tasks(*runtime, app.sleep)); |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 32 | }); |
| 33 | } |
| 34 | |
| 35 | #[derive(Debug)] |
| 36 | struct PingTask { |
| 37 | counter: Cell<i32>, |
| 38 | } |
| 39 | |
| 40 | impl PingTask { |
| 41 | pub fn new() -> Self { |
| 42 | Self { |
| 43 | counter: Cell::new(0), |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | /// Returns a future with all the tasks for the ping process |
Adam Snaider | e4367cb | 2023-10-20 15:14:31 -0400 | [diff] [blame^] | 48 | pub async fn tasks(&self, event_loop: EventLoopRuntime<'_>, sleep: u64) -> Never { |
| 49 | futures::join!(self.ping(&event_loop, sleep), self.handle_pong(&event_loop)); |
Adam Snaider | de51c67 | 2023-09-28 21:55:43 -0700 | [diff] [blame] | 50 | unreachable!("Let's hope `never_type` gets stabilized soon :)"); |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 51 | } |
| 52 | |
Adam Snaider | a3317c8 | 2023-10-02 16:02:36 -0700 | [diff] [blame] | 53 | pub async fn ping(&self, event_loop: &EventLoopRuntime<'_>, sleep: u64) -> Never { |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 54 | // The sender is used to send messages back to the pong channel. |
| 55 | let mut ping_sender: Sender<ping::Ping> = event_loop.make_sender("/test").unwrap(); |
Adam Snaider | 48a62f3 | 2023-10-02 15:49:23 -0700 | [diff] [blame] | 56 | let mut interval = event_loop.add_interval(Duration::from_micros(sleep)); |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 57 | |
Adam Snaider | a3317c8 | 2023-10-02 16:02:36 -0700 | [diff] [blame] | 58 | let on_run = event_loop.on_run(); |
| 59 | on_run.borrow().await; |
| 60 | |
Adam Snaider | de51c67 | 2023-09-28 21:55:43 -0700 | [diff] [blame] | 61 | loop { |
| 62 | interval.tick().await; |
| 63 | self.counter.set(self.counter.get() + 1); |
| 64 | let mut builder = ping_sender.make_builder(); |
| 65 | let mut ping = ping::PingBuilder::new(builder.fbb()); |
| 66 | let iter = self.counter.get(); |
| 67 | ping.add_value(iter); |
| 68 | ping.add_send_time(event_loop.monotonic_now().into()); |
| 69 | let ping = ping.finish(); |
| 70 | builder.send(ping).expect("Can't send ping"); |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 71 | } |
| 72 | } |
| 73 | |
Adam Snaider | a3317c8 | 2023-10-02 16:02:36 -0700 | [diff] [blame] | 74 | pub async fn handle_pong(&self, event_loop: &EventLoopRuntime<'_>) -> Never { |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 75 | // The watcher gives us incoming ping messages. |
| 76 | let mut pong_watcher: Watcher<pong::Pong> = event_loop.make_watcher("/test").unwrap(); |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 77 | |
Adam Snaider | a3317c8 | 2023-10-02 16:02:36 -0700 | [diff] [blame] | 78 | let on_run = event_loop.on_run(); |
| 79 | on_run.borrow().await; |
Adam Snaider | de51c67 | 2023-09-28 21:55:43 -0700 | [diff] [blame] | 80 | loop { |
Adam Snaider | a3317c8 | 2023-10-02 16:02:36 -0700 | [diff] [blame] | 81 | let pong = pong_watcher.next().await; |
Adam Snaider | de51c67 | 2023-09-28 21:55:43 -0700 | [diff] [blame] | 82 | assert_eq!( |
| 83 | pong.message().unwrap().value(), |
| 84 | self.counter.get(), |
| 85 | "Missed a reply" |
| 86 | ); |
Adam Snaider | 4351678 | 2023-06-26 15:14:18 -0700 | [diff] [blame] | 87 | } |
| 88 | } |
| 89 | } |