Scanframe Modular Application 0.1.0
Loading...
Searching...
No Matches
TListener.h
Go to the documentation of this file.
1#pragma once
2#include <functional>
3#include <memory>
4#include <misc/gen/pointer.h>
5
6namespace sf
7{
8
13{
14 public:
18 struct base_type
19 {
20 virtual ~base_type() = default;
21
27 virtual bool validListener() = 0;
28 };
29
34 {
36 }
37
44 {
45 size_t rv = list.size();
46 for (auto entry: list)
47 {
48 delete_null(entry);
49 }
50 list.clear();
51 return rv;
52 }
53
60 {
61 size_t rv = 0;
62 for (list_type::size_type i = 0; i < list.size(); i++)
63 {
64 if (list.at(i) == entry)
65 {
66 list.erase(list.begin() + i, list.begin() + i + 1);// NOLINT(cppcoreguidelines-narrowing-conversions)
67 rv++;
68 }
69 }
70 return rv;
71 }
72
82 {
83 size_t rv = 0;
84 // Iterate through the list of weak pointers.
85 for (auto it = list.begin(); it != list.end();)
86 {
87 auto entry = *it;
88 if (!entry->validListener())
89 {
90 // Remove the expired entry.
91 list.erase(it);
92 // Delete the entry.
93 delete entry;
94 // Increment the return value/
95 rv++;
96 // Do not move the iterator since erase has the same effect.
97 continue;
98 }
99 ++it;
100 }
101 return rv;
102 }
103
104 private:
110 void appendListener(base_type* entry)
111 {
112 // Do some cleanup if possible.
114 // Add the new entry.
115 list.insert(list.end(), entry);
116 }
117
118 typedef std::vector<base_type*> list_type;
119 list_type list;
120
124 template<typename... Args>
125 friend class TListener;
126};
127
133template<typename... Args>
135{
136 public:
140 typedef std::function<void(Args...)> func_type;
146 typedef TListener<Args...> listener_type;
147
154 explicit TListener(ListenerList* list, const func_type& lambda)
155 : owner(list)
156 {
157 owner->appendListener(this);
158 ptr.reset(new func_type(lambda));
159 }
160
164 TListener(const TListener&) = delete;
165
166 public:
170 ~TListener() override
171 {
172 ptr.reset();
173 owner->removeListener(this);
174 }
175
180 {
181 public:
185 emitter_type() = default;
189 ~emitter_type()// NOLINT(modernize-use-equals-default)
190 {
191 // Iterate through the list of weak pointers.
192 for (auto& i: list)
193 {
194 if (!i.expired())
195 {
196 // Assign an empty.
197 *i.lock().get() = func_type();
198 }
199 }
200 }
201
207 TListener* linkListener(ListenerList* listener_list, const func_type& function)
208 {
209 auto rv = new TListener(listener_list, function);
210 list.insert(list.end(), rv->ptr);
211 return rv;
212 }
213
221 void callListeners(Args... args)
222 {
223 // Iterate through the list of weak pointers.
224 for (auto it = list.begin(); it != list.end();)
225 {
226 if (it->expired())
227 {
228 // Erase the expired entry.
229 list.erase(it);
230 // Do not move the iterator since erase has the same effect.
231 continue;
232 }
233 // Execute the function.
234 (*it->lock().get())(args...);
235 // Move to the next instance in the list.
236 ++it;
237 }
238 }
239
245 size_t cleanup()
246 {
247 size_t rv = 0;
248 // Iterate through the list of weak pointers.
249 for (auto it = list.begin(); it != list.end();)
250 {
251 if (it->expired())
252 {
253 // Erase the expired entry.
254 list.erase(it);
255 // Increment the return value/
256 rv++;
257 }
258 else
259 {
260 // Move to the next instance in the list.
261 ++it;
262 }
263 }
264 return rv;
265 }
266
270 void flush()
271 {
272 list.clear();
273 }
274
275 private:
279 std::vector<std::weak_ptr<func_type>> list;
280 };
281
282 private:
288 bool validListener() override
289 {
290 return !!*ptr.get();
291 }
292
296 ListenerList* owner;
300 std::shared_ptr<func_type> ptr{};
301};
302
303}// namespace sf
Base class used as container for classes having listeners created by sf::TListener template.
Definition TListener.h:13
size_t cleanupListeners()
Removes all invalid/unused entries.
Definition TListener.h:81
size_t flushListeners()
Deletes all the linked entries in the list.
Definition TListener.h:43
size_t removeListener(base_type *entry)
Removes the given entry from the list.
Definition TListener.h:59
~ListenerList()
Destructor deleting all entries by calling flushListeners().
Definition TListener.h:33
Emitter class type for creating an instance which is emitting events to listeners.
Definition TListener.h:180
size_t cleanup()
Removes expired listeners.
Definition TListener.h:245
void callListeners(Args... args)
Call the registered listeners.
Definition TListener.h:221
TListener * linkListener(ListenerList *listener_list, const func_type &function)
Assigns a listener instance to this handler instance and also to the passed listener list.
Definition TListener.h:207
void flush()
Removes all listeners.
Definition TListener.h:270
~emitter_type()
Destructor clearing all shared pointers.
Definition TListener.h:189
Template class used to bind listeners to a handler_type instance.
Definition TListener.h:135
~TListener() override
Overridden destructor from ListenerList::base_type in order to delete entries of any instantiated tem...
Definition TListener.h:170
TListener< Args... > listener_type
Listener type of the lambda or function.
Definition TListener.h:146
TListener(ListenerList *list, const func_type &lambda)
Constructor.
Definition TListener.h:154
std::function< void(Args...)> func_type
Function type of the lambda or function.
Definition TListener.h:140
TListener(const TListener &)=delete
Do not allow copying.
Definition Application.h:10
void delete_null(T &p)
Deletes object and clears pointer.
Definition pointer.h:14
Type definition of a class having a virtual destructor used as a base class for sf::TListener.
Definition TListener.h:19
virtual ~base_type()=default
virtual bool validListener()=0
Will be overloaded in template to check the emitter has gone away.