Skip to content

Commit

Permalink
Major refactor of runtime interface (CI will fail)
Browse files Browse the repository at this point in the history
This is a major refactor of the runtime interface which makes it *much* easier to program against in a generic way. The most obvious changes are (1) the interface is no longer split into sync/unsync variants, (2) the runtime interface no longer requires a lifetime annotation on the machine type.

The type annotations required on callback arguments have gotten a little bit harrier... I really wish Rust was better at inferring the types of closure arguments--in this case all the info is obviously there to do it.

The runtime interface and its demos and tests have been updated and are working, but the code generator and integration tests have not been updated yet, so CI is expected to fail.
  • Loading branch information
walkie committed Jan 1, 2022
1 parent 6029bff commit b72b5ab
Show file tree
Hide file tree
Showing 11 changed files with 798 additions and 900 deletions.
64 changes: 64 additions & 0 deletions frame_runtime/src/callback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//! This module defines callbacks that can be registered with a state machine's `EventMonitor`.
use std::sync::{Arc, Mutex};

/// Trait for wrappers around callback functions that have a name and accept a reference to `Arg`
/// as an argument.
pub trait IsCallback<Arg> {
/// A name/ID associated with this callback to enable removing it later.
fn name(&self) -> &str;

/// Apply the wrapped function.
fn apply(&mut self, arg: &Arg);
}

/// A named callback function that accepts a reference to `Arg` as an argument.
pub struct Callback<Arg> {
name: String,
closure: Box<dyn FnMut(&Arg) + 'static>,
}

impl<Arg> Callback<Arg> {
/// Create a new callback from the given closure.
pub fn new(name: &str, f: impl FnMut(&Arg) + 'static) -> Self {
Callback {
closure: Box::new(f),
name: name.to_string(),
}
}
}

impl<Arg> IsCallback<Arg> for Callback<Arg> {
fn name(&self) -> &str {
&self.name
}
fn apply(&mut self, arg: &Arg) {
(*self.closure)(arg)
}
}

/// A named callback function that accepts a reference to `Arg` as an argument and implements the
/// `Send` trait.
pub struct CallbackSend<Arg> {
name: String,
closure: Arc<Mutex<dyn FnMut(&Arg) + Send + 'static>>,
}

impl<Arg> CallbackSend<Arg> {
/// Create a new callback from the given closure.
pub fn new(name: &str, f: impl FnMut(&Arg) + Send + 'static) -> Self {
CallbackSend {
closure: Arc::new(Mutex::new(f)),
name: name.to_string(),
}
}
}

impl<Arg> IsCallback<Arg> for CallbackSend<Arg> {
fn name(&self) -> &str {
&self.name
}
fn apply(&mut self, arg: &Arg) {
(*self.closure.lock().unwrap())(arg)
}
}
18 changes: 0 additions & 18 deletions frame_runtime/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,6 @@ impl<T: Environment + Clone> Environment for Mutex<T> {
}
}

/// Definitions specific to the synchronized/thread-safe interface.
pub mod sync {
pub use super::*;
use std::sync::Arc;

/// A reference-counted pointer to an environment.
pub type EnvironmentPtr = Arc<dyn super::Environment>;
}

/// Definitions specific to the unsynchronized interface.
pub mod unsync {
pub use super::*;
use std::rc::Rc;

/// A reference-counted pointer to an environment.
pub type EnvironmentPtr = Rc<dyn super::Environment>;
}

#[allow(clippy::approx_constant)]
#[cfg(test)]
mod tests {
Expand Down
Loading

0 comments on commit b72b5ab

Please sign in to comment.