diff --git a/knyst/src/controller.rs b/knyst/src/controller.rs index c28a947..da8aa79 100644 --- a/knyst/src/controller.rs +++ b/knyst/src/controller.rs @@ -192,7 +192,8 @@ pub trait KnystCommands { /// Creates a new local graph and sets it as the default graph fn init_local_graph(&mut self, settings: GraphSettings) -> GraphId; /// Upload the local graph to the previously default graph and restore the default graph to that previous default graph. - fn upload_local_graph(&mut self) -> crate::handles::Handle; + fn upload_local_graph(&mut self) + -> Option>; /// Start a scheduling bundle, meaning any change scheduled will not be applied until [`KnystCommands::upload_scheduling_bundle`] is called. Prefer using [`schedule_bundle`] as it is more difficult to misuse. fn start_scheduling_bundle(&mut self, time: Time); /// Uploads scheduled changes to the graph and schedules them for the time specified in [`KnystCommands::start_scheduling_bundle`]. Prefer [`schedule_bundle`] to help reinforce scoping and potential thread switches. @@ -206,7 +207,9 @@ pub fn upload_graph( ) -> crate::handles::Handle { knyst_commands().init_local_graph(settings); init(); - knyst_commands().upload_local_graph() + knyst_commands() + .upload_local_graph() + .expect("`upload_graph` initiated a local graph so it should exist") } /// Schedules any changes made in the closure at the given time. Currently limited to changes of constant values and spawning new nodes, not new connections. @@ -244,7 +247,7 @@ impl KnystCommands for MultiThreadedKnystCommands { let node_id = { let local_node_id = LOCAL_GRAPH.with_borrow_mut(|g| { if let Some(g) = g.last_mut() { - let mut node_id = NodeId::new(); + let mut node_id = NodeId::new(g.id()); g.push_with_existing_address_at_time( gen_or_graph, &mut node_id, @@ -276,7 +279,7 @@ impl KnystCommands for MultiThreadedKnystCommands { let found_in_local = LOCAL_GRAPH.with_borrow_mut(|g| { if let Some(g) = g.last_mut() { if g.id() == graph_id { - let mut node_id = NodeId::new(); + let mut node_id = NodeId::new(graph_id); if let Err(e) = g.push_with_existing_address_to_graph(gen_or_graph, &mut node_id, g.id()) { @@ -297,7 +300,7 @@ impl KnystCommands for MultiThreadedKnystCommands { match found_in_local { Ok(node_id) => node_id, Err(gen_or_graph) => { - let mut new_node_address = NodeId::new(); + let new_node_address = NodeId::new(graph_id); let command = Command::Push { gen_or_graph, node_address: new_node_address, @@ -305,7 +308,6 @@ impl KnystCommands for MultiThreadedKnystCommands { start_time: self.changes_bundle_time, }; self.sender.send(command).unwrap(); - new_node_address.set_graph_id(graph_id); new_node_address } } @@ -428,18 +430,45 @@ impl KnystCommands for MultiThreadedKnystCommands { if self.bundle_changes { self.changes_bundle.extend(changes.changes); } else { - LOCAL_GRAPH.with_borrow_mut(|g| { - if let Some(g) = g.last_mut() { - if let Err(e) = g.schedule_changes(changes.changes, changes.time) { - // TODO: report error - // TODO: recover the gen_or_graph from the PushError - eprintln!("{e:?}"); - } - } else { - // There is no local graph - self.sender.send(Command::ScheduleChanges(changes)).unwrap(); + let mut all_node_graphs = vec![]; + let time = changes.time; + for c in &changes.changes { + if !all_node_graphs.contains(&c.node.graph_id()) { + all_node_graphs.push(c.node.graph_id()); } - }); + } + let change_bundles_per_graph = if all_node_graphs.len() < 2 { + vec![changes.changes] + } else { + let mut per_graph = vec![vec![]; all_node_graphs.len()]; + for change in changes.changes { + let i = all_node_graphs + .iter() + .position(|graph| *graph == change.node.graph_id()) + .unwrap(); + per_graph[i].push(change); + } + per_graph + }; + for changes in change_bundles_per_graph { + LOCAL_GRAPH.with_borrow_mut(|g| { + if let Some(g) = g.last_mut() { + if let Err(e) = g.schedule_changes(changes, time) { + // TODO: report error + // TODO: recover the gen_or_graph from the PushError + eprintln!("Local graph schedule_changes error: {e:?}"); + } + } else { + // There is no local graph + self.sender + .send(Command::ScheduleChanges(SimultaneousChanges { + time, + changes, + })) + .unwrap(); + } + }); + } } } /// Inserts a new buffer in the [`Resources`] and returns an id which can be @@ -521,7 +550,7 @@ impl KnystCommands for MultiThreadedKnystCommands { graph_id } - fn upload_local_graph(&mut self) -> Handle { + fn upload_local_graph(&mut self) -> Option> { let graph_to_upload = LOCAL_GRAPH.with_borrow_mut(|g| g.pop()); if let Some(g) = graph_to_upload { let num_inputs = g.num_inputs(); @@ -529,10 +558,14 @@ impl KnystCommands for MultiThreadedKnystCommands { let graph_id = g.id(); let id = self.push_without_inputs(g); - Handle::new(GraphHandle::new(id, graph_id, num_inputs, num_outputs)) + Some(Handle::new(GraphHandle::new( + id, + graph_id, + num_inputs, + num_outputs, + ))) } else { - eprintln!("No local graph found"); - Handle::new(GraphHandle::new(NodeId::new(), 0, 0, 0)) + None } } @@ -827,6 +860,8 @@ impl Controller { .change_musical_time_map(change_fn) .map_err(|e| From::from(e)), Command::ScheduleChanges(changes) => { + let changes_clone = changes.clone(); + println!("Scheduling changes: {changes:?}"); match self .top_level_graph .schedule_changes(changes.changes, changes.time) @@ -835,7 +870,7 @@ impl Controller { Err(e) => match e { crate::graph::ScheduleError::GraphNotFound(_node) => { // println!("Didn't find graph for:"); - // println!("{changes_clone:?}"); + println!("Failed to schedule {changes_clone:?}"); Err(e.into()) } _ => Err(e.into()), @@ -1097,4 +1132,82 @@ mod tests { assert_eq!(o[19], 4.0); assert_eq!(o[20], 5.0); } + + #[test] + fn schedule_bundle_inner_graph_test() { + let sr = 44100; + let mut kt = KnystOffline::new(sr, 64, 0, 1); + // We create a first graph so that the top graph will try to schedule on this one first and fail. + let mut ignored_graph_node = None; + let _ignored_graph = upload_graph(knyst_commands().default_graph_settings(), || { + ignored_graph_node = Some(one_gen()); + }); + let mut inner_graph = None; + let graph = upload_graph(knyst_commands().default_graph_settings(), || { + let g = upload_graph(knyst_commands().default_graph_settings(), || ()); + graph_output(0, g); + inner_graph = Some(g); + }); + graph_output(0, graph); + inner_graph.unwrap().activate(); + schedule_bundle(crate::graph::Time::Immediately, || { + graph_output(0, once_trig()); + }); + schedule_bundle( + crate::graph::Time::Superseconds(Superseconds::from_samples(5, sr as u64)), + || { + graph_output(0, once_trig()); + }, + ); + schedule_bundle( + crate::graph::Time::Superseconds(Superseconds::from_samples(10, sr as u64)), + || { + graph_output(0, once_trig()); + }, + ); + let mut og = None; + schedule_bundle( + crate::graph::Time::Superseconds(Superseconds::from_samples(16, sr as u64)), + || { + og = Some(one_gen()); + graph_output(0, og.unwrap()); + }, + ); + let og = og.unwrap(); + schedule_bundle( + crate::graph::Time::Superseconds(Superseconds::from_samples(17, sr as u64)), + || { + og.passthrough(2.0); + + // This will set a value of a node in a different graph, but won't change the output + ignored_graph_node.unwrap().passthrough(10.); + }, + ); + schedule_bundle( + crate::graph::Time::Superseconds(Superseconds::from_samples(19, sr as u64)), + || { + og.passthrough(3.0); + }, + ); + // Try with the pure KnystCommands methods as well. + knyst_commands().start_scheduling_bundle(knyst::graph::Time::Superseconds( + Superseconds::from_samples(20, sr as u64), + )); + og.passthrough(4.0); + knyst_commands().upload_scheduling_bundle(); + kt.process_block(); + let o = kt.output_channel(0).unwrap(); + dbg!(o); + assert_eq!(o[0], 1.0); + assert_eq!(o[1], 0.0); + assert_eq!(o[4], 0.0); + assert_eq!(o[5], 1.0); + assert_eq!(o[6], 0.0); + assert_eq!(o[10], 1.0); + assert_eq!(o[11], 0.0); + assert_eq!(o[16], 1.0); + assert_eq!(o[17], 3.0); + assert_eq!(o[19], 4.0); + assert_eq!(o[20], 5.0); + } } diff --git a/knyst/src/graph.rs b/knyst/src/graph.rs index 20e59b6..1732430 100644 --- a/knyst/src/graph.rs +++ b/knyst/src/graph.rs @@ -102,7 +102,7 @@ pub struct RawNodeAddress { pub struct NodeId { unique_id: u64, /// If the graph_id is not set, every graph needs to search for the node id. - graph_id: Option, + graph_id: GraphId, // graph_id: Arc>>, // node_key: Arc>>, } @@ -122,18 +122,18 @@ impl std::hash::Hash for NodeId { impl NodeId { /// Create a new [`Self`] not yet connected to a specific node, but with a unique id. - pub fn new() -> Self { + pub fn new(graph_id: GraphId) -> Self { Self { unique_id: NEXT_ADDRESS_ID.fetch_add(1, Ordering::Relaxed), - graph_id: None, + graph_id, } } - /// Set the graph id of this NodeId. If you don't know the GraphId yet you can leave it unset. Setting it may speed up edits to the node routing, especially if the node is in a deep graph. - pub fn set_graph_id(&mut self, id: GraphId) { - self.graph_id = Some(id); - } + // /// Set the graph id of this NodeId. If you don't know the GraphId yet you can leave it unset. Setting it may speed up edits to the node routing, especially if the node is in a deep graph. + // pub fn set_graph_id(&mut self, id: GraphId) { + // self.graph_id = Some(id); + // } /// Retreive [`GraphId`] if one is set. - pub fn graph_id(&self) -> Option { + pub fn graph_id(&self) -> GraphId { self.graph_id } /// Create a [`NodeOutput`] based on `self` and a specific channel. @@ -261,8 +261,8 @@ impl SimultaneousChanges { /// # Example /// ```rust /// use knyst::graph::{NodeChanges, NodeId, SimultaneousChanges}; -/// // In reality, use a NodeAddress that points to a node. -/// let my_node= NodeId::new(); +/// // In reality, use a real NodeAddress that points to a node. +/// let my_node = NodeId::new(0); /// let node_changes = NodeChanges::new(my_node).set("freq", 442.0).set("amp", 0.5).trigger("reset"); /// // equivalent to: /// // let node_changes = my_node.change().set("freq", 442.0).set("amp", 0.5).trigger("reset"); @@ -622,6 +622,8 @@ pub enum FreeError { #[allow(missing_docs)] #[derive(thiserror::Error, Debug, PartialEq)] pub enum ScheduleError { + #[error("Changes for nodes in different graphs were attempted to be scheduled together.`")] + DifferentGraphs, #[error("The graph containing the NodeId provided was not found: `{0:?}`")] GraphNotFound(NodeId), #[error("The NodeId does not exist. The Node may have been freed already.")] @@ -1253,7 +1255,7 @@ impl Graph { to_node: impl Into, graph_id: GraphId, ) -> Result { - let mut new_node_address = NodeId::new(); + let mut new_node_address = NodeId::new(graph_id); self.push_with_existing_address_to_graph(to_node, &mut new_node_address, graph_id)?; Ok(new_node_address) } @@ -1265,7 +1267,7 @@ impl Graph { graph_id: GraphId, start_time: Time, ) -> Result { - let mut new_node_address = NodeId::new(); + let mut new_node_address = NodeId::new(graph_id); self.push_with_existing_address_to_graph_at_time( to_node, &mut new_node_address, @@ -1382,13 +1384,18 @@ impl Graph { } self.graphs_per_node.insert(node_key, graph); } - node_address.graph_id = Some(self.id); + node_address.graph_id = self.id; Ok(()) } else { // Try to find the graph containing the node by asking all the graphs in this graph to free the node let mut to_node = to_node.into(); for (_key, graph) in &mut self.graphs_per_node { - match graph.push_with_existing_address_to_graph(to_node, node_address, graph_id) { + match graph.push_with_existing_address_to_graph_at_time( + to_node, + node_address, + graph_id, + start_time, + ) { Ok(_) => { return Ok(()); } @@ -1448,10 +1455,8 @@ impl Graph { /// Making it not public means Graphs cannot be accidentally added, but a /// Node can still be created for the top level one if preferred. fn push_node(&mut self, mut node: Node, node_id: &mut NodeId) -> NodeKey { - if let Some(node_graph_id) = node_id.graph_id() { - if node_graph_id != self.id { - eprintln!("Warning: Pushing node to NodeId with a GraphId matching a different Graph than the current Graph.") - } + if node_id.graph_id() != self.id { + eprintln!("Warning: Pushing node to NodeId with a GraphId matching a different Graph than the current Graph.") } if node.num_inputs() > self.max_node_inputs { self.increase_max_node_inputs(node.num_inputs()); @@ -1462,7 +1467,6 @@ impl Graph { "Error: Trying to push a node into a Graph that is at capacity. Try increasing the number of node slots and make sure you free the nodes you don't need." ); } - node_id.set_graph_id(self.id); self.recalculation_required = true; let input_index_to_name = node.input_indices_to_names(); let input_name_to_index = input_index_to_name @@ -1657,10 +1661,8 @@ impl Graph { // is conencted to node4input3. // let mut node_might_be_in_graph = true; - if let Some(graph) = node.graph_id() { - if graph != self.id { - node_might_be_in_graph = false; - } + if node.graph_id != self.id { + node_might_be_in_graph = false; } if node_might_be_in_graph { if let Some((node_key, _id)) = self.node_ids.iter().find(|(_key, &id)| node == id) { @@ -1777,10 +1779,8 @@ impl Graph { /// Remove the node and any edges to/from the node. This may lead to other nodes being disconnected from the output and therefore not be run, but they will not be freed. pub fn free_node(&mut self, node: NodeId) -> Result<(), FreeError> { let mut node_might_be_in_graph = true; - if let Some(graph) = node.graph_id() { - if graph != self.id { - node_might_be_in_graph = false; - } + if node.graph_id() != self.id { + node_might_be_in_graph = false; } if node_might_be_in_graph { if let Some((node_key, _id)) = self.node_ids.iter().find(|(_key, &id)| node == id) { @@ -1963,22 +1963,32 @@ impl Graph { /// Schedule changes to input channel constants. The changes will only be /// applied if the [`Graph`] is running and its scheduler is regularly - /// updated. + /// updated. [`NodeChanges`] must all be in the same Graph. If you want to + /// schedule chagnes to nodes in multiple graphs, separate them and call + /// [`Graph::schedule_changes`] multiple times. pub fn schedule_changes( &mut self, node_changes: Vec, time: Time, ) -> Result<(), ScheduleError> { + // assert all changes are for the same graph + if node_changes.is_empty() { + return Ok(()); + } + let first_graph = node_changes[0].node.graph_id(); + for nc in &node_changes { + if nc.node.graph_id() != first_graph { + return Err(ScheduleError::DifferentGraphs); + } + } let mut scheduler_changes = vec![]; for node_changes in &node_changes { let node = node_changes.node; let change_pairs = &node_changes.parameters; let time_offset = node_changes.offset; let mut node_might_be_in_this_graph = true; - if let Some(node_graph) = node.graph_id() { - if node_graph != self.id { - node_might_be_in_this_graph = false; - } + if node.graph_id() != self.id { + node_might_be_in_this_graph = false; } if node_might_be_in_this_graph { if let Some((key, _id)) = self.node_ids.iter().find(|(_key, &id)| id == node) { @@ -2039,7 +2049,7 @@ impl Graph { } } if !found_graph { - eprintln!("{}", ScheduleError::GraphNotFound(node_changes.node)); + return Err(ScheduleError::GraphNotFound(node_changes.node)); } } } @@ -2055,10 +2065,8 @@ impl Graph { /// updated. pub fn schedule_change(&mut self, change: ParameterChange) -> Result<(), ScheduleError> { let mut node_might_be_in_this_graph = true; - if let Some(node_graph) = change.input.node.graph_id() { - if node_graph != self.id { - node_might_be_in_this_graph = false; - } + if change.input.node.graph_id() != self.id { + node_might_be_in_this_graph = false; } if node_might_be_in_this_graph { if let Some(key) = Self::key_from_id(&self.node_ids, change.input.node) { @@ -2153,18 +2161,11 @@ impl Graph { feedback, to_index_offset, } => { - match (source.graph_id(), sink.graph_id()) { - (Some(g0), Some(g1)) => { - if g0 != g1 { - return Err(ConnectionError::DifferentGraphs); - } - } - _ => (), + if source.graph_id() != sink.graph_id() { + return Err(ConnectionError::DifferentGraphs); } - if let Some(source_graph_id) = source.graph_id() { - if source_graph_id != self.id { - return try_disconnect_in_child_graphs(connection.clone()); - } + if source.graph_id() != self.id { + return try_disconnect_in_child_graphs(connection.clone()); } let Some(source_key) = Self::key_from_id(&self.node_ids, *source) else { return try_disconnect_in_child_graphs(connection.clone()); @@ -2305,10 +2306,8 @@ impl Graph { to_label: input_label, } => { if let Some(sink) = sink { - if let Some(graph_id) = sink.graph_id() { - if graph_id != self.id { - return try_disconnect_in_child_graphs(connection.clone()); - } + if sink.graph_id() != self.id { + return try_disconnect_in_child_graphs(connection.clone()); } let Some(sink_key) = Self::key_from_id(&self.node_ids, *sink) else { return try_disconnect_in_child_graphs(connection.clone()); @@ -2366,10 +2365,8 @@ impl Graph { to_index, channels, } => { - if let Some(graph_id) = source.graph_id() { - if graph_id != self.id { - return try_disconnect_in_child_graphs(connection.clone()); - } + if source.graph_id != self.id { + return try_disconnect_in_child_graphs(connection.clone()); } let Some((source_key, _)) = self.node_ids.iter().find(|(_key, &id)| id == *source) else { @@ -2428,10 +2425,8 @@ impl Graph { channels, to_index_offset, } => { - if let Some(graph_id) = sink.graph_id() { - if graph_id != self.id { - return try_disconnect_in_child_graphs(connection.clone()); - } + if sink.graph_id != self.id { + return try_disconnect_in_child_graphs(connection.clone()); } let Some((sink_key, _)) = self.node_ids.iter().find(|(_key, &id)| id == *sink) else { @@ -2589,18 +2584,11 @@ impl Graph { feedback, to_index_offset, } => { - match (source.graph_id(), sink.graph_id()) { - (Some(g0), Some(g1)) => { - if g0 != g1 { - return Err(ConnectionError::DifferentGraphs); - } - } - _ => (), + if source.graph_id() != sink.graph_id() { + return Err(ConnectionError::DifferentGraphs); } - if let Some(source_graph_id) = source.graph_id() { - if source_graph_id != self.id { - return try_connect_to_graphs(connection.clone()); - } + if source.graph_id != self.id { + return try_connect_to_graphs(connection.clone()); } let Some((source_key, _)) = self.node_ids.iter().find(|(_key, &id)| id == *source) else { @@ -2689,7 +2677,7 @@ impl Graph { index } else { let feedback_node = FeedbackGen::node(num_source_outputs); - let mut feedback_node_address = NodeId::new(); + let mut feedback_node_address = NodeId::new(self.id); let key = self.push_node(feedback_node, &mut feedback_node_address); self.feedback_node_indices.push(key); self.node_feedback_node_key.insert(source_key, key); @@ -2726,10 +2714,8 @@ impl Graph { to_label: input_label, } => { if let Some(sink) = sink { - if let Some(sink_graph_id) = sink.graph_id() { - if sink_graph_id != self.id { - return try_connect_to_graphs(connection.clone()); - } + if sink.graph_id != self.id { + return try_connect_to_graphs(connection.clone()); } let Some((sink_key, _)) = self.node_ids.iter().find(|(_key, &id)| id == *sink) else { @@ -2788,10 +2774,8 @@ impl Graph { to_index, channels, } => { - if let Some(source_graph_id) = source.graph_id() { - if source_graph_id != self.id { - return try_connect_to_graphs(connection.clone()); - } + if source.graph_id != self.id { + return try_connect_to_graphs(connection.clone()); } let Some((source_key, _)) = self.node_ids.iter().find(|(_key, &id)| id == *source) else { @@ -2849,10 +2833,8 @@ impl Graph { channels, to_index_offset, } => { - if let Some(sink_graph_id) = sink.graph_id() { - if sink_graph_id != self.id { - return try_connect_to_graphs(connection.clone()); - } + if sink.graph_id != self.id { + return try_connect_to_graphs(connection.clone()); } let Some((sink_key, _)) = self.node_ids.iter().find(|(_key, &id)| id == *sink) else { @@ -2910,10 +2892,8 @@ impl Graph { graph_inputs, channel, } => { - if let Some(node_graph_id) = node.graph_id() { - if node_graph_id != self.id { - return try_connect_to_graphs(connection.clone()); - } + if node.graph_id != self.id { + return try_connect_to_graphs(connection.clone()); } let Some((node_key, _)) = self.node_ids.iter().find(|(_key, &id)| id == *node) else { diff --git a/knyst/src/graph/connection.rs b/knyst/src/graph/connection.rs index 87cf262..3a1383a 100644 --- a/knyst/src/graph/connection.rs +++ b/knyst/src/graph/connection.rs @@ -1116,15 +1116,15 @@ mod tests { struct DNode; fn push_node(_node: DNode, defaults: impl Into) -> NodeId { let _d = defaults.into(); - NodeId::new() + NodeId::new(0) } fn connect(b: impl Into) { let b = b.into(); - let target_node = NodeId::new(); + let target_node = NodeId::new(0); b.to(target_node).as_connections(); } - let node = NodeId::new(); + let node = NodeId::new(0); let _c: InputBundle = ("freq", 440.0, [node.out(0)]).into(); let _c: InputBundle = [("freq", 440.0, [node.out(0)])].into(); connect(vec![ diff --git a/knyst/src/graph/run_graph.rs b/knyst/src/graph/run_graph.rs index e2b31ec..466eb05 100644 --- a/knyst/src/graph/run_graph.rs +++ b/knyst/src/graph/run_graph.rs @@ -57,7 +57,7 @@ impl RunGraph { // Create a new dummy NodeId since it doesn't matter; we know // that the Graph will not do anything with its NodeId in its init function // and the top level graph doesn't have a NodeId anyway. - match graph.split_and_create_top_level_node(NodeId::new()) { + match graph.split_and_create_top_level_node(NodeId::new(u64::MAX)) { Ok(graph_node) => { let input_buffer_length = graph_node.num_inputs() * graph_node.block_size; let input_buffer_ptr = if input_buffer_length != 0 { diff --git a/knyst/src/handles.rs b/knyst/src/handles.rs index ad52617..d7bbc23 100644 --- a/knyst/src/handles.rs +++ b/knyst/src/handles.rs @@ -89,7 +89,7 @@ impl Handle { /// Create a dummy handle pointing to nothing. pub fn void() -> Handle { Self::new(GenericHandle { - node_id: NodeId::new(), + node_id: NodeId::new(u64::MAX), num_inputs: 0, num_outputs: 0, }) diff --git a/knyst/src/modal_interface.rs b/knyst/src/modal_interface.rs index edec854..5ec76c1 100644 --- a/knyst/src/modal_interface.rs +++ b/knyst/src/modal_interface.rs @@ -54,7 +54,7 @@ impl KnystCommands for UnifiedKnystCommands { UnifiedKnystCommands::Real(kc) => kc.borrow_mut().push_without_inputs(gen_or_graph), UnifiedKnystCommands::Dummy(kc) => { kc.report_dummy(); - NodeId::new() + NodeId::new(u64::MAX) } } } @@ -68,7 +68,7 @@ impl KnystCommands for UnifiedKnystCommands { UnifiedKnystCommands::Real(kc) => kc.borrow_mut().push(gen_or_graph, inputs), UnifiedKnystCommands::Dummy(kc) => { kc.report_dummy(); - NodeId::new() + NodeId::new(u64::MAX) } } } @@ -84,7 +84,7 @@ impl KnystCommands for UnifiedKnystCommands { .push_to_graph_without_inputs(gen_or_graph, graph_id), UnifiedKnystCommands::Dummy(kc) => { kc.report_dummy(); - NodeId::new() + NodeId::new(u64::MAX) } } } @@ -102,7 +102,7 @@ impl KnystCommands for UnifiedKnystCommands { } UnifiedKnystCommands::Dummy(kc) => { kc.report_dummy(); - NodeId::new() + NodeId::new(u64::MAX) } } } @@ -273,12 +273,12 @@ impl KnystCommands for UnifiedKnystCommands { } } - fn upload_local_graph(&mut self) -> Handle { + fn upload_local_graph(&mut self) -> Option> { match self { UnifiedKnystCommands::Real(kc) => kc.borrow_mut().upload_local_graph(), UnifiedKnystCommands::Dummy(kc) => { kc.report_dummy(); - Handle::new(GraphHandle::new(NodeId::new(), 0, 0, 0)) + None } } }