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:
Dmitry Stepanov
2024-03-28 13:40:06 +03:00
parent c4c6f64ba5
commit 32b9ced7d3
3 changed files with 37 additions and 10 deletions
+7 -2
View File
@@ -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)?;
+11
View File
@@ -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;
+19 -8
View File
@@ -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,