diff --git a/fyrox-core/src/visitor/mod.rs b/fyrox-core/src/visitor/mod.rs index d807de595..7bc019c63 100644 --- a/fyrox-core/src/visitor/mod.rs +++ b/fyrox-core/src/visitor/mod.rs @@ -80,6 +80,9 @@ use std::{ sync::Arc, }; +/// Latest version number of the visitor. +pub const LATEST_VERSION: u32 = 1; + /// Proxy struct for plain data. It is used to serialize arrays of trivially copyable data (`Vec`) /// directly as a large chunk of data. For example, an attempt to serialize `Vec` serialize each /// byte as a separate node which is very inefficient. @@ -289,6 +292,7 @@ pub struct Visitor { reading: bool, current_node: Handle, root: Handle, + version: u32, /// A place to store whatever objects may be needed to help with reading and writing values. pub blackboard: Blackboard, /// Flags that can activate special behavior in some Visit values, such as @@ -376,6 +380,9 @@ pub enum Format { } impl Visitor { + /// Old header marker for binary version. + pub const MAGIC_BINARY_OLD: &'static str = "RG3D"; + /// Sequence of bytes that is automatically written at the start when a visitor is encoded into /// bytes. It is written by [Visitor::save_binary_to_file], [Visitor::save_binary_to_memory], /// and [Visitor::save_binary_to_vec]. @@ -383,7 +390,10 @@ impl Visitor { /// [Visitor::load_binary_from_file] will return an error if this sequence of bytes is not present /// at the beginning of the file, and [Visitor::load_binary_from_memory] will return an error of /// these bytes are not at the beginning of the given slice. - pub const MAGIC_BINARY: &'static str = "RG3D"; + pub const MAGIC_BINARY_CURRENT: &'static str = "FBAF"; + + /// Old header marker for ASCII version. + pub const MAGIC_ASCII_OLD: &'static str = "FTAF"; /// Sequence of bytes that is automatically written at the start when a visitor is encoded into /// ascii form. It is written by [Visitor::save_ascii_to_file], [Visitor::save_ascii_to_memory], @@ -392,8 +402,7 @@ impl Visitor { /// [Visitor::load_ascii_from_file] will return an error if this sequence of bytes is not present /// at the beginning of the file, and [Visitor::load_ascii_from_memory] will return an error of /// these bytes are not at the beginning of the given slice. - // Fyrox Text Asset Format. - pub const MAGIC_ASCII: &'static str = "FTAF"; + pub const MAGIC_ASCII_CURRENT: &'static str = "FTAX"; /// Checks whether the given reader points to a supported file format or not. #[must_use] @@ -405,9 +414,13 @@ impl Visitor { pub fn detect_format(src: &mut dyn Read) -> Format { let mut magic: [u8; 4] = Default::default(); if src.read_exact(&mut magic).is_ok() { - if magic.eq(Visitor::MAGIC_BINARY.as_bytes()) { + if magic.eq(Visitor::MAGIC_BINARY_OLD.as_bytes()) + || magic.eq(Visitor::MAGIC_BINARY_CURRENT.as_bytes()) + { return Format::Binary; - } else if magic.eq(Visitor::MAGIC_ASCII.as_bytes()) { + } else if magic.eq(Visitor::MAGIC_ASCII_OLD.as_bytes()) + || magic.eq(Visitor::MAGIC_ASCII_CURRENT.as_bytes()) + { return Format::Ascii; } } @@ -433,6 +446,7 @@ impl Visitor { reading: false, current_node: root, root, + version: LATEST_VERSION, blackboard: Blackboard::new(), flags: VisitorFlags::NONE, } diff --git a/fyrox-core/src/visitor/reader/ascii.rs b/fyrox-core/src/visitor/reader/ascii.rs index aaf7a38a1..d9de0b711 100644 --- a/fyrox-core/src/visitor/reader/ascii.rs +++ b/fyrox-core/src/visitor/reader/ascii.rs @@ -371,9 +371,17 @@ impl Reader for AsciiReader<'_> { let src = &mut self.src; let magic: [u8; 4] = [src.next()?, src.next()?, src.next()?, src.next()?]; - if !magic.eq(Visitor::MAGIC_ASCII.as_bytes()) { + + let version = if magic.eq(Visitor::MAGIC_ASCII_OLD.as_bytes()) { + 0u32 + } else if magic.eq(Visitor::MAGIC_ASCII_CURRENT.as_bytes()) { + src.skip_until(|ch| ch != b':')?; + src.skip_n(1)?; + src.read_num_until::(b';')? + } else { return Err(VisitError::NotSupportedFormat); - } + }; + let mut visitor = Visitor { nodes: Pool::new(), unique_id_counter: 1, @@ -382,6 +390,7 @@ impl Reader for AsciiReader<'_> { reading: true, current_node: Handle::NONE, root: Handle::NONE, + version, blackboard: Blackboard::new(), flags: VisitorFlags::NONE, }; @@ -583,7 +592,7 @@ mod test { #[test] fn test_parse_visitor() { - let input = r#"FTAF + let input = r#"FTAX:1; SomeNode [2: U8 @@ -609,6 +618,8 @@ mod test { let visitor = reader.read().unwrap(); + assert_eq!(visitor.version, 1); + let some_node = visitor.find_node("SomeNode").unwrap(); assert_eq!(some_node.fields.len(), 2); assert_eq!( diff --git a/fyrox-core/src/visitor/reader/binary.rs b/fyrox-core/src/visitor/reader/binary.rs index 85b844ecf..96cc55708 100644 --- a/fyrox-core/src/visitor/reader/binary.rs +++ b/fyrox-core/src/visitor/reader/binary.rs @@ -244,9 +244,15 @@ impl Reader for BinaryReader<'_> { let mut magic: [u8; 4] = Default::default(); src.read_exact(&mut magic)?; - if !magic.eq(Visitor::MAGIC_BINARY.as_bytes()) { + + 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::()? + } else { return Err(VisitError::NotSupportedFormat); - } + }; + let mut visitor = Visitor { nodes: Pool::new(), unique_id_counter: 1, @@ -255,6 +261,7 @@ impl Reader for BinaryReader<'_> { reading: true, current_node: Handle::NONE, root: Handle::NONE, + version, blackboard: Blackboard::new(), flags: VisitorFlags::NONE, }; diff --git a/fyrox-core/src/visitor/writer/ascii.rs b/fyrox-core/src/visitor/writer/ascii.rs index ecc73e071..41a2099a3 100644 --- a/fyrox-core/src/visitor/writer/ascii.rs +++ b/fyrox-core/src/visitor/writer/ascii.rs @@ -21,7 +21,7 @@ use crate::visitor::{ field::{Field, FieldKind}, writer::Writer, - VisitResult, Visitor, VisitorNode, + VisitResult, Visitor, VisitorNode, LATEST_VERSION, }; use base64::Engine; use byteorder::WriteBytesExt; @@ -250,7 +250,7 @@ impl Writer for AsciiWriter { } fn write(&self, visitor: &Visitor, dest: &mut dyn Write) -> VisitResult { - writeln!(dest, "{}", Visitor::MAGIC_ASCII)?; + writeln!(dest, "{}:{};", Visitor::MAGIC_ASCII_CURRENT, LATEST_VERSION)?; self.write_node(visitor, &visitor.nodes[visitor.root], 0, dest) } } diff --git a/fyrox-core/src/visitor/writer/binary.rs b/fyrox-core/src/visitor/writer/binary.rs index 5ed9a67d9..f2c9d9f40 100644 --- a/fyrox-core/src/visitor/writer/binary.rs +++ b/fyrox-core/src/visitor/writer/binary.rs @@ -273,7 +273,8 @@ impl Writer for BinaryWriter { } fn write(&self, visitor: &Visitor, dest: &mut dyn Write) -> VisitResult { - dest.write_all(Visitor::MAGIC_BINARY.as_bytes())?; + dest.write_all(Visitor::MAGIC_BINARY_CURRENT.as_bytes())?; + dest.write_u32::(visitor.version)?; let mut stack = vec![visitor.root]; while let Some(node_handle) = stack.pop() { let node = visitor.nodes.borrow(node_handle);