Struct ReactionCtx

Source
pub struct ReactionCtx<'a, 'x> { /* private fields */ }
Expand description

The context in which a reaction executes. Its API allows mutating the event queue of the scheduler. Only the interactions declared at assembly time are allowed.

Implementations§

Source§

impl<'a, 'x> ReactionCtx<'a, 'x>

Source

pub fn get_start_time(&self) -> Instant

Returns the start time of the execution of this program.

This is a logical instant with microstep zero.

Source

pub fn get_physical_time(&self) -> Instant

Returns the current physical time.

Repeated invocation of this method may produce different values, although Instant is monotonic. The physical time is necessarily greater than the logical time.

Source

pub fn get_logical_time(&self) -> Instant

Returns the current logical time.

Logical time is frozen during the execution of a reaction. Repeated invocation of this method will always produce the same value.

Source

pub fn get_tag(&self) -> EventTag

Returns the tag at which the reaction executes.

Repeated invocation of this method will always produce the same value.

Source

pub fn is_shutdown(&self) -> bool

Returns whether this tag is the shutdown tag of the application. If so, it’s necessarily the very last invocation of the current reaction (on a given reactor instance).

Repeated invocation of this method will always produce the same value.

Source

pub fn get_elapsed_logical_time(&self) -> Duration

Returns the amount of logical time elapsed since the start of the program. This does not take microsteps into account.

Source

pub fn get_elapsed_physical_time(&self) -> Duration

Returns the amount of physical time elapsed since the start of the program.

Since this uses Self::get_physical_time, be aware that this function’s result may change over time.

Source

pub fn num_workers(&self) -> usize

Returns the number of active workers in the execution of a reactor program.

Return values:

  • 1 if threading is not enabled.
  • If threading is enabled and a number of workers was specified, it returns that number.
  • And if the number of workers was left unspecified, the return value might vary.
Source

pub fn get<T: Copy>(&self, container: &impl ReactionTrigger<T>) -> Option<T>

Returns the current value of a port or action at this logical time. If the value is absent, Option::None is returned. This is the case if the action or port is not present (Self::is_present), or if no value was scheduled (action values are optional, see Self::schedule_with_v).

The value is copied out. See also Self::use_ref if this is to be avoided.

§Examples
if let Some(value) = ctx.get(port) {
    // branch is taken if the port is set
}
Source

pub fn get_ref<'q, T>( &self, container: &'q impl ReactionTriggerWithRefAccess<T>, ) -> Option<&'q T>

Returns a reference to the current value of a port or action at this logical time. If the value is absent, Option::None is returned. This is the case if the action or port is not present (Self::is_present), or if no value was scheduled (action values are optional, see Self::schedule_with_v).

This does not require the value to be Copy, however, the implementation of this method currently may require unsafe code. The method is therefore not offered when compiling with the no-unsafe feature.

§Examples
if let Some(value) = ctx.get_ref(port) {
    // value is a ref to the internal value
}
Source

pub fn use_ref<T, O>( &self, container: &impl ReactionTrigger<T>, action: impl FnOnce(Option<&T>) -> O, ) -> O

Executes the provided closure on the value of the port or action. The value is fetched by reference and not copied.

§Examples
let len = ctx.use_ref(port, |str| str.map(String::len).unwrap_or(0));
// equivalent to
let len = ctx.use_ref_opt(port, String::len).unwrap_or(0);

if let Some(str) = ctx.use_ref_opt(port, Clone::clone) {
    // only entered if the port value is present, so no need to check is_present
}

See also the similar Self::use_ref_opt.

Source

pub fn use_ref_opt<T, O>( &self, container: &impl ReactionTrigger<T>, action: impl FnOnce(&T) -> O, ) -> Option<O>

Executes the provided closure on the value of the port, only if it is present. The value is fetched by reference and not copied.

See also the similar Self::use_ref.

Source

pub fn set<T>(&mut self, port: &mut Port<T>, value: T)
where T: Sync,

Sets the value of the given port.

The change is visible at the same logical time, i.e. the value propagates immediately. This may hence schedule more reactions that should execute at the same logical time.

Source

pub fn set_opt<T>(&mut self, port: &mut Port<T>, value: Option<T>)
where T: Sync,

Sets the value of the given port, if the given value is Some. Otherwise the port is not set and no reactions are triggered.

