mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
fixed serialization issues when hot-reloading plugins
- inheritable variables have an optimization, that does not serialize unchagned variables. This optimization can now be turned off with appropriate flag
This commit is contained in:
@@ -2,7 +2,10 @@
|
||||
//!
|
||||
//! For more info see [`InheritableVariable`]
|
||||
|
||||
use crate::{reflect::prelude::*, visitor::prelude::*};
|
||||
use crate::{
|
||||
reflect::prelude::*,
|
||||
visitor::{prelude::*, VisitorFlags},
|
||||
};
|
||||
use bitflags::bitflags;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
@@ -278,7 +281,9 @@ where
|
||||
// region at all.
|
||||
self.flags.get_mut().remove(VariableFlags::MODIFIED);
|
||||
}
|
||||
} else if self.flags.get().contains(VariableFlags::MODIFIED) {
|
||||
} else if self.flags.get().contains(VariableFlags::MODIFIED)
|
||||
|| visitor.flags.contains(VisitorFlags::SERIALIZE_EVERYTHING)
|
||||
{
|
||||
let mut region = visitor.enter_region(name)?;
|
||||
self.value.visit("Value", &mut region)?;
|
||||
self.flags.get_mut().0.visit("Flags", &mut region)?;
|
||||
|
||||
@@ -26,6 +26,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use base64::Engine;
|
||||
use bitflags::bitflags;
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use fxhash::FxHashMap;
|
||||
use std::any::TypeId;
|
||||
@@ -1131,6 +1132,13 @@ impl Blackboard {
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct VisitorFlags: u32 {
|
||||
const NONE = 0;
|
||||
const SERIALIZE_EVERYTHING = 1 << 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Visitor {
|
||||
nodes: Pool<VisitorNode>,
|
||||
rc_map: FxHashMap<u64, Rc<dyn Any>>,
|
||||
@@ -1139,6 +1147,7 @@ pub struct Visitor {
|
||||
current_node: Handle<VisitorNode>,
|
||||
root: Handle<VisitorNode>,
|
||||
pub blackboard: Blackboard,
|
||||
pub flags: VisitorFlags,
|
||||
}
|
||||
|
||||
pub trait Visit {
|
||||
@@ -1165,6 +1174,7 @@ impl Visitor {
|
||||
current_node: root,
|
||||
root,
|
||||
blackboard: Blackboard::new(),
|
||||
flags: VisitorFlags::NONE,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1352,6 +1362,7 @@ impl Visitor {
|
||||
current_node: Handle::NONE,
|
||||
root: Handle::NONE,
|
||||
blackboard: Blackboard::new(),
|
||||
flags: VisitorFlags::NONE,
|
||||
};
|
||||
visitor.root = visitor.load_node_binary(&mut reader)?;
|
||||
visitor.current_node = visitor.root;
|
||||
|
||||
@@ -102,7 +102,7 @@ use crate::scene::node::container::NodeContainer;
|
||||
use fyrox_core::notify;
|
||||
use fyrox_core::notify::{EventKind, RecursiveMode, Watcher};
|
||||
use fyrox_core::pool::{PayloadContainer, Ticket};
|
||||
use fyrox_core::visitor::{Visit, Visitor};
|
||||
use fyrox_core::visitor::{Visit, Visitor, VisitorFlags};
|
||||
use winit::{
|
||||
dpi::{Position, Size},
|
||||
event_loop::EventLoopWindowTarget,
|
||||
@@ -2540,7 +2540,13 @@ impl Engine {
|
||||
false
|
||||
}
|
||||
|
||||
fn read_binary_blob(
|
||||
fn make_writing_visitor() -> Visitor {
|
||||
let mut visitor = Visitor::new();
|
||||
visitor.flags = VisitorFlags::SERIALIZE_EVERYTHING;
|
||||
visitor
|
||||
}
|
||||
|
||||
fn make_reading_visitor(
|
||||
binary_blob: &[u8],
|
||||
serialization_context: &Arc<SerializationContext>,
|
||||
resource_manager: &ResourceManager,
|
||||
@@ -2629,7 +2635,7 @@ impl Engine {
|
||||
// Take the node out of the graph first.
|
||||
let (ticket, node) = scene.graph.take_reserve(handle);
|
||||
let mut container = NodeContainer::new(node);
|
||||
let mut visitor = Visitor::new();
|
||||
let mut visitor = Self::make_writing_visitor();
|
||||
container
|
||||
.visit("Node", &mut visitor)
|
||||
.map_err(|e| e.to_string())?;
|
||||
@@ -2648,7 +2654,7 @@ impl Engine {
|
||||
// Take the script out of the node and serialize it. The script will be
|
||||
// dropped and destroyed.
|
||||
let mut script = record.script.take();
|
||||
let mut visitor = Visitor::new();
|
||||
let mut visitor = Self::make_writing_visitor();
|
||||
visit_opt_script("Script", &mut script, &mut visitor)
|
||||
.map_err(|e| e.to_string())?;
|
||||
let binary_blob =
|
||||
@@ -2702,7 +2708,7 @@ impl Engine {
|
||||
|
||||
// Unload the plugin.
|
||||
if let DynamicPluginState::Loaded(dynamic) = state {
|
||||
let mut visitor = Visitor::new();
|
||||
let mut visitor = Self::make_writing_visitor();
|
||||
dynamic
|
||||
.plugin_mut()
|
||||
.visit("Plugin", &mut visitor)
|
||||
@@ -2735,7 +2741,12 @@ impl Engine {
|
||||
if let DynamicPluginState::Unloaded { binary_blob } = state {
|
||||
let mut dynamic = DynamicPlugin::load(lib_path)?;
|
||||
|
||||
let mut visitor = Visitor::load_from_memory(binary_blob).map_err(|e| e.to_string())?;
|
||||
let mut visitor = Self::make_reading_visitor(
|
||||
binary_blob,
|
||||
&self.serialization_context,
|
||||
&self.resource_manager,
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
dynamic
|
||||
.plugin_mut()
|
||||
.visit("Plugin", &mut visitor)
|
||||
@@ -2766,7 +2777,7 @@ impl Engine {
|
||||
if node_state.binary_blob.is_empty() {
|
||||
// Only scripts needs to be reloaded.
|
||||
for script in node_state.scripts {
|
||||
let mut visitor = Self::read_binary_blob(
|
||||
let mut visitor = Self::make_reading_visitor(
|
||||
&script.binary_blob,
|
||||
&self.serialization_context,
|
||||
&self.resource_manager,
|
||||
@@ -2783,7 +2794,7 @@ impl Engine {
|
||||
));
|
||||
}
|
||||
} else {
|
||||
let mut visitor = Self::read_binary_blob(
|
||||
let mut visitor = Self::make_reading_visitor(
|
||||
&node_state.binary_blob,
|
||||
&self.serialization_context,
|
||||
&self.resource_manager,
|
||||
|
||||
Reference in New Issue
Block a user