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
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}