1use std::convert::TryFrom;
21use strum::FromRepr;
22use crate::tree::NodeId;
23use crate::interface::model;
24use crate::interface::controller::controls;
25
26pub trait Application : Sized {
28 type CallbackIds : std::fmt::Debug + Into <CallbackId>
29 + TryFrom <CallbackId>
30 + std::ops::Deref <Target = Callback <Self>>;
31 type AxisControls : controls::Id <controls::Axis> = controls::Nil;
33 type ButtonControls : controls::Id <controls::Button> = controls::Nil;
34 type MotionControls : controls::Id <controls::Motion> = controls::Nil;
35 type PointerControls : controls::Id <controls::Pointer> = controls::Nil;
36 type SystemControls : controls::Id <controls::System> = controls::Nil;
37 type TextControls : controls::Id <controls::Text> = controls::Nil;
38 type WheelControls : controls::Id <controls::Wheel> = controls::Nil;
39}
40
41#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
43pub struct CallbackId (pub CallbackReprType);
44pub type CallbackReprType = u16;
46
47pub type Callback <A> = fn (&mut A, model::Component, NodeId);
49
50pub fn callback <A : Application> (callback_id : CallbackId) -> A::CallbackIds {
55 A::CallbackIds::try_from (callback_id).ok().unwrap()
56}
57
58#[derive(Debug, Default)]
60pub struct Default;
61
62impl Application for Default {
63 type CallbackIds = Nil;
64 type AxisControls = controls::Nil;
65 type ButtonControls = controls::Nil;
66 type MotionControls = controls::Nil;
67 type PointerControls = controls::Nil;
68 type SystemControls = controls::Nil;
69 type TextControls = controls::Nil;
70 type WheelControls = controls::Nil;
71}
72
73#[derive(Debug, Eq, PartialEq, FromRepr)]
75pub enum Nil { }
76
77impl From <Nil> for CallbackId {
78 fn from (_ : Nil) -> CallbackId {
79 unreachable!()
80 }
81}
82impl std::convert::TryFrom <CallbackId> for Nil {
83 type Error = CallbackId;
84 fn try_from (_ : CallbackId) -> Result <Self, CallbackId> {
85 unreachable!()
86 }
87}
88impl std::ops::Deref for Nil {
89 type Target = fn (&mut Default, model::Component, NodeId);
90 fn deref (&self) -> &fn (&mut Default, model::Component, NodeId) {
91 unreachable!()
92 }
93}
94
95#[macro_export]
97macro_rules! def_callback_ids {
98 ( $callback_ids:ident <$application:ty> {
99 $($callback_id:ident => $callback:path)*
100 }
101 ) => {
102 #[derive(Debug, Eq, PartialEq, $crate::strum::FromRepr)]
103 #[repr(u16)]
105 pub enum $callback_ids {
106 $($callback_id),*
107 }
108
109 impl From <$callback_ids> for $crate::application::CallbackId {
110 fn from (id : $callback_ids) -> $crate::application::CallbackId {
111 $crate::application::CallbackId (
112 id as $crate::application::CallbackReprType
113 )
114 }
115 }
116
117 impl std::convert::TryFrom <$crate::application::CallbackId>
118 for $callback_ids
119 {
120 type Error = $crate::application::CallbackId;
121 fn try_from (callback_id : $crate::application::CallbackId)
122 -> Result <Self, $crate::application::CallbackId>
123 {
124 $callback_ids::from_repr (callback_id.0).ok_or (callback_id)
125 }
126 }
127
128 impl std::ops::Deref for $callback_ids {
129 type Target = fn (&mut $application,
130 $crate::interface::model::Component, $crate::tree::NodeId);
131 fn deref (&self) -> &fn (&mut $application,
132 $crate::interface::model::Component, $crate::tree::NodeId
133 ) {
134 match self {
135 $($callback_ids :: $callback_id => {
136 static F : fn (&mut $application,
137 $crate::interface::model::Component, $crate::tree::NodeId
138 ) = $callback;
139 &F
140 })*
141 }
142 }
143 }
144 }
145}