mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 23:38:06 +08:00
146 lines
4.5 KiB
Rust
146 lines
4.5 KiB
Rust
use crate::messages::prelude::*;
|
|
use graphite_proc_macros::*;
|
|
|
|
#[impl_message]
|
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
|
|
pub enum Message {
|
|
// Sub-messages
|
|
#[child]
|
|
Animation(AnimationMessage),
|
|
#[child]
|
|
AppWindow(AppWindowMessage),
|
|
#[child]
|
|
Broadcast(BroadcastMessage),
|
|
#[child]
|
|
Debug(DebugMessage),
|
|
#[child]
|
|
Defer(DeferMessage),
|
|
#[child]
|
|
Dialog(DialogMessage),
|
|
#[child]
|
|
Frontend(FrontendMessage),
|
|
#[child]
|
|
Globals(GlobalsMessage),
|
|
#[child]
|
|
InputPreprocessor(InputPreprocessorMessage),
|
|
#[child]
|
|
KeyMapping(KeyMappingMessage),
|
|
#[child]
|
|
Layout(LayoutMessage),
|
|
#[child]
|
|
Portfolio(PortfolioMessage),
|
|
#[child]
|
|
Preferences(PreferencesMessage),
|
|
#[child]
|
|
Tool(ToolMessage),
|
|
|
|
// Messages
|
|
Batched {
|
|
messages: Box<[Message]>,
|
|
},
|
|
NoOp,
|
|
}
|
|
|
|
/// Provides an impl of `specta::Type` for `MessageDiscriminant`, the struct created by `impl_message`.
|
|
/// Specta isn't integrated with `impl_message`, so a remote impl must be provided using this struct.
|
|
impl specta::Type for MessageDiscriminant {
|
|
fn inline(_type_map: &mut specta::TypeCollection, _generics: specta::Generics) -> specta::DataType {
|
|
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.message_handler_data_fields().is_some() || tree.message_handler_fields().is_some() {
|
|
("├── ", 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 message field if any
|
|
if let Some(fields) = tree.fields() {
|
|
let len = fields.len();
|
|
for (i, field) in fields.iter().enumerate() {
|
|
let is_last_field = i == len - 1;
|
|
let branch = if is_last_field { "└── " } else { "├── " };
|
|
|
|
file.write_all(format!("{child_prefix}{branch}{field}\n").as_bytes()).unwrap();
|
|
}
|
|
}
|
|
|
|
// Print handler field if any
|
|
if let Some(data) = tree.message_handler_fields() {
|
|
let len = data.fields().len();
|
|
let (branch, child_prefix) = if tree.message_handler_data_fields().is_some() {
|
|
("├── ", format!("{prefix}│ "))
|
|
} else {
|
|
("└── ", format!("{prefix} "))
|
|
};
|
|
|
|
const FRONTEND_MESSAGE_STR: &str = "FrontendMessage";
|
|
if data.name().is_empty() && tree.name() != FRONTEND_MESSAGE_STR {
|
|
panic!("{}'s MessageHandler is missing #[message_handler_data]", tree.name());
|
|
} else if tree.name() != FRONTEND_MESSAGE_STR {
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|