mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-05 18:28:11 +08:00
Generate a visualization of the editor's hierarchical message system tree (#2499)
* Feat: implement the hierarchical tree for visualization * rename HierarchicalTree trait function * feat: change the HierarchicalTree from String to DebugMessageTree struct * Nits * feat: impliment proc macro to extract field from messagedata structs * update the hierarchical-tree for hanlder data * feat: added message handler struct to hierarchical tree * feat: add the line number to message handler struct * feat: added handler path to tree and NITS * clean the white spaces in type string * fixes some white spaces * feat: added path to message enum in hierarchical tree * feat: add file creation of hierarchical message system tree * cleanup * Code review * Add todo comment for deferred change --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
d0e1d8982f
commit
00236c8136
@@ -6,3 +6,4 @@ profile.json
|
|||||||
flamegraph.svg
|
flamegraph.svg
|
||||||
.idea/
|
.idea/
|
||||||
.direnv
|
.direnv
|
||||||
|
hierarchical_message_system_tree.txt
|
||||||
|
|||||||
@@ -15,3 +15,4 @@ pub mod node_graph_executor;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod test_utils;
|
pub mod test_utils;
|
||||||
pub mod utility_traits;
|
pub mod utility_traits;
|
||||||
|
pub mod utility_types;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ enum AnimationState {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq)]
|
#[derive(Default, Debug, Clone, PartialEq, ExtractField)]
|
||||||
pub struct AnimationMessageHandler {
|
pub struct AnimationMessageHandler {
|
||||||
/// Used to re-send the UI on the next frame after playback starts
|
/// Used to re-send the UI on the next frame after playback starts
|
||||||
live_preview_recently_zero: bool,
|
live_preview_recently_zero: bool,
|
||||||
@@ -57,6 +57,7 @@ impl AnimationMessageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<AnimationMessage, ()> for AnimationMessageHandler {
|
impl MessageHandler<AnimationMessage, ()> for AnimationMessageHandler {
|
||||||
fn process_message(&mut self, message: AnimationMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: AnimationMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct BroadcastMessageHandler {
|
pub struct BroadcastMessageHandler {
|
||||||
listeners: HashMap<BroadcastEvent, Vec<Message>>,
|
listeners: HashMap<BroadcastEvent, Vec<Message>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<BroadcastMessage, ()> for BroadcastMessageHandler {
|
impl MessageHandler<BroadcastMessage, ()> for BroadcastMessageHandler {
|
||||||
fn process_message(&mut self, message: BroadcastMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: BroadcastMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use super::utility_types::MessageLoggingVerbosity;
|
use super::utility_types::MessageLoggingVerbosity;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, ExtractField)]
|
||||||
pub struct DebugMessageHandler {
|
pub struct DebugMessageHandler {
|
||||||
pub message_logging_verbosity: MessageLoggingVerbosity,
|
pub message_logging_verbosity: MessageLoggingVerbosity,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<DebugMessage, ()> for DebugMessageHandler {
|
impl MessageHandler<DebugMessage, ()> for DebugMessageHandler {
|
||||||
fn process_message(&mut self, message: DebugMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: DebugMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -2,19 +2,21 @@ use super::simple_dialogs::{self, AboutGraphiteDialog, ComingSoonDialog, DemoArt
|
|||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct DialogMessageData<'a> {
|
pub struct DialogMessageData<'a> {
|
||||||
pub portfolio: &'a PortfolioMessageHandler,
|
pub portfolio: &'a PortfolioMessageHandler,
|
||||||
pub preferences: &'a PreferencesMessageHandler,
|
pub preferences: &'a PreferencesMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores the dialogs which require state. These are the ones that have their own message handlers, and are not the ones defined in `simple_dialogs`.
|
/// Stores the dialogs which require state. These are the ones that have their own message handlers, and are not the ones defined in `simple_dialogs`.
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone, ExtractField)]
|
||||||
pub struct DialogMessageHandler {
|
pub struct DialogMessageHandler {
|
||||||
export_dialog: ExportDialogMessageHandler,
|
export_dialog: ExportDialogMessageHandler,
|
||||||
new_document_dialog: NewDocumentDialogMessageHandler,
|
new_document_dialog: NewDocumentDialogMessageHandler,
|
||||||
preferences_dialog: PreferencesDialogMessageHandler,
|
preferences_dialog: PreferencesDialogMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<DialogMessage, DialogMessageData<'_>> for DialogMessageHandler {
|
impl MessageHandler<DialogMessage, DialogMessageData<'_>> for DialogMessageHandler {
|
||||||
fn process_message(&mut self, message: DialogMessage, responses: &mut VecDeque<Message>, data: DialogMessageData) {
|
fn process_message(&mut self, message: DialogMessage, responses: &mut VecDeque<Message>, data: DialogMessageData) {
|
||||||
let DialogMessageData { portfolio, preferences } = data;
|
let DialogMessageData { portfolio, preferences } = data;
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ use crate::messages::layout::utility_types::widget_prelude::*;
|
|||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct ExportDialogMessageData<'a> {
|
pub struct ExportDialogMessageData<'a> {
|
||||||
pub portfolio: &'a PortfolioMessageHandler,
|
pub portfolio: &'a PortfolioMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A dialog to allow users to customize their file export.
|
/// A dialog to allow users to customize their file export.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, ExtractField)]
|
||||||
pub struct ExportDialogMessageHandler {
|
pub struct ExportDialogMessageHandler {
|
||||||
pub file_type: FileType,
|
pub file_type: FileType,
|
||||||
pub scale_factor: f64,
|
pub scale_factor: f64,
|
||||||
@@ -31,6 +32,7 @@ impl Default for ExportDialogMessageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<ExportDialogMessage, ExportDialogMessageData<'_>> for ExportDialogMessageHandler {
|
impl MessageHandler<ExportDialogMessage, ExportDialogMessageData<'_>> for ExportDialogMessageHandler {
|
||||||
fn process_message(&mut self, message: ExportDialogMessage, responses: &mut VecDeque<Message>, data: ExportDialogMessageData) {
|
fn process_message(&mut self, message: ExportDialogMessage, responses: &mut VecDeque<Message>, data: ExportDialogMessageData) {
|
||||||
let ExportDialogMessageData { portfolio } = data;
|
let ExportDialogMessageData { portfolio } = data;
|
||||||
|
|||||||
+2
-1
@@ -4,13 +4,14 @@ use glam::{IVec2, UVec2};
|
|||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
|
|
||||||
/// A dialog to allow users to set some initial options about a new document.
|
/// A dialog to allow users to set some initial options about a new document.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct NewDocumentDialogMessageHandler {
|
pub struct NewDocumentDialogMessageHandler {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub infinite: bool,
|
pub infinite: bool,
|
||||||
pub dimensions: UVec2,
|
pub dimensions: UVec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<NewDocumentDialogMessage, ()> for NewDocumentDialogMessageHandler {
|
impl MessageHandler<NewDocumentDialogMessage, ()> for NewDocumentDialogMessageHandler {
|
||||||
fn process_message(&mut self, message: NewDocumentDialogMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: NewDocumentDialogMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -4,14 +4,16 @@ use crate::messages::portfolio::document::utility_types::wires::GraphWireStyle;
|
|||||||
use crate::messages::preferences::SelectionMode;
|
use crate::messages::preferences::SelectionMode;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct PreferencesDialogMessageData<'a> {
|
pub struct PreferencesDialogMessageData<'a> {
|
||||||
pub preferences: &'a PreferencesMessageHandler,
|
pub preferences: &'a PreferencesMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A dialog to allow users to customize Graphite editor options
|
/// A dialog to allow users to customize Graphite editor options
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct PreferencesDialogMessageHandler {}
|
pub struct PreferencesDialogMessageHandler {}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<PreferencesDialogMessage, PreferencesDialogMessageData<'_>> for PreferencesDialogMessageHandler {
|
impl MessageHandler<PreferencesDialogMessage, PreferencesDialogMessageData<'_>> for PreferencesDialogMessageHandler {
|
||||||
fn process_message(&mut self, message: PreferencesDialogMessage, responses: &mut VecDeque<Message>, data: PreferencesDialogMessageData) {
|
fn process_message(&mut self, message: PreferencesDialogMessage, responses: &mut VecDeque<Message>, data: PreferencesDialogMessageData) {
|
||||||
let PreferencesDialogMessageData { preferences } = data;
|
let PreferencesDialogMessageData { preferences } = data;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, ExtractField)]
|
||||||
pub struct GlobalsMessageHandler {}
|
pub struct GlobalsMessageHandler {}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<GlobalsMessage, ()> for GlobalsMessageHandler {
|
impl MessageHandler<GlobalsMessage, ()> for GlobalsMessageHandler {
|
||||||
fn process_message(&mut self, message: GlobalsMessage, _responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: GlobalsMessage, _responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -6,16 +6,18 @@ use crate::messages::portfolio::utility_types::KeyboardPlatformLayout;
|
|||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct InputMapperMessageData<'a> {
|
pub struct InputMapperMessageData<'a> {
|
||||||
pub input: &'a InputPreprocessorMessageHandler,
|
pub input: &'a InputPreprocessorMessageHandler,
|
||||||
pub actions: ActionList,
|
pub actions: ActionList,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, ExtractField)]
|
||||||
pub struct InputMapperMessageHandler {
|
pub struct InputMapperMessageHandler {
|
||||||
mapping: Mapping,
|
mapping: Mapping,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<InputMapperMessage, InputMapperMessageData<'_>> for InputMapperMessageHandler {
|
impl MessageHandler<InputMapperMessage, InputMapperMessageData<'_>> for InputMapperMessageHandler {
|
||||||
fn process_message(&mut self, message: InputMapperMessage, responses: &mut VecDeque<Message>, data: InputMapperMessageData) {
|
fn process_message(&mut self, message: InputMapperMessage, responses: &mut VecDeque<Message>, data: InputMapperMessageData) {
|
||||||
let InputMapperMessageData { input, actions } = data;
|
let InputMapperMessageData { input, actions } = data;
|
||||||
|
|||||||
@@ -2,16 +2,18 @@ use crate::messages::input_mapper::input_mapper_message_handler::InputMapperMess
|
|||||||
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct KeyMappingMessageData<'a> {
|
pub struct KeyMappingMessageData<'a> {
|
||||||
pub input: &'a InputPreprocessorMessageHandler,
|
pub input: &'a InputPreprocessorMessageHandler,
|
||||||
pub actions: ActionList,
|
pub actions: ActionList,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, ExtractField)]
|
||||||
pub struct KeyMappingMessageHandler {
|
pub struct KeyMappingMessageHandler {
|
||||||
mapping_handler: InputMapperMessageHandler,
|
mapping_handler: InputMapperMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<KeyMappingMessage, KeyMappingMessageData<'_>> for KeyMappingMessageHandler {
|
impl MessageHandler<KeyMappingMessage, KeyMappingMessageData<'_>> for KeyMappingMessageHandler {
|
||||||
fn process_message(&mut self, message: KeyMappingMessage, responses: &mut VecDeque<Message>, data: KeyMappingMessageData) {
|
fn process_message(&mut self, message: KeyMappingMessage, responses: &mut VecDeque<Message>, data: KeyMappingMessageData) {
|
||||||
let KeyMappingMessageData { input, actions } = data;
|
let KeyMappingMessageData { input, actions } = data;
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ use crate::messages::prelude::*;
|
|||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct InputPreprocessorMessageData {
|
pub struct InputPreprocessorMessageData {
|
||||||
pub keyboard_platform: KeyboardPlatformLayout,
|
pub keyboard_platform: KeyboardPlatformLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, ExtractField)]
|
||||||
pub struct InputPreprocessorMessageHandler {
|
pub struct InputPreprocessorMessageHandler {
|
||||||
pub frame_time: FrameTimeInfo,
|
pub frame_time: FrameTimeInfo,
|
||||||
pub time: u64,
|
pub time: u64,
|
||||||
@@ -19,6 +20,7 @@ pub struct InputPreprocessorMessageHandler {
|
|||||||
pub viewport_bounds: ViewportBounds,
|
pub viewport_bounds: ViewportBounds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageData> for InputPreprocessorMessageHandler {
|
impl MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageData> for InputPreprocessorMessageHandler {
|
||||||
fn process_message(&mut self, message: InputPreprocessorMessage, responses: &mut VecDeque<Message>, data: InputPreprocessorMessageData) {
|
fn process_message(&mut self, message: InputPreprocessorMessage, responses: &mut VecDeque<Message>, data: InputPreprocessorMessageData) {
|
||||||
let InputPreprocessorMessageData { keyboard_platform } = data;
|
let InputPreprocessorMessageData { keyboard_platform } = data;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use graphene_std::text::Font;
|
|||||||
use graphene_std::vector::style::{FillChoice, GradientStops};
|
use graphene_std::vector::style::{FillChoice, GradientStops};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct LayoutMessageHandler {
|
pub struct LayoutMessageHandler {
|
||||||
layouts: [Layout; LayoutTarget::LayoutTargetLength as usize],
|
layouts: [Layout; LayoutTarget::LayoutTargetLength as usize],
|
||||||
}
|
}
|
||||||
@@ -342,6 +342,15 @@ impl LayoutMessageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn custom_data() -> MessageData {
|
||||||
|
// TODO: When <https://github.com/dtolnay/proc-macro2/issues/503> is resolved and released,
|
||||||
|
// TODO: use <https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.line> to get
|
||||||
|
// TODO: the line number instead of hardcoding it to the magic number on the following line.
|
||||||
|
// TODO: Also, utilize the line number in the actual output, since it is currently unused.
|
||||||
|
MessageData::new(String::from("Function"), vec![(String::from("Fn(&MessageDiscriminant) -> Option<KeysGroup>"), 350)], file!())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[message_handler_data(CustomData)]
|
||||||
impl<F: Fn(&MessageDiscriminant) -> Option<KeysGroup>> MessageHandler<LayoutMessage, F> for LayoutMessageHandler {
|
impl<F: Fn(&MessageDiscriminant) -> Option<KeysGroup>> MessageHandler<LayoutMessage, F> for LayoutMessageHandler {
|
||||||
fn process_message(&mut self, message: LayoutMessage, responses: &mut std::collections::VecDeque<Message>, action_input_mapping: F) {
|
fn process_message(&mut self, message: LayoutMessage, responses: &mut std::collections::VecDeque<Message>, action_input_mapping: F) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -45,3 +45,86 @@ impl specta::Type for MessageDiscriminant {
|
|||||||
specta::DataType::Any
|
specta::DataType::Any
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generate_message_tree() {
|
||||||
|
let result = Message::build_message_tree();
|
||||||
|
let mut file = std::fs::File::create("../hierarchical_message_system_tree.txt").unwrap();
|
||||||
|
file.write_all(format!("{} `{}`\n", result.name(), result.path()).as_bytes()).unwrap();
|
||||||
|
if let Some(variants) = result.variants() {
|
||||||
|
for (i, variant) in variants.iter().enumerate() {
|
||||||
|
let is_last = i == variants.len() - 1;
|
||||||
|
print_tree_node(variant, "", is_last, &mut file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_tree_node(tree: &DebugMessageTree, prefix: &str, is_last: bool, file: &mut std::fs::File) {
|
||||||
|
// Print the current node
|
||||||
|
let (branch, child_prefix) = if tree.has_message_handler_data_fields() || tree.has_message_handler_fields() {
|
||||||
|
("├── ", format!("{}│ ", prefix))
|
||||||
|
} else {
|
||||||
|
if is_last {
|
||||||
|
("└── ", format!("{} ", prefix))
|
||||||
|
} else {
|
||||||
|
("├── ", format!("{}│ ", prefix))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if tree.path().is_empty() {
|
||||||
|
file.write_all(format!("{}{}{}\n", prefix, branch, tree.name()).as_bytes()).unwrap();
|
||||||
|
} else {
|
||||||
|
file.write_all(format!("{}{}{} `{}`\n", prefix, branch, tree.name(), tree.path()).as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print children if any
|
||||||
|
if let Some(variants) = tree.variants() {
|
||||||
|
let len = variants.len();
|
||||||
|
for (i, variant) in variants.iter().enumerate() {
|
||||||
|
let is_last_child = i == len - 1;
|
||||||
|
print_tree_node(variant, &child_prefix, is_last_child, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print handler field if any
|
||||||
|
if let Some(data) = tree.message_handler_fields() {
|
||||||
|
let len = data.fields().len();
|
||||||
|
let (branch, child_prefix) = if tree.has_message_handler_data_fields() {
|
||||||
|
("├── ", format!("{}│ ", prefix))
|
||||||
|
} else {
|
||||||
|
("└── ", format!("{} ", prefix))
|
||||||
|
};
|
||||||
|
if data.path().is_empty() {
|
||||||
|
file.write_all(format!("{}{}{}\n", prefix, branch, data.name()).as_bytes()).unwrap();
|
||||||
|
} else {
|
||||||
|
file.write_all(format!("{}{}{} `{}`\n", prefix, branch, data.name(), data.path()).as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
for (i, field) in data.fields().iter().enumerate() {
|
||||||
|
let is_last_field = i == len - 1;
|
||||||
|
let branch = if is_last_field { "└── " } else { "├── " };
|
||||||
|
|
||||||
|
file.write_all(format!("{}{}{}\n", child_prefix, branch, field.0).as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print data field if any
|
||||||
|
if let Some(data) = tree.message_handler_data_fields() {
|
||||||
|
let len = data.fields().len();
|
||||||
|
if data.path().is_empty() {
|
||||||
|
file.write_all(format!("{}{}{}\n", prefix, "└── ", data.name()).as_bytes()).unwrap();
|
||||||
|
} else {
|
||||||
|
file.write_all(format!("{}{}{} `{}`\n", prefix, "└── ", data.name(), data.path()).as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
for (i, field) in data.fields().iter().enumerate() {
|
||||||
|
let is_last_field = i == len - 1;
|
||||||
|
let branch = if is_last_field { "└── " } else { "├── " };
|
||||||
|
file.write_all(format!("{}{}{}\n", format!("{} ", prefix), branch, field.0).as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ use graphene_std::vector::click_target::{ClickTarget, ClickTargetType};
|
|||||||
use graphene_std::vector::style::ViewMode;
|
use graphene_std::vector::style::ViewMode;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct DocumentMessageData<'a> {
|
pub struct DocumentMessageData<'a> {
|
||||||
pub document_id: DocumentId,
|
pub document_id: DocumentId,
|
||||||
pub ipp: &'a InputPreprocessorMessageHandler,
|
pub ipp: &'a InputPreprocessorMessageHandler,
|
||||||
@@ -48,7 +49,7 @@ pub struct DocumentMessageData<'a> {
|
|||||||
pub device_pixel_ratio: f64,
|
pub device_pixel_ratio: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ExtractField)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct DocumentMessageHandler {
|
pub struct DocumentMessageHandler {
|
||||||
// ======================
|
// ======================
|
||||||
@@ -168,6 +169,7 @@ impl Default for DocumentMessageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessageHandler {
|
impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessageHandler {
|
||||||
fn process_message(&mut self, message: DocumentMessage, responses: &mut VecDeque<Message>, data: DocumentMessageData) {
|
fn process_message(&mut self, message: DocumentMessage, responses: &mut VecDeque<Message>, data: DocumentMessageData) {
|
||||||
let DocumentMessageData {
|
let DocumentMessageData {
|
||||||
|
|||||||
+3
-1
@@ -21,17 +21,19 @@ struct ArtboardInfo {
|
|||||||
merge_node: NodeId,
|
merge_node: NodeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct GraphOperationMessageData<'a> {
|
pub struct GraphOperationMessageData<'a> {
|
||||||
pub network_interface: &'a mut NodeNetworkInterface,
|
pub network_interface: &'a mut NodeNetworkInterface,
|
||||||
pub collapsed: &'a mut CollapsedLayers,
|
pub collapsed: &'a mut CollapsedLayers,
|
||||||
pub node_graph: &'a mut NodeGraphMessageHandler,
|
pub node_graph: &'a mut NodeGraphMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize, serde::Deserialize, ExtractField)]
|
||||||
pub struct GraphOperationMessageHandler {}
|
pub struct GraphOperationMessageHandler {}
|
||||||
|
|
||||||
// GraphOperationMessageHandler always modified the document network. This is so changes to the layers panel will only affect the document network.
|
// GraphOperationMessageHandler always modified the document network. This is so changes to the layers panel will only affect the document network.
|
||||||
// For changes to the selected network, use NodeGraphMessageHandler. No NodeGraphMessage's should be added here, since they will affect the selected nested network.
|
// For changes to the selected network, use NodeGraphMessageHandler. No NodeGraphMessage's should be added here, since they will affect the selected nested network.
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for GraphOperationMessageHandler {
|
impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for GraphOperationMessageHandler {
|
||||||
fn process_message(&mut self, message: GraphOperationMessage, responses: &mut VecDeque<Message>, data: GraphOperationMessageData) {
|
fn process_message(&mut self, message: GraphOperationMessage, responses: &mut VecDeque<Message>, data: GraphOperationMessageData) {
|
||||||
let network_interface = data.network_interface;
|
let network_interface = data.network_interface;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
|||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct NavigationMessageData<'a> {
|
pub struct NavigationMessageData<'a> {
|
||||||
pub network_interface: &'a mut NodeNetworkInterface,
|
pub network_interface: &'a mut NodeNetworkInterface,
|
||||||
pub breadcrumb_network_path: &'a [NodeId],
|
pub breadcrumb_network_path: &'a [NodeId],
|
||||||
@@ -23,7 +24,7 @@ pub struct NavigationMessageData<'a> {
|
|||||||
pub preferences: &'a PreferencesMessageHandler,
|
pub preferences: &'a PreferencesMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default, ExtractField)]
|
||||||
pub struct NavigationMessageHandler {
|
pub struct NavigationMessageHandler {
|
||||||
navigation_operation: NavigationOperation,
|
navigation_operation: NavigationOperation,
|
||||||
mouse_position: ViewportPosition,
|
mouse_position: ViewportPosition,
|
||||||
@@ -31,6 +32,7 @@ pub struct NavigationMessageHandler {
|
|||||||
abortable_pan_start: Option<f64>,
|
abortable_pan_start: Option<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<NavigationMessage, NavigationMessageData<'_>> for NavigationMessageHandler {
|
impl MessageHandler<NavigationMessage, NavigationMessageData<'_>> for NavigationMessageHandler {
|
||||||
fn process_message(&mut self, message: NavigationMessage, responses: &mut VecDeque<Message>, data: NavigationMessageData) {
|
fn process_message(&mut self, message: NavigationMessage, responses: &mut VecDeque<Message>, data: NavigationMessageData) {
|
||||||
let NavigationMessageData {
|
let NavigationMessageData {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use graphene_std::*;
|
|||||||
use renderer::Quad;
|
use renderer::Quad;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, ExtractField)]
|
||||||
pub struct NodeGraphHandlerData<'a> {
|
pub struct NodeGraphHandlerData<'a> {
|
||||||
pub network_interface: &'a mut NodeNetworkInterface,
|
pub network_interface: &'a mut NodeNetworkInterface,
|
||||||
pub selection_network_path: &'a [NodeId],
|
pub selection_network_path: &'a [NodeId],
|
||||||
@@ -41,7 +41,7 @@ pub struct NodeGraphHandlerData<'a> {
|
|||||||
pub preferences: &'a PreferencesMessageHandler,
|
pub preferences: &'a PreferencesMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, ExtractField)]
|
||||||
pub struct NodeGraphMessageHandler {
|
pub struct NodeGraphMessageHandler {
|
||||||
// TODO: Remove network and move to NodeNetworkInterface
|
// TODO: Remove network and move to NodeNetworkInterface
|
||||||
pub network: Vec<NodeId>,
|
pub network: Vec<NodeId>,
|
||||||
@@ -92,6 +92,7 @@ pub struct NodeGraphMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// NodeGraphMessageHandler always modifies the network which the selected nodes are in. No GraphOperationMessages should be added here, since those messages will always affect the document network.
|
/// NodeGraphMessageHandler always modifies the network which the selected nodes are in. No GraphOperationMessages should be added here, since those messages will always affect the document network.
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGraphMessageHandler {
|
impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGraphMessageHandler {
|
||||||
fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, data: NodeGraphHandlerData<'a>) {
|
fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, data: NodeGraphHandlerData<'a>) {
|
||||||
let NodeGraphHandlerData {
|
let NodeGraphHandlerData {
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
use super::utility_types::{OverlayProvider, OverlaysVisibilitySettings};
|
use super::utility_types::{OverlayProvider, OverlaysVisibilitySettings};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct OverlaysMessageData<'a> {
|
pub struct OverlaysMessageData<'a> {
|
||||||
pub visibility_settings: OverlaysVisibilitySettings,
|
pub visibility_settings: OverlaysVisibilitySettings,
|
||||||
pub ipp: &'a InputPreprocessorMessageHandler,
|
pub ipp: &'a InputPreprocessorMessageHandler,
|
||||||
pub device_pixel_ratio: f64,
|
pub device_pixel_ratio: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct OverlaysMessageHandler {
|
pub struct OverlaysMessageHandler {
|
||||||
pub overlay_providers: HashSet<OverlayProvider>,
|
pub overlay_providers: HashSet<OverlayProvider>,
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
@@ -16,6 +17,7 @@ pub struct OverlaysMessageHandler {
|
|||||||
context: Option<web_sys::CanvasRenderingContext2d>,
|
context: Option<web_sys::CanvasRenderingContext2d>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<OverlaysMessage, OverlaysMessageData<'_>> for OverlaysMessageHandler {
|
impl MessageHandler<OverlaysMessage, OverlaysMessageData<'_>> for OverlaysMessageHandler {
|
||||||
fn process_message(&mut self, message: OverlaysMessage, responses: &mut VecDeque<Message>, data: OverlaysMessageData) {
|
fn process_message(&mut self, message: OverlaysMessage, responses: &mut VecDeque<Message>, data: OverlaysMessageData) {
|
||||||
let OverlaysMessageData { visibility_settings, ipp, .. } = data;
|
let OverlaysMessageData { visibility_settings, ipp, .. } = data;
|
||||||
|
|||||||
+2
-1
@@ -4,9 +4,10 @@ use crate::messages::portfolio::document::node_graph::document_node_definitions:
|
|||||||
use crate::messages::portfolio::utility_types::PersistentData;
|
use crate::messages::portfolio::utility_types::PersistentData;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct PropertiesPanelMessageHandler {}
|
pub struct PropertiesPanelMessageHandler {}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPanelMessageHandlerData<'_>)> for PropertiesPanelMessageHandler {
|
impl MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPanelMessageHandlerData<'_>)> for PropertiesPanelMessageHandler {
|
||||||
fn process_message(&mut self, message: PropertiesPanelMessage, responses: &mut VecDeque<Message>, (persistent_data, data): (&PersistentData, PropertiesPanelMessageHandlerData)) {
|
fn process_message(&mut self, message: PropertiesPanelMessage, responses: &mut VecDeque<Message>, (persistent_data, data): (&PersistentData, PropertiesPanelMessageHandlerData)) {
|
||||||
let PropertiesPanelMessageHandlerData {
|
let PropertiesPanelMessageHandlerData {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate,
|
|||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use graphene_std::path_bool::BooleanOperation;
|
use graphene_std::path_bool::BooleanOperation;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct MenuBarMessageHandler {
|
pub struct MenuBarMessageHandler {
|
||||||
pub has_active_document: bool,
|
pub has_active_document: bool,
|
||||||
pub canvas_tilted: bool,
|
pub canvas_tilted: bool,
|
||||||
@@ -21,6 +21,7 @@ pub struct MenuBarMessageHandler {
|
|||||||
pub reset_node_definitions_on_open: bool,
|
pub reset_node_definitions_on_open: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<MenuBarMessage, ()> for MenuBarMessageHandler {
|
impl MessageHandler<MenuBarMessage, ()> for MenuBarMessageHandler {
|
||||||
fn process_message(&mut self, message: MenuBarMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: MenuBarMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use graphene_std::renderer::Quad;
|
|||||||
use graphene_std::text::Font;
|
use graphene_std::text::Font;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct PortfolioMessageData<'a> {
|
pub struct PortfolioMessageData<'a> {
|
||||||
pub ipp: &'a InputPreprocessorMessageHandler,
|
pub ipp: &'a InputPreprocessorMessageHandler,
|
||||||
pub preferences: &'a PreferencesMessageHandler,
|
pub preferences: &'a PreferencesMessageHandler,
|
||||||
@@ -35,7 +36,7 @@ pub struct PortfolioMessageData<'a> {
|
|||||||
pub animation: &'a AnimationMessageHandler,
|
pub animation: &'a AnimationMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, ExtractField)]
|
||||||
pub struct PortfolioMessageHandler {
|
pub struct PortfolioMessageHandler {
|
||||||
menu_bar_message_handler: MenuBarMessageHandler,
|
menu_bar_message_handler: MenuBarMessageHandler,
|
||||||
pub documents: HashMap<DocumentId, DocumentMessageHandler>,
|
pub documents: HashMap<DocumentId, DocumentMessageHandler>,
|
||||||
@@ -52,6 +53,7 @@ pub struct PortfolioMessageHandler {
|
|||||||
pub reset_node_definitions_on_open: bool,
|
pub reset_node_definitions_on_open: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMessageHandler {
|
impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMessageHandler {
|
||||||
fn process_message(&mut self, message: PortfolioMessage, responses: &mut VecDeque<Message>, data: PortfolioMessageData) {
|
fn process_message(&mut self, message: PortfolioMessage, responses: &mut VecDeque<Message>, data: PortfolioMessageData) {
|
||||||
let PortfolioMessageData {
|
let PortfolioMessageData {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use std::any::Any;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// The spreadsheet UI allows for instance data to be previewed.
|
/// The spreadsheet UI allows for instance data to be previewed.
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone, ExtractField)]
|
||||||
pub struct SpreadsheetMessageHandler {
|
pub struct SpreadsheetMessageHandler {
|
||||||
/// Sets whether or not the spreadsheet is drawn.
|
/// Sets whether or not the spreadsheet is drawn.
|
||||||
pub spreadsheet_view_open: bool,
|
pub spreadsheet_view_open: bool,
|
||||||
@@ -25,6 +25,7 @@ pub struct SpreadsheetMessageHandler {
|
|||||||
viewing_vector_data_domain: VectorDataDomain,
|
viewing_vector_data_domain: VectorDataDomain,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<SpreadsheetMessage, ()> for SpreadsheetMessageHandler {
|
impl MessageHandler<SpreadsheetMessage, ()> for SpreadsheetMessageHandler {
|
||||||
fn process_message(&mut self, message: SpreadsheetMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: SpreadsheetMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::messages::preferences::SelectionMode;
|
|||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use graph_craft::wasm_application_io::EditorPreferences;
|
use graph_craft::wasm_application_io::EditorPreferences;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, specta::Type)]
|
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, specta::Type, ExtractField)]
|
||||||
pub struct PreferencesMessageHandler {
|
pub struct PreferencesMessageHandler {
|
||||||
pub selection_mode: SelectionMode,
|
pub selection_mode: SelectionMode,
|
||||||
pub zoom_with_scroll: bool,
|
pub zoom_with_scroll: bool,
|
||||||
@@ -44,6 +44,7 @@ impl Default for PreferencesMessageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
|
impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
|
||||||
fn process_message(&mut self, message: PreferencesMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: PreferencesMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Root
|
// Root
|
||||||
pub use crate::utility_traits::{ActionList, AsMessage, MessageHandler, ToDiscriminant, TransitiveChild};
|
pub use crate::utility_traits::{ActionList, AsMessage, HierarchicalTree, MessageHandler, ToDiscriminant, TransitiveChild};
|
||||||
|
pub use crate::utility_types::{DebugMessageTree, MessageData};
|
||||||
// Message, MessageData, MessageDiscriminant, MessageHandler
|
// Message, MessageData, MessageDiscriminant, MessageHandler
|
||||||
pub use crate::messages::animation::{AnimationMessage, AnimationMessageDiscriminant, AnimationMessageHandler};
|
pub use crate::messages::animation::{AnimationMessage, AnimationMessageDiscriminant, AnimationMessageHandler};
|
||||||
pub use crate::messages::broadcast::{BroadcastMessage, BroadcastMessageDiscriminant, BroadcastMessageHandler};
|
pub use crate::messages::broadcast::{BroadcastMessage, BroadcastMessageDiscriminant, BroadcastMessageHandler};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use graphene_std::raster::color::Color;
|
|||||||
|
|
||||||
const ARTBOARD_OVERLAY_PROVIDER: OverlayProvider = |context| DocumentMessage::DrawArtboardOverlays(context).into();
|
const ARTBOARD_OVERLAY_PROVIDER: OverlayProvider = |context| DocumentMessage::DrawArtboardOverlays(context).into();
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct ToolMessageData<'a> {
|
pub struct ToolMessageData<'a> {
|
||||||
pub document_id: DocumentId,
|
pub document_id: DocumentId,
|
||||||
pub document: &'a mut DocumentMessageHandler,
|
pub document: &'a mut DocumentMessageHandler,
|
||||||
@@ -21,7 +22,7 @@ pub struct ToolMessageData<'a> {
|
|||||||
pub preferences: &'a PreferencesMessageHandler,
|
pub preferences: &'a PreferencesMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, ExtractField)]
|
||||||
pub struct ToolMessageHandler {
|
pub struct ToolMessageHandler {
|
||||||
pub tool_state: ToolFsmState,
|
pub tool_state: ToolFsmState,
|
||||||
pub transform_layer_handler: TransformLayerMessageHandler,
|
pub transform_layer_handler: TransformLayerMessageHandler,
|
||||||
@@ -29,6 +30,7 @@ pub struct ToolMessageHandler {
|
|||||||
pub tool_is_active: bool,
|
pub tool_is_active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<ToolMessage, ToolMessageData<'_>> for ToolMessageHandler {
|
impl MessageHandler<ToolMessage, ToolMessageData<'_>> for ToolMessageHandler {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, data: ToolMessageData) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, data: ToolMessageData) {
|
||||||
let ToolMessageData {
|
let ToolMessageData {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use crate::messages::tool::common_functionality::transformation_cage::*;
|
|||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graphene_std::renderer::Quad;
|
use graphene_std::renderer::Quad;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct ArtboardTool {
|
pub struct ArtboardTool {
|
||||||
fsm_state: ArtboardToolFsmState,
|
fsm_state: ArtboardToolFsmState,
|
||||||
data: ArtboardToolData,
|
data: ArtboardToolData,
|
||||||
@@ -48,6 +48,7 @@ impl ToolMetadata for ArtboardTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for ArtboardTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for ArtboardTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
self.fsm_state.process_event(message, &mut self.data, tool_data, &(), responses, false);
|
self.fsm_state.process_event(message, &mut self.data, tool_data, &(), responses, false);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub enum DrawMode {
|
|||||||
Restore,
|
Restore,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct BrushTool {
|
pub struct BrushTool {
|
||||||
fsm_state: BrushToolFsmState,
|
fsm_state: BrushToolFsmState,
|
||||||
data: BrushToolData,
|
data: BrushToolData,
|
||||||
@@ -185,6 +185,7 @@ impl LayoutHolder for BrushTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for BrushTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for BrushTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
let ToolMessage::Brush(BrushToolMessage::UpdateOptions(action)) = message else {
|
let ToolMessage::Brush(BrushToolMessage::UpdateOptions(action)) = message else {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::tool_prelude::*;
|
use super::tool_prelude::*;
|
||||||
use crate::messages::tool::utility_types::DocumentToolData;
|
use crate::messages::tool::utility_types::DocumentToolData;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct EyedropperTool {
|
pub struct EyedropperTool {
|
||||||
fsm_state: EyedropperToolFsmState,
|
fsm_state: EyedropperToolFsmState,
|
||||||
data: EyedropperToolData,
|
data: EyedropperToolData,
|
||||||
@@ -39,6 +39,7 @@ impl LayoutHolder for EyedropperTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for EyedropperTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for EyedropperTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
self.fsm_state.process_event(message, &mut self.data, tool_data, &(), responses, true);
|
self.fsm_state.process_event(message, &mut self.data, tool_data, &(), responses, true);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use crate::messages::portfolio::document::overlays::utility_types::OverlayContex
|
|||||||
use crate::messages::tool::common_functionality::graph_modification_utils::NodeGraphLayer;
|
use crate::messages::tool::common_functionality::graph_modification_utils::NodeGraphLayer;
|
||||||
use graphene_std::vector::style::Fill;
|
use graphene_std::vector::style::Fill;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct FillTool {
|
pub struct FillTool {
|
||||||
fsm_state: FillToolFsmState,
|
fsm_state: FillToolFsmState,
|
||||||
}
|
}
|
||||||
@@ -41,6 +41,7 @@ impl LayoutHolder for FillTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FillTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FillTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
self.fsm_state.process_event(message, &mut (), tool_data, &(), responses, true);
|
self.fsm_state.process_event(message, &mut (), tool_data, &(), responses, true);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use graphene_std::Color;
|
|||||||
use graphene_std::vector::VectorModificationType;
|
use graphene_std::vector::VectorModificationType;
|
||||||
use graphene_std::vector::{PointId, SegmentId};
|
use graphene_std::vector::{PointId, SegmentId};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct FreehandTool {
|
pub struct FreehandTool {
|
||||||
fsm_state: FreehandToolFsmState,
|
fsm_state: FreehandToolFsmState,
|
||||||
data: FreehandToolData,
|
data: FreehandToolData,
|
||||||
@@ -116,6 +116,7 @@ impl LayoutHolder for FreehandTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FreehandTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FreehandTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
let ToolMessage::Freehand(FreehandToolMessage::UpdateOptions(action)) = message else {
|
let ToolMessage::Freehand(FreehandToolMessage::UpdateOptions(action)) = message else {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::messages::tool::common_functionality::graph_modification_utils::{Node
|
|||||||
use crate::messages::tool::common_functionality::snapping::SnapManager;
|
use crate::messages::tool::common_functionality::snapping::SnapManager;
|
||||||
use graphene_std::vector::style::{Fill, Gradient, GradientType};
|
use graphene_std::vector::style::{Fill, Gradient, GradientType};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct GradientTool {
|
pub struct GradientTool {
|
||||||
fsm_state: GradientToolFsmState,
|
fsm_state: GradientToolFsmState,
|
||||||
data: GradientToolData,
|
data: GradientToolData,
|
||||||
@@ -53,6 +53,7 @@ impl ToolMetadata for GradientTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for GradientTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for GradientTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
let ToolMessage::Gradient(GradientToolMessage::UpdateOptions(action)) = message else {
|
let ToolMessage::Gradient(GradientToolMessage::UpdateOptions(action)) = message else {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use super::tool_prelude::*;
|
use super::tool_prelude::*;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct NavigateTool {
|
pub struct NavigateTool {
|
||||||
fsm_state: NavigateToolFsmState,
|
fsm_state: NavigateToolFsmState,
|
||||||
tool_data: NavigateToolData,
|
tool_data: NavigateToolData,
|
||||||
@@ -38,6 +38,7 @@ impl LayoutHolder for NavigateTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for NavigateTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for NavigateTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, true);
|
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, true);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use graphene_std::vector::{HandleExt, HandleId, NoHashBuilder, SegmentId, Vector
|
|||||||
use graphene_std::vector::{ManipulatorPointId, PointId, VectorModificationType};
|
use graphene_std::vector::{ManipulatorPointId, PointId, VectorModificationType};
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct PathTool {
|
pub struct PathTool {
|
||||||
fsm_state: PathToolFsmState,
|
fsm_state: PathToolFsmState,
|
||||||
tool_data: PathToolData,
|
tool_data: PathToolData,
|
||||||
@@ -305,6 +305,7 @@ impl LayoutHolder for PathTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PathTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PathTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
let updating_point = message == ToolMessage::Path(PathToolMessage::SelectedPointUpdated);
|
let updating_point = message == ToolMessage::Path(PathToolMessage::SelectedPointUpdated);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use graphene_std::Color;
|
|||||||
use graphene_std::vector::{HandleId, ManipulatorPointId, NoHashBuilder, SegmentId, StrokeId, VectorData};
|
use graphene_std::vector::{HandleId, ManipulatorPointId, NoHashBuilder, SegmentId, StrokeId, VectorData};
|
||||||
use graphene_std::vector::{PointId, VectorModificationType};
|
use graphene_std::vector::{PointId, VectorModificationType};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct PenTool {
|
pub struct PenTool {
|
||||||
fsm_state: PenToolFsmState,
|
fsm_state: PenToolFsmState,
|
||||||
tool_data: PenToolData,
|
tool_data: PenToolData,
|
||||||
@@ -186,6 +186,7 @@ impl LayoutHolder for PenTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PenTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PenTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
let ToolMessage::Pen(PenToolMessage::UpdateOptions(action)) = message else {
|
let ToolMessage::Pen(PenToolMessage::UpdateOptions(action)) = message else {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ use graphene_std::renderer::Rect;
|
|||||||
use graphene_std::transform::ReferencePoint;
|
use graphene_std::transform::ReferencePoint;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct SelectTool {
|
pub struct SelectTool {
|
||||||
fsm_state: SelectToolFsmState,
|
fsm_state: SelectToolFsmState,
|
||||||
tool_data: SelectToolData,
|
tool_data: SelectToolData,
|
||||||
@@ -272,6 +272,7 @@ impl LayoutHolder for SelectTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for SelectTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for SelectTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
let mut redraw_reference_pivot = false;
|
let mut redraw_reference_pivot = false;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use graph_craft::document::{NodeId, NodeInput};
|
|||||||
use graphene_std::Color;
|
use graphene_std::Color;
|
||||||
use graphene_std::vector::{PointId, SegmentId, VectorModificationType};
|
use graphene_std::vector::{PointId, SegmentId, VectorModificationType};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct SplineTool {
|
pub struct SplineTool {
|
||||||
fsm_state: SplineToolFsmState,
|
fsm_state: SplineToolFsmState,
|
||||||
tool_data: SplineToolData,
|
tool_data: SplineToolData,
|
||||||
@@ -123,6 +123,7 @@ impl LayoutHolder for SplineTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for SplineTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for SplineTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
let ToolMessage::Spline(SplineToolMessage::UpdateOptions(action)) = message else {
|
let ToolMessage::Spline(SplineToolMessage::UpdateOptions(action)) = message else {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use graphene_std::renderer::Quad;
|
|||||||
use graphene_std::text::{Font, FontCache, TypesettingConfig, lines_clipping, load_font};
|
use graphene_std::text::{Font, FontCache, TypesettingConfig, lines_clipping, load_font};
|
||||||
use graphene_std::vector::style::Fill;
|
use graphene_std::vector::style::Fill;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, ExtractField)]
|
||||||
pub struct TextTool {
|
pub struct TextTool {
|
||||||
fsm_state: TextToolFsmState,
|
fsm_state: TextToolFsmState,
|
||||||
tool_data: TextToolData,
|
tool_data: TextToolData,
|
||||||
@@ -170,6 +170,7 @@ impl LayoutHolder for TextTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for TextTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for TextTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
let ToolMessage::Text(TextToolMessage::UpdateOptions(action)) = message else {
|
let ToolMessage::Text(TextToolMessage::UpdateOptions(action)) = message else {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const TRANSFORM_GRS_OVERLAY_PROVIDER: OverlayProvider = |context| TransformLayer
|
|||||||
const SLOW_KEY: Key = Key::Shift;
|
const SLOW_KEY: Key = Key::Shift;
|
||||||
const INCREMENTS_KEY: Key = Key::Control;
|
const INCREMENTS_KEY: Key = Key::Control;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct TransformLayerMessageHandler {
|
pub struct TransformLayerMessageHandler {
|
||||||
pub transform_operation: TransformOperation,
|
pub transform_operation: TransformOperation,
|
||||||
|
|
||||||
@@ -175,6 +175,26 @@ fn update_colinear_handles(selected_layers: &[LayerNodeIdentifier], document: &D
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TransformData<'a> = (&'a DocumentMessageHandler, &'a InputPreprocessorMessageHandler, &'a ToolData, &'a mut ShapeState);
|
type TransformData<'a> = (&'a DocumentMessageHandler, &'a InputPreprocessorMessageHandler, &'a ToolData, &'a mut ShapeState);
|
||||||
|
|
||||||
|
pub fn custom_data() -> MessageData {
|
||||||
|
MessageData::new(
|
||||||
|
String::from("TransformData<'a>"),
|
||||||
|
// TODO: When <https://github.com/dtolnay/proc-macro2/issues/503> is resolved and released,
|
||||||
|
// TODO: use <https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.line> to get
|
||||||
|
// TODO: the line number instead of hardcoding it to the magic number on the following lines
|
||||||
|
// TODO: which points to the line of the `type TransformData<'a> = ...` definition above.
|
||||||
|
// TODO: Also, utilize the line number in the actual output, since it is currently unused.
|
||||||
|
vec![
|
||||||
|
(String::from("&'a DocumentMessageHandler"), 177),
|
||||||
|
(String::from("&'a InputPreprocessorMessageHandler"), 177),
|
||||||
|
(String::from("&'a ToolData"), 177),
|
||||||
|
(String::from("&'a mut ShapeState"), 177),
|
||||||
|
],
|
||||||
|
file!(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[message_handler_data(CustomData)]
|
||||||
impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayerMessageHandler {
|
impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayerMessageHandler {
|
||||||
fn process_message(&mut self, message: TransformLayerMessage, responses: &mut VecDeque<Message>, (document, input, tool_data, shape_editor): TransformData) {
|
fn process_message(&mut self, message: TransformLayerMessage, responses: &mut VecDeque<Message>, (document, input, tool_data, shape_editor): TransformData) {
|
||||||
let using_path_tool = tool_data.active_tool_type == ToolType::Path;
|
let using_path_tool = tool_data.active_tool_type == ToolType::Path;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use graphene_std::text::FontCache;
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
|
|
||||||
|
#[derive(ExtractField)]
|
||||||
pub struct ToolActionHandlerData<'a> {
|
pub struct ToolActionHandlerData<'a> {
|
||||||
pub document: &'a mut DocumentMessageHandler,
|
pub document: &'a mut DocumentMessageHandler,
|
||||||
pub document_id: DocumentId,
|
pub document_id: DocumentId,
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default, ExtractField)]
|
||||||
pub struct WorkspaceMessageHandler {
|
pub struct WorkspaceMessageHandler {
|
||||||
node_graph_visible: bool,
|
node_graph_visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[message_handler_data]
|
||||||
impl MessageHandler<WorkspaceMessage, ()> for WorkspaceMessageHandler {
|
impl MessageHandler<WorkspaceMessage, ()> for WorkspaceMessageHandler {
|
||||||
fn process_message(&mut self, message: WorkspaceMessage, _responses: &mut VecDeque<Message>, _data: ()) {
|
fn process_message(&mut self, message: WorkspaceMessage, _responses: &mut VecDeque<Message>, _data: ()) {
|
||||||
match message {
|
match message {
|
||||||
|
|||||||
@@ -45,3 +45,19 @@ pub trait TransitiveChild: Into<Self::Parent> + Into<Self::TopParent> {
|
|||||||
pub trait Hint {
|
pub trait Hint {
|
||||||
fn hints(&self) -> HashMap<String, String>;
|
fn hints(&self) -> HashMap<String, String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait HierarchicalTree {
|
||||||
|
fn build_message_tree() -> DebugMessageTree;
|
||||||
|
|
||||||
|
fn message_handler_data_str() -> MessageData {
|
||||||
|
MessageData::new(String::new(), Vec::new(), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn message_handler_str() -> MessageData {
|
||||||
|
MessageData::new(String::new(), Vec::new(), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MessageData {
|
||||||
|
name: String,
|
||||||
|
fields: Vec<(String, usize)>,
|
||||||
|
path: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MessageData {
|
||||||
|
pub fn new(name: String, fields: Vec<(String, usize)>, path: &'static str) -> MessageData {
|
||||||
|
MessageData { name, fields, path }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fields(&self) -> &Vec<(String, usize)> {
|
||||||
|
&self.fields
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &'static str {
|
||||||
|
self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DebugMessageTree {
|
||||||
|
name: String,
|
||||||
|
variants: Option<Vec<DebugMessageTree>>,
|
||||||
|
message_handler: Option<MessageData>,
|
||||||
|
message_handler_data: Option<MessageData>,
|
||||||
|
path: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugMessageTree {
|
||||||
|
pub fn new(name: &str) -> DebugMessageTree {
|
||||||
|
DebugMessageTree {
|
||||||
|
name: name.to_string(),
|
||||||
|
variants: None,
|
||||||
|
message_handler: None,
|
||||||
|
message_handler_data: None,
|
||||||
|
path: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_path(&mut self, path: &'static str) {
|
||||||
|
self.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_variant(&mut self, variant: DebugMessageTree) {
|
||||||
|
if let Some(variants) = &mut self.variants {
|
||||||
|
variants.push(variant);
|
||||||
|
} else {
|
||||||
|
self.variants = Some(vec![variant]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_message_handler_data_field(&mut self, message_handler_data: MessageData) {
|
||||||
|
self.message_handler_data = Some(message_handler_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_message_handler_field(&mut self, message_handler: MessageData) {
|
||||||
|
self.message_handler = Some(message_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &'static str {
|
||||||
|
self.path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variants(&self) -> Option<&Vec<DebugMessageTree>> {
|
||||||
|
self.variants.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn message_handler_data_fields(&self) -> Option<&MessageData> {
|
||||||
|
self.message_handler_data.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn message_handler_fields(&self) -> Option<&MessageData> {
|
||||||
|
self.message_handler.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_message_handler_data_fields(&self) -> bool {
|
||||||
|
match self.message_handler_data_fields() {
|
||||||
|
Some(_) => true,
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_message_handler_fields(&self) -> bool {
|
||||||
|
match self.message_handler_fields() {
|
||||||
|
Some(_) => true,
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@ pub fn combined_message_attrs_impl(attr: TokenStream, input_item: TokenStream) -
|
|||||||
<#parent as ToDiscriminant>::Discriminant
|
<#parent as ToDiscriminant>::Discriminant
|
||||||
};
|
};
|
||||||
|
|
||||||
input.attrs.push(syn::parse_quote! { #[derive(ToDiscriminant, TransitiveChild)] });
|
input.attrs.push(syn::parse_quote! { #[derive(ToDiscriminant, TransitiveChild, HierarchicalTree)] });
|
||||||
input.attrs.push(syn::parse_quote! { #[parent(#parent, #parent::#variant)] });
|
input.attrs.push(syn::parse_quote! { #[parent(#parent, #parent::#variant)] });
|
||||||
if parent_is_top {
|
if parent_is_top {
|
||||||
input.attrs.push(syn::parse_quote! { #[parent_is_top] });
|
input.attrs.push(syn::parse_quote! { #[parent_is_top] });
|
||||||
@@ -97,7 +97,7 @@ pub fn combined_message_attrs_impl(attr: TokenStream, input_item: TokenStream) -
|
|||||||
fn top_level_impl(input_item: TokenStream) -> syn::Result<TokenStream> {
|
fn top_level_impl(input_item: TokenStream) -> syn::Result<TokenStream> {
|
||||||
let mut input = syn::parse2::<ItemEnum>(input_item)?;
|
let mut input = syn::parse2::<ItemEnum>(input_item)?;
|
||||||
|
|
||||||
input.attrs.push(syn::parse_quote! { #[derive(ToDiscriminant)] });
|
input.attrs.push(syn::parse_quote! { #[derive(ToDiscriminant, HierarchicalTree)] });
|
||||||
input.attrs.push(syn::parse_quote! { #[discriminant_attr(derive(Debug, Copy, Clone, PartialEq, Eq, Hash, AsMessage))] });
|
input.attrs.push(syn::parse_quote! { #[discriminant_attr(derive(Debug, Copy, Clone, PartialEq, Eq, Hash, AsMessage))] });
|
||||||
|
|
||||||
for var in &mut input.variants {
|
for var in &mut input.variants {
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
use crate::helpers::clean_rust_type_syntax;
|
||||||
|
use proc_macro2::{Span, TokenStream};
|
||||||
|
use quote::{ToTokens, format_ident, quote};
|
||||||
|
use syn::{Data, DeriveInput, Fields, Type, parse2};
|
||||||
|
|
||||||
|
pub fn derive_extract_field_impl(input: TokenStream) -> syn::Result<TokenStream> {
|
||||||
|
let input = parse2::<DeriveInput>(input)?;
|
||||||
|
let struct_name = &input.ident;
|
||||||
|
let generics = &input.generics;
|
||||||
|
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
|
let fields = match &input.data {
|
||||||
|
Data::Struct(data) => match &data.fields {
|
||||||
|
Fields::Named(fields) => &fields.named,
|
||||||
|
_ => return Err(syn::Error::new(Span::call_site(), "ExtractField only works on structs with named fields")),
|
||||||
|
},
|
||||||
|
_ => return Err(syn::Error::new(Span::call_site(), "ExtractField only works on structs")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut field_line = Vec::new();
|
||||||
|
// Extract field names and types as strings at compile time
|
||||||
|
let field_info = fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| {
|
||||||
|
let ident = field.ident.as_ref().unwrap();
|
||||||
|
let name = ident.to_string();
|
||||||
|
let ty = clean_rust_type_syntax(field.ty.to_token_stream().to_string());
|
||||||
|
let line = ident.span().start().line;
|
||||||
|
field_line.push(line);
|
||||||
|
(name, ty)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let field_str = field_info.into_iter().map(|(name, ty)| (format!("{}: {}", name, ty)));
|
||||||
|
|
||||||
|
let res = quote! {
|
||||||
|
impl #impl_generics #struct_name #ty_generics #where_clause {
|
||||||
|
pub fn field_types() -> Vec<(String, usize)> {
|
||||||
|
vec![
|
||||||
|
#((String::from(#field_str), #field_line)),*
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_field_types() {
|
||||||
|
for (field, line) in Self::field_types() {
|
||||||
|
println!("{} at line {}", field, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path() -> &'static str {
|
||||||
|
file!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
@@ -42,6 +42,58 @@ pub fn two_segment_path(left_ident: Ident, right_ident: Ident) -> Path {
|
|||||||
Path { leading_colon: None, segments }
|
Path { leading_colon: None, segments }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clean_rust_type_syntax(input: String) -> String {
|
||||||
|
let mut result = String::new();
|
||||||
|
let mut chars = input.chars().peekable();
|
||||||
|
|
||||||
|
while let Some(c) = chars.next() {
|
||||||
|
match c {
|
||||||
|
'&' => {
|
||||||
|
result.push('&');
|
||||||
|
while let Some(' ') = chars.peek() {
|
||||||
|
chars.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'<' => {
|
||||||
|
while let Some(' ') = result.chars().rev().next() {
|
||||||
|
result.pop();
|
||||||
|
}
|
||||||
|
result.push('<');
|
||||||
|
while let Some(' ') = chars.peek() {
|
||||||
|
chars.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'>' => {
|
||||||
|
while let Some(' ') = result.chars().rev().next() {
|
||||||
|
result.pop();
|
||||||
|
}
|
||||||
|
result.push('>');
|
||||||
|
while let Some(' ') = chars.peek() {
|
||||||
|
chars.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
':' => {
|
||||||
|
if let Some(':') = chars.peek() {
|
||||||
|
while let Some(' ') = result.chars().rev().next() {
|
||||||
|
result.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push(':');
|
||||||
|
chars.next();
|
||||||
|
result.push(':');
|
||||||
|
while let Some(' ') = chars.peek() {
|
||||||
|
chars.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
result.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
use proc_macro2::{Span, TokenStream};
|
||||||
|
use quote::{ToTokens, quote};
|
||||||
|
use syn::{Data, DeriveInput, Fields, Type, parse2};
|
||||||
|
|
||||||
|
pub fn generate_hierarchical_tree(input: TokenStream) -> syn::Result<TokenStream> {
|
||||||
|
let input = parse2::<DeriveInput>(input)?;
|
||||||
|
let input_type = &input.ident;
|
||||||
|
|
||||||
|
let data = match &input.data {
|
||||||
|
Data::Enum(data) => data,
|
||||||
|
_ => return Err(syn::Error::new(Span::call_site(), "Tried to derive HierarchicalTree for non-enum")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let build_message_tree = data.variants.iter().map(|variant| {
|
||||||
|
let variant_type = &variant.ident;
|
||||||
|
|
||||||
|
let has_child = variant
|
||||||
|
.attrs
|
||||||
|
.iter()
|
||||||
|
.any(|attr| attr.path().get_ident().is_some_and(|ident| ident == "sub_discriminant" || ident == "child"));
|
||||||
|
|
||||||
|
if has_child {
|
||||||
|
if let Fields::Unnamed(fields) = &variant.fields {
|
||||||
|
let field_type = &fields.unnamed.first().unwrap().ty;
|
||||||
|
quote! {
|
||||||
|
{
|
||||||
|
let mut variant_tree = DebugMessageTree::new(stringify!(#variant_type));
|
||||||
|
let field_name = stringify!(#field_type);
|
||||||
|
const message_string: &str = "Message";
|
||||||
|
if message_string == &field_name[field_name.len().saturating_sub(message_string.len())..] {
|
||||||
|
// The field is a Message type, recursively build its tree
|
||||||
|
let sub_tree = #field_type::build_message_tree();
|
||||||
|
variant_tree.add_variant(sub_tree);
|
||||||
|
}
|
||||||
|
message_tree.add_variant(variant_tree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
message_tree.add_variant(DebugMessageTree::new(stringify!(#variant_type)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
message_tree.add_variant(DebugMessageTree::new(stringify!(#variant_type)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let res = quote! {
|
||||||
|
impl HierarchicalTree for #input_type {
|
||||||
|
fn build_message_tree() -> DebugMessageTree {
|
||||||
|
let mut message_tree = DebugMessageTree::new(stringify!(#input_type));
|
||||||
|
#(#build_message_tree)*
|
||||||
|
let message_handler_str = #input_type::message_handler_str();
|
||||||
|
if message_handler_str.fields().len() > 0 {
|
||||||
|
message_tree.add_message_handler_field(message_handler_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
let message_handler_data_str = #input_type::message_handler_data_str();
|
||||||
|
if message_handler_data_str.fields().len() > 0 {
|
||||||
|
message_tree.add_message_handler_data_field(message_handler_data_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
message_tree.set_path(file!());
|
||||||
|
|
||||||
|
message_tree
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
@@ -3,17 +3,23 @@
|
|||||||
mod as_message;
|
mod as_message;
|
||||||
mod combined_message_attrs;
|
mod combined_message_attrs;
|
||||||
mod discriminant;
|
mod discriminant;
|
||||||
|
mod extract_fields;
|
||||||
mod helper_structs;
|
mod helper_structs;
|
||||||
mod helpers;
|
mod helpers;
|
||||||
|
mod hierarchical_tree;
|
||||||
mod hint;
|
mod hint;
|
||||||
|
mod message_handler_data_attr;
|
||||||
mod transitive_child;
|
mod transitive_child;
|
||||||
mod widget_builder;
|
mod widget_builder;
|
||||||
|
|
||||||
use crate::as_message::derive_as_message_impl;
|
use crate::as_message::derive_as_message_impl;
|
||||||
use crate::combined_message_attrs::combined_message_attrs_impl;
|
use crate::combined_message_attrs::combined_message_attrs_impl;
|
||||||
use crate::discriminant::derive_discriminant_impl;
|
use crate::discriminant::derive_discriminant_impl;
|
||||||
|
use crate::extract_fields::derive_extract_field_impl;
|
||||||
use crate::helper_structs::AttrInnerSingleString;
|
use crate::helper_structs::AttrInnerSingleString;
|
||||||
|
use crate::hierarchical_tree::generate_hierarchical_tree;
|
||||||
use crate::hint::derive_hint_impl;
|
use crate::hint::derive_hint_impl;
|
||||||
|
use crate::message_handler_data_attr::message_handler_data_attr_impl;
|
||||||
use crate::transitive_child::derive_transitive_child_impl;
|
use crate::transitive_child::derive_transitive_child_impl;
|
||||||
use crate::widget_builder::derive_widget_builder_impl;
|
use crate::widget_builder::derive_widget_builder_impl;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
@@ -281,6 +287,21 @@ pub fn derive_widget_builder(input_item: TokenStream) -> TokenStream {
|
|||||||
TokenStream::from(derive_widget_builder_impl(input_item.into()).unwrap_or_else(|err| err.to_compile_error()))
|
TokenStream::from(derive_widget_builder_impl(input_item.into()).unwrap_or_else(|err| err.to_compile_error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(HierarchicalTree)]
|
||||||
|
pub fn derive_hierarchical_tree(input_item: TokenStream) -> TokenStream {
|
||||||
|
TokenStream::from(generate_hierarchical_tree(input_item.into()).unwrap_or_else(|err| err.to_compile_error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(ExtractField)]
|
||||||
|
pub fn derive_extract_field(input_item: TokenStream) -> TokenStream {
|
||||||
|
TokenStream::from(derive_extract_field_impl(input_item.into()).unwrap_or_else(|err| err.to_compile_error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn message_handler_data(attr: TokenStream, input_item: TokenStream) -> TokenStream {
|
||||||
|
TokenStream::from(message_handler_data_attr_impl(attr.into(), input_item.into()).unwrap_or_else(|err| err.to_compile_error()))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
use crate::helpers::{call_site_ident, clean_rust_type_syntax};
|
||||||
|
use proc_macro2::{Span, TokenStream};
|
||||||
|
use quote::{ToTokens, quote};
|
||||||
|
use syn::{ItemImpl, Type, parse2, spanned::Spanned};
|
||||||
|
|
||||||
|
pub fn message_handler_data_attr_impl(attr: TokenStream, input_item: TokenStream) -> syn::Result<TokenStream> {
|
||||||
|
// Parse the input as an impl block
|
||||||
|
let impl_block = parse2::<ItemImpl>(input_item.clone())?;
|
||||||
|
|
||||||
|
let self_ty = &impl_block.self_ty;
|
||||||
|
|
||||||
|
let path = match &**self_ty {
|
||||||
|
Type::Path(path) => &path.path,
|
||||||
|
_ => return Err(syn::Error::new(Span::call_site(), "Expected impl implementation")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let input_type = path.segments.last().map(|s| &s.ident).unwrap();
|
||||||
|
|
||||||
|
// Extract the message type from the trait path
|
||||||
|
let trait_path = match &impl_block.trait_ {
|
||||||
|
Some((_, path, _)) => path,
|
||||||
|
None => return Err(syn::Error::new(Span::call_site(), "Expected trait implementation")),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the trait generics (should be MessageHandler<M, D>)
|
||||||
|
if let Some(segment) = trait_path.segments.last() {
|
||||||
|
if segment.ident != "MessageHandler" {
|
||||||
|
return Err(syn::Error::new(segment.ident.span(), "Expected MessageHandler trait"));
|
||||||
|
}
|
||||||
|
if let syn::PathArguments::AngleBracketed(args) = &segment.arguments {
|
||||||
|
if args.args.len() >= 2 {
|
||||||
|
// Extract the message type (M) and data type (D) from the trait params
|
||||||
|
let message_type = &args.args[0];
|
||||||
|
let data_type = &args.args[1];
|
||||||
|
|
||||||
|
// Check if the attribute is "CustomData"
|
||||||
|
let is_custom_data = attr.to_string().contains("CustomData");
|
||||||
|
|
||||||
|
let impl_item = match data_type {
|
||||||
|
syn::GenericArgument::Type(t) => {
|
||||||
|
match t {
|
||||||
|
syn::Type::Path(type_path) if !type_path.path.segments.is_empty() => {
|
||||||
|
// Get just the base identifier (ToolMessageData) without generics
|
||||||
|
let type_name = &type_path.path.segments.first().unwrap().ident;
|
||||||
|
|
||||||
|
if is_custom_data {
|
||||||
|
quote! {
|
||||||
|
#input_item
|
||||||
|
impl #message_type {
|
||||||
|
pub fn message_handler_data_str() -> MessageData {
|
||||||
|
custom_data()
|
||||||
|
}
|
||||||
|
pub fn message_handler_str() -> MessageData {
|
||||||
|
MessageData::new(format!("{}",stringify!(#input_type)), #input_type::field_types(), #input_type::path())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
#input_item
|
||||||
|
impl #message_type {
|
||||||
|
pub fn message_handler_data_str() -> MessageData
|
||||||
|
{
|
||||||
|
MessageData::new(format!("{}",stringify!(#type_name)), #type_name::field_types(), #type_name::path())
|
||||||
|
|
||||||
|
}
|
||||||
|
pub fn message_handler_str() -> MessageData {
|
||||||
|
MessageData::new(format!("{}",stringify!(#input_type)), #input_type::field_types(), #input_type::path())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syn::Type::Tuple(_) => quote! {
|
||||||
|
#input_item
|
||||||
|
impl #message_type {
|
||||||
|
pub fn message_handler_str() -> MessageData {
|
||||||
|
MessageData::new(format!("{}",stringify!(#input_type)), #input_type::field_types(), #input_type::path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
syn::Type::Reference(type_reference) => {
|
||||||
|
let message_type = call_site_ident(format!("{input_type}Message"));
|
||||||
|
let type_ident = match &*type_reference.elem {
|
||||||
|
syn::Type::Path(type_path) => &type_path.path.segments.first().unwrap().ident,
|
||||||
|
_ => return Err(syn::Error::new(type_reference.elem.span(), "Expected type path")),
|
||||||
|
};
|
||||||
|
let tr = clean_rust_type_syntax(type_reference.to_token_stream().to_string());
|
||||||
|
quote! {
|
||||||
|
#input_item
|
||||||
|
impl #message_type {
|
||||||
|
pub fn message_handler_data_str() -> MessageData {
|
||||||
|
MessageData::new(format!("{}", #tr),#type_ident::field_types(), #type_ident::path())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn message_handler_str() -> MessageData {
|
||||||
|
MessageData::new(format!("{}",stringify!(#input_type)), #input_type::field_types(), #input_type::path())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return Err(syn::Error::new(t.span(), "Unsupported type format")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => quote! {
|
||||||
|
#input_item
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return Ok(impl_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(input_item)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user