open_dis_rust/entity_information/
entity_state_update_pdu.rs1use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::{
11 common::{
12 dis_error::DISError,
13 entity_id::EntityId,
14 euler_angles::EulerAngles,
15 linear_velocity::LinearVelocity,
16 pdu::Pdu,
17 pdu_header::{PduHeader, PduType, ProtocolFamily},
18 world_coordinate::WorldCoordinate,
19 },
20 warfare::data_types::variable_parameter::VariableParameter,
21};
22
23#[derive(Clone, Debug)]
24pub struct EntityStateUpdatePdu {
26 pub pdu_header: PduHeader,
27 pub entity_id: EntityId,
28 pub padding: u8,
29 pub number_of_variable_parameters: u8,
30 pub entity_linear_velocity: LinearVelocity,
31 pub entity_location: WorldCoordinate,
32 pub entity_orientation: EulerAngles,
33 pub entity_appearance: u32,
34 pub variable_parameter_records: Vec<VariableParameter>,
35}
36
37impl Default for EntityStateUpdatePdu {
38 fn default() -> Self {
39 EntityStateUpdatePdu {
40 pdu_header: PduHeader::default(
41 PduType::EntityStateUpdate,
42 ProtocolFamily::EntityInformation,
43 864 / 8,
44 ),
45 entity_id: EntityId::default(1),
46 padding: 0,
47 number_of_variable_parameters: 0,
48 entity_linear_velocity: LinearVelocity::default(),
49 entity_location: WorldCoordinate::default(),
50 entity_orientation: EulerAngles::default(),
51 entity_appearance: 0,
52 variable_parameter_records: vec![],
53 }
54 }
55}
56
57impl Pdu for EntityStateUpdatePdu {
58 fn serialize(&mut self, buf: &mut BytesMut) {
59 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
60 .expect("The length of the PDU should fit in a u16.");
61 self.pdu_header.serialize(buf);
62 self.entity_id.serialize(buf);
63 buf.put_u8(self.padding);
64 buf.put_u8(self.number_of_variable_parameters);
65 self.entity_linear_velocity.serialize(buf);
66 self.entity_location.serialize(buf);
67 self.entity_orientation.serialize(buf);
68 buf.put_u32(self.entity_appearance);
69 for i in 0..self.variable_parameter_records.len() {
70 self.variable_parameter_records[i].serialize(buf);
71 }
72 }
73
74 fn deserialize(mut buffer: BytesMut) -> Result<EntityStateUpdatePdu, DISError> {
75 let pdu_header = PduHeader::deserialize(&mut buffer);
76 if pdu_header.pdu_type == PduType::EntityStateUpdate {
77 let entity_id = EntityId::deserialize(&mut buffer);
78 let padding = buffer.get_u8();
79 let number_of_variable_parameters = buffer.get_u8();
80 let entity_linear_velocity = LinearVelocity::deserialize(&mut buffer);
81 let entity_location = WorldCoordinate::deserialize(&mut buffer);
82 let entity_orientation = EulerAngles::deserialize(&mut buffer);
83 let entity_appearance = buffer.get_u32();
84 let mut variable_parameter_records: Vec<VariableParameter> = vec![];
85 for _i in 0..number_of_variable_parameters {
86 variable_parameter_records.push(VariableParameter::deserialize(&mut buffer));
87 }
88 Ok(EntityStateUpdatePdu {
89 pdu_header,
90 entity_id,
91 padding,
92 number_of_variable_parameters,
93 entity_linear_velocity,
94 entity_location,
95 entity_orientation,
96 entity_appearance,
97 variable_parameter_records,
98 })
99 } else {
100 Err(DISError::invalid_header(
101 format!(
102 "Expected PDU type EntityStateUpdate, got {:?}",
103 pdu_header.pdu_type
104 ),
105 None,
106 ))
107 }
108 }
109
110 fn as_any(&self) -> &dyn Any {
111 self
112 }
113
114 fn deserialize_without_header(
115 mut buffer: BytesMut,
116 pdu_header: PduHeader,
117 ) -> Result<Self, DISError>
118 where
119 Self: Sized,
120 {
121 let entity_id = EntityId::deserialize(&mut buffer);
122 let padding = buffer.get_u8();
123 let number_of_variable_parameters = buffer.get_u8();
124 let entity_linear_velocity = LinearVelocity::deserialize(&mut buffer);
125 let entity_location = WorldCoordinate::deserialize(&mut buffer);
126 let entity_orientation = EulerAngles::deserialize(&mut buffer);
127 let entity_appearance = buffer.get_u32();
128 let mut variable_parameter_records: Vec<VariableParameter> = vec![];
129 for _i in 0..number_of_variable_parameters {
130 variable_parameter_records.push(VariableParameter::deserialize(&mut buffer));
131 }
132 Ok(EntityStateUpdatePdu {
133 pdu_header,
134 entity_id,
135 padding,
136 number_of_variable_parameters,
137 entity_linear_velocity,
138 entity_location,
139 entity_orientation,
140 entity_appearance,
141 variable_parameter_records,
142 })
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use super::EntityStateUpdatePdu;
149 use crate::common::{
150 pdu::Pdu,
151 pdu_header::{PduHeader, PduType, ProtocolFamily},
152 };
153 use bytes::BytesMut;
154
155 #[test]
156 fn create_header() {
157 let entity_state_update_pdu = EntityStateUpdatePdu::default();
158 let header = PduHeader::default(
159 PduType::EntityStateUpdate,
160 ProtocolFamily::EntityInformation,
161 864 / 8,
162 );
163 assert_eq!(
164 header.protocol_version,
165 entity_state_update_pdu.pdu_header.protocol_version
166 );
167 assert_eq!(
168 header.exercise_id,
169 entity_state_update_pdu.pdu_header.exercise_id
170 );
171 assert_eq!(header.pdu_type, entity_state_update_pdu.pdu_header.pdu_type);
172 assert_eq!(
173 header.protocol_family,
174 entity_state_update_pdu.pdu_header.protocol_family
175 );
176 assert_eq!(header.length, entity_state_update_pdu.pdu_header.length);
177 assert_eq!(
178 header.status_record,
179 entity_state_update_pdu.pdu_header.status_record
180 );
181 }
182
183 #[test]
184 fn deserialize_header() {
185 let mut entity_state_update_pdu = EntityStateUpdatePdu::default();
186 let mut buffer = BytesMut::new();
187 entity_state_update_pdu.serialize(&mut buffer);
188
189 let new_entity_state_update_pdu = EntityStateUpdatePdu::deserialize(buffer).unwrap();
190 assert_eq!(
191 new_entity_state_update_pdu.pdu_header,
192 entity_state_update_pdu.pdu_header
193 );
194 }
195}