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