Struct asynchronix::time::Scheduler

source ·
pub struct Scheduler<M: Model> { /* private fields */ }
Expand description

A local scheduler for models.

A Scheduler is a handle to the global scheduler associated to a model instance. It can be used by the model to retrieve the simulation time or schedule delayed actions on itself.

Caveat: self-scheduling async methods

Due to a current rustc issue, async methods that schedule themselves will not compile unless an explicit Send bound is added to the returned future. This can be done by replacing the async signature with a partially desugared signature such as:

fn self_scheduling_method<'a>(
    &'a mut self,
    arg: MyEventType,
    scheduler: &'a Scheduler<Self>
) -> impl Future<Output=()> + Send + 'a {
    async move {
        /* implementation */
    }
}

Self-scheduling methods which are not async are not affected by this issue.

Examples

A model that sends a greeting after some delay.

use std::time::Duration;
use asynchronix::model::{Model, Output}; use asynchronix::time::Scheduler;

#[derive(Default)]
pub struct DelayedGreeter {
    msg_out: Output<String>,
}

impl DelayedGreeter {
    // Triggers a greeting on the output port after some delay [input port].
    pub async fn greet_with_delay(&mut self, delay: Duration, scheduler: &Scheduler<Self>) {
        let time = scheduler.time();
        let greeting = format!("Hello, this message was scheduled at: {:?}.", time);
         
        if delay.is_zero() {
            self.msg_out.send(greeting).await;
        } else {
            scheduler.schedule_event(delay, Self::send_msg, greeting).unwrap();
        }
    }

    // Sends a message to the output [private input port].
    async fn send_msg(&mut self, msg: String) {
        self.msg_out.send(msg).await;
    }
}
impl Model for DelayedGreeter {}

Implementations§

source§

impl<M: Model> Scheduler<M>

source

pub fn time(&self) -> MonotonicTime

Returns the current simulation time.

Examples
use asynchronix::model::Model;
use asynchronix::time::{MonotonicTime, Scheduler};

fn is_third_millenium<M: Model>(scheduler: &Scheduler<M>) -> bool {
    let time = scheduler.time();

    time >= MonotonicTime::new(978307200, 0) && time < MonotonicTime::new(32535216000, 0)
}
source

pub fn schedule_event<F, T, S>( &self, deadline: impl Deadline, func: F, arg: T ) -> Result<(), SchedulingError>where F: for<'a> InputFn<'a, M, T, S>, T: Send + Clone + 'static, S: Send + 'static,

Schedules an event at a future time.

An error is returned if the specified deadline is not in the future of the current simulation time.

Examples
use std::time::Duration;

use asynchronix::model::Model;
use asynchronix::time::Scheduler;

// A timer.
pub struct Timer {}

impl Timer {
    // Sets an alarm [input port].
    pub fn set(&mut self, setting: Duration, scheduler: &Scheduler<Self>) {
        if scheduler.schedule_event(setting, Self::ring, ()).is_err() {
            println!("The alarm clock can only be set for a future time");
        }
    }

    // Rings [private input port].
    fn ring(&mut self) {
        println!("Brringggg");
    }
}

impl Model for Timer {}
source

pub fn schedule_keyed_event<F, T, S>( &self, deadline: impl Deadline, func: F, arg: T ) -> Result<EventKey, SchedulingError>where F: for<'a> InputFn<'a, M, T, S>, T: Send + Clone + 'static, S: Send + 'static,

Schedules a cancellable event at a future time and returns an event key.

An error is returned if the specified deadline is not in the future of the current simulation time.

Examples
use asynchronix::model::Model;
use asynchronix::time::{EventKey, MonotonicTime, Scheduler};

// An alarm clock that can be cancelled.
#[derive(Default)]
pub struct CancellableAlarmClock {
    event_key: Option<EventKey>,
}

