1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
/*!
# [Actor]s clients
The module holds the implementation of the different clients that can be assigned to [Actor]s.
Any structure can become a client to an Actor if it implements the [Update] trait with either or both [Read] and [Write] traits.
# Example
## Logging
A simple logger with a single entry:
```
use gmt_dos_clients::Logging;
let logging = Logging::<f64>::default();
```
A logger with 2 entries and pre-allocated with 1000 elements:
```
use gmt_dos_clients::Logging;
let logging = Logging::<f64>::default().n_entry(2).capacity(1_000);
```
## Signals
A constant signal for 100 steps
```
use gmt_dos_clients::{Signals, Signal};
let signal: Signals = Signals::new(1, 100).signals(Signal::Constant(3.14));
```
A 2 outputs signal made of a constant and a sinusoid for 100 steps
```
use gmt_dos_clients::{Signals, Signal};
let signal: Signals = Signals::new(2, 100)
.output_signal(0, Signal::Constant(3.14))
.output_signal(1, Signal::Sinusoid{
amplitude: 1f64,
sampling_frequency_hz: 1000f64,
frequency_hz: 20f64,
phase_s: 0f64
});
```
## Rate transitionner
A rate transition actor for a named output/input pair sampling a [Vec]
```
use gmt_dos_clients::Sampler;
#[derive(interface::UID)]
enum MyIO {};
let sampler = Sampler::<Vec<f64>, MyIO>::default();
```
## Alias to input/output UID
Creating an alias to an already existing [UniqueIdentifier] (UID)
```
use std::sync::Arc;
use interface::{Data, Write, UniqueIdentifier,Size, UID, Update};
// Original UID
#[derive(UID)]
#[uid(data = u8)]
pub enum A {}
pub struct Client {}
impl Update for Client {}
impl Write<A> for Client {
fn write(&mut self) -> Option<Data<A>> {
Some(Data::new(10u8))
}
}
impl Size<A> for Client {
fn len(&self) -> usize {
123
}
}
// A alias with `Write` and `Size` trait implementation for `Client`
#[derive(UID)]
#[uid(data = u8)]
#[alias(name = A, client = Client, traits = Write ,Size)]
pub enum B {}
let _: <A as UniqueIdentifier>::DataType = 1u8;
let _: <B as UniqueIdentifier>::DataType = 2u8;
let mut client = Client {};
println!(
"Client Write<B>: {:?}",
<Client as Write<B>>::write(&mut client)
);
println!(
"Client Size<B>: {:?}",
<Client as Size<B>>::len(&mut client)
);
```
[Actor]: https://docs.rs/gmt_dos-actors
[Update]: https://docs.rs/gmt_dos-actors-clients_interface/latest/gmt_dos_actors-clients_interface/struct.Update.html
[Read]: https://docs.rs/gmt_dos-actors-clients_interface/latest/gmt_dos_actors-clients_interface/struct.Read.html
[Write]: https://docs.rs/gmt_dos-actors-clients_interface/latest/gmt_dos_actors-clients_interface/struct.Write.html
[UniqueIdentifier]: https://docs.rs/gmt_dos-actors-clients_interface/latest/gmt_dos_actors-clients_interface/struct.UniqueIdentifier.html
*/
pub use interface::Tick;
use interface::{Data, Read, TimerMarker, UniqueIdentifier, Update, Write};
use std::mem::take;
pub mod signals;
pub mod multiplex;
pub mod low_pass_filter;
pub mod fill;
pub use signals::{OneSignal, Signal, Signals};
pub mod timer;
pub use timer::Timer;
pub mod logging;
pub use logging::Logging;
pub mod sampler;
pub use sampler::Sampler;
pub mod pulse;
pub use pulse::Pulse;
pub mod integrator;
pub use integrator::{Integrator, Offset};
pub mod smooth;
pub use smooth::{Smooth, Weight};
pub mod average;
pub use average::Average;
#[cfg(feature = "nalgebra")]
mod gain;
#[cfg(feature = "nalgebra")]
pub use gain::Gain;
pub mod leftright;
pub mod once;
pub mod operator;
pub mod print;
pub mod select;
/// Concatenates data into a [Vec]
pub struct Concat<T>(Vec<T>);
impl<T: Default> Default for Concat<T> {
fn default() -> Self {
Self(Vec::new())
}
}
impl<T> Update for Concat<T> where T: Send + Sync {}
impl<T, U> Read<U> for Concat<T>
where
T: Clone + Default + Send + Sync,
U: UniqueIdentifier<DataType = T>,
{
fn read(&mut self, data: Data<U>) {
self.0.push((*data).clone());
}
}
impl<T, U> Write<U> for Concat<T>
where
T: Clone + Send + Sync,
U: UniqueIdentifier<DataType = Vec<T>>,
{
fn write(&mut self) -> Option<Data<U>> {
Some(Data::new(take(&mut self.0)))
}
}
/// Discrete data sets
pub struct Source<T> {
n: usize,
data: Vec<T>,
}
impl<T> Source<T> {
pub fn new(data: Vec<T>, n: usize) -> Self {
Source { n, data }
}
}
impl<T> TimerMarker for Source<T> {}
impl<T> Update for Source<T> where T: Send + Sync {}
impl<T, V> Write<V> for Source<T>
where
V: UniqueIdentifier<DataType = Vec<T>>,
T: Send + Sync,
{
fn write(&mut self) -> Option<Data<V>> {
if self.data.is_empty() {
None
} else {
let y: Vec<T> = self.data.drain(..self.n).collect();
Some(Data::new(y))
}
}
}
pub trait Progress {
fn progress<S: Into<String>>(name: S, len: usize) -> Self;
fn increment(&mut self);
fn finish(&mut self) {}
}
impl Progress for indicatif::ProgressBar {
fn progress<S: Into<String>>(name: S, len: usize) -> Self {
let progress = indicatif::ProgressBar::new(len as u64);
progress.set_style(
indicatif::ProgressStyle::with_template(
"{msg} [{eta_precise}] {bar:50.cyan/blue} {percent:>3}%",
)
.unwrap(),
);
progress.set_message(name.into());
// let bar: Bar = progress.bar(self.tick, "Timer:");
progress
}
#[inline]
fn increment(&mut self) {
self.inc(1)
}
#[inline]
fn finish(&mut self) {
Self::finish(self);
}
}