From 0c75da09123e2ec6d8a4e8f7e32001c81ff65ced Mon Sep 17 00:00:00 2001 From: Weird Constructor Date: Thu, 4 Aug 2022 03:46:56 +0200 Subject: [PATCH] Made serialization working --- src/blocklang.rs | 40 ++++++++++++++++++++++++++++++++-------- src/matrix.rs | 26 +++++++++++++++++++++++--- src/matrix_repr.rs | 25 ++++++++++++++++++++++++- src/nodes/node_conf.rs | 2 +- 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/src/blocklang.rs b/src/blocklang.rs index 0856c56..b88c59b 100644 --- a/src/blocklang.rs +++ b/src/blocklang.rs @@ -1116,7 +1116,7 @@ pub struct BlockFunSnapshot { } impl BlockFunSnapshot { - pub fn serialize(&self) -> String { + pub fn serialize(&self) -> Value { let mut v = json!({ "VERSION": 1, }); @@ -1132,12 +1132,10 @@ impl BlockFunSnapshot { v["areas"] = areas; - v.to_string() + v } - pub fn deserialize(s: &str) -> Result { - let v: Value = serde_json::from_str(s)?; - + pub fn deserialize(v: &Value) -> Result { let mut a = vec![]; let areas = &v["areas"]; @@ -1184,6 +1182,10 @@ impl BlockFun { } } + pub fn is_unset(&self) -> bool { + self.generation == 0 + } + pub fn block_language(&self) -> Rc> { self.language.clone() } @@ -1817,12 +1819,34 @@ mod test { let mut bf = BlockFun::new(lang.clone()); let sn = bf.save_snapshot(); - let serialized = sn.serialize(); + let serialized = sn.serialize().to_string(); assert_eq!(serialized, "{\"VERSION\":1,\"areas\":[{\"auto_shrink\":false,\"blocks\":[],\"header\":\"\",\"size\":[16,16]}],\"current_block_id_counter\":0}"); - let sn = BlockFunSnapshot::deserialize(&serialized).expect("No deserialization error"); + let v: Value = serde_json::from_str(&serialized).unwrap(); + let sn = BlockFunSnapshot::deserialize(&v).expect("No deserialization error"); let mut bf2 = BlockFun::new(lang); let bf2 = bf2.load_snapshot(&sn); } -} + #[test] + fn check_blockfun_serialize_1() { + let dsp_lib = synfx_dsp_jit::get_standard_library(); + let lang = crate::blocklang_def::setup_hxdsp_block_language(dsp_lib); + let mut bf = BlockFun::new(lang.clone()); + + bf.instanciate_at(0, 0, 0, "+", None); + + let sn = bf.save_snapshot(); + let serialized = sn.serialize().to_string(); + assert_eq!(serialized, + "{\"VERSION\":1,\"areas\":[{\"auto_shrink\":false,\"blocks\":[{\"block\":{\"color\":4,\"contains\":[null,null],\"expanded\":true,\"id\":1,\"inputs\":[\"\",\"\"],\"lbl\":\"+\",\"outputs\":[\"\"],\"rows\":2,\"typ\":\"+\"},\"x\":0,\"y\":0}],\"header\":\"\",\"size\":[16,16]}],\"current_block_id_counter\":1}"); + + let v: Value = serde_json::from_str(&serialized).unwrap(); + let sn = BlockFunSnapshot::deserialize(&v).expect("No deserialization error"); + let mut bf2 = BlockFun::new(lang); + bf2.load_snapshot(&sn); + + let bv = bf2.block_at(0, 0, 0).unwrap(); + assert!(bv.has_input(0)); + } +} diff --git a/src/matrix.rs b/src/matrix.rs index b592fca..9817541 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -10,7 +10,7 @@ pub use crate::nodes::MinMaxMonitorSamples; use crate::nodes::{NodeConfigurator, NodeGraphOrdering, NodeProg, MAX_ALLOCATED_NODES}; pub use crate::CellDir; use crate::ScopeHandle; -use crate::blocklang::BlockFun; +use crate::blocklang::{BlockFun, BlockFunSnapshot}; use crate::block_compiler::BlkJITCompileError; use std::collections::{HashMap, HashSet}; @@ -607,7 +607,7 @@ impl Matrix { /// Retrieve a handle to the block function `id`. In case you modify the block function, /// make sure to call [check_block_function]. - pub fn get_block_function(&mut self, id: usize) -> Option>> { + pub fn get_block_function(&self, id: usize) -> Option>> { self.config.get_block_function(id) } @@ -845,9 +845,21 @@ impl Matrix { tracker_id += 1; } + let mut block_funs: Vec> = vec![]; + let mut bf_id = 0; + while let Some(bf) = self.get_block_function(bf_id) { + block_funs.push(if bf.lock().unwrap().is_unset() { + None + } else { + Some(bf.lock().unwrap().save_snapshot()) + }); + + bf_id += 1; + } + let properties = self.properties.iter().map(|(k, v)| (k.to_string(), v.clone())).collect(); - MatrixRepr { cells, params, atoms, patterns, properties, version: 2 } + MatrixRepr { cells, params, atoms, patterns, block_funs, properties, version: 2 } } /// Loads the matrix from a previously my [Matrix::to_repr] @@ -879,6 +891,14 @@ impl Matrix { } } + for (bf_id, block_fun) in repr.block_funs.iter().enumerate() { + if let Some(block_fun) = block_fun { + if let Some(bf) = self.get_block_function(bf_id) { + bf.lock().unwrap().load_snapshot(block_fun); + } + } + } + let ret = self.sync(); if let Some(obs) = &self.observer { diff --git a/src/matrix_repr.rs b/src/matrix_repr.rs index 93866d5..6611d0a 100644 --- a/src/matrix_repr.rs +++ b/src/matrix_repr.rs @@ -4,6 +4,7 @@ use crate::dsp::{NodeId, ParamId, SAtom}; use serde_json::{json, Value}; +use crate::blocklang::BlockFunSnapshot; #[derive(Debug, Clone, Copy)] pub struct CellRepr { @@ -187,6 +188,7 @@ pub struct MatrixRepr { pub atoms: Vec<(ParamId, SAtom)>, pub patterns: Vec>, pub properties: Vec<(String, SAtom)>, + pub block_funs: Vec>, pub version: i64, } @@ -289,8 +291,9 @@ impl MatrixRepr { let atoms = vec![]; let patterns = vec![]; let properties = vec![]; + let block_funs = vec![]; - Self { cells, params, atoms, patterns, properties, version: 2 } + Self { cells, params, atoms, patterns, block_funs, properties, version: 2 } } pub fn write_to_file(&mut self, filepath: &str) -> std::io::Result<()> { @@ -398,6 +401,17 @@ impl MatrixRepr { } } + let block_funs = &v["block_funs"]; + if let Value::Array(block_funs) = block_funs { + for p in block_funs.iter() { + m.block_funs.push(if p.is_object() { + Some(BlockFunSnapshot::deserialize(&p)?) + } else { + None + }); + } + } + Ok(m) } @@ -468,6 +482,15 @@ impl MatrixRepr { v["patterns"] = patterns; + let mut block_funs = json!([]); + if let Value::Array(block_funs) = &mut block_funs { + for p in self.block_funs.iter() { + block_funs.push(if let Some(p) = p { p.serialize() } else { Value::Null }); + } + } + + v["block_funs"] = block_funs; + v.to_string() } } diff --git a/src/nodes/node_conf.rs b/src/nodes/node_conf.rs index de70b06..e44850a 100644 --- a/src/nodes/node_conf.rs +++ b/src/nodes/node_conf.rs @@ -719,7 +719,7 @@ impl NodeConfigurator { /// Retrieve a handle to the block function `id`. In case you modify the block function, /// make sure to call [check_block_function]. - pub fn get_block_function(&mut self, id: usize) -> Option>> { + pub fn get_block_function(&self, id: usize) -> Option>> { self.block_functions.get(id).map(|pair| pair.1.clone()) }