CFx SDK Documentation 2024 SP0
Loading...
Searching...
No Matches
slot.h
Go to the documentation of this file.
1//
2// signal_set.h
3// slimsig
4//
5// Created by Christopher Tarquini on 4/23/14.
6//
7//
8
9#ifndef slimsig_signal_set_h
10#define slimsig_signal_set_h
11
12#include <vector>
13#include <iterator>
14#include <algorithm>
15#include <type_traits>
16
17namespace slimsig {
18namespace detail {
19
20#if defined(_MSC_VER)
21#define _FORCE_INLINE __forceinline
22#else
23#define _FORCE_INLINE [[gnu::always_inline]] inline
24#endif
25
26template <class T>
27_FORCE_INLINE T default_value() { return T(); }
29};
30
31
32template <class Callback, class SlotID>
34
35template <class R, class... Args, class SlotID>
36class basic_slot<R(Args...), SlotID> {
37public:
38 using callback = std::function<R(Args...)>;
39 using slot_id = SlotID;
40
41 basic_slot(slot_id sid, callback fn) : m_fn(std::move(fn)), m_slot_id(sid), m_is_connected(bool(m_fn)), m_is_running(false) {};
42 basic_slot() : basic_slot(0, nullptr) {};
43 template <class... Arguments>
44 basic_slot(slot_id sid, Arguments&&... args) : m_fn(std::forward<Arguments>(args)...), m_slot_id(sid), m_is_connected(bool(m_fn)), m_is_running(false) {};
45 basic_slot(basic_slot&&) = default;
46 basic_slot(const basic_slot&) = default;
47 inline basic_slot& operator=(const basic_slot&) = default;
48 inline basic_slot& operator=(basic_slot&&) = default;
49
51 bool operator==(const basic_slot& other) const{
52 return m_slot_id == other.m_slot_id;
53 }
55 bool operator==(const slot_id& other) const {
56 return m_slot_id == other;
57 }
59 bool operator <(const basic_slot& other) const {
60 return m_slot_id < other.m_slot_id;
61 }
63 bool operator <(const slot_id& other) const {
64 return m_slot_id < other;
65 }
67 bool operator >(const basic_slot& other) const {
68 return m_slot_id > other.m_slot_id;
69 }
71 bool operator >(const slot_id& other) const {
72 return m_slot_id > other;
73 }
75 bool operator <=(const slot_id& other) const {
76 return m_slot_id <= other;
77 }
79 bool operator >=(const slot_id& other) const {
80 return m_slot_id >= other;
81 }
83 explicit operator bool() const{
84 return m_is_connected;
85 }
87 bool connected() const {
88 return m_is_connected;
89 }
91 void disconnect() {
92 m_is_connected = false;
93 if (!m_is_running) {
94 m_fn = nullptr;
95 }
96 }
97
98 [[deprecated("Use operator()")]] _FORCE_INLINE
99 const callback& operator*() const{
100 return m_fn;
101 };
102 [[deprecated( "Use operator()" )]] _FORCE_INLINE
103 const callback* operator->() const {
104 return &m_fn;
105 }
107 R operator() (Args... args) const{
108 struct invoke_guard
109 {
110 const basic_slot& slot;
111 ~invoke_guard() { slot.m_is_running = false;}
112 } guard { *this };
113 m_is_running = true;
114 return m_fn(std::forward<Args>(args)...);
115 }
119 mutable bool m_is_running;
120};
121
151template < class T,
152 class IDGenerator = std::size_t,
153 class FlagType = bool,
154 class Allocator = std::allocator<std::function<T>>
155 >
156class slot_list : public std::enable_shared_from_this<slot_list<T, IDGenerator, FlagType, Allocator>>{
157 using id_generator = IDGenerator;
158 using flag = FlagType;
159 static auto slot_id_helper(IDGenerator gen) -> decltype(gen++);
160public:
161 using slot_id = decltype(slot_id_helper(std::declval<IDGenerator>()));
163 using callback = typename slot::callback;
164 using allocator_type = typename std::allocator_traits<Allocator>::template rebind_traits<slot>::allocator_type;
165 using container_type = std::vector<slot, allocator_type>;
166 using value_type = typename container_type::value_type;
167 using reference = typename container_type::reference;
168 using const_reference = typename container_type::const_reference;
169 using size_type = typename container_type::size_type;
170 using pointer = typename container_type::pointer;
171 using iterator = typename container_type::iterator;
172 using const_iterator = typename container_type::const_iterator;
173
174 slot_list() : active(), pending(), last_id(1), is_locked(false) {};
175 slot_list(allocator_type alloc) : active{alloc}, pending{std::move(alloc)}, last_id(1), is_locked(false) {};
176 slot_list(slot_list&&) = default;
177 slot_list(const slot_list&) = default;
178
179 bool try_lock() { lock(); return true; }
180 void lock() { is_locked = true; }
181
182
183 void unlock() {
184 using std::make_move_iterator;
185 using std::sort;
186
187 struct guard_t{
188 flag& locked;
189 container_type& pending;
190 ~guard_t() { locked = false; pending.clear();};
191 } guard { is_locked, pending };
192 // sort offset in case of error
193 auto offset = active_size() - !active_empty();
194 try {
195 active.insert(active.end(), make_move_iterator(pending.begin()), make_move_iterator(pending.end()));
196 } catch (...) {
197 // make sure we are still sorted properly
198 sort(active.begin() + offset, active.end());
199 throw;
200 }
201 }
202
203 bool locked() const noexcept (noexcept(bool(std::declval<FlagType>()))) { return is_locked; }
204
206 using std::move;
207 auto& queue = !is_locked ? active : pending;
208 auto sid = last_id++;
209 queue.emplace_back({ sid, move(value)});
210 return sid;
211 }
212
214 using std::move;
215 auto& queue = !is_locked ? active : pending;
216 auto sid = last_id++;
217 queue.emplace_back({ sid, move(value)});
218 return sid;
219 }
220
221 template <class... Args>
222 slot_id emplace(Args&&... args) {
223 auto& queue = !is_locked ? active : pending;
224 auto sid = last_id++;
225 queue.emplace_back(sid, std::forward<Args>(args)...);
226 return sid;
227 }
228
229 template <class U, class... Args>
230 slot_id emplace_extended(Args&&... args) {
231 auto& queue = !is_locked ? active : pending;
232 auto sid = last_id++;
233 queue.emplace_back(sid, U{std::forward<Args>(args)..., {this->shared_from_this(), sid}});
234 return sid;
235 }
236
237
238
239 inline iterator erase(const_iterator position) { return active.erase(position); }
240 inline iterator erase(const_iterator begin, const_iterator end) { return active.erase(begin, end); }
241
242 inline iterator begin() { return active.begin(); }
243 inline iterator end() { return active.end(); }
244 inline const_iterator cbegin() const { return active.cbegin(); }
245 inline const_iterator cend() const { return active.cend(); }
246 inline size_type active_size() const { return active.size(); }
247 inline reference back() { return active.back(); }
248 inline const_reference cback() const { return active.cback(); }
249 inline size_type pending_size() const { return pending_size(); }
250 inline size_type total_size() const { return active.size() + pending.size(); }
251 inline void clear() { active.clear(); pending.clear(); }
252 inline bool active_empty() const { return active_size() == 0; }
253 inline bool pending_empty() const { return pending_size() == 0; }
254 inline bool empty() const { return total_size() == 0; }
255
257 auto end = active.end();
258 auto slot = find(index, active.begin(), end);
259 if (slot == end) {
260 auto pend = pending.end();
261 slot = find(index, pending.begin(), pend);
262 if (slot == pend) slot = end;
263 }
264 return slot;
265 };
266
268 auto end = active.cend();
269 auto slot = find(index, active.cbegin(), end);
270 if (slot == end) {
271 auto pend = pending.cend();
272 slot = find(index, pending.cbegin(), pend);
273 if (slot == pend) slot = end;
274 }
275 return slot;
276 };
277private:
278 // for internal use only
279 template <class Iterator>
280 static Iterator find(slot_id index, Iterator begin, Iterator end) noexcept{
281 using std::distance;
282 using std::lower_bound;
283 using std::find_if;
284 using std::bind;
285 using std::less_equal;
286
287 begin = find_if(lower_bound(begin, end, index), end, [&] (const_reference slot){
288 return index >= index;
289 });
290 return begin != end && *begin == index ? begin : end;
291 };
292 container_type active;
293 container_type pending;
294 id_generator last_id;
295 flag is_locked;
296};
297
298}
299
300
301#endif
false
Definition: DimVarDefs.h:165
bool operator>=(const OdString &s1, const OdString &s2)
Definition: OdString.h:1376
bool operator<=(const OdString &s1, const OdString &s2)
Definition: OdString.h:1354
bool operator<(const OdString &s1, const OdString &s2)
Definition: OdString.h:1309
bool operator>(const OdString &s1, const OdString &s2)
Definition: OdString.h:1332
_FORCE_INLINE void disconnect()
Definition: slot.h:91
_FORCE_INLINE bool operator==(const basic_slot &other) const
Definition: slot.h:51
_FORCE_INLINE bool connected() const
Definition: slot.h:87
basic_slot(slot_id sid, callback fn)
Definition: slot.h:41
basic_slot(const basic_slot &)=default
std::function< R(Args...)> callback
Definition: slot.h:38
_FORCE_INLINE const callback * operator->() const
Definition: slot.h:103
basic_slot & operator=(basic_slot &&)=default
_FORCE_INLINE bool operator==(const slot_id &other) const
Definition: slot.h:55
_FORCE_INLINE const callback & operator*() const
Definition: slot.h:99
basic_slot(slot_id sid, Arguments &&... args)
Definition: slot.h:44
basic_slot & operator=(const basic_slot &)=default
iterator erase(const_iterator position)
Definition: slot.h:239
basic_slot< T, slot_id > slot
Definition: slot.h:162
bool locked() const noexcept(noexcept(bool(std::declval< FlagType >())))
Definition: slot.h:203
iterator end()
Definition: slot.h:243
bool pending_empty() const
Definition: slot.h:253
const_iterator cbegin() const
Definition: slot.h:244
typename std::allocator_traits< Allocator >::template rebind_traits< slot >::allocator_type allocator_type
Definition: slot.h:164
size_type pending_size() const
Definition: slot.h:249
decltype(slot_id_helper(std::declval< IDGenerator >())) slot_id
Definition: slot.h:161
iterator begin()
Definition: slot.h:242
void lock()
Definition: slot.h:180
size_type active_size() const
Definition: slot.h:246
typename container_type::value_type value_type
Definition: slot.h:166
slot_id push(const value_type &value)
Definition: slot.h:205
void unlock()
Definition: slot.h:183
typename container_type::reference reference
Definition: slot.h:167
reference back()
Definition: slot.h:247
bool active_empty() const
Definition: slot.h:252
slot_list(allocator_type alloc)
Definition: slot.h:175
bool empty() const
Definition: slot.h:254
typename slot::callback callback
Definition: slot.h:163
iterator find(slot_id index) noexcept
Definition: slot.h:256
slot_list(slot_list &&)=default
const_iterator cend() const
Definition: slot.h:245
const_iterator find(slot_id index) const noexcept
Definition: slot.h:267
typename container_type::pointer pointer
Definition: slot.h:170
typename container_type::iterator iterator
Definition: slot.h:171
bool try_lock()
Definition: slot.h:179
slot_list(const slot_list &)=default
slot_id emplace_extended(Args &&... args)
Definition: slot.h:230
void clear()
Definition: slot.h:251
std::vector< slot, allocator_type > container_type
Definition: slot.h:165
typename container_type::const_reference const_reference
Definition: slot.h:168
iterator erase(const_iterator begin, const_iterator end)
Definition: slot.h:240
slot_id push(value_type &&value)
Definition: slot.h:213
const_reference cback() const
Definition: slot.h:248
typename container_type::size_type size_type
Definition: slot.h:169
size_type total_size() const
Definition: slot.h:250
typename container_type::const_iterator const_iterator
Definition: slot.h:172
slot_id emplace(Args &&... args)
Definition: slot.h:222
GLuint index
Definition: gles2_ext.h:265
GLintptr offset
Definition: gles2_ext.h:183
GLsizei const GLfloat * value
Definition: gles2_ext.h:302
_FORCE_INLINE T default_value()
Definition: slot.h:27
_FORCE_INLINE void default_value< void >()
Definition: slot.h:28
#define _FORCE_INLINE
Definition: slot.h:23