diff --git a/finny/Cargo.toml b/finny/Cargo.toml index 205a477..b7cf5f6 100644 --- a/finny/Cargo.toml +++ b/finny/Cargo.toml @@ -14,12 +14,12 @@ readme = "../README.md" derive_more = "0.99.11" finny_derive = { path = "../finny_derive", version = "0.2.0" } arraydeque = { version = "0.4", default-features = false } -slog = { version = "2.7.0", optional = true } - +slog = { version = "2.7.0", optional = true, default-features = false } +heapless = { version = "0.7" } [features] default = ["std", "inspect_slog", "timers_std"] -std = ["arraydeque/std", "timers_std"] +std = ["arraydeque/std", "timers_std", "slog/std"] inspect_slog = ["slog"] timers_std = [] generate_plantuml = ["finny_derive/generate_plantuml"] \ No newline at end of file diff --git a/finny/src/fsm/queue.rs b/finny/src/fsm/queue.rs index 32f39f0..9d75db7 100644 --- a/finny/src/fsm/queue.rs +++ b/finny/src/fsm/queue.rs @@ -171,6 +171,79 @@ mod queue_array { pub use self::queue_array::*; + +pub mod heapless_shared { + //! A heapless queue with Clone and Arc support. + + use core::sync::atomic::{AtomicUsize, Ordering}; + + use crate::FsmError; + + use super::*; + + extern crate alloc; + use alloc::sync::Arc; + use heapless::mpmc::Q64; + +/// An unbound event queue that uses `VecDeque`. + pub struct FsmEventQueueHeaplessShared { + inner: Arc> + } + + impl Clone for FsmEventQueueHeaplessShared where F: FsmBackend { + fn clone(&self) -> Self { + Self { inner: self.inner.clone() } + } + } + + struct Inner { + queue: Q64<::Events>, + len: AtomicUsize + } + + impl FsmEventQueueHeaplessShared { + pub fn new() -> Self { + let q = Q64::new(); + let inner = Inner { + queue: q, + len: AtomicUsize::new(0) + }; + FsmEventQueueHeaplessShared { + inner: Arc::new(inner) + } + } + } + + impl FsmEventQueue for FsmEventQueueHeaplessShared { + fn dequeue(&mut self) -> Option<::Events> { + match self.inner.queue.dequeue() { + Some(e) => { + self.inner.len.fetch_sub(1, Ordering::SeqCst); + Some(e) + }, + None => None + } + } + + fn len(&self) -> usize { + self.inner.len.load(Ordering::SeqCst) + } + } + + impl FsmEventQueueSender for FsmEventQueueHeaplessShared { + fn enqueue::Events>>(&mut self, event: E) -> FsmResult<()> { + match self.inner.queue.enqueue(event.into()) { + Ok(_) => { + self.inner.len.fetch_add(1, Ordering::SeqCst); + Ok(()) + }, + Err(_) => Err(FsmError::QueueOverCapacity) + } + } + } + +} + pub struct FsmEventQueueNull { _ty: PhantomData } @@ -260,6 +333,13 @@ fn test_dequeue_vec_shared() { test_queue(queue); } +#[test] +fn test_heapless_shared() { + use self::heapless_shared::FsmEventQueueHeaplessShared; + let queue = FsmEventQueueHeaplessShared::::new(); + test_queue(queue); +} + #[cfg(test)] fn test_queue>(mut queue: Q) { use super::tests_fsm::{Events, EventA}; diff --git a/finny/src/inspect/slog.rs b/finny/src/inspect/slog.rs index cc04cba..3a11756 100644 --- a/finny/src/inspect/slog.rs +++ b/finny/src/inspect/slog.rs @@ -1,9 +1,13 @@ +extern crate alloc; + use slog::{info, o, error}; use crate::{FsmBackend, FsmBackendImpl, FsmEvent, Inspect, InspectEvent, InspectFsmEvent}; use crate::lib::*; use AsRef; use core::fmt::Debug; use core::any::Any; +use alloc::string::ToString; +use alloc::format; pub struct InspectSlog { pub logger: slog::Logger diff --git a/finny_derive/src/codegen_meta.rs b/finny_derive/src/codegen_meta.rs index bd05ca8..e5411b5 100644 --- a/finny_derive/src/codegen_meta.rs +++ b/finny_derive/src/codegen_meta.rs @@ -155,7 +155,7 @@ pub fn generate_fsm_meta(fsm: &FsmFnInput) -> TokenStream { impl #fsm_info_ty { pub fn plantuml_inner() -> String { - use std::fmt::Write; + use alloc::fmt::Write; let mut output = ( #plant_uml_str ).to_string(); @@ -165,7 +165,7 @@ pub fn generate_fsm_meta(fsm: &FsmFnInput) -> TokenStream { } pub fn plantuml() -> String { - use std::fmt::Write; + use alloc::fmt::Write; let mut output = String::new();