27 template<
typename P,
typename T,
template<
typename>
typename F>
class TEvent;
61 weakDisconnector = std::move(other.weakDisconnector);
82 template<
typename P,
typename T,
template<
typename>
typename F>
friend class TEvent;
121 reset(std::move(other.connection));
128 : connection(std::forward<WeakEventConnection>(c)) {}
139 reset(std::forward<WeakEventConnection>(c));
149 connection = std::move(c);
163 [[nodiscard]]
bool connected() const noexcept {
return connection.connected(); }
192 static void yield() noexcept { std::this_thread::yield(); }
216 static constexpr void yield() noexcept {}
240 using ResultType =
decltype(std::declval<F>()(std::declval<T>(), std::declval<typename S::SlotType::result_type>()));
276 ResultType operator()(A&&... args)
const {
return event.triggerWithAccumulator(init, func, std::forward<A>(args)...); }
311 template<
typename P,
typename R,
template<
typename>
typename F,
typename...
A>
class TEvent<
P,
R(
A...),
F>
final {
341 slots.push_back(std::forward<T>(slot));
342 const std::size_t index = slots.size() - 1;
343 if(sharedDisconnector ==
nullptr) {
344 disconnector = Disconnector{
this};
352 return connect([target, ptr](
A&&... args) {
return (target->*ptr)(std::forward<A>(args)...); });
366 for(
const SlotType& slot : copySlots()) {
408 static_assert(!std::is_same<R, void>::value,
409 "Unable to accumulate slot return values "
410 "with 'void' as return type.");
411 return {*
this, init, op};
422 template<
typename C> [[nodiscard]]
C aggregate(A
const&... args)
const {
423 static_assert(!std::is_same<R, void>::value,
424 "Unable to aggregate slot return values "
425 "with 'void' as return type.");
427 auto iterator = std::back_inserter(container);
428 for(
const SlotType& slot : copySlots()) {
430 (*iterator) = slot(args...);
444 [[nodiscard]]
bool empty() const noexcept {
return getSlotCount() == 0; }
452 invalidateDisconnector();
484 sharedDisconnector.reset();
485 while(weak.lock() !=
nullptr) {
488 ThreadPolicy::yield();
505 template<
typename T,
typename O>
507 for(
const SlotType& slot : copySlots()) {
509 value = func(value, slot(args...));
523 assert(slots.size() > index);
524 if(slots[index] !=
nullptr) {
528 while(!slots.empty() && !slots.back()) {
551 ptr->disconnect(index);
579 if(
const auto ptr = weakDisconnector.lock()) {
582 weakDisconnector.reset();
589 template<
typename P,
template<
typename>
typename F>
auto operator co_await(
TEvent<
P,
void(),
F>& event)
noexcept {
600 explicit constexpr Awaiter(
TEvent<
P,
void(),
F>& event) noexcept : mEvent(event) {}
604 ~Awaiter()
noexcept { mConnection.
disconnect(); }
607 [[nodiscard]]
static bool await_ready() {
613 [[nodiscard]]
bool await_suspend(
615 mConnection = mEvent.connect([
this, coroutineHandle]()
mutable {
616 coroutineHandle.resume();
624 static void await_resume() {}
636 template<
typename P,
template<
typename>
typename F,
typename...
A>
auto operator co_await(
TEvent<
P,
void(
A...),
F>& event)
noexcept {
640 using ValueType =
Tuple<
A...>;
653 explicit constexpr Awaiter(
TEvent<
P,
void(
A...),
F>& event) noexcept : mEvent(event) {}
657 ~Awaiter()
noexcept { mConnection.
disconnect(); }
660 [[nodiscard]]
static bool await_ready() {
666 [[nodiscard]]
bool await_suspend(
668 mConnection = mEvent.connect([
this, coroutineHandle](
A... args)
mutable {
669 ValueType value = std::tie(args...);
671 coroutineHandle.resume();
672 mConnection.disconnect();
679 [[nodiscard]]
decltype(
auto) await_resume() {
680 if constexpr(
sizeof...(A) == 1) {
681 return std::get<0>(*mValue);
Event accumulator class template.
Definition Event.hpp:237
T init
Initial value of the accumulate algorithm.
Definition Event.hpp:283
EventAccumulator(S const &event, T init, F func)
Construct a EventAccumulator as a proxy to a given event.
Definition Event.hpp:262
ResultType operator()(A &&... args) const
Function call operator.
Definition Event.hpp:276
S const & event
Reference to the underlying event to proxy.
Definition Event.hpp:280
F func
Accumulator function.
Definition Event.hpp:286
decltype(std::declval< F >()(std::declval< T >(), std::declval< typename S::SlotType::result_type >())) ResultType
Result type when calling the accumulating function operator.
Definition Event.hpp:240
Scoped connection class.
Definition Event.hpp:104
WeakEventConnection release() noexcept
Release the underlying connection, without disconnecting it.
Definition Event.hpp:154
~EventConnection()
destructor
Definition Event.hpp:131
EventConnection & operator=(WeakEventConnection &&c)
Assignment operator moving a new connection into the instance.
Definition Event.hpp:138
bool connected() const noexcept
Definition Event.hpp:163
WeakEventConnection connection
Underlying connection object.
Definition Event.hpp:175
EventConnection(WeakEventConnection &&c) noexcept
Construct a scoped connection from a connection object.
Definition Event.hpp:127
void disconnect()
Disconnect the slot from the connection.
Definition Event.hpp:171
void reset(WeakEventConnection &&c={})
Reset the underlying connection to another connection.
Definition Event.hpp:147
EventConnection() noexcept=default
Scoped are default constructible.
EventConnection & operator=(EventConnection &&other) noexcept
Move assign operator.
Definition Event.hpp:120
SPtr< EventDisconnector > sharedDisconnector
Shared pointer to the disconnector.
Definition Event.hpp:574
typename Vector< SlotType >::size_type SizeType
Type that is used for counting the slots connected to this event.
Definition Event.hpp:329
EventAccumulator< TEvent, T, O, A... >::ResultType triggerWithAccumulator(T value, O &func, A const &... args) const
Implementation of the event accumulator function call.
Definition Event.hpp:506
EventAccumulator< TEvent, T, O, A... > accumulate(T init, O op) const
Construct a accumulator proxy object for the event.
Definition Event.hpp:407
C aggregate(A const &... args) const
Trigger the event, calling the slots and aggregate all the slot return values into a container.
Definition Event.hpp:422
WeakEventConnection connect(T &&slot)
Connect a new slot to the event.
Definition Event.hpp:339
Vector< SlotType > slots
Vector of all connected slots.
Definition Event.hpp:563
Vector< SlotType > copySlots() const
Retrieve a copy of the current slots.
Definition Event.hpp:499
TEvent(TEvent const &)=delete
events are not copy constructible
void disconnectAllSlots()
Disconnects all slots.
Definition Event.hpp:448
void invalidateDisconnector() noexcept
Invalidate the internal disconnector object in a way that is safe according to the current thread pol...
Definition Event.hpp:472
MutexType mutex
Mutex to synchronize access to the slot vector.
Definition Event.hpp:560
SizeType getSlotCount() const noexcept
Count the number of slots connected to this event.
Definition Event.hpp:438
SizeType slotCount
Number of connected slots.
Definition Event.hpp:566
void operator()(A const &... args) const
Function call operator.
Definition Event.hpp:365
friend class EventAccumulator
Definition Event.hpp:456
typename ThreadPolicy::MutexLockType MutexLockType
Type of mutex lock, provided by threading policy.
Definition Event.hpp:464
typename ThreadPolicy::MutexType MutexType
Type of mutex, provided by threading policy.
Definition Event.hpp:461
Disconnector disconnector
Disconnector operation, used for executing disconnection in a type erased manner.
Definition Event.hpp:570
~TEvent()
Definition Event.hpp:323
F< R(A...)> SlotType
Type that will be used to store the slots for this event type.
Definition Event.hpp:326
void disconnect(std::size_t index)
Implementation of the disconnection operation.
Definition Event.hpp:521
WeakEventConnection connect(T *target, Func &&ptr)
Definition Event.hpp:351
TEvent & operator=(TEvent const &)=delete
events are not copy assignable
TEvent() noexcept
events are default constructible
Definition Event.hpp:320
P ThreadPolicy
Thread policy currently in use.
Definition Event.hpp:458
bool empty() const noexcept
Determine if the event is empty, i.e.
Definition Event.hpp:444
Base template for the event class.
Definition Event.hpp:27
Tuple is a fixed-size collection of heterogeneous values.
Definition Tuple.hpp:15
The class UniqueLock is a general-purpose mutex ownership wrapper allowing deferred locking,...
Definition Threading.hpp:270
Connection class.
Definition Event.hpp:44
WPtr< EventDisconnector > weakDisconnector
Weak pointer to the current disconnector functor.
Definition Event.hpp:94
bool connected() const noexcept
Definition Event.hpp:68
WeakEventConnection() noexcept
Default constructor.
Definition Event.hpp:47
std::size_t index
Slot index of the connected slot.
Definition Event.hpp:96
WeakEventConnection & operator=(WeakEventConnection const &)=delete
WeakEventConnection(WeakEventConnection &&other) noexcept
Move constructor.
Definition Event.hpp:56
WeakEventConnection(WeakEventConnection const &)=delete
void disconnect()
Disconnect the slot from the connection.
Definition Event.hpp:578
WeakEventConnection & operator=(WeakEventConnection &&other) noexcept
Move assign operator.
Definition Event.hpp:60
WeakEventConnection(SPtr< EventDisconnector > const &sharedDisconnector, const std::size_t index)
Create a connection.
Definition Event.hpp:91
Definition Application.hpp:19
decltype(auto) lock(Func &&func, Ts &... objects)
Definition Threading.hpp:667
std::shared_ptr< T > SPtr
SPtr is a smart pointer that retains shared ownership of an object through a pointer.
Definition SmartPtr.hpp:37
std::coroutine_handle< T > CoroutineHandle
A type alias to the C++ standard library coroutine handle.
Definition Coroutine.hpp:26
std::vector< T, ScopedAllocatorAdaptor< StdAllocator< T, RawAllocator > > > Vector
Vector is a sequence container that encapsulates dynamic size arrays.
Definition Vector.hpp:17
std::mutex Mutex
The Mutex class is a synchronization primitive that can be used to protect shared data from being sim...
Definition Threading.hpp:73
std::weak_ptr< T > WPtr
WPtr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by SP...
Definition SmartPtr.hpp:42
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Interface for type erasure when disconnecting slots.
Definition Event.hpp:30
virtual void operator()(std::size_t index) const =0
virtual ~EventDisconnector() noexcept=default
Policy for multi threaded use of events.
Definition Event.hpp:186
static void yield() noexcept
Function that yields the current thread, allowing the OS to reschedule.
Definition Event.hpp:192
Mutex MutexType
Definition Event.hpp:187
Dummy lock type, that doesn't do any locking.
Definition Event.hpp:208
constexpr MutexLockType(const MutexType &) noexcept
A lock type must be constructible from a mutex type from the same thread policy.
Definition Event.hpp:211
Dummy mutex type that doesn't do anything.
Definition Event.hpp:205
Policy for single threaded use of events.
Definition Event.hpp:203
static constexpr void yield() noexcept
Dummy implementation of thread yielding, that doesn't do any actual yielding.
Definition Event.hpp:216
Disconnector(TEvent< P, R(A...), F > *ptr) noexcept
Create a disconnector that works with a given event instance.
Definition Event.hpp:546
Disconnector() noexcept
Default constructor, resulting in a no-op disconnector.
Definition Event.hpp:540
void operator()(const std::size_t index) const override
Definition Event.hpp:549
TEvent< P, R(A...), F > * ptr
Pointer to the current event.
Definition Event.hpp:556