@@ -137,11 +137,34 @@ pub struct EditorHandle {
137
137
frontend_message_handler_callback : js_sys:: Function ,
138
138
}
139
139
140
- // Defined separately from the `impl` block below since this `impl` block lacks the `#[wasm_bindgen]` attribute.
141
- // Quirks in wasm-bindgen prevent functions in `#[wasm_bindgen]` `impl` blocks from being made publicly accessible from Rust.
142
140
impl EditorHandle {
143
- pub fn send_frontend_message_to_js_rust_proxy ( & self , message : FrontendMessage ) {
144
- self . send_frontend_message_to_js ( message) ;
141
+ // Sends a FrontendMessage to JavaScript
142
+ pub fn send_frontend_message_to_js ( & self , mut message : FrontendMessage ) {
143
+ if let FrontendMessage :: UpdateImageData { ref image_data } = message {
144
+ let new_hash = calculate_hash ( image_data) ;
145
+ let prev_hash = IMAGE_DATA_HASH . load ( Ordering :: Relaxed ) ;
146
+
147
+ if new_hash != prev_hash {
148
+ render_image_data_to_canvases ( image_data. as_slice ( ) ) ;
149
+ IMAGE_DATA_HASH . store ( new_hash, Ordering :: Relaxed ) ;
150
+ }
151
+ return ;
152
+ }
153
+
154
+ if let FrontendMessage :: UpdateDocumentLayerStructure { data_buffer } = message {
155
+ message = FrontendMessage :: UpdateDocumentLayerStructureJs { data_buffer : data_buffer. into ( ) } ;
156
+ }
157
+
158
+ let message_type = message. to_discriminant ( ) . local_name ( ) ;
159
+
160
+ let serializer = serde_wasm_bindgen:: Serializer :: new ( ) . serialize_large_number_types_as_bigints ( true ) ;
161
+ let message_data = message. serialize ( & serializer) . expect ( "Failed to serialize FrontendMessage" ) ;
162
+
163
+ let js_return_value = self . frontend_message_handler_callback . call2 ( & JsValue :: null ( ) , & JsValue :: from ( message_type) , & message_data) ;
164
+
165
+ if let Err ( error) = js_return_value {
166
+ error ! ( "While handling FrontendMessage {:?}, JavaScript threw an error:\n {:?}" , message. to_discriminant( ) . local_name( ) , error, )
167
+ }
145
168
}
146
169
}
147
170
@@ -179,28 +202,12 @@ impl EditorHandle {
179
202
#[ cfg( not( feature = "native" ) ) ]
180
203
fn dispatch < T : Into < Message > > ( & self , message : T ) {
181
204
// Process no further messages after a crash to avoid spamming the console
182
-
183
- use crate :: MESSAGE_BUFFER ;
184
205
if EDITOR_HAS_CRASHED . load ( Ordering :: SeqCst ) {
185
206
return ;
186
207
}
187
-
188
- // Get the editor, dispatch the message, and store the `FrontendMessage` queue response
189
- let frontend_messages = EDITOR . with ( |editor| {
190
- let mut guard = editor. try_lock ( ) ;
191
- let Ok ( Some ( editor) ) = guard. as_deref_mut ( ) else {
192
- // Enqueue messages which can't be procssed currently
193
- MESSAGE_BUFFER . with_borrow_mut ( |buffer| buffer. push ( message. into ( ) ) ) ;
194
- return vec ! [ ] ;
195
- } ;
196
-
197
- editor. handle_message ( message)
208
+ let _ = editor ( |editor| {
209
+ self . process_messages ( std:: iter:: once ( message. into ( ) ) , editor) ;
198
210
} ) ;
199
-
200
- // Send each `FrontendMessage` to the JavaScript frontend
201
- for message in frontend_messages. into_iter ( ) {
202
- self . send_frontend_message_to_js ( message) ;
203
- }
204
211
}
205
212
206
213
#[ cfg( feature = "native" ) ]
@@ -213,43 +220,22 @@ impl EditorHandle {
213
220
crate :: native_communcation:: send_message_to_cef ( serialized_message)
214
221
}
215
222
216
- // Sends a FrontendMessage to JavaScript
217
- fn send_frontend_message_to_js ( & self , mut message : FrontendMessage ) {
218
- // Intercept any requests to render the node graph overlay
219
- if message == FrontendMessage :: RequestNativeNodeGraphRender {
220
- executor_editor_and_handle ( |executor, editor, _handle| {
223
+ // Messages can come from the runtime, browser, or a timed callback. This processes them in the editor and does all the side effects
224
+ // Like updating the frontend and node graph ui network.
225
+ fn process_messages ( & self , messages : impl IntoIterator < Item = Message > , editor : & mut Editor ) {
226
+ // Get the editor, dispatch the message, and store the `FrontendMessage` queue response
227
+ for side_effect in messages. into_iter ( ) . flat_map ( |message| editor. handle_message ( message) ) . collect :: < Vec < _ > > ( ) {
228
+ if side_effect == FrontendMessage :: RequestNativeNodeGraphRender {
221
229
if let Some ( node_graph_overlay_network) = editor. generate_node_graph_overlay_network ( ) {
222
230
let compilation_request = CompilationRequest { network : node_graph_overlay_network } ;
223
- executor. compilation_request ( compilation_request) ;
231
+ let res = executor ( |executor| executor. compilation_request ( compilation_request) ) ;
232
+ if let Err ( _) = res {
233
+ log:: error!( "Could not borrow executor in process_messages_in_editor" ) ;
234
+ }
224
235
}
225
- } ) ;
226
- return ;
227
- }
228
-
229
- if let FrontendMessage :: UpdateImageData { ref image_data } = message {
230
- let new_hash = calculate_hash ( image_data) ;
231
- let prev_hash = IMAGE_DATA_HASH . load ( Ordering :: Relaxed ) ;
232
-
233
- if new_hash != prev_hash {
234
- render_image_data_to_canvases ( image_data. as_slice ( ) ) ;
235
- IMAGE_DATA_HASH . store ( new_hash, Ordering :: Relaxed ) ;
236
+ } else {
237
+ self . send_frontend_message_to_js ( side_effect) ;
236
238
}
237
- return ;
238
- }
239
-
240
- if let FrontendMessage :: UpdateDocumentLayerStructure { data_buffer } = message {
241
- message = FrontendMessage :: UpdateDocumentLayerStructureJs { data_buffer : data_buffer. into ( ) } ;
242
- }
243
-
244
- let message_type = message. to_discriminant ( ) . local_name ( ) ;
245
-
246
- let serializer = serde_wasm_bindgen:: Serializer :: new ( ) . serialize_large_number_types_as_bigints ( true ) ;
247
- let message_data = message. serialize ( & serializer) . expect ( "Failed to serialize FrontendMessage" ) ;
248
-
249
- let js_return_value = self . frontend_message_handler_callback . call2 ( & JsValue :: null ( ) , & JsValue :: from ( message_type) , & message_data) ;
250
-
251
- if let Err ( error) = js_return_value {
252
- error ! ( "While handling FrontendMessage {:?}, JavaScript threw an error:\n {:?}" , message. to_discriminant( ) . local_name( ) , error, )
253
239
}
254
240
}
255
241
@@ -284,16 +270,18 @@ impl EditorHandle {
284
270
285
271
// Poll the UI node graph
286
272
#[ cfg( not( feature = "native" ) ) ]
287
- executor_editor_and_handle ( |executor, editor, handle| {
288
- for frontend_message in executor
289
- . poll_node_graph_ui_evaluation ( editor)
290
- . into_iter ( )
291
- . flat_map ( |runtime_response| editor. handle_message ( runtime_response) )
292
- {
293
- handle. send_frontend_message_to_js ( frontend_message) ;
273
+ let result = editor ( |editor| {
274
+ let node_graph_response = executor ( |executor| executor. poll_node_graph_ui_evaluation ( editor) ) ;
275
+
276
+ match node_graph_response {
277
+ Ok ( node_graph_ui_messages) => handle ( |handle| handle. process_messages ( node_graph_ui_messages, editor) ) ,
278
+ Err ( _) => log:: error!( "Could not get executor in frame loop" ) ,
294
279
}
295
280
} ) ;
296
281
282
+ if let Err ( _) = result {
283
+ log:: error!( "Could not get editor in frame loop" ) ;
284
+ }
297
285
if !EDITOR_HAS_CRASHED . load ( Ordering :: SeqCst ) {
298
286
handle ( |handle| {
299
287
// Process all messages that have been queued up
@@ -1000,64 +988,49 @@ fn set_timeout(f: &Closure<dyn FnMut()>, delay: Duration) {
1000
988
1001
989
/// Provides access to the `Editor` by calling the given closure with it as an argument.
1002
990
#[ cfg( not( feature = "native" ) ) ]
1003
- fn editor < T : Default > ( callback : impl FnOnce ( & mut editor:: application:: Editor ) -> T ) -> T {
991
+ fn editor < T > ( callback : impl FnOnce ( & mut editor:: application:: Editor ) -> T ) -> Result < T , ( ) > {
1004
992
EDITOR . with ( |editor| {
1005
993
let mut guard = editor. try_lock ( ) ;
1006
994
let Ok ( Some ( editor) ) = guard. as_deref_mut ( ) else {
1007
- log:: error!( "Failed to borrow editor" ) ;
1008
- return T :: default ( ) ;
995
+ return Err ( ( ) ) ;
1009
996
} ;
1010
-
1011
- callback ( editor)
997
+ Ok ( callback ( editor) )
1012
998
} )
1013
999
}
1014
1000
1015
1001
#[ cfg( not( feature = "native" ) ) ]
1016
- fn executor < T : Default > ( callback : impl FnOnce ( & mut WasmNodeGraphUIExecutor ) -> T ) -> T {
1002
+ fn executor < T > ( callback : impl FnOnce ( & mut WasmNodeGraphUIExecutor ) -> T ) -> Result < T , ( ) > {
1017
1003
WASM_NODE_GRAPH_EXECUTOR . with ( |executor| {
1018
1004
let mut guard = executor. try_lock ( ) ;
1019
1005
let Ok ( Some ( executor) ) = guard. as_deref_mut ( ) else {
1020
- log:: error!( "Failed to borrow editor" ) ;
1021
- return T :: default ( ) ;
1006
+ return Err ( ( ) ) ;
1022
1007
} ;
1023
1008
1024
- callback ( executor)
1009
+ Ok ( callback ( executor) )
1025
1010
} )
1026
1011
}
1027
1012
1028
- #[ cfg( not( feature = "native" ) ) ]
1029
- pub ( crate ) fn executor_editor_and_handle ( callback : impl FnOnce ( & mut WasmNodeGraphUIExecutor , & mut Editor , & mut EditorHandle ) ) {
1030
- executor ( |executor| {
1031
- handle ( |editor_handle| {
1032
- editor ( |editor| {
1033
- // Call the closure with the editor and its handle
1034
- callback ( executor, editor, editor_handle) ;
1035
- } )
1036
- } ) ;
1037
- } )
1038
- }
1039
-
1040
- /// Provides access to the `Editor` and its `EditorHandle` by calling the given closure with them as arguments.
1041
- #[ cfg( not( feature = "native" ) ) ]
1042
- pub ( crate ) fn editor_and_handle ( callback : impl FnOnce ( & mut Editor , & mut EditorHandle ) ) {
1043
- handle ( |editor_handle| {
1044
- editor ( |editor| {
1045
- // Call the closure with the editor and its handle
1046
- callback ( editor, editor_handle) ;
1047
- } )
1048
- } ) ;
1049
- }
1050
1013
/// Provides access to the `EditorHandle` by calling the given closure with them as arguments.
1051
1014
pub ( crate ) fn handle ( callback : impl FnOnce ( & mut EditorHandle ) ) {
1052
1015
EDITOR_HANDLE . with ( |editor_handle| {
1053
1016
let mut guard = editor_handle. try_lock ( ) ;
1054
1017
let Ok ( Some ( editor_handle) ) = guard. as_deref_mut ( ) else {
1055
- log:: error!( "Failed to borrow editor handle" ) ;
1056
- return ;
1018
+ return log:: error!( "Failed to borrow handle" ) ;
1057
1019
} ;
1058
1020
1059
1021
// Call the closure with the editor and its handle
1060
- callback ( editor_handle) ;
1022
+ callback ( editor_handle)
1023
+ } )
1024
+ }
1025
+
1026
+ /// Provides access to the `Editor` and its `EditorHandle` by calling the given closure with them as arguments.
1027
+ #[ cfg( not( feature = "native" ) ) ]
1028
+ pub ( crate ) fn editor_and_handle ( callback : impl FnOnce ( & mut Editor , & mut EditorHandle ) ) {
1029
+ let _ = handle ( |editor_handle| {
1030
+ let _ = editor ( |editor| {
1031
+ // Call the closure with the editor and its handle
1032
+ callback ( editor, editor_handle) ;
1033
+ } ) ;
1061
1034
} ) ;
1062
1035
}
1063
1036
@@ -1086,10 +1059,7 @@ async fn poll_node_graph_evaluation() {
1086
1059
crate :: NODE_GRAPH_ERROR_DISPLAYED . store ( false , Ordering :: SeqCst ) ;
1087
1060
}
1088
1061
1089
- // Send each `FrontendMessage` to the JavaScript frontend
1090
- for response in messages. into_iter ( ) . flat_map ( |message| editor. handle_message ( message) ) {
1091
- handle. send_frontend_message_to_js ( response) ;
1092
- }
1062
+ handle. process_messages ( messages, editor) ;
1093
1063
1094
1064
// If the editor cannot be borrowed then it has encountered a panic - we should just ignore new dispatches
1095
1065
} ) ;
0 commit comments