@@ -14,14 +14,15 @@ use graph_craft::graphene_compiler::Compiler;
14
14
use graph_craft:: imaginate_input:: ImaginatePreferences ;
15
15
use graph_craft:: { concrete, Type } ;
16
16
use graphene_core:: application_io:: { ApplicationIo , NodeGraphUpdateMessage , NodeGraphUpdateSender , RenderConfig } ;
17
+ use graphene_core:: memo:: IORecord ;
17
18
use graphene_core:: raster:: { Image , ImageFrame } ;
18
19
use graphene_core:: renderer:: { ClickTarget , GraphicElementRendered , SvgSegment , SvgSegmentList } ;
19
20
use graphene_core:: text:: FontCache ;
20
21
use graphene_core:: transform:: { Footprint , Transform } ;
21
22
use graphene_core:: vector:: style:: ViewMode ;
22
23
use graphene_core:: vector:: VectorData ;
23
24
24
- use graphene_core:: { Color , SurfaceFrame , SurfaceId } ;
25
+ use graphene_core:: { Color , GraphicElementData , SurfaceFrame , SurfaceId } ;
25
26
use graphene_std:: wasm_application_io:: { WasmApplicationIo , WasmEditorApi } ;
26
27
use interpreted_executor:: dynamic_executor:: DynamicExecutor ;
27
28
@@ -56,10 +57,10 @@ pub struct NodeRuntime {
56
57
imaginate_preferences : ImaginatePreferences ,
57
58
pub ( crate ) thumbnails : HashMap < NodeId , SvgSegmentList > ,
58
59
pub ( crate ) click_targets : HashMap < NodeId , Vec < ClickTarget > > ,
59
- pub ( crate ) transforms : HashMap < NodeId , DAffine2 > ,
60
- pub ( crate ) upstream_transforms : HashMap < NodeId , DAffine2 > ,
60
+ pub ( crate ) upstream_transforms : HashMap < NodeId , ( Footprint , DAffine2 ) > ,
61
61
graph_hash : Option < u64 > ,
62
62
canvas_cache : HashMap < Vec < LayerId > , SurfaceId > ,
63
+ monitor_nodes : Vec < Vec < NodeId > > ,
63
64
}
64
65
65
66
enum NodeRuntimeMessage {
@@ -81,8 +82,7 @@ pub(crate) struct GenerationResponse {
81
82
updates : VecDeque < Message > ,
82
83
new_thumbnails : HashMap < NodeId , SvgSegmentList > ,
83
84
new_click_targets : HashMap < LayerNodeIdentifier , Vec < ClickTarget > > ,
84
- new_transforms : HashMap < LayerNodeIdentifier , DAffine2 > ,
85
- new_upstream_transforms : HashMap < NodeId , DAffine2 > ,
85
+ new_upstream_transforms : HashMap < NodeId , ( Footprint , DAffine2 ) > ,
86
86
transform : DAffine2 ,
87
87
}
88
88
@@ -109,8 +109,6 @@ thread_local! {
109
109
pub ( crate ) static NODE_RUNTIME : Rc <RefCell <Option <NodeRuntime >>> = Rc :: new( RefCell :: new( None ) ) ;
110
110
}
111
111
112
- type MonitorNodes = Vec < Vec < NodeId > > ;
113
-
114
112
impl NodeRuntime {
115
113
fn new ( receiver : Receiver < NodeRuntimeMessage > , sender : Sender < NodeGraphUpdate > ) -> Self {
116
114
let executor = DynamicExecutor :: default ( ) ;
@@ -124,9 +122,9 @@ impl NodeRuntime {
124
122
wasm_io : None ,
125
123
canvas_cache : HashMap :: new ( ) ,
126
124
click_targets : HashMap :: new ( ) ,
127
- transforms : HashMap :: new ( ) ,
128
125
graph_hash : None ,
129
126
upstream_transforms : HashMap :: new ( ) ,
127
+ monitor_nodes : Vec :: new ( ) ,
130
128
}
131
129
}
132
130
pub async fn run ( & mut self ) {
@@ -151,19 +149,18 @@ impl NodeRuntime {
151
149
..
152
150
} ) => {
153
151
let transform = render_config. viewport . transform ;
154
- let ( result, monitor_nodes ) = self . execute_network ( & path, graph, render_config) . await ;
152
+ let result = self . execute_network ( & path, graph, render_config) . await ;
155
153
let mut responses = VecDeque :: new ( ) ;
156
- if let Some ( ref monitor_nodes ) = monitor_nodes {
157
- self . update_thumbnails ( & path, monitor_nodes , & mut responses) ;
158
- self . update_upstream_transforms ( monitor_nodes ) ;
159
- }
154
+
155
+ self . update_thumbnails ( & path, & mut responses) ;
156
+ self . update_upstream_transforms ( ) ;
157
+
160
158
let response = GenerationResponse {
161
159
generation_id,
162
160
result,
163
161
updates : responses,
164
162
new_thumbnails : self . thumbnails . clone ( ) ,
165
163
new_click_targets : self . click_targets . clone ( ) . into_iter ( ) . map ( |( id, targets) | ( LayerNodeIdentifier :: new_unchecked ( id) , targets) ) . collect ( ) ,
166
- new_transforms : self . transforms . clone ( ) . into_iter ( ) . map ( |( id, transform) | ( LayerNodeIdentifier :: new_unchecked ( id) , transform) ) . collect ( ) ,
167
164
new_upstream_transforms : self . upstream_transforms . clone ( ) ,
168
165
transform,
169
166
} ;
@@ -173,7 +170,7 @@ impl NodeRuntime {
173
170
}
174
171
}
175
172
176
- async fn execute_network < ' a > ( & ' a mut self , path : & [ LayerId ] , graph : NodeNetwork , render_config : RenderConfig ) -> ( Result < TaggedValue , String > , Option < MonitorNodes > ) {
173
+ async fn execute_network < ' a > ( & ' a mut self , path : & [ LayerId ] , graph : NodeNetwork , render_config : RenderConfig ) -> Result < TaggedValue , String > {
177
174
if self . wasm_io . is_none ( ) {
178
175
self . wasm_io = Some ( WasmApplicationIo :: new ( ) . await ) ;
179
176
}
@@ -200,12 +197,10 @@ impl NodeRuntime {
200
197
self . graph_hash = None ;
201
198
}
202
199
203
- let mut cached_monitor_nodes = None ;
204
-
205
200
if self . graph_hash . is_none ( ) {
206
201
let scoped_network = wrap_network_in_scope ( graph, font_hash_code) ;
207
202
208
- let monitor_nodes = scoped_network
203
+ self . monitor_nodes = scoped_network
209
204
. recursive_nodes ( )
210
205
. filter ( |( _, node) | node. implementation == DocumentNodeImplementation :: proto ( "graphene_core::memo::MonitorNode<_, _, _>" ) )
211
206
. map ( |( _, node) | node. path . clone ( ) . unwrap_or_default ( ) )
@@ -216,16 +211,15 @@ impl NodeRuntime {
216
211
let c = Compiler { } ;
217
212
let proto_network = match c. compile_single ( scoped_network) {
218
213
Ok ( network) => network,
219
- Err ( e) => return ( Err ( e) , Some ( monitor_nodes ) ) ,
214
+ Err ( e) => return Err ( e) ,
220
215
} ;
221
216
222
217
assert_ne ! ( proto_network. nodes. len( ) , 0 , "No protonodes exist?" ) ;
223
218
if let Err ( e) = self . executor . update ( proto_network) . await {
224
219
error ! ( "Failed to update executor:\n {e}" ) ;
225
- return ( Err ( e) , Some ( monitor_nodes ) ) ;
220
+ return Err ( e) ;
226
221
}
227
222
228
- cached_monitor_nodes = Some ( monitor_nodes) ;
229
223
self . graph_hash = Some ( hash_code) ;
230
224
}
231
225
@@ -239,7 +233,7 @@ impl NodeRuntime {
239
233
} ;
240
234
let result = match result {
241
235
Ok ( value) => value,
242
- Err ( e) => return ( Err ( e) , cached_monitor_nodes ) ,
236
+ Err ( e) => return Err ( e) ,
243
237
} ;
244
238
245
239
if let TaggedValue :: SurfaceFrame ( SurfaceFrame { surface_id, transform : _ } ) = result {
@@ -252,13 +246,14 @@ impl NodeRuntime {
252
246
}
253
247
}
254
248
}
255
- ( Ok ( result) , cached_monitor_nodes )
249
+ Ok ( result)
256
250
}
257
251
258
252
/// Recomputes the thumbnails for the layers in the graph, modifying the state and updating the UI.
259
- pub fn update_thumbnails ( & mut self , layer_path : & [ LayerId ] , monitor_nodes : & [ Vec < u64 > ] , responses : & mut VecDeque < Message > ) {
253
+ pub fn update_thumbnails ( & mut self , layer_path : & [ LayerId ] , responses : & mut VecDeque < Message > ) {
260
254
let mut image_data: Vec < _ > = Vec :: new ( ) ;
261
- for node_path in monitor_nodes {
255
+ self . thumbnails . retain ( |id, _| self . monitor_nodes . iter ( ) . any ( |node_path| node_path. contains ( id) ) ) ;
256
+ for node_path in & self . monitor_nodes {
262
257
let Some ( node_id) = node_path. get ( node_path. len ( ) - 2 ) . copied ( ) else {
263
258
warn ! ( "Monitor node has invalid node id" ) ;
264
259
continue ;
@@ -268,8 +263,7 @@ impl NodeRuntime {
268
263
continue ;
269
264
} ;
270
265
271
- let Some ( io_data) = value. downcast_ref :: < graphene_core:: memo:: IORecord < Footprint , graphene_core:: GraphicElementData > > ( ) else {
272
- warn ! ( "Failed to downcast thumbnail to graphic element data" ) ;
266
+ let Some ( io_data) = value. downcast_ref :: < IORecord < Footprint , graphene_core:: GraphicElementData > > ( ) else {
273
267
continue ;
274
268
} ;
275
269
let graphic_element_data = & io_data. output ;
@@ -283,10 +277,9 @@ impl NodeRuntime {
283
277
284
278
let click_targets = self . click_targets . entry ( node_id) . or_default ( ) ;
285
279
click_targets. clear ( ) ;
280
+ // Add the graphic element data's click targets to the click targets vector
286
281
graphic_element_data. add_click_targets ( click_targets) ;
287
282
288
- self . transforms . insert ( node_id, graphic_element_data. transform ( ) ) ;
289
-
290
283
let old_thumbnail = self . thumbnails . entry ( node_id) . or_default ( ) ;
291
284
if * old_thumbnail != render. svg {
292
285
responses. add ( FrontendMessage :: UpdateNodeThumbnail {
@@ -305,8 +298,8 @@ impl NodeRuntime {
305
298
}
306
299
}
307
300
308
- pub fn update_upstream_transforms ( & mut self , monitor_nodes : & [ Vec < u64 > ] ) {
309
- for node_path in monitor_nodes {
301
+ pub fn update_upstream_transforms ( & mut self ) {
302
+ for node_path in & self . monitor_nodes {
310
303
let Some ( node_id) = node_path. get ( node_path. len ( ) - 2 ) . copied ( ) else {
311
304
warn ! ( "Monitor node has invalid node id" ) ;
312
305
continue ;
@@ -315,14 +308,16 @@ impl NodeRuntime {
315
308
warn ! ( "Failed to introspect monitor node for upstream transforms" ) ;
316
309
continue ;
317
310
} ;
318
- let Some ( transform) = value
319
- . downcast_ref :: < graphene_core:: memo:: IORecord < Footprint , VectorData > > ( )
320
- . map ( |vector_data| vector_data. output . transform ( ) )
321
- . or_else ( || {
322
- value
323
- . downcast_ref :: < graphene_core:: memo:: IORecord < Footprint , ImageFrame < Color > > > ( )
324
- . map ( |image| image. output . transform ( ) )
325
- } )
311
+
312
+ fn try_downcast < T : Transform + ' static > ( value : & dyn std:: any:: Any ) -> Option < ( Footprint , DAffine2 ) > {
313
+ let io_data = value. downcast_ref :: < IORecord < Footprint , T > > ( ) ?;
314
+ let transform = io_data. output . transform ( ) ;
315
+ Some ( ( io_data. input , transform) )
316
+ }
317
+
318
+ let Some ( transform) = try_downcast :: < VectorData > ( value. as_ref ( ) )
319
+ . or_else ( || try_downcast :: < ImageFrame < Color > > ( value. as_ref ( ) ) )
320
+ . or_else ( || try_downcast :: < GraphicElementData > ( value. as_ref ( ) ) )
326
321
else {
327
322
warn ! ( "Failed to downcast transform input" ) ;
328
323
continue ;
@@ -527,7 +522,6 @@ impl NodeGraphExecutor {
527
522
updates,
528
523
new_thumbnails,
529
524
new_click_targets,
530
- new_transforms,
531
525
new_upstream_transforms,
532
526
transform,
533
527
} ) => {
@@ -566,7 +560,7 @@ impl NodeGraphExecutor {
566
560
} ) ;
567
561
}
568
562
self . thumbnails = new_thumbnails;
569
- document. metadata . update_transforms ( new_transforms , new_upstream_transforms) ;
563
+ document. metadata . update_transforms ( new_upstream_transforms) ;
570
564
document. metadata . update_click_targets ( new_click_targets) ;
571
565
let node_graph_output = result. map_err ( |e| format ! ( "Node graph evaluation failed: {e:?}" ) ) ?;
572
566
let execution_context = self . futures . remove ( & generation_id) . ok_or_else ( || "Invalid generation ID" . to_string ( ) ) ?;
0 commit comments