]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/signal/isignal.h
e6cb215d4091d261b649934cb52bbb5c14fbff53
[xonotic/netradiant.git] / libs / signal / isignal.h
1
2 #if !defined(INCLUDED_ISIGNAL_H)
3 #define INCLUDED_ISIGNAL_H
4
5 #include "generic/callback.h"
6 #include "signal/signalfwd.h"
7
8 class SignalHandlerResult
9 {
10   bool value;
11 public:
12   explicit SignalHandlerResult(bool value) : value(value)
13   {
14   }
15   bool operator==(SignalHandlerResult other) const
16   {
17     return value == other.value;
18   }
19   bool operator!=(SignalHandlerResult other) const
20   {
21     return !operator==(other);
22   }
23 };
24
25 const SignalHandlerResult SIGNAL_CONTINUE_EMISSION = SignalHandlerResult(false);
26 const SignalHandlerResult SIGNAL_STOP_EMISSION = SignalHandlerResult(true);
27
28 template<typename Caller> 
29 class SignalHandlerCaller1
30 {
31 public:
32   typedef typename Caller::first_argument_type first_argument_type;
33   typedef SignalHandlerResult result_type;
34   static result_type call(first_argument_type a1)
35   {
36     Caller::call(a1);
37     return SIGNAL_CONTINUE_EMISSION;
38   }
39 };
40
41 template<typename Caller> 
42 class SignalHandlerCaller2
43 {
44 public:
45   typedef typename Caller::first_argument_type first_argument_type;
46   typedef typename Caller::second_argument_type second_argument_type;
47   typedef SignalHandlerResult result_type;
48   static result_type call(first_argument_type a1, second_argument_type a2)
49   {
50     Caller::call(a1, a2);
51     return SIGNAL_CONTINUE_EMISSION;
52   }
53 };
54
55 template<typename Caller> 
56 class SignalHandlerCaller3
57 {
58 public:
59   typedef typename Caller::first_argument_type first_argument_type;
60   typedef typename Caller::second_argument_type second_argument_type;
61   typedef typename Caller::third_argument_type third_argument_type;
62   typedef SignalHandlerResult result_type;
63   static result_type call(first_argument_type a1, second_argument_type a2, third_argument_type a3)
64   {
65     Caller::call(a1, a2, a3);
66     return SIGNAL_CONTINUE_EMISSION;
67   }
68 };
69
70 template<typename Caller> 
71 class SignalHandlerCaller4
72 {
73 public:
74   typedef typename Caller::first_argument_type first_argument_type;
75   typedef typename Caller::second_argument_type second_argument_type;
76   typedef typename Caller::third_argument_type third_argument_type;
77   typedef typename Caller::fourth_argument_type fourth_argument_type;
78   typedef SignalHandlerResult result_type;
79   static result_type call(first_argument_type a1, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
80   {
81     Caller::call(a1, a2, a3, a4);
82     return SIGNAL_CONTINUE_EMISSION;
83   }
84 };
85
86 class SignalHandler : public Callback0<SignalHandlerResult>
87 {
88 public:
89   template<typename Caller>
90   SignalHandler(const BindFirstOpaque<Caller>& caller)
91     : Callback0<SignalHandlerResult>(BindFirstOpaque<typename TypeEqual<
92       typename Caller::result_type,
93       SignalHandlerResult,
94       Caller,
95       SignalHandlerCaller1<Caller>
96     >::type>(caller.getBound()))
97   {
98   }
99 };
100
101 template<typename Caller>
102 inline SignalHandler makeSignalHandler(const BindFirstOpaque<Caller>& caller)
103 {
104   return SignalHandler(caller);
105 }
106 template<typename Caller>
107 inline SignalHandler makeSignalHandler(const Caller& caller, typename Caller::first_argument_type callee)
108 {
109   return SignalHandler(BindFirstOpaque<Caller>(callee));
110 }
111
112
113 template<typename FirstArgument>
114 class SignalHandler1 : public Callback1<FirstArgument, SignalHandlerResult>
115 {
116 public:
117   template<typename Caller>
118   SignalHandler1(const BindFirstOpaque1<Caller>& caller)
119     : Callback1<FirstArgument, SignalHandlerResult>(BindFirstOpaque1<typename TypeEqual<
120       typename Caller::result_type,
121       SignalHandlerResult,
122       Caller,
123       SignalHandlerCaller2<Caller>
124     >::type>(caller.getBound()))
125   {
126   }
127 };
128
129 template<typename Caller>
130 inline SignalHandler1<typename Caller::second_argument_type> makeSignalHandler1(const BindFirstOpaque1<Caller>& caller)
131 {
132   return SignalHandler1<typename Caller::second_argument_type>(caller);
133 }
134 template<typename Caller>
135 inline SignalHandler1<typename Caller::second_argument_type> makeSignalHandler1(const Caller& caller, typename Caller::first_argument_type callee)
136 {
137   return SignalHandler1<typename Caller::second_argument_type>(BindFirstOpaque1<Caller>(callee));
138 }
139
140
141 template<typename FirstArgument, typename SecondArgument>
142 class SignalHandler2 : public Callback2<FirstArgument, SecondArgument, SignalHandlerResult>
143 {
144 public:
145   template<typename Caller>
146   SignalHandler2(const BindFirstOpaque2<Caller>& caller)
147     : Callback2<FirstArgument, SecondArgument, SignalHandlerResult>(BindFirstOpaque2<typename TypeEqual<
148       typename Caller::result_type,
149       SignalHandlerResult,
150       Caller,
151       SignalHandlerCaller3<Caller>
152     >::type>(caller.getBound()))
153   {
154   }
155 };
156
157 template<typename Caller>
158 inline SignalHandler2<
159   typename Caller::second_argument_type,
160   typename Caller::third_argument_type
161 > makeSignalHandler2(const BindFirstOpaque2<Caller>& caller)
162 {
163   return SignalHandler2<
164     typename Caller::second_argument_type,
165     typename Caller::third_argument_type
166   >(caller);
167 }
168 template<typename Caller>
169 inline SignalHandler2<
170   typename Caller::second_argument_type,
171   typename Caller::third_argument_type
172 > makeSignalHandler2(const Caller& caller, typename Caller::first_argument_type callee)
173 {
174   return SignalHandler2<
175     typename Caller::second_argument_type,
176     typename Caller::third_argument_type
177   >(BindFirstOpaque2<Caller>(callee));
178 }
179
180
181 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
182 class SignalHandler3 : public Callback3<FirstArgument, SecondArgument, ThirdArgument, SignalHandlerResult>
183 {
184 public:
185   template<typename Caller>
186   SignalHandler3(const BindFirstOpaque3<Caller>& caller)
187     : Callback3<FirstArgument, SecondArgument, ThirdArgument, SignalHandlerResult>(BindFirstOpaque3<typename TypeEqual<
188       typename Caller::result_type,
189       SignalHandlerResult,
190       Caller,
191       SignalHandlerCaller4<Caller>
192     >::type>(caller.getBound()))
193   {
194   }
195 };
196
197 template<typename Caller>
198 inline SignalHandler3<
199   typename Caller::second_argument_type,
200   typename Caller::third_argument_type,
201   typename Caller::fourth_argument_type
202 > makeSignalHandler3(const BindFirstOpaque3<Caller>& caller)
203 {
204   return SignalHandler3<
205     typename Caller::second_argument_type,
206     typename Caller::third_argument_type,
207     typename Caller::fourth_argument_type
208   >(caller);
209 }
210 template<typename Caller>
211 inline SignalHandler3<
212   typename Caller::second_argument_type,
213   typename Caller::third_argument_type,
214   typename Caller::fourth_argument_type
215 > makeSignalHandler3(const Caller& caller, typename Caller::first_argument_type callee)
216 {
217   return SignalHandler3<
218     typename Caller::second_argument_type,
219     typename Caller::third_argument_type,
220     typename Caller::fourth_argument_type
221   >(BindFirstOpaque3<Caller>(callee));
222 }
223
224 #endif