Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions desktop/wrapper/src/message_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ impl<'a> DesktopWrapperMessageDispatcher<'a> {
.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));
});
// .into_iter()
// .filter_map(|m| intercept_frontend_message(self, m));
frontend_messages.extend(current_frontend_messages);
}

Expand Down
36 changes: 3 additions & 33 deletions editor/src/application.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::dispatcher::Dispatcher;
use crate::messages::portfolio::document::node_graph::generate_node_graph_overlay::generate_node_graph_overlay;
use crate::dispatcher::EditorOutput;
use crate::messages::prelude::*;
use graph_craft::document::{NodeInput, NodeNetwork};
use graphene_std::node_graph_overlay::types::NodeGraphOverlayData;
pub use graphene_std::uuid::*;

// TODO: serialize with serde to save the current editor state
Expand All @@ -24,41 +22,13 @@ impl Editor {
(Self { dispatcher }, runtime)
}

pub fn handle_message<T: Into<Message>>(&mut self, message: T) -> Vec<FrontendMessage> {
self.dispatcher.handle_message(message, true);

std::mem::take(&mut self.dispatcher.responses)
pub fn handle_message<T: Into<Message>>(&mut self, message: T) -> Vec<EditorOutput> {
self.dispatcher.handle_message(message, true)
}

pub fn poll_node_graph_evaluation(&mut self, responses: &mut VecDeque<Message>) -> Result<(), String> {
self.dispatcher.poll_node_graph_evaluation(responses)
}

pub fn generate_node_graph_overlay_network(&mut self) -> Option<NodeNetwork> {
let Some(active_document) = self.dispatcher.message_handlers.portfolio_message_handler.active_document_mut() else {
return None;
};
let breadcrumb_network_path = &active_document.breadcrumb_network_path;
let nodes_to_render = active_document.network_interface.collect_nodes(
&active_document.node_graph_handler.node_graph_errors,
self.dispatcher.message_handlers.preferences_message_handler.graph_wire_style,
breadcrumb_network_path,
);
let previewed_node = active_document.network_interface.previewed_node(breadcrumb_network_path);
let node_graph_render_data = NodeGraphOverlayData {
nodes_to_render,
open: active_document.graph_view_overlay_open,
in_selected_network: &active_document.selection_network_path == breadcrumb_network_path,
previewed_node,
};
let opacity = active_document.graph_fade_artwork_percentage;
let node_graph_overlay_node = generate_node_graph_overlay(node_graph_render_data, opacity);
Some(NodeNetwork {
exports: vec![NodeInput::node(NodeId(0), 0)],
nodes: vec![(NodeId(0), node_graph_overlay_node)].into_iter().collect(),
..Default::default()
})
}
}

