1#![allow(clippy::bad_bit_mask)]
5#![allow(dead_code)]
6
7use core::cell::RefCell;
8use std::collections::HashMap;
9use std::sync::Arc;
10
11use bitflags::bitflags;
12
13#[derive(PartialEq, Eq, Clone, Copy)]
14pub struct HavokValueType(u32);
15
16bitflags! {
17 impl HavokValueType: u32 {
18 const EMPTY = 0;
19 const BYTE = 1;
20 const INT = 2;
21 const REAL = 3;
22 const VEC4 = 4;
23 const VEC8 = 5;
24 const VEC12 = 6;
25 const VEC16 = 7;
26 const OBJECT = 8;
27 const STRUCT = 9;
28 const STRING = 10;
29
30 const ARRAY = 0x10;
31 const ARRAYBYTE = Self::ARRAY.bits() | Self::BYTE.bits();
32 const ARRAYINT = Self::ARRAY.bits() | Self::INT.bits();
33 const ARRAYREAL = Self::ARRAY.bits() | Self::REAL.bits();
34 const ARRAYVEC4 = Self::ARRAY.bits() | Self::VEC4.bits();
35 const ARRAYVEC8 = Self::ARRAY.bits() | Self::VEC8.bits();
36 const ARRAYVEC12 = Self::ARRAY.bits() | Self::VEC12.bits();
37 const ARRAYVEC16 = Self::ARRAY.bits() | Self::VEC16.bits();
38 const ARRAYOBJECT = Self::ARRAY.bits() | Self::OBJECT.bits();
39 const ARRAYSTRUCT = Self::ARRAY.bits() | Self::STRUCT.bits();
40 const ARRAYSTRING = Self::ARRAY.bits() | Self::STRING.bits();
41
42 const TUPLE = 0x20;
43 const TUPLEBYTE = Self::TUPLE.bits() | Self::BYTE.bits();
44 const TUPLEINT = Self::TUPLE.bits() | Self::INT.bits();
45 const TUPLEREAL = Self::TUPLE.bits() | Self::REAL.bits();
46 const TUPLEVEC4 = Self::TUPLE.bits() | Self::VEC4.bits();
47 const TUPLEVEC8 = Self::TUPLE.bits() | Self::VEC8.bits();
48 const TUPLEVEC12 = Self::TUPLE.bits() | Self::VEC12.bits();
49 const TUPLEVEC16 = Self::TUPLE.bits() | Self::VEC16.bits();
50 const TUPLEOBJECT = Self::TUPLE.bits() | Self::OBJECT.bits();
51 const TUPLESTRUCT = Self::TUPLE.bits() | Self::STRUCT.bits();
52 const TUPLESTRING = Self::TUPLE.bits() | Self::STRING.bits();
53 }
54}
55
56impl HavokValueType {
57 pub fn is_tuple(self) -> bool {
58 (self.bits() & HavokValueType::TUPLE.bits()) != 0
59 }
60
61 pub fn is_array(self) -> bool {
62 (self.bits() & HavokValueType::ARRAY.bits()) != 0
63 }
64
65 pub fn base_type(self) -> HavokValueType {
66 HavokValueType::from_bits(self.bits() & 0x0f).unwrap()
67 }
68
69 pub fn is_vec(self) -> bool {
70 let base_type = self.base_type();
71 base_type == HavokValueType::VEC4
72 || base_type == HavokValueType::VEC8
73 || base_type == HavokValueType::VEC12
74 || base_type == HavokValueType::VEC16
75 }
76
77 pub fn vec_size(self) -> u8 {
78 match self.base_type() {
79 HavokValueType::VEC4 => 4,
80 HavokValueType::VEC8 => 8,
81 HavokValueType::VEC12 => 12,
82 HavokValueType::VEC16 => 16,
83 _ => panic!(),
84 }
85 }
86}
87
88pub type HavokInteger = i32;
89pub type HavokReal = f32;
90
91pub enum HavokValue {
92 Integer(HavokInteger),
93 Real(HavokReal),
94 String(Arc<str>),
95 Vec(Vec<HavokReal>),
96 Array(Vec<HavokValue>),
97 Object(Arc<RefCell<HavokObject>>),
98
99 ObjectReference(usize),
100}
101
102impl HavokValue {
103 pub fn as_int(&self) -> HavokInteger {
104 match self {
105 Self::Integer(x) => *x,
106 _ => panic!(),
107 }
108 }
109
110 pub fn as_object(&self) -> Arc<RefCell<HavokObject>> {
111 match self {
112 Self::Object(x) => x.clone(),
113 _ => panic!(),
114 }
115 }
116
117 pub fn as_array(&self) -> &Vec<HavokValue> {
118 match self {
119 Self::Array(x) => x,
120 _ => panic!(),
121 }
122 }
123
124 pub fn as_string(&self) -> &str {
125 match self {
126 Self::String(x) => x,
127 _ => panic!(),
128 }
129 }
130
131 pub fn as_vec(&self) -> &Vec<HavokReal> {
132 match self {
133 Self::Vec(x) => x,
134 _ => panic!(),
135 }
136 }
137
138 pub fn as_real(&self) -> HavokReal {
139 match self {
140 Self::Real(x) => *x,
141 _ => panic!(),
142 }
143 }
144}
145
146pub struct HavokRootObject {
147 object: Arc<RefCell<HavokObject>>,
148}
149
150impl HavokRootObject {
151 pub fn new(object: Arc<RefCell<HavokObject>>) -> Self {
152 Self { object }
153 }
154
155 pub fn find_object_by_type(&self, type_name: &'static str) -> Arc<RefCell<HavokObject>> {
156 let root_obj = self.object.borrow();
157 let named_variants = root_obj.get("namedVariants");
158
159 for variant in named_variants.as_array() {
160 let variant_obj = variant.as_object();
161 if variant_obj.borrow().get("className").as_string() == type_name {
162 return variant_obj.borrow().get("variant").as_object();
163 }
164 }
165 unreachable!()
166 }
167}
168
169pub struct HavokObjectTypeMember {
170 pub name: Arc<str>,
171 pub type_: HavokValueType,
172 pub tuple_size: u32,
173 pub class_name: Option<Arc<str>>,
174}
175
176impl HavokObjectTypeMember {
177 pub fn new(
178 name: Arc<str>,
179 type_: HavokValueType,
180 tuple_size: u32,
181 type_name: Option<Arc<str>>,
182 ) -> Self {
183 Self {
184 name,
185 type_,
186 tuple_size,
187 class_name: type_name,
188 }
189 }
190}
191
192pub struct HavokObjectType {
193 pub name: Arc<str>,
194 parent: Option<Arc<HavokObjectType>>,
195 members: Vec<HavokObjectTypeMember>,
196}
197
198impl HavokObjectType {
199 pub fn new(
200 name: Arc<str>,
201 parent: Option<Arc<HavokObjectType>>,
202 members: Vec<HavokObjectTypeMember>,
203 ) -> Self {
204 Self {
205 name,
206 parent,
207 members,
208 }
209 }
210
211 pub fn members(&self) -> Vec<&HavokObjectTypeMember> {
212 if let Some(x) = &self.parent {
213 x.members()
214 .into_iter()
215 .chain(self.members.iter())
216 .collect::<Vec<_>>()
217 } else {
218 self.members.iter().collect::<Vec<_>>()
219 }
220 }
221
222 pub fn member_count(&self) -> usize {
223 (if let Some(x) = &self.parent {
224 x.members.len()
225 } else {
226 0
227 }) + self.members.len()
228 }
229}
230
231pub struct HavokObject {
232 pub object_type: Arc<HavokObjectType>,
233 data: HashMap<usize, HavokValue>,
234}
235
236impl HavokObject {
237 pub fn new(object_type: Arc<HavokObjectType>, data: HashMap<usize, HavokValue>) -> Self {
238 Self { object_type, data }
239 }
240
241 pub fn set(&mut self, index: usize, value: HavokValue) {
242 self.data.insert(index, value);
243 }
244
245 pub fn get(&self, member_name: &str) -> &HavokValue {
246 let member_index = self
247 .object_type
248 .members()
249 .iter()
250 .position(|&x| &*x.name == member_name)
251 .unwrap();
252
253 self.data.get(&member_index).unwrap()
254 }
255
256 pub(crate) fn members_mut(&mut self) -> impl Iterator<Item = (&usize, &mut HavokValue)> {
257 self.data.iter_mut()
258 }
259}