impl CancellableAlarmClock {
    // Sets an alarm [input port].
    pub fn set(&mut self, setting: MonotonicTime, scheduler: &Scheduler<Self>) {
        self.cancel();
        match scheduler.schedule_keyed_event(setting, Self::ring, ()) {
            Ok(event_key) => self.event_key = Some(event_key),
            Err(_) => println!("The alarm clock can only be set for a future time"),
        };
    }

    // Cancels the current alarm, if any [input port].
    pub fn cancel(&mut self) {
        self.event_key.take().map(|k| k.cancel());
    }

    // Rings the alarm [private input port].
    fn ring(&mut self) {
        println!("Brringggg!");
    }
}

impl Model for CancellableAlarmClock {}
source

pub fn schedule_periodic_event<F, T, S>( &self, deadline: impl Deadline, period: Duration, func: F, arg: T ) -> Result<(), SchedulingError>where F: for<'a> InputFn<'a, M, T, S> + Clone, T: Send + Clone + 'static, S: Send + 'static,

Schedules a periodically recurring event at a future time.

An error is returned if the specified deadline is not in the future of the current simulation time or if the specified period is null.

Examples
use std::time::Duration;

use asynchronix::model::Model;
use asynchronix::time::{MonotonicTime, Scheduler};

// An alarm clock beeping at 1Hz.
pub struct BeepingAlarmClock {}

impl BeepingAlarmClock {
    // Sets an alarm [input port].
    pub fn set(&mut self, setting: MonotonicTime, scheduler: &Scheduler<Self>) {
        if scheduler.schedule_periodic_event(
            setting,
            Duration::from_secs(1), // 1Hz = 1/1s
            Self::beep,
            ()
        ).is_err() {
            println!("The alarm clock can only be set for a future time");
        }
    }

    // Emits a single beep [private input port].
    fn beep(&mut self) {
        println!("Beep!");
    }
}

impl Model for BeepingAlarmClock {}
source

pub fn schedule_keyed_periodic_event<F, T, S>( &self, deadline: impl Deadline, period: Duration, func: F, arg: T ) -> Result<EventKey, SchedulingError>where F: for<'a> InputFn<'a, M, T, S> + Clone, T: Send + Clone + 'static, S: Send + 'static,

Schedules a cancellable, periodically recurring event at a future time and returns an event key.

An error is returned if the specified deadline is not in the future of the current simulation time or if the specified period is null.

Examples
use std::time::Duration;

use asynchronix::model::Model;
use asynchronix::time::{EventKey, MonotonicTime, Scheduler};

// An alarm clock beeping at 1Hz that can be cancelled before it sets off, or
// stopped after it sets off.
#[derive(Default)]
pub struct CancellableBeepingAlarmClock {
    event_key: Option<EventKey>,
}

impl CancellableBeepingAlarmClock {
    // Sets an alarm [input port].
    pub fn set(&mut self, setting: MonotonicTime, scheduler: &Scheduler<Self>) {
        self.cancel();
        match scheduler.schedule_keyed_periodic_event(
            setting,
            Duration::from_secs(1), // 1Hz = 1/1s
            Self::beep,
            ()
        ) {
            Ok(event_key) => self.event_key = Some(event_key),
            Err(_) => println!("The alarm clock can only be set for a future time"),
        };
    }

    // Cancels or stops the alarm [input port].
    pub fn cancel(&mut self) {
        self.event_key.take().map(|k| k.cancel());
    }

    // Emits a single beep [private input port].
    fn beep(&mut self) {
        println!("Beep!");
    }
}

impl Model for CancellableBeepingAlarmClock {}

Trait Implementations§

source§

impl<M: Model> Debug for Scheduler<M>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<M> !RefUnwindSafe for Scheduler<M>

§

impl<M> Send for Scheduler<M>

§

impl<M> Sync for Scheduler<M>

§

impl<M> Unpin for Scheduler<M>

§

impl<M> !UnwindSafe for Scheduler<M>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.