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