mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
273 lines
11 KiB
Rust
273 lines
11 KiB
Rust
// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
// SOFTWARE.
|
|
|
|
use crate::{
|
|
pool::{Handle, Pool},
|
|
visitor::{
|
|
blackboard::Blackboard,
|
|
error::VisitError,
|
|
field::{Field, FieldKind},
|
|
reader::Reader,
|
|
VisitableElementaryField, Visitor, VisitorFlags, VisitorNode,
|
|
},
|
|
};
|
|
use byteorder::{LittleEndian, ReadBytesExt};
|
|
use nalgebra::{
|
|
Complex, Const, Matrix, Matrix2, Matrix3, Matrix4, Quaternion, RawStorage, RawStorageMut,
|
|
Scalar, UnitComplex, UnitQuaternion, Vector2, Vector3, Vector4, U1,
|
|
};
|
|
use std::io::Read;
|
|
use uuid::Uuid;
|
|
|
|
pub struct BinaryReader<'a> {
|
|
src: &'a mut dyn Read,
|
|
}
|
|
|
|
impl<'a> BinaryReader<'a> {
|
|
pub fn new(src: &'a mut dyn Read) -> Self {
|
|
Self { src }
|
|
}
|
|
}
|
|
|
|
fn read_vec_n<T, S, const N: usize>(
|
|
src: &mut dyn Read,
|
|
) -> Result<Matrix<T, Const<N>, U1, S>, VisitError>
|
|
where
|
|
T: VisitableElementaryField + Scalar + Default,
|
|
S: RawStorage<T, Const<N>> + RawStorageMut<T, Const<N>> + Default,
|
|
{
|
|
let mut vec = Matrix::<T, Const<N>, U1, S>::default();
|
|
for v in vec.iter_mut() {
|
|
v.read(src)?;
|
|
}
|
|
Ok(vec)
|
|
}
|
|
|
|
impl Reader for BinaryReader<'_> {
|
|
fn read_field(&mut self) -> Result<Field, VisitError> {
|
|
let src = &mut *self.src;
|
|
let name_len = src.read_u32::<LittleEndian>()? as usize;
|
|
let mut raw_name = vec![Default::default(); name_len];
|
|
src.read_exact(raw_name.as_mut_slice())?;
|
|
let id = src.read_u8()?;
|
|
Ok(Field::new(
|
|
String::from_utf8(raw_name)?.as_str(),
|
|
match id {
|
|
1 => FieldKind::U8(src.read_u8()?),
|
|
2 => FieldKind::I8(src.read_i8()?),
|
|
3 => FieldKind::U16(src.read_u16::<LittleEndian>()?),
|
|
4 => FieldKind::I16(src.read_i16::<LittleEndian>()?),
|
|
5 => FieldKind::U32(src.read_u32::<LittleEndian>()?),
|
|
6 => FieldKind::I32(src.read_i32::<LittleEndian>()?),
|
|
7 => FieldKind::U64(src.read_u64::<LittleEndian>()?),
|
|
8 => FieldKind::I64(src.read_i64::<LittleEndian>()?),
|
|
9 => FieldKind::F32(src.read_f32::<LittleEndian>()?),
|
|
10 => FieldKind::F64(src.read_f64::<LittleEndian>()?),
|
|
11 => FieldKind::Vector3F32({
|
|
let x = src.read_f32::<LittleEndian>()?;
|
|
let y = src.read_f32::<LittleEndian>()?;
|
|
let z = src.read_f32::<LittleEndian>()?;
|
|
Vector3::new(x, y, z)
|
|
}),
|
|
12 => FieldKind::UnitQuaternion({
|
|
let x = src.read_f32::<LittleEndian>()?;
|
|
let y = src.read_f32::<LittleEndian>()?;
|
|
let z = src.read_f32::<LittleEndian>()?;
|
|
let w = src.read_f32::<LittleEndian>()?;
|
|
UnitQuaternion::new_normalize(Quaternion::new(w, x, y, z))
|
|
}),
|
|
13 => FieldKind::Matrix4({
|
|
let mut f = [0.0f32; 16];
|
|
for n in &mut f {
|
|
*n = src.read_f32::<LittleEndian>()?;
|
|
}
|
|
Matrix4::from_row_slice(&f)
|
|
}),
|
|
14 => FieldKind::BinaryBlob({
|
|
let len = src.read_u32::<LittleEndian>()? as usize;
|
|
let mut vec = vec![Default::default(); len];
|
|
src.read_exact(vec.as_mut_slice())?;
|
|
vec
|
|
}),
|
|
15 => FieldKind::Bool(src.read_u8()? != 0),
|
|
16 => FieldKind::Matrix3({
|
|
let mut f = [0.0f32; 9];
|
|
for n in &mut f {
|
|
*n = src.read_f32::<LittleEndian>()?;
|
|
}
|
|
Matrix3::from_row_slice(&f)
|
|
}),
|
|
17 => FieldKind::Vector2F32({
|
|
let x = src.read_f32::<LittleEndian>()?;
|
|
let y = src.read_f32::<LittleEndian>()?;
|
|
Vector2::new(x, y)
|
|
}),
|
|
18 => FieldKind::Vector4F32({
|
|
let x = src.read_f32::<LittleEndian>()?;
|
|
let y = src.read_f32::<LittleEndian>()?;
|
|
let z = src.read_f32::<LittleEndian>()?;
|
|
let w = src.read_f32::<LittleEndian>()?;
|
|
Vector4::new(x, y, z, w)
|
|
}),
|
|
19 => FieldKind::Uuid({
|
|
let mut bytes = uuid::Bytes::default();
|
|
src.read_exact(&mut bytes)?;
|
|
Uuid::from_bytes(bytes)
|
|
}),
|
|
20 => FieldKind::UnitComplex({
|
|
let re = src.read_f32::<LittleEndian>()?;
|
|
let im = src.read_f32::<LittleEndian>()?;
|
|
UnitComplex::from_complex(Complex::new(re, im))
|
|
}),
|
|
21 => {
|
|
let type_id = src.read_u8()?;
|
|
let element_size = src.read_u32::<LittleEndian>()?;
|
|
let data_size = src.read_u64::<LittleEndian>()?;
|
|
let mut bytes = vec![0; data_size as usize];
|
|
src.read_exact(&mut bytes)?;
|
|
FieldKind::PodArray {
|
|
type_id,
|
|
element_size,
|
|
bytes,
|
|
}
|
|
}
|
|
22 => FieldKind::Matrix2({
|
|
let mut f = [0.0f32; 4];
|
|
for n in &mut f {
|
|
*n = src.read_f32::<LittleEndian>()?;
|
|
}
|
|
Matrix2::from_row_slice(&f)
|
|
}),
|
|
23 => FieldKind::Vector2F64(read_vec_n(src)?),
|
|
24 => FieldKind::Vector3F64(read_vec_n(src)?),
|
|
25 => FieldKind::Vector4F64(read_vec_n(src)?),
|
|
|
|
26 => FieldKind::Vector2I8(read_vec_n(src)?),
|
|
27 => FieldKind::Vector3I8(read_vec_n(src)?),
|
|
28 => FieldKind::Vector4I8(read_vec_n(src)?),
|
|
|
|
29 => FieldKind::Vector2U8(read_vec_n(src)?),
|
|
30 => FieldKind::Vector3U8(read_vec_n(src)?),
|
|
31 => FieldKind::Vector4U8(read_vec_n(src)?),
|
|
|
|
32 => FieldKind::Vector2I16(read_vec_n(src)?),
|
|
33 => FieldKind::Vector3I16(read_vec_n(src)?),
|
|
34 => FieldKind::Vector4I16(read_vec_n(src)?),
|
|
|
|
35 => FieldKind::Vector2U16(read_vec_n(src)?),
|
|
36 => FieldKind::Vector3U16(read_vec_n(src)?),
|
|
37 => FieldKind::Vector4U16(read_vec_n(src)?),
|
|
|
|
38 => FieldKind::Vector2I32(read_vec_n(src)?),
|
|
39 => FieldKind::Vector3I32(read_vec_n(src)?),
|
|
40 => FieldKind::Vector4I32(read_vec_n(src)?),
|
|
|
|
41 => FieldKind::Vector2U32(read_vec_n(src)?),
|
|
42 => FieldKind::Vector3U32(read_vec_n(src)?),
|
|
43 => FieldKind::Vector4U32(read_vec_n(src)?),
|
|
|
|
44 => FieldKind::Vector2I64(read_vec_n(src)?),
|
|
45 => FieldKind::Vector3I64(read_vec_n(src)?),
|
|
46 => FieldKind::Vector4I64(read_vec_n(src)?),
|
|
|
|
47 => FieldKind::Vector2U64(read_vec_n(src)?),
|
|
48 => FieldKind::Vector3U64(read_vec_n(src)?),
|
|
49 => FieldKind::Vector4U64(read_vec_n(src)?),
|
|
50 => FieldKind::String({
|
|
let len = src.read_u32::<LittleEndian>()? as usize;
|
|
let mut vec = vec![Default::default(); len];
|
|
src.read_exact(vec.as_mut_slice())?;
|
|
String::from_utf8(vec)?
|
|
}),
|
|
|
|
_ => return Err(VisitError::UnknownFieldType(id)),
|
|
},
|
|
))
|
|
}
|
|
|
|
fn read_node(&mut self, visitor: &mut Visitor) -> Result<Handle<VisitorNode>, VisitError> {
|
|
let src = &mut *self.src;
|
|
|
|
let name_len = src.read_u32::<LittleEndian>()? as usize;
|
|
let mut raw_name = vec![Default::default(); name_len];
|
|
src.read_exact(raw_name.as_mut_slice())?;
|
|
|
|
let mut node = VisitorNode {
|
|
name: String::from_utf8(raw_name)?,
|
|
..VisitorNode::default()
|
|
};
|
|
|
|
let field_count = src.read_u32::<LittleEndian>()? as usize;
|
|
for _ in 0..field_count {
|
|
let field = self.read_field()?;
|
|
node.fields.push(field);
|
|
}
|
|
|
|
let src = &mut *self.src;
|
|
|
|
let child_count = src.read_u32::<LittleEndian>()? as usize;
|
|
let mut children = Vec::with_capacity(child_count);
|
|
for _ in 0..child_count {
|
|
children.push(self.read_node(visitor)?);
|
|
}
|
|
|
|
node.children.clone_from(&children);
|
|
|
|
let handle = visitor.nodes.spawn(node);
|
|
for child_handle in children.iter() {
|
|
let child = visitor.nodes.borrow_mut(*child_handle);
|
|
child.parent = handle;
|
|
}
|
|
|
|
Ok(handle)
|
|
}
|
|
|
|
fn read(&mut self) -> Result<Visitor, VisitError> {
|
|
let src = &mut *self.src;
|
|
|
|
let mut magic: [u8; 4] = Default::default();
|
|
src.read_exact(&mut magic)?;
|
|
|
|
let version = if magic.eq(Visitor::MAGIC_BINARY_OLD.as_bytes()) {
|
|
0u32
|
|
} else if magic.eq(Visitor::MAGIC_BINARY_CURRENT.as_bytes()) {
|
|
src.read_u32::<LittleEndian>()?
|
|
} else {
|
|
return Err(VisitError::NotSupportedFormat);
|
|
};
|
|
|
|
let mut visitor = Visitor {
|
|
nodes: Pool::new(),
|
|
unique_id_counter: 1,
|
|
rc_map: Default::default(),
|
|
arc_map: Default::default(),
|
|
reading: true,
|
|
current_node: Handle::NONE,
|
|
root: Handle::NONE,
|
|
version,
|
|
blackboard: Blackboard::new(),
|
|
flags: VisitorFlags::NONE,
|
|
};
|
|
visitor.root = self.read_node(&mut visitor)?;
|
|
visitor.current_node = visitor.root;
|
|
Ok(visitor)
|
|
}
|
|
}
|