geop_core_editor/
part_operation.rs1use std::fmt::Debug;
10
11use geop_core_math::geop_error::GeopResult;
12use geop_core_program::part::StepContext;
13use serde::{Serialize, de::DeserializeOwned};
14
15use crate::{
16 edit_form::{Edit, EditForm, FormState},
17 editable::{Context, OperationInfo},
18 editing::CanvasEvent,
19};
20
21pub trait PartOperation: 'static {
23 const KIND: &'static str;
25 const INFO: OperationInfo;
26 type Args: Serialize + DeserializeOwned + Debug + PartialEq + Clone + 'static;
29 type Session: Clone + Default + 'static;
32
33 fn new_args(context: &Context) -> Self::Args;
36
37 fn run(ctx: &mut StepContext, args: &Self::Args) -> GeopResult<()>;
40
41 fn form<'a>(
45 context: &'a Context<'a>,
46 args: &Self::Args,
47 editing: &FormState<Self::Session>,
48 ) -> EditForm<'a, Self::Args, Self::Session>;
49
50 fn begin_event(session: &mut Self::Session) {
53 let _ = session;
54 }
55
56 fn canvas(context: &Context, edit: Edit<'_, Self::Args, Self::Session>, event: &CanvasEvent) {
58 let _ = (context, edit, event);
59 }
60}
61
62#[macro_export]
69macro_rules! part_operation {
70 ($($operation:ident($args:ty)),* $(,)?) => {$(
71 impl $crate::__program::operation::StepArgs for $args {
72 const KIND: &'static str = <$operation as $crate::part_operation::PartOperation>::KIND;
73 }
74
75 impl $crate::__program::operation::Operation for $operation {
76 const KIND: &'static str = <$operation as $crate::part_operation::PartOperation>::KIND;
77 type Args = <$operation as $crate::part_operation::PartOperation>::Args;
78
79 fn run(
80 ctx: &mut $crate::__program::part::StepContext,
81 args: &Self::Args,
82 ) -> $crate::__GeopResult<()> {
83 <$operation as $crate::part_operation::PartOperation>::run(ctx, args)
84 }
85 }
86
87 impl $crate::editable::Editable for $operation {
88 const INFO: $crate::editable::OperationInfo =
89 <$operation as $crate::part_operation::PartOperation>::INFO;
90 type EditingState = $crate::edit_form::FormState<
91 <$operation as $crate::part_operation::PartOperation>::Session,
92 >;
93
94 fn new_args(
95 context: &$crate::editable::Context,
96 ) -> Self::Args {
97 <$operation as $crate::part_operation::PartOperation>::new_args(context)
98 }
99
100 fn presentation(
101 context: &$crate::editable::Context,
102 args: &Self::Args,
103 editing: &Self::EditingState,
104 ) -> $crate::editing::Form {
105 <$operation as $crate::part_operation::PartOperation>::form(context, args, editing)
106 .into_form()
107 }
108
109 fn process_user_event(
110 context: &$crate::editable::Context,
111 args: &Self::Args,
112 editing: &Self::EditingState,
113 event: $crate::editing::Event,
114 ) -> (Self::Args, Self::EditingState) {
115 let mut editing = editing.clone();
116 <$operation as $crate::part_operation::PartOperation>::begin_event(
117 &mut editing.session,
118 );
119 editing.handle(
120 args,
121 event,
122 |args, editing| {
123 <$operation as $crate::part_operation::PartOperation>::form(
124 context, args, editing,
125 )
126 },
127 |edit, event| {
128 <$operation as $crate::part_operation::PartOperation>::canvas(
129 context, edit, event,
130 )
131 },
132 )
133 }
134 }
135 )*};
136}