@@ -12,6 +12,7 @@ use graph_craft::document::value::TaggedValue;
12
12
use graph_craft::document::{generate_uuid, DocumentNodeImplementation, NodeId, NodeNetwork};
13
13
use graph_craft::graphene_compiler::Compiler;
14
14
use graph_craft::imaginate_input::ImaginatePreferences;
15
+ use graph_craft::proto::ProtoNetwork;
15
16
use graph_craft::{concrete, Type};
16
17
use graphene_core::application_io::{ApplicationIo, NodeGraphUpdateMessage, NodeGraphUpdateSender, RenderConfig};
17
18
use graphene_core::raster::Image;
@@ -57,6 +58,7 @@ pub struct NodeRuntime {
57
58
pub(crate) click_targets: HashMap<NodeId, Vec<ClickTarget>>,
58
59
pub(crate) transforms: HashMap<NodeId, DAffine2>,
59
60
pub(crate) upstream_transforms: HashMap<NodeId, DAffine2>,
61
+ compile_cache: Option<(u64, Vec<Vec<NodeId>>)>,
60
62
canvas_cache: HashMap<Vec<LayerId>, SurfaceId>,
61
63
}
62
64
@@ -124,6 +126,7 @@ impl NodeRuntime {
124
126
canvas_cache: HashMap::new(),
125
127
click_targets: HashMap::new(),
126
128
transforms: HashMap::new(),
129
+ compile_cache: None,
127
130
upstream_transforms: HashMap::new(),
128
131
}
129
132
}
@@ -198,28 +201,40 @@ impl NodeRuntime {
198
201
// Required to ensure that the appropriate protonodes are reinserted when the Editor API changes.
199
202
let mut graph_input_hash = DefaultHasher::new();
200
203
editor_api.font_cache.hash(&mut graph_input_hash);
204
+ let font_hash_code = graph_input_hash.finish();
205
+ graph.hash(&mut graph_input_hash);
206
+ let hash_code = graph_input_hash.finish();
201
207
202
- let scoped_network = wrap_network_in_scope(graph, graph_input_hash.finish());
208
+ if self.compile_cache.as_ref().map(|(hash, _)| *hash) != Some(hash_code) {
209
+ self.compile_cache = None;
210
+ }
203
211
204
- let monitor_nodes = scoped_network
205
- .recursive_nodes()
206
- .filter(|(_, node)| node.implementation == DocumentNodeImplementation::proto("graphene_core::memo::MonitorNode<_, _, _>"))
207
- .map(|(_, node)| node.path.clone().unwrap_or_default())
208
- .collect::<Vec<_>>();
212
+ if self.compile_cache.is_none() {
213
+ let scoped_network = wrap_network_in_scope(graph, font_hash_code);
214
+
215
+ let monitor_nodes = scoped_network
216
+ .recursive_nodes()
217
+ .filter(|(_, node)| node.implementation == DocumentNodeImplementation::proto("graphene_core::memo::MonitorNode<_, _, _>"))
218
+ .map(|(_, node)| node.path.clone().unwrap_or_default())
219
+ .collect::<Vec<_>>();
220
+
221
+ // We assume only one output
222
+ assert_eq!(scoped_network.outputs.len(), 1, "Graph with multiple outputs not yet handled");
223
+ let c = Compiler {};
224
+ let proto_network = match c.compile_single(scoped_network) {
225
+ Ok(network) => network,
226
+ Err(e) => return (Err(e), monitor_nodes),
227
+ };
209
228
210
- // We assume only one output
211
- assert_eq!(scoped_network.outputs.len(), 1, "Graph with multiple outputs not yet handled");
212
- let c = Compiler {};
213
- let proto_network = match c.compile_single(scoped_network) {
214
- Ok(network) => network,
215
- Err(e) => return (Err(e), monitor_nodes),
216
- };
229
+ assert_ne!(proto_network.nodes.len(), 0, "No protonodes exist?");
230
+ if let Err(e) = self.executor.update(proto_network).await {
231
+ error!("Failed to update executor:\n{e}");
232
+ return (Err(e), monitor_nodes);
233
+ }
217
234
218
- assert_ne!(proto_network.nodes.len(), 0, "No protonodes exist?");
219
- if let Err(e) = self.executor.update(proto_network).await {
220
- error!("Failed to update executor:\n{e}");
221
- return (Err(e), monitor_nodes);
235
+ self.compile_cache = Some((hash_code, monitor_nodes));
222
236
}
237
+ let (hash_code, monitor_nodes) = self.compile_cache.as_ref().unwrap();
223
238
224
239
use graph_craft::graphene_compiler::Executor;
225
240
@@ -231,7 +246,7 @@ impl NodeRuntime {
231
246
};
232
247
let result = match result {
233
248
Ok(value) => value,
234
- Err(e) => return (Err(e), monitor_nodes),
249
+ Err(e) => return (Err(e), monitor_nodes.clone() ),
235
250
};
236
251
237
252
if let TaggedValue::SurfaceFrame(SurfaceFrame { surface_id, transform: _ }) = result {
@@ -244,7 +259,7 @@ impl NodeRuntime {
244
259
}
245
260
}
246
261
}
247
- (Ok(result), monitor_nodes)
262
+ (Ok(result), monitor_nodes.clone() )
248
263
}
249
264
250
265
/// Recomputes the thumbnails for the layers in the graph, modifying the state and updating the UI.
0 commit comments