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
/*!
# Scope server (features = `"server"`)

The scopes defined in the server module send data to the scope clients.

## Example

```ignore
use gmt_dos_clients_scope::server;

#[derive(interface::UID)]
pub enum Signal {}

let server_address = "127.0.0.1:5001";
let sampling_period = 1e-3; // 1ms

let mut monitor = server::Monitor::new();
let server = server::Scope::<Signal>::builder(server_address, &mut monitor)
    .sampling_period(sampling_period)
    .build().unwrap();
```
*/

mod scope;
mod shot;
use std::marker::PhantomData;

pub use gmt_dos_clients_transceiver::Monitor;

use gmt_dos_clients_transceiver::{On, Transceiver, TransceiverError, Transmitter};
use interface::UniqueIdentifier;
pub use shot::{GmtShot, Shot};

use crate::{payload::ScopeData, PlotScope};

#[derive(Debug, thiserror::Error)]
pub enum ServerError {
    #[error("failed to create a transmiter for a scope server")]
    Transmitter(#[from] TransceiverError),
}

/// Builder for scope server
#[derive(Debug)]
pub struct Builder<'a, FU, K>
where
    FU: UniqueIdentifier,
    K: crate::ScopeKind,
{
    address: String,
    monitor: Option<&'a mut Monitor>,
    tau: Option<f64>,
    idx: Option<usize>,
    scale: Option<f64>,
    size: Option<[usize; 2]>,
    frame_by_frame: bool,
    minmax: Option<(f64, f64)>,
    payload: PhantomData<FU>,
    kind: PhantomData<K>,
}

impl<'a, FU, K> Default for Builder<'a, FU, K>
where
    FU: UniqueIdentifier,
    K: crate::ScopeKind,
{
    fn default() -> Self {
        Self {
            address: Default::default(),
            monitor: Default::default(),
            tau: Default::default(),
            idx: Default::default(),
            scale: Default::default(),
            size: Default::default(),
            frame_by_frame: false,
            minmax: Default::default(),
            payload: PhantomData,
            kind: PhantomData,
        }
    }
}

impl<'a, FU, K> Builder<'a, FU, K>
where
    FU: UniqueIdentifier + 'static,
    K: crate::ScopeKind,
{
    /// Selects the signal channel #
    pub fn channel(mut self, idx: usize) -> Self {
        self.idx = Some(idx);
        self
    }
    /// Sets the signal sampling period `[s]`
    pub fn sampling_period(mut self, tau: f64) -> Self {
        self.tau = Some(tau);
        self
    }
    /// Sets the signal sampling frequency `[Hz]`
    pub fn sampling_frequency(mut self, freq: f64) -> Self {
        self.tau = Some(freq.recip());
        self
    }
    /// Sets the factor to scale up the data
    pub fn scale(mut self, scale: f64) -> Self {
        self.scale = Some(scale);
        self
    }
}

/// Server for signal for plotting scope
pub type Scope<FU> = XScope<FU, crate::PlotScope>;

/// Scope server
///
/// Wraps a signal into the scope payload before sending it to the scope [client](crate::client)
#[derive(Debug)]
pub struct XScope<FU, K = PlotScope>
where
    FU: UniqueIdentifier,
{
    tx: Transceiver<ScopeData<FU>, Transmitter, On>,
    tau: f64,
    idx: Option<usize>,
    size: [usize; 2],
    minmax: Option<(f64, f64)>,
    scale: Option<f64>,
    kind: PhantomData<K>,
}

impl<FU, K> interface::Update for XScope<FU, K>
where
    FU: UniqueIdentifier,
    K: crate::ScopeKind + Send + Sync,
{
}