Source/Gorgon/ConsumableEvent.h

Tue, 06 Jul 2021 10:22:49 +0300

author
cemkalyoncu
date
Tue, 06 Jul 2021 10:22:49 +0300
branch
4.x-dev
changeset 1701
b168349a931d
parent 1557
bd3f2c078d7e
permissions
-rw-r--r--

* Image/Bitmap rotate

901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
1 /// @file Event.h contains event distribution mechanism
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
2 #pragma once
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
3
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
4 #include <type_traits>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
5 #include <vector>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
6 #include <functional>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
7 #include <mutex>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
8
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
9 #include <atomic>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
10
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
11 #include "Types.h"
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
12 #include "Containers/Collection.h"
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
13 #include "Utils/Assert.h"
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
14 #include "TMP.h"
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
15
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
16
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
17 namespace Gorgon {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
18
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
19 /// @cond INTERNAL
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
20 namespace internal {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
21 namespace consumableevent {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
22 template<class Source_, typename... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
23 struct HandlerBase {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
24 virtual bool Fire(std::mutex &locker, Source_ *, Params_...) = 0;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
25
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
26 virtual ~HandlerBase() {}
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
27
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
28 bool enabled = true;
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
29 };
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
30
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
31 template<class Source_, typename... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
32 struct EmptyHandlerFn : public HandlerBase<Source_, Params_...> {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
33 EmptyHandlerFn(std::function<bool()> fn) : fn(fn) { }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
34
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
35 virtual bool Fire(std::mutex &locker, Source_ *, Params_...) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
36 auto f=fn;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
37 locker.unlock();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
38 return f();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
39 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
40
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
41 std::function<bool()> fn;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
42 };
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
43
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
44 template<class Source_, typename... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
45 struct ArgsHandlerFn : public HandlerBase<Source_, Params_...> {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
46 ArgsHandlerFn(std::function<bool(Params_...)> fn) : fn(fn) { }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
47
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
48 virtual bool Fire(std::mutex &locker, Source_ *, Params_... args) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
49 auto f=fn;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
50 locker.unlock();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
51 return f(std::forward<Params_>(args)...);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
52 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
53
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
54 std::function<bool(Params_...)> fn;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
55 };
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
56
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
57 template<class Source_, typename... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
58 struct FullHandlerFn : public HandlerBase<Source_, Params_...> {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
59 static_assert(!std::is_same<Source_, void>::value, "No source class exists for this event (void cannot be passed around)");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
60
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
61 FullHandlerFn(std::function<bool(Source_&, Params_...)> fn) : fn(fn) { }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
62
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
63 virtual bool Fire(std::mutex &locker, Source_ *source, Params_... args) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
64 auto f=fn;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
65 locker.unlock();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
66 return f(*source, std::forward<Params_>(args)...);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
67 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
68
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
69 std::function<bool(Source_&, Params_...)> fn;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
70 };
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
71
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
72 template<class Source_, class... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
73 static HandlerBase<Source_, Params_...>& createhandlerfn(bool(*fn)()) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
74 return *new EmptyHandlerFn<Source_, Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
75 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
76
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
77 template<class Source_, class... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
78 static HandlerBase<Source_, Params_...>& createhandlerfn(bool(*fn)(Params_...)) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
79 return *new ArgsHandlerFn<Source_, Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
80 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
81
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
82 template<class Source_, class... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
83 static HandlerBase<Source_, Params_...>& createhandlerfn(bool(*fn)(Source_ &, Params_...)) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
84 return *new FullHandlerFn<Source_, Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
85 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
86
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
87 template<class F_, class Source_, int N, class... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
88 static typename std::enable_if<TMP::FunctionTraits<F_>::Arity==0, HandlerBase<Source_, Params_...>&>::type
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
89 createhandler_internal(F_ fn) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
90 return *new EmptyHandlerFn<Source_, Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
91 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
92
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
93 template<class F_, class Source_, int N, typename... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
94 static typename std::enable_if<TMP::FunctionTraits<F_>::Arity!=0 && TMP::FunctionTraits<F_>::Arity==N, HandlerBase<Source_, Params_...>&>::type
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
95 createhandler_internal(F_ fn) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
96 return *new ArgsHandlerFn<Source_, Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
97 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
98
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
99 template<class F_, class Source_, int N, class... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
100 static typename std::enable_if<TMP::FunctionTraits<F_>::Arity==N+1, HandlerBase<Source_, Params_...>&>::type
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
101 createhandler_internal(F_ fn) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
102 return *new FullHandlerFn<Source_, Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
103 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
104
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
105 template<class F_, class Source_, class... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
106 typename std::enable_if<TMP::HasParanthesisOperator<F_>::value, HandlerBase<Source_, Params_...>&>::type
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
107 create_handler(F_ fn) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
108 static_assert(std::is_same<typename TMP::FunctionTraits<F_>::ReturnType, bool>::value, "Function must return a bool");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
109
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
110 return createhandler_internal<F_, Source_, sizeof...(Params_), Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
111 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
112
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
113 template<class F_, class Source_, class... Params_, typename N=void>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
114 typename std::enable_if<!TMP::HasParanthesisOperator<F_>::value, HandlerBase<Source_, Params_...>&>::type
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
115 create_handler(F_ fn) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
116 static_assert(std::is_same<typename TMP::FunctionTraits<F_>::ReturnType, bool>::value, "Function must return a bool");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
117
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
118 return createhandlerfn<Source_, Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
119 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
120 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
121 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
122
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
123 /// @endcond
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
124
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
125 /// This class provides event mechanism that can be consumed. Once an event is consumed by a handler
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
126 /// rest of the handler will not receive it. Different function signatures are allowed to
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
127 /// as event handlers. These are:
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
128 ///
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
129 /// * <b>`bool fn()`</b> neither event source nor event parameters are supplied.
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
130 /// * <b>`bool fn(Params_... params)`</b> parameters will be passed
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
131 /// * <b>`bool fn(Source_ &source, Params_... params)`</b> the source and parameters
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
132 /// will be passed
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
133 ///
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
134 /// Class members or lambda functions can also be used as event handlers. An
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
135 /// event handler can be registered using Register function.
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
136 template<class Source_=void, typename... Params_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
137 class ConsumableEvent {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
138 public:
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
139
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
140 /// Data type for tokens
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
141 typedef intptr_t Token;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
142
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
143 /// Constructor for empty source
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
144 ConsumableEvent() : source(nullptr) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
145 fire.clear();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
146 static_assert( std::is_same<Source_, void>::value , "Empty constructor cannot be used." );
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
147 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
148
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
149 /// Constructor for class specific source
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
150 template <class S_ = Source_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
151 explicit ConsumableEvent(typename std::enable_if<!std::is_same<S_, void>::value, S_>::type &source) : source(&source) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
152 fire.clear();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
153 static_assert(!std::is_same<Source_, void>::value, "Filling constructor is not required, use the default.");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
154 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
155
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
156 /// Constructor for class specific source
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
157 template <class S_ = Source_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
158 explicit ConsumableEvent(typename std::enable_if<!std::is_same<S_, void>::value, S_>::type *source) : source(source) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
159 ASSERT(source, "Source cannot be nullptr");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
160 fire.clear();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
161 static_assert(!std::is_same<Source_, void>::value, "Filling constructor is not required, use the default.");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
162 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
163
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
164 /// Move constructor
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
165 ConsumableEvent(ConsumableEvent &&event) : source(nullptr) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
166 Swap(event);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
167 #ifndef NDEBUG
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
168 event.movedout = true;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
169 #endif
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
170 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
171
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
172 /// Destructor
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
173 ~ConsumableEvent() {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
174 ASSERT(!fire.test_and_set(), "An event cannot be destroyed while its being fired.");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
175 std::lock_guard<std::mutex> g(access);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
176
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
177 handlers.Destroy();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
178 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
179
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
180 /// Copy constructor is disabled
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
181 ConsumableEvent(const ConsumableEvent &) = delete;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
182
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
183 /// Copy assignment is disabled
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
184 ConsumableEvent &operator =(const ConsumableEvent &) = delete;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
185
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
186 /// Move assignment, should be called synchronized
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
187 ConsumableEvent &operator =(const ConsumableEvent &&other) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
188 if(&other==this) return *this;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
189
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
190 std::lock_guard<std::mutex> g(access);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
191
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
192 ASSERT(!fire.test_and_set(), "An event cannot be moved into while its being fired.");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
193
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
194 handlers.Destroy();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
195
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
196 source=nullptr;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
197 Swap(other);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
198
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
199 fire.clear();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
200 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
201
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
202 /// Swaps two Events, used for move semantics
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
203 void Swap(ConsumableEvent &other) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
204 if(&other==this) return;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
205
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
206 using std::swap;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
207
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
208 ASSERT(!fire.test_and_set() && !other.fire.test_and_set(), "An event cannot be swapped while its being fired.");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
209
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
210 swap(source, other.source);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
211 swap(handlers, other.handlers);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
212
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
213 fire.clear();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
214 other.fire.clear();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
215 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
216
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
217 /// Registers a new function to be called when this event is triggered. This function can
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
218 /// be called from event handler of the same event. The registered event handler will be
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
219 /// called immediately in this case. If you register a class with a () operator, this class
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
220 /// will be copied. If you require call to be made to the same instance, instead of using
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
221 /// `Register(a)` use `Register(a, &decltype(a)::operator())`
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
222 template<class F_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
223 Token Register(F_ fn) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
224
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
225 ASSERT(!movedout, "This event is moved out of");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
226
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
227 auto &handler=internal::consumableevent::create_handler<F_, Source_, Params_...>(fn);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
228
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
229 std::lock_guard<std::mutex> g(access);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
230 handlers.Add(handler);
1443
11fc019aa4ae * A sneaky spacing bug
cemkalyoncu
parents: 1070
diff changeset
231
11fc019aa4ae * A sneaky spacing bug
cemkalyoncu
parents: 1070
diff changeset
232 if(NewHandler)
11fc019aa4ae * A sneaky spacing bug
cemkalyoncu
parents: 1070
diff changeset
233 NewHandler();
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
234
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
235 return reinterpret_cast<Token>(&handler);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
236 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
237
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
238 /// Registers a new function to be called when this event is triggered. This variant is
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
239 /// designed to be used with member functions. **Example:**
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
240 /// @code
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
241 /// A a;
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
242 /// b.ClickEvent.Register(a, &A::f);
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
243 /// @endcode
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
244 ///
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
245 /// This function can be called from event handler of the same event. The registered
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
246 /// event handler will be called immediately in this case.
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
247 template<class C_, typename... A_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
248 Token Register(C_ &c, bool(C_::*fn)(A_...)) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
249
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
250 ASSERT(!movedout, "This event is moved out of");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
251
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
252 std::function<bool(A_...)> f=TMP::MakeFunctionFromMember(fn, &c);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
253
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
254 return Register(f);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
255 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
256
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
257 /// Unregisters the given marked with the given token. This function performs no
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
258 /// operation if the token is not contained within this event. A handler can be
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
259 /// unregistered safely while the event is being fired. In this case, if the event that
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
260 /// is being deleted is different from the current event handler, the deleted event
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
261 /// handler might have already been fired. If not, it will not be fired.
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
262 void Unregister(Token token) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
263
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
264 ASSERT(!movedout, "This event is moved out of");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
265
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
266 std::lock_guard<std::mutex> g(access);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
267
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
268 auto item=reinterpret_cast<internal::consumableevent::HandlerBase<Source_, Params_...>*>(token);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
269
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
270 auto l=handlers.FindLocation(item);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
271 if(l==-1) return;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
272
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
273 if(iterator.IsValid() && iterator.CurrentPtr()==item) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
274 handlers.Delete(l);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
275
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
276 //Collection iterator can point element -1
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
277 iterator.Previous();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
278 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
279 else {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
280 handlers.Delete(l);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
281 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
282 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
283
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
284 /// Fire this event. This function will never allow recursive firing, i.e. an event handler
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
285 /// cannot cause this event to be fired again.
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
286 Token operator()(Params_... args) {
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
287 //stops the request if it is received from a different thread.
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
288 std::lock_guard<std::recursive_mutex> g(firemtx);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
289
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
290 ASSERT(!movedout, "This event is moved out of");
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
291
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
292 try {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
293 for(iterator=handlers.Last(); iterator.IsValid(); iterator.Previous()) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
294 access.lock();
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
295 if(iterator->enabled) {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
296 // fire method will unlock access after it creates a local copy of the function
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
297 // this allows the fired object to be safely deleted.
1557
bd3f2c078d7e * A critical event bug is fixed
cemkalyoncu
parents: 1543
diff changeset
298 bool res = iterator->Fire(access, source, args...);
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
299
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
300 if(res) {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
301 fire.clear();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
302 return reinterpret_cast<Token>(iterator.CurrentPtr());
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
303 }
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
304 }
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
305 else {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
306 access.unlock();
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
307 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
308 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
309 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
310 catch(...) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
311 //unlock everything if something goes bad
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
312
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
313 //just in case
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
314 access.unlock();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
315
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
316 fire.clear();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
317
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
318 throw;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
319 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
320
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
321 fire.clear();
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
322
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
323 return EmptyToken;
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
324 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
325
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
326 bool FireFor(Token token, Params_... args) {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
327 //stops the request if it is received from a different thread.
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
328 std::lock_guard<std::recursive_mutex> g(firemtx);
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
329
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
330 #ifndef NDEBUG
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
331 ASSERT(!fire.test_and_set(), "Recursion detected during event execution.");
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
332 #else
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
333 //prevent recursion
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
334 if(fire.test_and_set()) return false;
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
335 #endif
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
336
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
337 ASSERT(!movedout, "This event is moved out of");
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
338
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
339 try {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
340 access.lock();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
341 auto pos = handlers.FindLocation(reinterpret_cast<internal::consumableevent::HandlerBase<Source_, Params_...>*>(token));
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
342
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
343 if(pos == -1) {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
344 access.unlock();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
345 fire.clear();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
346 return false;
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
347 }
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
348
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
349 auto handler = reinterpret_cast<internal::consumableevent::HandlerBase<Source_, Params_...>*>(token);
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
350
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
351 if(!handler->enabled) {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
352 access.unlock();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
353 fire.clear();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
354 return false;
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
355 }
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
356
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
357 handler->Fire(access, source, args...);
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
358
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
359 fire.clear();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
360
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
361 return true;
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
362 }
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
363 catch(...) {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
364 //unlock everything if something goes bad
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
365
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
366 //just in case
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
367 access.unlock();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
368
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
369 fire.clear();
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
370
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
371 throw;
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
372 }
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
373 }
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
374
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
375 /// Moves a handler to be the first to get fired.
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
376 void MoveToTop(Token token) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
377 std::lock_guard<std::mutex> g(access);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
378
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
379 handlers.MoveBefore(*reinterpret_cast<internal::consumableevent::HandlerBase<Source_, Params_...>*>(token), handlers.GetSize());
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
380 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
381
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
382 /// Moves a handler to be the last to get fired.
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
383 void MoveToBottom(Token token) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
384 std::lock_guard<std::mutex> g(access);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
385
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
386 handlers.MoveBefore(*reinterpret_cast<internal::consumableevent::HandlerBase<Source_, Params_...>*>(token), 0);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
387 }
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
388
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
389 /// Disable given event handler. This functionality allows handlers to be pseudo removed without changing
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
390 /// their location in the hierarchy.
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
391 void Disable(Token token) {
1070
d52068ce190d * Scene support is ready, waiting for unit tests
cemkalyoncu
parents: 902
diff changeset
392 if(!token) return;
902
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
393 std::lock_guard<std::mutex> g(access);
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
394
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
395 reinterpret_cast<internal::consumableevent::HandlerBase<Source_, Params_...>*>(token)->enabled = false;
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
396 }
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
397
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
398 /// Enables given event handler. This functionality allows handlers to be pseudo removed without changing
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
399 /// their location in the hierarchy.
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
400 void Enable(Token token) {
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
401 std::lock_guard<std::mutex> g(access);
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
402
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
403 reinterpret_cast<internal::consumableevent::HandlerBase<Source_, Params_...>*>(token)->enabled = true;
508c5250770b * Enable/disable semantics for ConsumableEvent
cemkalyoncu
parents: 901
diff changeset
404 }
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
405
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
406 /// value for an empty token
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
407 static const Token EmptyToken;
1443
11fc019aa4ae * A sneaky spacing bug
cemkalyoncu
parents: 1070
diff changeset
408
11fc019aa4ae * A sneaky spacing bug
cemkalyoncu
parents: 1070
diff changeset
409 std::function<void()> NewHandler;
901
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
410
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
411 private:
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
412
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
413 #ifndef NDEBUG
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
414 bool movedout = false;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
415 #endif
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
416
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
417
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
418 std::mutex access;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
419 std::atomic_flag fire;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
420 Source_ *source;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
421 Containers::Collection<internal::consumableevent::HandlerBase<Source_, Params_...>> handlers;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
422 typename Containers::Collection<internal::consumableevent::HandlerBase<Source_, Params_...>>::Iterator iterator;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
423 std::recursive_mutex firemtx;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
424 };
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
425
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
426 template<class C_, class ...P_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
427 const typename ConsumableEvent<C_, P_...>::Token ConsumableEvent<C_, P_...>::EmptyToken = 0;
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
428
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
429 /// Swaps two events
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
430 template<class Source_, class... Args_>
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
431 void swap(ConsumableEvent<Source_, Args_...> &l, ConsumableEvent<Source_, Args_...> &r) {
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
432 l.Swap(r);
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
433 }
12ceb6e663d9 * Consumable event
cemkalyoncu
parents:
diff changeset
434 }

mercurial