Skip to content

Commit 78679a5

Browse files
Implement editor level future message handler (#4182)
* Implement proper editor level async message handler * Take application_io and wake callback as Editor::new arguments * Rename AsyncMessage -> FutureMessage * add DesktopWrapperMessage::Wake --------- Co-authored-by: Timon <me@timon.zip>
1 parent 51427be commit 78679a5

22 files changed

Lines changed: 261 additions & 82 deletions

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

desktop/src/app.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,13 @@ impl App {
9393
});
9494

9595
let resource_storage = MmapResourceStorage::new(dirs::app_resources_dir()).expect("Failed to initialize on-disk resource storage");
96-
let desktop_wrapper = DesktopWrapper::new(rand::rng().random(), Box::new(resource_storage));
96+
97+
// Wake the winit event loop when an editor future completes.
98+
let wake_scheduler = app_event_scheduler.clone();
99+
let wake = std::sync::Arc::new(move || {
100+
wake_scheduler.schedule(AppEvent::DesktopWrapperMessage(DesktopWrapperMessage::Wake));
101+
});
102+
let desktop_wrapper = DesktopWrapper::new(rand::rng().random(), Box::new(resource_storage), wgpu_context.clone(), wake);
97103

98104
Self {
99105
render_state: None,
@@ -528,8 +534,6 @@ impl ApplicationHandler for App {
528534

529535
self.resize();
530536

531-
self.desktop_wrapper.init(self.wgpu_context.clone());
532-
533537
self.startup_time = Some(Instant::now());
534538
}
535539

desktop/wrapper/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ wgpu-executor = { workspace = true }
2020

2121
wgpu = { workspace = true }
2222
thiserror = { workspace = true }
23-
futures = { workspace = true }
2423
tracing = { workspace = true }
2524
dirs = { workspace = true }
2625
ron = { workspace = true}

desktop/wrapper/src/handle_desktop_wrapper_message.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ pub(super) fn handle_desktop_wrapper_message(dispatcher: &mut DesktopWrapperMess
99
DesktopWrapperMessage::FromWeb(message) => {
1010
dispatcher.queue_editor_message(*message);
1111
}
12+
DesktopWrapperMessage::Wake => {
13+
dispatcher.queue_editor_message(EditorMessage::Future(FutureMessage::Wake));
14+
}
1215
DesktopWrapperMessage::Input(message) => {
1316
dispatcher.queue_editor_message(EditorMessage::InputPreprocessor(message));
1417
}

desktop/wrapper/src/intercept_frontend_message.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ use super::messages::{DesktopFrontendMessage, FileFilter, OpenFileDialogContext,
77

88
pub(super) fn intercept_frontend_message(dispatcher: &mut DesktopWrapperMessageDispatcher, message: FrontendMessage) -> Option<FrontendMessage> {
99
match message {
10-
FrontendMessage::Await { future } => {
11-
let message = futures::executor::block_on(async move { future.await });
12-
return intercept_frontend_message(dispatcher, message);
13-
}
1410
FrontendMessage::RenderOverlays { context } => {
1511
dispatcher.respond(DesktopFrontendMessage::UpdateOverlays(context.take_scene()));
1612
}

desktop/wrapper/src/lib.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use graph_craft::application_io::PlatformApplicationIo;
22
use graph_craft::application_io::resource::ResourceStorage;
33
use graphite_editor::application::{Editor, Environment, Host, Platform};
4-
use graphite_editor::messages::prelude::{FrontendMessage, Message};
4+
use graphite_editor::messages::prelude::{FrontendMessage, Message, Wake};
55
use message_dispatcher::DesktopWrapperMessageDispatcher;
66
use messages::{DesktopFrontendMessage, DesktopWrapperMessage};
77

@@ -24,25 +24,21 @@ pub struct DesktopWrapper {
2424
}
2525

2626
impl DesktopWrapper {
27-
pub fn new(uuid_random_seed: u64, resource_storage: Box<dyn ResourceStorage>) -> Self {
27+
pub fn new(uuid_random_seed: u64, resource_storage: Box<dyn ResourceStorage>, wgpu_context: WgpuContext, schedule_wake: Wake) -> Self {
2828
#[cfg(target_os = "windows")]
2929
let host = Host::Windows;
3030
#[cfg(target_os = "macos")]
3131
let host = Host::Mac;
3232
#[cfg(target_os = "linux")]
3333
let host = Host::Linux;
3434
let env = Environment { platform: Platform::Desktop, host };
35+
let application_io = PlatformApplicationIo::new_with_context(wgpu_context);
3536

3637
Self {
37-
editor: Editor::new(env, uuid_random_seed, resource_storage),
38+
editor: Editor::new(env, uuid_random_seed, resource_storage, application_io, schedule_wake),
3839
}
3940
}
4041

41-
pub fn init(&mut self, wgpu_context: WgpuContext) {
42-
let application_io = PlatformApplicationIo::new_with_context(wgpu_context);
43-
self.editor.replace_application_io(application_io);
44-
}
45-
4642
pub fn dispatch(&mut self, message: DesktopWrapperMessage) -> Vec<DesktopFrontendMessage> {
4743
let mut executor = DesktopWrapperMessageDispatcher::new(&mut self.editor);
4844
executor.queue_desktop_wrapper_message(message);

desktop/wrapper/src/messages.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ pub enum DesktopFrontendMessage {
8282

8383
pub enum DesktopWrapperMessage {
8484
FromWeb(Box<EditorMessage>),
85+
Wake,
8586
Input(InputMessage),
8687
FileDialogResult { path: PathBuf, content: Vec<u8>, context: OpenFileDialogContext },
8788
SaveFileDialogResult { path: PathBuf, context: SaveFileDialogContext },

editor/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,13 @@ wgpu-executor = { workspace = true, optional = true }
5555
# Optional workspace dependencies
5656
wasm-bindgen = { workspace = true, optional = true }
5757

58+
[target.'cfg(not(target_family = "wasm"))'.dependencies]
59+
tokio = { workspace = true }
60+
61+
[target.'cfg(target_family = "wasm")'.dependencies]
62+
wasm-bindgen-futures = { workspace = true }
63+
5864
[dev-dependencies]
5965
# Workspace dependencies
6066
env_logger = { workspace = true }
6167
futures = { workspace = true }
62-
tokio = { workspace = true }

editor/src/application.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ pub struct Editor {
1010
}
1111

1212
impl Editor {
13-
pub fn new(environment: Environment, uuid_random_seed: u64, resource_storage: Box<dyn ResourceStorage>) -> Self {
13+
pub fn new(environment: Environment, uuid_random_seed: u64, resource_storage: Box<dyn ResourceStorage>, mut application_io: PlatformApplicationIo, wake: Wake) -> Self {
1414
ENVIRONMENT.set(environment).expect("Editor shoud only be initialized once");
1515
graphene_std::uuid::set_uuid_seed(uuid_random_seed);
1616

17-
Self {
18-
dispatcher: Dispatcher::new(resource_storage),
19-
}
17+
let mut dispatcher = Dispatcher::new(resource_storage);
18+
dispatcher.message_handlers.async_message_handler.set_wake(wake);
19+
application_io.inject_resource_proxy(dispatcher.message_handlers.resource_storage_message_handler.resources());
20+
crate::node_graph_executor::replace_application_io(application_io);
21+
22+
Self { dispatcher }
2023
}
2124

2225
#[cfg(test)]
@@ -45,11 +48,6 @@ impl Editor {
4548
pub fn poll_node_graph_evaluation(&mut self, responses: &mut VecDeque<Message>) -> Result<(), String> {
4649
self.dispatcher.poll_node_graph_evaluation(responses)
4750
}
48-
49-
pub fn replace_application_io(&mut self, mut application_io: PlatformApplicationIo) {
50-
application_io.inject_resource_proxy(self.dispatcher.message_handlers.resource_storage_message_handler.resources());
51-
crate::node_graph_executor::replace_application_io(application_io)
52-
}
5351
}
5452

5553
static ENVIRONMENT: OnceLock<Environment> = OnceLock::new();

editor/src/dispatcher.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub struct Dispatcher {
2020
pub struct DispatcherMessageHandlers {
2121
animation_message_handler: AnimationMessageHandler,
2222
app_window_message_handler: AppWindowMessageHandler,
23+
pub(crate) async_message_handler: FutureMessageHandler,
2324
broadcast_message_handler: BroadcastMessageHandler,
2425
clipboard_message_handler: ClipboardMessageHandler,
2526
color_picker_message_handler: ColorPickerMessageHandler,
@@ -124,6 +125,13 @@ impl Dispatcher {
124125
pub fn handle_message<T: Into<Message>>(&mut self, message: T, process_after_all_current: bool) {
125126
let message = message.into();
126127

128+
// Drain async results into the queue before processing the new message.
129+
let mut async_results = VecDeque::new();
130+
self.message_handlers.async_message_handler.drain_results(&mut async_results);
131+
if !async_results.is_empty() {
132+
Self::schedule_execution(&mut self.message_queues, true, async_results);
133+
}
134+
127135
// If we are not maintaining the buffer, simply add to the current queue
128136
Self::schedule_execution(&mut self.message_queues, process_after_all_current, [message]);
129137

@@ -173,6 +181,9 @@ impl Dispatcher {
173181
Message::AppWindow(message) => {
174182
self.message_handlers.app_window_message_handler.process_message(message, &mut queue, ());
175183
}
184+
Message::Future(message) => {
185+
self.message_handlers.async_message_handler.process_message(message, &mut queue, FutureMessageContext {});
186+
}
176187
Message::Broadcast(message) => self.message_handlers.broadcast_message_handler.process_message(message, &mut queue, ()),
177188
Message::Clipboard(message) => self.message_handlers.clipboard_message_handler.process_message(message, &mut queue, ()),
178189
Message::ColorPicker(message) => self.message_handlers.color_picker_message_handler.process_message(message, &mut queue, ()),

0 commit comments

Comments
 (0)