subtr_actor/processor/
actor_state.rs1use crate::{SubtrActorError, SubtrActorErrorVariant, SubtrActorResult};
2use boxcars;
3use std::collections::HashMap;
4
5#[derive(PartialEq, Debug, Clone)]
10pub struct ActorState {
11 pub attributes: HashMap<boxcars::ObjectId, (boxcars::Attribute, usize)>,
14 pub derived_attributes: HashMap<String, (boxcars::Attribute, usize)>,
17 pub object_id: boxcars::ObjectId,
19 pub name_id: Option<i32>,
21}
22
23impl ActorState {
24 fn new(new_actor: &boxcars::NewActor) -> Self {
34 Self {
35 attributes: HashMap::new(),
36 derived_attributes: HashMap::new(),
37 object_id: new_actor.object_id,
38 name_id: new_actor.name_id,
39 }
40 }
41
42 fn update_attribute(
53 &mut self,
54 update: &boxcars::UpdatedAttribute,
55 frame_index: usize,
56 ) -> Option<(boxcars::Attribute, usize)> {
57 self.attributes
58 .insert(update.object_id, (update.attribute.clone(), frame_index))
59 }
60
61 pub(crate) fn set_derived_attribute(
62 &mut self,
63 key: &'static str,
64 attribute: boxcars::Attribute,
65 frame_index: usize,
66 ) {
67 if let Some(entry) = self.derived_attributes.get_mut(key) {
68 *entry = (attribute, frame_index);
69 } else {
70 self.derived_attributes
71 .insert(key.to_owned(), (attribute, frame_index));
72 }
73 }
74}
75
76pub struct ActorStateModeler {
80 pub actor_states: HashMap<boxcars::ActorId, ActorState>,
82 pub actor_ids_by_type: HashMap<boxcars::ObjectId, Vec<boxcars::ActorId>>,
84 pub recently_deleted_actor_states: HashMap<boxcars::ActorId, ActorState>,
90}
91
92impl Default for ActorStateModeler {
93 fn default() -> Self {
94 Self::new()
95 }
96}
97
98impl ActorStateModeler {
99 pub fn new() -> Self {
105 Self {
106 actor_states: HashMap::new(),
107 actor_ids_by_type: HashMap::new(),
108 recently_deleted_actor_states: HashMap::new(),
109 }
110 }
111
112 pub fn process_frame(
123 &mut self,
124 frame: &boxcars::Frame,
125 frame_index: usize,
126 ) -> SubtrActorResult<()> {
127 self.recently_deleted_actor_states.clear();
128 if let Some(err) = frame
129 .deleted_actors
130 .iter()
131 .map(|n| self.delete_actor(n))
132 .find(|r| r.is_err())
133 {
134 return err.map(|_| ());
135 }
136 if let Some(err) = frame
137 .new_actors
138 .iter()
139 .map(|n| self.new_actor(n))
140 .find(|r| r.is_err())
141 {
142 return err;
143 }
144 if let Some(err) = frame
145 .updated_actors
146 .iter()
147 .map(|u| self.update_attribute(u, frame_index))
148 .find(|r| r.is_err())
149 {
150 return err.map(|_| ());
151 }
152 Ok(())
153 }
154
155 pub fn new_actor(&mut self, new_actor: &boxcars::NewActor) -> SubtrActorResult<()> {
156 if let Some(state) = self.actor_states.get(&new_actor.actor_id) {
157 if state.object_id != new_actor.object_id {
158 return SubtrActorError::new_result(SubtrActorErrorVariant::ActorIdAlreadyExists {
159 actor_id: new_actor.actor_id,
160 object_id: new_actor.object_id,
161 });
162 }
163 } else {
164 self.actor_states
165 .insert(new_actor.actor_id, ActorState::new(new_actor));
166 self.actor_ids_by_type
167 .entry(new_actor.object_id)
168 .or_default()
169 .push(new_actor.actor_id)
170 }
171 Ok(())
172 }
173
174 pub fn update_attribute(
175 &mut self,
176 update: &boxcars::UpdatedAttribute,
177 frame_index: usize,
178 ) -> SubtrActorResult<Option<(boxcars::Attribute, usize)>> {
179 self.actor_states
180 .get_mut(&update.actor_id)
181 .map(|state| state.update_attribute(update, frame_index))
182 .ok_or_else(|| {
183 SubtrActorError::new(SubtrActorErrorVariant::UpdatedActorIdDoesNotExist {
184 update: update.clone(),
185 })
186 })
187 }
188
189 pub fn delete_actor(&mut self, actor_id: &boxcars::ActorId) -> SubtrActorResult<ActorState> {
190 let state = self.actor_states.remove(actor_id).ok_or_else(|| {
191 SubtrActorError::new(SubtrActorErrorVariant::NoStateForActorId {
192 actor_id: *actor_id,
193 })
194 })?;
195
196 self.actor_ids_by_type
197 .entry(state.object_id)
198 .or_default()
199 .retain(|x| x != actor_id);
200
201 self.recently_deleted_actor_states
202 .insert(*actor_id, state.clone());
203
204 Ok(state)
205 }
206}