subtr_actor_spec/
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}
71
72impl ActorStateModeler {
73 pub fn new() -> Self {
79 Self {
80 actor_states: HashMap::new(),
81 actor_ids_by_type: HashMap::new(),
82 }
83 }
84
85 pub fn process_frame(
96 &mut self,
97 frame: &boxcars::Frame,
98 frame_index: usize,
99 ) -> SubtrActorResult<()> {
100 if let Some(err) = frame
101 .deleted_actors
102 .iter()
103 .map(|n| self.delete_actor(n))
104 .find(|r| r.is_err())
105 {
106 return err.map(|_| ());
107 }
108 if let Some(err) = frame
109 .new_actors
110 .iter()
111 .map(|n| self.new_actor(n))
112 .find(|r| r.is_err())
113 {
114 return err;
115 }
116 if let Some(err) = frame
117 .updated_actors
118 .iter()
119 .map(|u| self.update_attribute(u, frame_index))
120 .find(|r| r.is_err())
121 {
122 return err.map(|_| ());
123 }
124 Ok(())
125 }
126
127 pub fn new_actor(&mut self, new_actor: &boxcars::NewActor) -> SubtrActorResult<()> {
128 if let Some(state) = self.actor_states.get(&new_actor.actor_id) {
129 if state.object_id != new_actor.object_id {
130 return SubtrActorError::new_result(SubtrActorErrorVariant::ActorIdAlreadyExists {
131 actor_id: new_actor.actor_id.clone(),
132 object_id: new_actor.object_id.clone(),
133 });
134 }
135 } else {
136 self.actor_states
137 .insert(new_actor.actor_id, ActorState::new(new_actor));
138 self.actor_ids_by_type
139 .entry(new_actor.object_id)
140 .or_insert_with(|| Vec::new())
141 .push(new_actor.actor_id)
142 }
143 Ok(())
144 }
145
146 pub fn update_attribute(
147 &mut self,
148 update: &boxcars::UpdatedAttribute,
149 frame_index: usize,
150 ) -> SubtrActorResult<Option<(boxcars::Attribute, usize)>> {
151 self.actor_states
152 .get_mut(&update.actor_id)
153 .map(|state| state.update_attribute(update, frame_index))
154 .ok_or_else(|| {
155 SubtrActorError::new(SubtrActorErrorVariant::UpdatedActorIdDoesNotExist {
156 update: update.clone(),
157 })
158 })
159 }
160
161 pub fn delete_actor(&mut self, actor_id: &boxcars::ActorId) -> SubtrActorResult<ActorState> {
162 let state = self.actor_states.remove(actor_id).ok_or_else(|| {
163 SubtrActorError::new(SubtrActorErrorVariant::NoStateForActorId {
164 actor_id: actor_id.clone(),
165 })
166 })?;
167
168 self.actor_ids_by_type
169 .entry(state.object_id)
170 .or_insert_with(|| Vec::new())
171 .retain(|x| x != actor_id);
172
173 Ok(state)
174 }
175}