asynchronics / asynchronix

High-performance asynchronous computation framework for system simulation
Apache License 2.0
170 stars 9 forks source link

Delayed outputs? #10

Closed leon-thomm closed 11 months ago

leon-thomm commented 12 months ago

What is the best way to implement sending messages to an output with a delay? The docs suggest a self-scheduling mechanism, e.g.:

scheduler.schedule_event(Duration::from_secs(1), Self::push_msg, msg);

with a corresponding handler

fn push_msg(&mut self, msg: Msg) {
    self.output.send(msg);
}

but I feel this might get slightly tedious in complex models. Ideally, I would like to simply write

self.output.send_in(Duration::from_secs(1), msg);

Any suggestions how I should do this?

leon-thomm commented 12 months ago

(though much of my struggles might stem from my inexperience with the language :) so apologies if I'm over-engineering simple things, happy to learn more)

sbarral commented 11 months ago

There is no real way to avoid the scheduler here, but you could save yourself a bit of typing by declaring a macro:

macro_rules! deferred_send {
    ($m:ty, $o:ident, $v:ty) => {{
        async fn deferred(m: &mut $m, v: $v) {
            let _ = m.$o.send(v).await;
        }

        deferred
    }};
}

which you would use as follows:

scheduler.schedule_event(Duration::from_secs(1), deferred_send!(MyModel, output, Msg), msg).unwrap();

The macro works for requestor ports too, but obviously the reply is ignored.

If you come to the conclusion that the macro is worth adding to the library and/or have ideas how to improve it, please let me know.

leon-thomm commented 11 months ago

Thanks, this works.