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