impl Default for Editor {
Expand Down
60 changes: 41 additions & 19 deletions editor/src/dispatcher.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::time::Duration;

use interpreted_executor::ui_runtime::CompilationRequest;

use crate::messages::debug::utility_types::MessageLoggingVerbosity;
use crate::messages::defer::DeferMessageContext;
use crate::messages::dialog::DialogMessageContext;
Expand All @@ -7,7 +11,6 @@ use crate::messages::prelude::*;
#[derive(Debug, Default)]
pub struct Dispatcher {
message_queues: Vec<VecDeque<Message>>,
pub responses: Vec<FrontendMessage>,
pub message_handlers: DispatcherMessageHandlers,
}

Expand All @@ -28,6 +31,16 @@ pub struct DispatcherMessageHandlers {
tool_message_handler: ToolMessageHandler,
}

// Output messages are what the editor returns after processing Messages. It is handled by the scope outside the editor,
// which has access to the node graph executor, frontend, etc
#[derive(Debug)]
pub enum EditorOutput {
// These messages perform some side effect other than updating the frontend, but outside the scope of the editor
RequestNativeNodeGraphRender { compilation_request: CompilationRequest },
RequestDeferredMessage { message: Box<Message>, timeout: Duration },
FrontendMessage { frontend_message: FrontendMessage },
}

impl DispatcherMessageHandlers {
pub fn with_executor(executor: crate::node_graph_executor::NodeGraphExecutor) -> Self {
Self {
Expand All @@ -41,7 +54,6 @@ impl DispatcherMessageHandlers {
/// The last occurrence of the message in the message queue is sufficient to ensure correct behavior.
/// In addition, these messages do not change any state in the backend (aside from caches).
const SIDE_EFFECT_FREE_MESSAGES: &[MessageDiscriminant] = &[
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::NodeGraph(NodeGraphMessageDiscriminant::SendGraph))),
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::PropertiesPanel(
PropertiesPanelMessageDiscriminant::Refresh,
))),
Expand Down Expand Up @@ -93,12 +105,14 @@ impl Dispatcher {
}
}

pub fn handle_message<T: Into<Message>>(&mut self, message: T, process_after_all_current: bool) {
pub fn handle_message<T: Into<Message>>(&mut self, message: T, process_after_all_current: bool) -> Vec<EditorOutput> {
let message = message.into();

// If we are not maintaining the buffer, simply add to the current queue
Self::schedule_execution(&mut self.message_queues, process_after_all_current, [message]);

let mut side_effects = Vec::new();
let mut output_messages = Vec::new();

while let Some(message) = self.message_queues.last_mut().and_then(VecDeque::pop_front) {
// Skip processing of this message if it will be processed later (at the end of the shallowest level queue)
if SIDE_EFFECT_FREE_MESSAGES.contains(&message.to_discriminant()) {
Expand Down Expand Up @@ -148,17 +162,8 @@ impl Dispatcher {
self.message_handlers.dialog_message_handler.process_message(message, &mut queue, context);
}
Message::Frontend(message) => {
// Handle these messages immediately by returning early
if let FrontendMessage::TriggerFontLoad { .. } = message {
self.responses.push(message);
self.cleanup_queues(false);

// Return early to avoid running the code after the match block
return;
} else {
// `FrontendMessage`s are saved and will be sent to the frontend after the message queue is done being processed
self.responses.push(message);
}
// `FrontendMessage`s are saved and will be sent to the frontend after the message queue is done being processed
output_messages.push(EditorOutput::FrontendMessage { frontend_message: message });
}
Message::Globals(message) => {
self.message_handlers.globals_message_handler.process_message(message, &mut queue, ());
Expand Down Expand Up @@ -210,14 +215,19 @@ impl Dispatcher {
Message::Preferences(message) => {
self.message_handlers.preferences_message_handler.process_message(message, &mut queue, ());
}
Message::SideEffect(message) => {
if !side_effects.contains(&message) {
side_effects.push(message);
}
}
Message::Tool(message) => {
let Some(document_id) = self.message_handlers.portfolio_message_handler.active_document_id() else {
warn!("Called ToolMessage without an active document.\nGot {message:?}");
return;
return Vec::new();
};
let Some(document) = self.message_handlers.portfolio_message_handler.documents.get_mut(&document_id) else {
warn!("Called ToolMessage with an invalid active document.\nGot {message:?}");
return;
return Vec::new();
};

let context = ToolMessageContext {
Expand All @@ -233,7 +243,9 @@ impl Dispatcher {
}
Message::NoOp => {}
Message::Batched { messages } => {
messages.iter().for_each(|message| self.handle_message(message.to_owned(), false));
for nested_outputs in messages.into_iter().map(|message| self.handle_message(message, false)) {
output_messages.extend(nested_outputs);
}
}
}

Expand All @@ -244,6 +256,12 @@ impl Dispatcher {

self.cleanup_queues(false);
}

// The full message tree has been processed, so the side effects can be processed
for message in side_effects {
output_messages.extend(self.handle_side_effect(message));
}
output_messages
}

pub fn collect_actions(&self) -> ActionList {
Expand Down Expand Up @@ -311,6 +329,7 @@ impl Dispatcher {

#[cfg(test)]
mod test {
use crate::messages::side_effects::EditorOutputMessage;
pub use crate::test_utils::test_prelude::*;

/// Create an editor with three layers
Expand Down Expand Up @@ -510,7 +529,10 @@ mod test {

for response in responses {
// Check for the existence of the file format incompatibility warning dialog after opening the test file
if let FrontendMessage::UpdateDialogColumn1 { layout_target: _, diff } = response {
if let EditorOutputMessage::FrontendMessage {
frontend_message: FrontendMessage::UpdateDialogColumn1 { layout_target: _, diff },
} = response
{
if let DiffUpdate::SubLayout(sub_layout) = &diff[0].new_value {
if let LayoutGroup::Row { widgets } = &sub_layout[0] {
if let Widget::TextLabel(TextLabel { value, .. }) = &widgets[0].widget {
Expand Down
5 changes: 4 additions & 1 deletion editor/src/messages/frontend/frontend_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ pub enum FrontendMessage {
UpdateMouseCursor {
cursor: MouseCursorIcon,
},
RequestNativeNodeGraphRender,
UpdateNativeNodeGraphSVG {
#[serde(rename = "svgString")]
svg_string: String,
Expand All @@ -293,6 +292,10 @@ pub enum FrontendMessage {
layout_target: LayoutTarget,
diff: Vec<WidgetDiff>,
},
UpdateTooltip {
position: Option<FrontendXY>,
text: String,
},
UpdateToolOptionsLayout {
#[serde(rename = "layoutTarget")]
layout_target: LayoutTarget,
Expand Down
4 changes: 3 additions & 1 deletion editor/src/messages/message.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::messages::prelude::*;
use crate::messages::{prelude::*, side_effects::{SideEffectMessage}};
use graphite_proc_macros::*;

#[impl_message]
Expand All @@ -18,6 +18,8 @@ pub enum Message {
#[child]
Dialog(DialogMessage),
#[child]
SideEffect(SideEffectMessage),
#[child]
Frontend(FrontendMessage),
#[child]
Globals(GlobalsMessage),
Expand Down
1 change: 1 addition & 0 deletions editor/src/messages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ pub mod message;
pub mod portfolio;
pub mod preferences;
pub mod prelude;
pub mod side_effects;
pub mod tool;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use graphene_std::gradient::GradientStops;
use graphene_std::memo::IORecord;
use graphene_std::raster_types::{CPU, GPU, Raster};
use graphene_std::table::Table;
use graphene_std::text::Typography;
use graphene_std::vector::Vector;
use graphene_std::vector::style::{Fill, FillChoice};
use graphene_std::{Artboard, Graphic};
Expand Down Expand Up @@ -266,6 +267,7 @@ impl TableRowLayout for Graphic {
Self::RasterGPU(table) => table.identifier(),
Self::Color(table) => table.identifier(),
Self::Gradient(table) => table.identifier(),
Self::Typography(table) => table.identifier(),
}
}
// Don't put a breadcrumb for Graphic
Expand All @@ -280,6 +282,7 @@ impl TableRowLayout for Graphic {
Self::RasterGPU(table) => table.layout_with_breadcrumb(data),
Self::Color(table) => table.layout_with_breadcrumb(data),
Self::Gradient(table) => table.layout_with_breadcrumb(data),
Self::Typography(table) => table.layout_with_breadcrumb(data),
}
}
}
Expand Down Expand Up @@ -504,6 +507,21 @@ impl TableRowLayout for GradientStops {
}
}

impl TableRowLayout for Typography {
fn type_name() -> &'static str {
"Typography"
}
fn identifier(&self) -> String {
"Typography".to_string()
}
fn element_widget(&self, _index: usize) -> WidgetHolder {
TextLabel::new("Not supported").widget_holder()
}
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
vec![LayoutGroup::Row { widgets: Vec::new() }]
}
}

impl TableRowLayout for f64 {
fn type_name() -> &'static str {
"Number (f64)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,8 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
x: transform.translation.x,
y: transform.translation.y,
},
})
});
responses.add(NodeGraphMessage::PointerMove { shift: Key::Shift });
}
}
DocumentMessage::SelectionStepBack => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn generate_node_graph_overlay(node_graph_overlay_data: NodeGraphOverlayData
generate_nodes_id,
DocumentNode {
call_argument: concrete!(UIContext),
inputs: vec![NodeInput::network(concrete!(UIContext), 1)],
inputs: vec![NodeInput::network(concrete!(UIContext), 1), NodeInput::scope("font-cache")],
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::node_graph_overlay::GenerateNodesNode".into()),
..Default::default()
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use glam::IVec2;
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput};
use graph_craft::proto::GraphErrors;
use graphene_std::Graphic;
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypesDelta;

#[impl_message(Message, DocumentMessage, NodeGraph)]
Expand Down Expand Up @@ -214,10 +215,15 @@ pub enum NodeGraphMessage {
SetLockedOrVisibilitySideEffects {
node_ids: Vec<NodeId>,
},
TryDisplayTooltip,
UpdateBoxSelection,
UpdateImportsExports,
UpdateLayerPanel,
UpdateNewNodeGraph,
UpdateThumbnail {
node_id: NodeId,
graphic: Graphic,
},
UpdateTypes {
#[serde(skip)]
resolved_types: ResolvedDocumentNodeTypesDelta,
Expand Down
Loading
Loading