1use serde::{Deserialize, Serialize};
4use std::any::TypeId;
5use std::ops::{Deref, DerefMut};
6
7use crate::{Error, Result};
8
9#[derive(Clone, Copy, PartialEq, Serialize, Deserialize)]
13pub struct Position
14{
15 pub longitude: f64,
17 pub latitude: f64,
19}
20
21#[derive(Clone, Copy, PartialEq, Serialize, Deserialize)]
23pub struct Velocity
24{
25 pub x: f32,
27 pub y: f32,
29}
30
31pub trait StateTrait
33{
34 fn to_state(self) -> State;
36}
37
38#[derive(Clone, Copy, PartialEq, Serialize, Deserialize)]
46pub enum State
47{
48 Position(Position),
50 Velocity(Velocity),
52}
53
54#[derive(Default, Clone, PartialEq, Serialize, Deserialize)]
62pub struct States(Vec<State>);
63
64impl Deref for States
65{
66 type Target = Vec<State>;
67 fn deref(&self) -> &Self::Target
68 {
69 &self.0
70 }
71}
72
73impl DerefMut for States
74{
75 fn deref_mut(&mut self) -> &mut Self::Target
76 {
77 &mut self.0
78 }
79}
80
81macro_rules! build_states_getter {
84 ($(#[$attr:meta])* => ($name:tt, $type:tt)) => {
85 $(#[$attr])*
86 pub fn $name(&self) -> Result<$type>
87 {
88 let res = self.0.iter().find_map(|x| match x
89 {
90 State::$type(p) => Some(p),
91 _ => None,
92 });
93 if res.is_none()
94 {
95 Err(Error::UnknownState(std::any::type_name::<$type>()))
96 }
97 else
98 {
99 Ok(*res.unwrap())
100 }
101 }
102 };
103}
104
105impl States
106{
107 build_states_getter!(
108 => (get_position, Position));
110 build_states_getter!(
111 => (get_velocity, Velocity));
113 pub fn add_state<T: StateTrait + 'static>(&mut self, t: T) -> crate::Result<&mut States>
115 {
116 let it = self.0.iter().find(|x| match x
117 {
118 State::Position(_) => TypeId::of::<Position>() == TypeId::of::<T>(),
119 State::Velocity(_) => TypeId::of::<Velocity>() == TypeId::of::<T>(),
120 });
121 if it.is_none()
122 {
123 self.push(t.to_state());
124 Ok(self)
125 }
126 else
127 {
128 Err(Error::DuplicateState(std::any::type_name::<T>()))
129 }
130 }
131 pub fn update_state<T: StateTrait + 'static>(&mut self, t: T) -> crate::Result<&mut States>
133 {
134 let it = self.0.iter().enumerate().find(|(_, x)| match x
135 {
136 State::Position(_) => TypeId::of::<Position>() == TypeId::of::<T>(),
137 State::Velocity(_) => TypeId::of::<Velocity>() == TypeId::of::<T>(),
138 });
139 if let Some((index, _)) = it
140 {
141 self.remove(index);
142 self.push(t.to_state());
143 Ok(self)
144 }
145 else
146 {
147 Err(Error::UnknownState(std::any::type_name::<T>()))
148 }
149 }
150}
151
152impl From<States> for SharedStates
153{
154 fn from(val: States) -> Self
155 {
156 SharedStates::new(val)
157 }
158}
159
160impl StateTrait for Position
161{
162 fn to_state(self) -> State
163 {
164 State::Position(self)
165 }
166}
167
168impl StateTrait for Velocity
169{
170 fn to_state(self) -> State
171 {
172 State::Velocity(self)
173 }
174}
175
176macro_rules! build_shared_states_getter {
183 ($(#[$attr:meta])* => ($name:tt, $type:tt)) => {
184 $(#[$attr])*
185 pub fn $name(&self) -> Result<$type>
186 {
187 self.states.lock()?.$name()
188 }
189 };
190}
191
192#[derive(Clone)]
194pub struct SharedStates
195{
196 states: ccutils::sync::ArcMutex<States>,
197}
198
199impl SharedStates
200{
201 build_shared_states_getter!(
202 => (get_position, Position));
204 build_shared_states_getter!(
205 => (get_velocity, Velocity));
207 pub fn new(states: States) -> Self
209 {
210 Self {
211 states: states.into(),
212 }
213 }
214 pub fn update_states(&self, updater: impl Fn(&mut crate::states::States)) -> Result<()>
216 {
217 let mut locked = self.states.lock()?;
218 updater(&mut locked);
219 Ok(())
220 }
221 pub fn update_state<T: crate::states::StateTrait + 'static>(&self, state: T)
223 -> crate::Result<()>
224 {
225 self.states.lock()?.update_state(state)?;
226 Ok(())
227 }
228 pub fn to_owned_states(&self) -> Result<States>
230 {
231 Ok(self.states.lock()?.to_owned())
232 }
233}