The change is visible at the same logical time, i.e. the value propagates immediately. This may hence schedule more reactions that should execute at the same logical time.


ctx.set_opt(sink, ctx.get(source));
// equivalent to
if let Some(value) = ctx.get(source) {
    ctx.set(sink, value);
}
Source

pub fn is_present<T>(&self, action: &impl ReactionTrigger<T>) -> bool

Returns true if the given action was triggered at the current logical time.

If so, then it may, but must not, present a value (Self::get).

Source

pub fn schedule<T: Sync>( &mut self, action: &mut impl SchedulableAsAction<T>, offset: Offset, )

Schedule an action to trigger at some point in the future. The action will trigger after its own implicit time delay, plus an optional additional time delay (see Offset). This delay is added to the current logical (resp. physical) time for logical (resp. physical) actions.

This is like Self::schedule_with_v, where the value is None.

§Examples
ctx.schedule(action, Asap);         // will be executed one microstep from now (+ own delay)
ctx.schedule(action, after!(2 ms)); // will be executed 2 milliseconds from now (+ own delay)
ctx.schedule(action, After(delay!(2 ms)));             // equivalent to the previous
ctx.schedule(action, After(Duration::from_millis(2))); // equivalent to the previous
Source

pub fn schedule_with_v<T: Sync>( &mut self, action: &mut impl SchedulableAsAction<T>, value: Option<T>, offset: Offset, )

Schedule an action to trigger at some point in the future,

The action will carry the given value at the time it is triggered, unless it is overwritten by another call to this method. The value can be cleared by using None as a value. Note that even if the value is absent, the action will still be present at the time it is triggered (see Self::is_present).

The action will trigger after its own implicit time delay, plus an optional additional time delay (see Offset). This delay is added to the current logical (resp. physical) time for logical (resp. physical) actions.

§Examples
// will be executed 2 milliseconds (+ own delay) from now with that value.
ctx.schedule_with_v(action, Some("value"), after!(2 msec));
// will be executed one microstep from now, with no value
ctx.schedule_with_v(action, None, Asap);
// that's equivalent to
ctx.schedule(action, Asap);
Source

pub fn spawn_physical_thread<F, R>(&mut self, f: F) -> JoinHandle<R>
where F: FnOnce(&mut AsyncCtx) -> R + Send + 'static, R: Send + 'static,

Spawn a new thread that can use a AsyncCtx to push asynchronous events to the reaction queue. This is only useful with physical actions.

Since the thread is allowed to keep references into the internals of the scheduler, it is joined when the scheduler shuts down. This means the scheduler will wait for the thread to finish its task. For that reason, the thread’s closure should not execute an infinite loop, it should at least check that the scheduler has not been terminated by polling AsyncCtx::was_terminated.

§Example
fn some_reaction(ctx: &mut ReactionCtx, phys_action: &PhysicalActionRef<u32>) {
    let phys_action = phys_action.clone(); // clone to move it into other thread
    ctx.spawn_physical_thread(move |link| {
        std::thread::sleep(Duration::from_millis(200));
        // This will push an event whose tag is the
        // current physical time at the point of this
        // statement.
        link.schedule_physical_with_v(&phys_action, Some(123), Asap).unwrap();
    });
}
Source

pub fn request_stop(&mut self, offset: Offset)

Request that the application shutdown, possibly with a particular offset. Just like for actions, even a zero offset will only trigger the special shutdown trigger at the earliest one microstep after the current tag.

// trigger shutdown on the next microstep
ctx.request_stop(Asap);

// trigger shutdown in *at most* 1 msec (in logical time).
// If in the meantime, another `request_stop` call schedules
// shutdown for an earlier tag, that one will be honored instead.
ctx.request_stop(after!(1 msec));

Auto Trait Implementations§

§

impl<'a, 'x> Freeze for ReactionCtx<'a, 'x>

§

impl<'a, 'x> RefUnwindSafe for ReactionCtx<'a, 'x>

§

impl<'a, 'x> Send for ReactionCtx<'a, 'x>

§

impl<'a, 'x> Sync for ReactionCtx<'a, 'x>

§

impl<'a, 'x> Unpin for ReactionCtx<'a, 'x>

§

impl<'a, 'x> UnwindSafe for ReactionCtx<'a, 'x>

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where 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 T
where 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 T
where U: Into<T>,

Source§

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 T
where U: TryFrom<T>,

Source§

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.