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
use enumflags2::BitFlags;

use crate::{structure::guid::GUID};
use crate::structure::time::Timestamp;

//use std::num::Zero; // unstable

/// DDS spec 2.2.2.5.4
/// "Read" indicates whether or not the corresponding data sample has already been read.
#[derive(BitFlags, Debug, Copy, Clone, PartialEq)]
#[repr(u32)] // DDS Spec 1.4 section 2.3.3 DCPS PSM : IDL defines these as "unsigned long", so u32
pub enum SampleState {
  Read = 0b0001,
  NotRead = 0b0010,
}

impl SampleState {
  /// Set that contains all possible states
  pub fn any() -> BitFlags<Self> {
    BitFlags::<Self>::all()
  }
}

/// DDS spec 2.2.2.5.1.8
///
#[derive(BitFlags, Debug, Copy, Clone, PartialEq)]
#[repr(u32)]
pub enum ViewState {
  ///  indicates that either this is the first time that the DataReader has ever
  /// accessed samples of that instance, or else that the DataReader has accessed previous
  /// samples of the instance, but the instance has since been reborn (i.e., become
  /// not-alive and then alive again).
  New = 0b0001,
  /// indicates that the DataReader has already accessed samples of the same
  ///instance and that the instance has not been reborn since
  NotNew = 0b0010,
}
impl ViewState {
  /// Set that contains all possible states
  pub fn any() -> BitFlags<Self> {
    BitFlags::<Self>::all()
  }
}

#[derive(BitFlags, Debug, Copy, Clone, PartialEq)]
#[repr(u32)]
pub enum InstanceState {
  Alive = 0b0001,
  /// A DataWriter has actively disposed this instance
  NotAlive_Disposed = 0b0010,
  /// There are no writers alive.
  NotAlive_NoWriters = 0b0100,
}

impl InstanceState {
  /// Set that contains all possible states
  pub fn any() -> BitFlags<Self> {
    BitFlags::<Self>::all()
  }
  /// Set that contains both not_alive states.
  pub fn not_alive() -> BitFlags<Self> {
    InstanceState::NotAlive_Disposed | InstanceState::NotAlive_NoWriters
  }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct NotAliveGenerationCounts {
  pub disposed_generation_count: i32,
  pub no_writers_generation_count: i32,
}

impl NotAliveGenerationCounts {
  /// Initial count value
  pub fn zero() -> Self {
    NotAliveGenerationCounts {
      disposed_generation_count: 0,
      no_writers_generation_count: 0,
    }
  }

  /// Marker value for "never accessed"
  pub fn sub_zero() -> Self {
    NotAliveGenerationCounts {
      disposed_generation_count: -1,
      no_writers_generation_count: -1,
    }
  }

  pub fn total(&self) -> i32 {
    self.disposed_generation_count + self.no_writers_generation_count
  }
}

/// DDS SampleInfo
#[derive(Debug, Clone, PartialEq)]
pub struct SampleInfo {
  pub sample_state: SampleState,
  pub view_state: ViewState,
  pub instance_state: InstanceState,
  // For each instance the middleware internally maintains these counts relative
  // to each DataReader. The counts capture snapshots if the corresponding
  // counters at the time the sample was received.
  pub generation_counts: NotAliveGenerationCounts,
  // The ranks are are computed based solely on the actual samples in the
  // ordered collection returned by the read or take.
  // The sample_rank indicates the number of samples of the same instance that
  // follow the current one in the collection.
  pub sample_rank: i32,
  // The generation_rank indicates the difference in generations between the
  // samples S and the Most Recent Sample of the same instance that appears In
  // the returned Collection (MRSIC). It counts the number of times the instance
  // transitioned from not-alive to alive in the time from the reception of the
  // S to the  reception of MRSIC. The generation rank is computed with:
  // generation_rank =
  //(MRSIC.disposed_generation_count + MRSIC.no_writers_generation_count)
  //- (S.disposed_generation_count + S.no_writers_generation_count)
  pub generation_rank: i32,
  // The absolute_generation_rank indicates the difference in "generations"
  // between sample S and the Most Recent Sample of the instance that the
  // middlware has received (MRS). It counts the number of times the instance
  // transitioned from not-alive to alive in the time from the reception of the
  // S to the time when the read or take was called. absolute_generation_rank =
  //(MRS.disposed_generation_count + MRS.no_writers_generation_count)
  //- (S.disposed_generation_count + S.no_writers_generation_count)
  pub absolute_generation_rank: i32,
  pub source_timestamp: Option<Timestamp>,

  // the publication_handle that identifies locally the DataWriter that modified
  // the instance (wrote the sample)
  pub publication_handle: GUID,
}

#[allow(clippy::new_without_default)]
impl SampleInfo {
  pub fn new_deprecated() -> Self {
    Self {
      sample_state: SampleState::NotRead,
      view_state: ViewState::New,
      instance_state: InstanceState::Alive,
      generation_counts: NotAliveGenerationCounts::zero(),
      sample_rank: 0,
      generation_rank: 0,
      absolute_generation_rank: 0,
      source_timestamp: None,
      publication_handle: GUID::GUID_UNKNOWN,
    }
  }

  /* These accessor methods should not be needed, as the SampleInfo structure is likely
     not about to change too much, as it is specified by the DDS spec.

  pub fn sample_state(&self) -> SampleState {
    self.sample_state
  }

  pub fn set_sample_state(&mut self, sample_state: SampleState) {
    self.sample_state = sample_state
  }

  pub fn view_state(&self) -> ViewState {
    self.view_state
  }

  pub fn set_view_state(&mut self, view_state: ViewState) {
    self.view_state = view_state
  }

  pub fn instance_state(&self) -> InstanceState {
    self.instance_state
  }

  pub fn set_instance_state(&mut self, instance_state: InstanceState) {
    self.instance_state = instance_state
  }

  pub fn disposed_generation_count(&self) -> i32 {
    self.disposed_generation_count
  }

  pub fn no_writers_generation_count(&self) -> i32 {
    self.no_writers_generation_count
  }

  pub fn sample_rank(&self) -> i32 {
    self.sample_rank
  }

  pub fn generation_rank(&self) -> i32 {
    self.generation_rank
  }

  pub fn absolute_generation_rank(&self) -> i32 {
    self.absolute_generation_rank
  }

  pub fn source_timestamp(&self) -> Timestamp {
    self.source_timestamp
  }

  pub fn set_source_timestamp(&mut self, source_timestamp: Timestamp) {
    self.source_timestamp = source_timestamp
  }

  pub fn publication_handle(&self) -> GUID {
    self.publication_handle
  }

  pub fn set_publication_handle(&mut self, publication_handle: GUID) {
    self.publication_handle = publication_handle
  }
  */
}