physis/havok/
object.rs

1// SPDX-FileCopyrightText: 2020 Inseok Lee
2// SPDX-License-Identifier: MIT
3
4#![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}