subtr_actor/
actor_state.rs1use crate::*;
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
62pub struct ActorStateModeler {
66 pub actor_states: HashMap<boxcars::ActorId, ActorState>,
68 pub actor_ids_by_type: HashMap<boxcars::ObjectId, Vec<boxcars::ActorId>>,
70 pub recently_deleted_actor_states: HashMap<boxcars::ActorId, ActorState>,
76}
77
78impl Default for ActorStateModeler {
79 fn default() -> Self {
80 Self::new()
81 }
82}
83
84impl ActorStateModeler {
85 pub fn new() -> Self {
91 Self {
92 actor_states: HashMap::new(),
93 actor_ids_by_type: HashMap::new(),
94 recently_deleted_actor_states: HashMap::new(),
95 }
96 }
97
98 pub fn process_frame(
109 &mut self,
110 frame: &boxcars::Frame,
111 frame_index: usize,
112 ) -> SubtrActorResult<()> {
113 self.recently_deleted_actor_states.clear();
114 if let Some(err) = frame
115 .deleted_actors
116 .iter()
117 .map(|n| self.delete_actor(n))
118 .find(|r| r.is_err())
119 {
120 return err.map(|_| ());
121 }
122 if let Some(err) = frame
123 .new_actors
124 .iter()
125 .map(|n| self.new_actor(n))
126 .find(|r| r.is_err())
127 {
128 return err;
129 }
130 if let Some(err) = frame
131 .updated_actors
132 .iter()
133 .map(|u| self.update_attribute(u, frame_index))
134 .find(|r| r.is_err())
135 {
136 return err.map(|_| ());
137 }
138 Ok(())
139 }
140
141 pub fn new_actor(&mut self, new_actor: &boxcars::NewActor) -> SubtrActorResult<()> {
142 if let Some(state) = self.actor_states.get(&new_actor.actor_id) {
143 if state.object_id != new_actor.object_id {
144 return SubtrActorError::new_result(SubtrActorErrorVariant::ActorIdAlreadyExists {
145 actor_id: new_actor.actor_id,
146 object_id: new_actor.object_id,
147 });
148 }
149 } else {
150 self.actor_states
151 .insert(new_actor.actor_id, ActorState::new(new_actor));
152 self.actor_ids_by_type
153 .entry(new_actor.object_id)
154 .or_default()
155 .push(new_actor.actor_id)
156 }
157 Ok(())
158 }
159
160 pub fn update_attribute(
161 &mut self,
162 update: &boxcars::UpdatedAttribute,
163 frame_index: usize,
164 ) -> SubtrActorResult<Option<(boxcars::Attribute, usize)>> {
165 self.actor_states
166 .get_mut(&update.actor_id)
167 .map(|state| state.update_attribute(update, frame_index))
168 .ok_or_else(|| {
169 SubtrActorError::new(SubtrActorErrorVariant::UpdatedActorIdDoesNotExist {
170 update: update.clone(),
171 })
172 })
173 }
174
175 pub fn delete_actor(&mut self, actor_id: &boxcars::ActorId) -> SubtrActorResult<ActorState> {
176 let state = self.actor_states.remove(actor_id).ok_or_else(|| {
177 SubtrActorError::new(SubtrActorErrorVariant::NoStateForActorId {
178 actor_id: *actor_id,
179 })
180 })?;
181
182 self.actor_ids_by_type
183 .entry(state.object_id)
184 .or_default()
185 .retain(|x| x != actor_id);
186
187 self.recently_deleted_actor_states
188 .insert(*actor_id, state.clone());
189
190 Ok(state)
191 }
192}