open_dis_rust/entity_information/
collision_pdu.rs1use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::common::{
11 dis_error::DISError,
12 entity_id::EntityId,
13 event_id::EventId,
14 pdu::Pdu,
15 pdu_header::{PduHeader, PduType, ProtocolFamily},
16 vector3_float::Vector3Float,
17};
18
19#[derive(Clone, Debug)]
20pub struct CollisionPdu {
22 pub pdu_header: PduHeader,
23 pub issuing_entity_id: EntityId,
24 pub colliding_entity_id: EntityId,
25 pub event_id: EventId,
26 pub collision_type: u8,
27 pub padding: u8,
28 pub velocity: Vector3Float,
29 pub mass: f32,
30 pub location_wrt_entity: Vector3Float,
31}
32
33impl Default for CollisionPdu {
34 fn default() -> Self {
35 CollisionPdu {
36 pdu_header: PduHeader::default(
37 PduType::Collision,
38 ProtocolFamily::EntityInformation,
39 60,
40 ),
41 issuing_entity_id: EntityId::default(1),
42 colliding_entity_id: EntityId::default(2),
43 event_id: EventId::default(1),
44 collision_type: 0,
45 padding: 0,
46 velocity: Vector3Float::default(),
47 mass: 0.0,
48 location_wrt_entity: Vector3Float::default(),
49 }
50 }
51}
52
53impl Pdu for CollisionPdu {
54 fn serialize(&mut self, buf: &mut BytesMut) {
55 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
56 .expect("The length of the PDU should fit in a u16.");
57 self.pdu_header.serialize(buf);
58 self.issuing_entity_id.serialize(buf);
59 self.colliding_entity_id.serialize(buf);
60 self.event_id.serialize(buf);
61 buf.put_u8(self.collision_type);
62 buf.put_u8(self.padding);
63 self.velocity.serialize(buf);
64 buf.put_f32(self.mass);
65 self.location_wrt_entity.serialize(buf);
66 }
67
68 fn deserialize(mut buffer: BytesMut) -> Result<CollisionPdu, DISError> {
69 let pdu_header = PduHeader::deserialize(&mut buffer);
70 if pdu_header.pdu_type == PduType::Collision {
71 let issuing_entity_id = EntityId::deserialize(&mut buffer);
72 let colliding_entity_id = EntityId::deserialize(&mut buffer);
73 let event_id = EventId::deserialize(&mut buffer);
74 let collision_type = buffer.get_u8();
75 let padding = buffer.get_u8();
76 let velocity = Vector3Float::deserialize(&mut buffer);
77 let mass = buffer.get_f32();
78 let location_wrt_entity = Vector3Float::deserialize(&mut buffer);
79 Ok(CollisionPdu {
80 pdu_header,
81 issuing_entity_id,
82 colliding_entity_id,
83 event_id,
84 collision_type,
85 padding,
86 velocity,
87 mass,
88 location_wrt_entity,
89 })
90 } else {
91 Err(DISError::invalid_header(
92 format!("Expected PDU type Collision, got {:?}", pdu_header.pdu_type),
93 None,
94 ))
95 }
96 }
97
98 fn as_any(&self) -> &dyn Any {
99 self
100 }
101
102 fn deserialize_without_header(
103 mut buffer: BytesMut,
104 pdu_header: PduHeader,
105 ) -> Result<Self, DISError>
106 where
107 Self: Sized,
108 {
109 let issuing_entity_id = EntityId::deserialize(&mut buffer);
110 let colliding_entity_id = EntityId::deserialize(&mut buffer);
111 let event_id = EventId::deserialize(&mut buffer);
112 let collision_type = buffer.get_u8();
113 let padding = buffer.get_u8();
114 let velocity = Vector3Float::deserialize(&mut buffer);
115 let mass = buffer.get_f32();
116 let location_wrt_entity = Vector3Float::deserialize(&mut buffer);
117 Ok(CollisionPdu {
118 pdu_header,
119 issuing_entity_id,
120 colliding_entity_id,
121 event_id,
122 collision_type,
123 padding,
124 velocity,
125 mass,
126 location_wrt_entity,
127 })
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::CollisionPdu;
134 use crate::common::{
135 pdu::Pdu,
136 pdu_header::{PduHeader, PduType, ProtocolFamily},
137 };
138 use bytes::BytesMut;
139
140 #[test]
141 fn create_header() {
142 let collision_pdu = CollisionPdu::default();
143 let header = PduHeader::default(PduType::Collision, ProtocolFamily::EntityInformation, 60);
144 assert_eq!(
145 header.protocol_version,
146 collision_pdu.pdu_header.protocol_version
147 );
148 assert_eq!(header.exercise_id, collision_pdu.pdu_header.exercise_id);
149 assert_eq!(header.pdu_type, collision_pdu.pdu_header.pdu_type);
150 assert_eq!(
151 header.protocol_family,
152 collision_pdu.pdu_header.protocol_family
153 );
154 assert_eq!(header.length, collision_pdu.pdu_header.length);
155 assert_eq!(header.status_record, collision_pdu.pdu_header.status_record);
156 }
157
158 #[test]
159 fn deserialize_header() {
160 let mut collision_pdu = CollisionPdu::default();
161 let mut buffer = BytesMut::new();
162 collision_pdu.serialize(&mut buffer);
163
164 let new_collision_pdu = CollisionPdu::deserialize(buffer).unwrap();
165 assert_eq!(new_collision_pdu.pdu_header, collision_pdu.pdu_header);
166 }
167}