Graphite/desktop/wrapper/src/message_dispatcher.rs

79 lines
2.5 KiB
Rust

use graphite_editor::application::Editor;
use std::collections::VecDeque;
use super::handle_desktop_wrapper_message::handle_desktop_wrapper_message;
use super::intercept_editor_message::intercept_editor_message;
use super::intercept_frontend_message::intercept_frontend_message;
use super::messages::{DesktopFrontendMessage, DesktopWrapperMessage, EditorMessage};
pub(crate) struct DesktopWrapperMessageDispatcher<'a> {
editor: &'a mut Editor,
desktop_wrapper_message_queue: VecDeque<DesktopWrapperMessage>,
editor_message_queue: Vec<EditorMessage>,
responses: Vec<DesktopFrontendMessage>,
}
impl<'a> DesktopWrapperMessageDispatcher<'a> {
pub(crate) fn new(editor: &'a mut Editor) -> Self {
Self {
editor,
desktop_wrapper_message_queue: VecDeque::new(),
editor_message_queue: Vec::new(),
responses: Vec::new(),
}
}
pub(crate) fn execute(mut self) -> Vec<DesktopFrontendMessage> {
self.process_queue();
self.responses
}
pub(crate) fn queue_desktop_wrapper_message(&mut self, message: DesktopWrapperMessage) {
self.desktop_wrapper_message_queue.push_back(message);
}
pub(super) fn queue_editor_message<T: Into<EditorMessage>>(&mut self, message: T) {
if let Some(message) = intercept_editor_message(self, message.into()) {
self.editor_message_queue.push(message);
}
}
pub(super) fn respond(&mut self, response: DesktopFrontendMessage) {
self.responses.push(response);
}
pub(super) fn poll_node_graph_evaluation(&mut self) {
let mut responses = VecDeque::new();
if let Err(e) = self.editor.poll_node_graph_evaluation(&mut responses) {
if e != "No active document" {
tracing::error!("Error poling node graph: {}", e);
}
}
while let Some(message) = responses.pop_front() {
self.queue_editor_message(message);
}
}
fn process_queue(&mut self) {
let mut frontend_messages = Vec::new();
while !self.desktop_wrapper_message_queue.is_empty() || !self.editor_message_queue.is_empty() {
while let Some(message) = self.desktop_wrapper_message_queue.pop_front() {
handle_desktop_wrapper_message(self, message);
}
let current_frontend_messages = self
.editor
.handle_message(EditorMessage::Batched {
messages: std::mem::take(&mut self.editor_message_queue).into_boxed_slice(),
})
.into_iter()
.filter_map(|m| intercept_frontend_message(self, m));
frontend_messages.extend(current_frontend_messages);
}
if !frontend_messages.is_empty() {
self.respond(DesktopFrontendMessage::ToWeb(frontend_messages));
}
}
}