3#ifndef _aspose_system_multicast_delegate_h_
4#define _aspose_system_multicast_delegate_h_
9#include "system/details/delegate_holding_variables.h"
16#define ASPOSE_REMOVE_EMPTY_CALLBACKS
18#ifdef ASPOSE_THREADSAFE_DELEGATES
27 template<
class Unused>
28 class MulticastDelegate;
31 using AsyncCallback = MulticastDelegate<void(SharedPtr<IAsyncResult>)>;
93 template <
class ReturnType,
class... ArgumentTypes>
94 class ASPOSECPP_SHARED_CLASS MulticastDelegate<ReturnType(ArgumentTypes...)> :
public Details::DelegateHoldingVariables
101 using Callback = Delegate<ReturnType(ArgumentTypes...)>;
106 m_callbacks = std::make_shared<const std::list<Callback>>();
120 : Details::DelegateHoldingVariables(o)
121 , m_callbacks(o.m_callbacks)
126 MulticastDelegate&
operator=(
const MulticastDelegate& o)
131#ifdef ASPOSE_THREADSAFE_DELEGATES
132 std::lock(m_guard, o.m_guard);
133 std::lock_guard<std::recursive_mutex> l1( m_guard, std::adopt_lock );
134 std::lock_guard<std::recursive_mutex> l2(o.m_guard, std::adopt_lock);
136 m_callbacks = o.m_callbacks;
137 Details::DelegateHoldingVariables::operator = (o);
145 : Details::DelegateHoldingVariables(o)
146 , m_callbacks(std::move(o.m_callbacks))
151 MulticastDelegate&
operator=(MulticastDelegate&& o)
noexcept
153 m_callbacks = std::move(o.m_callbacks);
154 Details::DelegateHoldingVariables::operator = (std::move(o));
162 mutable_list()->push_back(std::move(initial));
168 template <class T, typename = decltype(Callback(std::declval<T>()))>
183#ifdef ASPOSE_THREADSAFE_DELEGATES
184 std::lock_guard<std::recursive_mutex> lock(m_guard);
187#ifdef ASPOSE_REMOVE_EMPTY_CALLBACKS
191 for (
auto it = m_callbacks->begin(); it != m_callbacks->end(); ++it)
196 return m_callbacks->empty();
216#ifdef ASPOSE_THREADSAFE_DELEGATES
217 std::lock_guard<std::recursive_mutex> lock(m_guard);
222 bool Equals(
const MulticastDelegate& other)
224 return *
this == other;
246#ifdef ASPOSE_THREADSAFE_DELEGATES
247 std::lock_guard<std::recursive_mutex> lock(m_guard);
250 mutable_list()->push_back(std::move(callback));
260 template <
class R,
class... Args>
261 MulticastDelegate&
connect(std::function<R(Args...)> f)
269 MulticastDelegate&
connect(MulticastDelegate& other)
271 if (other.m_callbacks)
272 for (
auto &callback : *other.m_callbacks)
283 template <
class MemberType,
class ClassType>
284 MulticastDelegate&
connect(MemberType ClassType::* member, ClassType * obj)
286 CODEPORTING_DEBUG_ASSERT( obj !=
nullptr );
287 return connect(
Callback(member, obj));
296 template <
class MemberType,
class ClassType>
299 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
300 return connect(
Callback(member, obj));
308 return connect(std::move(callback));
316#ifdef ASPOSE_THREADSAFE_DELEGATES
317 std::lock_guard<std::recursive_mutex> lock(m_guard);
319 auto callbacks = mutable_list();
320 auto it = std::find_if(callbacks->rbegin(), callbacks->rend(), [&](
const Callback& c){return callback == c;});
321 if (it != callbacks->rend())
322 callbacks->erase(std::next(it).base());
332 template <
class MemberType,
class ClassType>
333 MulticastDelegate&
disconnect(MemberType ClassType::* member, ClassType * obj)
335 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
336 return disconnect(
Callback(member, obj));
345 template <
class MemberType,
class ClassType>
348 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
349 return disconnect(
Callback(member, obj));
357 if (other.m_callbacks)
359#ifdef ASPOSE_THREADSAFE_DELEGATES
360 std::lock(m_guard, o.m_guard);
361 std::lock_guard<std::recursive_mutex> l1(m_guard, std::adopt_lock);
362 std::lock_guard<std::recursive_mutex> l2(o.m_guard, std::adopt_lock);
364 for (
auto &callback : *other.m_callbacks)
365 disconnect(callback);
375 return disconnect(std::move(callback));
383 CODEPORTING_DEBUG_ASSERT(m_callbacks !=
nullptr && other.m_callbacks !=
nullptr);
386 if (m_callbacks == other.m_callbacks)
390 return *m_callbacks == *other.m_callbacks;
405#ifdef ASPOSE_THREADSAFE_DELEGATES
406 std::lock_guard<std::recursive_mutex> lock(m_guard);
408 mutable_list()->clear();
416 if (m_callbacks && !m_callbacks->empty())
419 auto* mutable_callbacks =
const_cast<std::list<Callback>*
>(m_callbacks.get());
421 for (
auto it = mutable_callbacks->begin(); it != mutable_callbacks->end();)
424 it = mutable_callbacks->erase(it);
434 ReturnType
invoke(ArgumentTypes... args)
const
436#ifdef ASPOSE_THREADSAFE_DELEGATES
437 std::lock_guard<std::recursive_mutex> lock(m_guard);
440#ifdef ASPOSE_REMOVE_EMPTY_CALLBACKS
441 remove_empty_callbacks();
443 if (m_callbacks && !m_callbacks->empty())
445 auto callbacks_copy = m_callbacks;
446 auto last = std::prev(callbacks_copy->end());
447 for (
auto it = callbacks_copy->begin(); it != last; ++it)
450 return (*last)(args...);
453 throw NullReferenceException(u
"MulticastDelegate: Object reference not set to an instance of an object.");
461 return invoke(args...);
467 return *static_holder<ThisTypeInfo>();
473 template <
typename CallbackArgumentType>
476 throw System::NotImplementedException(ASPOSE_CURRENT_FUNCTION);
483 throw System::NotImplementedException(ASPOSE_CURRENT_FUNCTION);
486#if defined(ASPOSE_GET_SHARED_MEMBERS) || defined(__DBG_FOR_EACH_MEMBER)
488 std::shared_ptr<Details::HeldVariables> GetHeldVariables()
const
490 auto heldVariables = std::make_shared<Details::HeldVariables>();
492 heldVariables->CopyFrom(m_heldVariables);
494 if (m_callbacks && !m_callbacks->empty())
496 for (
auto it = m_callbacks->cbegin(); it != m_callbacks->cend(); ++it)
498 heldVariables->CopyFrom(it->GetHeldVariables());
502 return heldVariables;
509 std::list<Callback>* mutable_list()
511 CODEPORTING_DEBUG_ASSERT(m_callbacks !=
nullptr);
513 if (m_callbacks.use_count() > 1)
514 m_callbacks = std::make_shared<std::list<Callback>>(*m_callbacks);
516 return const_cast<std::list<Callback>*
>(m_callbacks.get());
520 mutable std::shared_ptr<const std::list<Callback>> m_callbacks;
522#ifdef ASPOSE_THREADSAFE_DELEGATES
524 mutable std::recursive_mutex m_guard;
532 template <
typename T>
533 MulticastDelegate<T>
operator+(MulticastDelegate<T> lhv, MulticastDelegate<T> rhv)
535 return lhv.connect(rhv);
542 template <
typename T>
543 MulticastDelegate<T>
operator-(MulticastDelegate<T> lhv, MulticastDelegate<T> rhv)
545 return lhv.disconnect(rhv);
550 template <
typename TTo>
struct CastResult;
554 template <
typename T>
555 struct ASPOSECPP_SHARED_CLASS CastResult<MulticastDelegate<T>>
558 typedef MulticastDelegate<T> type;
562 struct IsBoxable<MulticastDelegate<
T>> : std::true_type
Represents a pointer to a function, method or a function object. This type should be allocated on sta...
Definition: delegate.h:56
MulticastDelegate & connect(MulticastDelegate &other)
Adds the specified MulticastDelegate object to the delegate collection.
Definition: multicast_delegate.h:269
MulticastDelegate & disconnect(MemberType ClassType::*member, const SharedPtr< ClassType > &obj)
Removes the specified non-static method of the specified object from the delegate collection.
Definition: multicast_delegate.h:346
MulticastDelegate(MulticastDelegate &&o) noexcept
Moving constructor.
Definition: multicast_delegate.h:144
bool operator!=(const std::nullptr_t &) const
Determines whether the delegate collection is not empty.
Definition: multicast_delegate.h:236
bool empty() const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:181
ReturnType operator()(ArgumentTypes... args) const
Invokes all delegates currently present in the delegates collection. Delegates are invoked in the sam...
Definition: multicast_delegate.h:459
MulticastDelegate & operator=(const MulticastDelegate &o)
Assigns the collection of delegates represented by the specified object to the current object....
Definition: multicast_delegate.h:126
bool IsNull() const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:202
MulticastDelegate & disconnect(MulticastDelegate &other)
Removes the specified MulticastDelegate object from the delegate collection.
Definition: multicast_delegate.h:355
MulticastDelegate & operator=(MulticastDelegate &&o) noexcept
Moving assignment operator.
Definition: multicast_delegate.h:151
MulticastDelegate & connect(MemberType ClassType::*member, const SharedPtr< ClassType > &obj)
Adds the specified non-static method of the specified object to the delegate collection.
Definition: multicast_delegate.h:297
MulticastDelegate & disconnect(Callback callback)
Removes the specified delegate from the delegate collection.
Definition: multicast_delegate.h:314
MulticastDelegate & disconnect(MemberType ClassType::*member, ClassType *obj)
Removes the specified non-static method of the specified object from the delegate collection.
Definition: multicast_delegate.h:333
MulticastDelegate(const MulticastDelegate &o)
Performs a shallow copy of the delegate collection.
Definition: multicast_delegate.h:119
MulticastDelegate & connect(MemberType ClassType::*member, ClassType *obj)
Adds the specified non-static method of the specified object to the delegate collection.
Definition: multicast_delegate.h:284
ReturnType EndInvoke(const SharedPtr< IAsyncResult > &)
NOT IMPLEMENTED.
Definition: multicast_delegate.h:481
MulticastDelegate(Callback &&initial)
Constructs an instance and puts the specified delegate to the delegates collection.
Definition: multicast_delegate.h:160
String ToString() const
Definition: multicast_delegate.h:209
MulticastDelegate(T arg)
Constructs an instance and puts the specified value to the delegates collection.
Definition: multicast_delegate.h:169
ReturnType invoke(ArgumentTypes... args) const
Invokes all delegates currently present in the delegates collection. Delegates are invoked in the sam...
Definition: multicast_delegate.h:434
static const TypeInfo & Type()
Returns a reference to the TypeInfo object representing the MulticastDelegate class type information.
Definition: multicast_delegate.h:465
MulticastDelegate & connect(std::function< R(Args...)> f)
Adds the specified function object to the delegate collection. The function object is converted to th...
Definition: multicast_delegate.h:261
MulticastDelegate & disconnect_all_slots()
Removes all delegates from the delegate collection.
Definition: multicast_delegate.h:403
~MulticastDelegate()
Destructor.
Definition: multicast_delegate.h:110
MulticastDelegate & connect(Callback callback)
Adds the specified delegate to the collection.
Definition: multicast_delegate.h:244
MulticastDelegate(std::function< ReturnType(ArgumentTypes...)> arg)
Constructs an instance and puts the specified value to the delegates collection.
Definition: multicast_delegate.h:175
const TypeInfo & GetType() const
Definition: multicast_delegate.h:204
MulticastDelegate()
Constructs an empty collection.
Definition: multicast_delegate.h:104
bool Equals(const MulticastDelegate &other)
Definition: multicast_delegate.h:222
int GetHashCode() const
Definition: multicast_delegate.h:214
void remove_empty_callbacks() const
Cleans out contained callbacks that are empty (not actually calling anything).
Definition: multicast_delegate.h:414
bool operator==(const std::nullptr_t &) const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:229
MulticastDelegate(std::nullptr_t)
Equivalent to defalt constructor.
Definition: multicast_delegate.h:114
SharedPtr< IAsyncResult > BeginInvoke(ArgumentTypes... args, const AsyncCallback &member, const CallbackArgumentType &obj)
NOT IMPLEMENTED.
Definition: multicast_delegate.h:474
Pointer class to wrap types being allocated on heap. Use it to manage memory for classes inheriting O...
Definition: smart_ptr.h:180
String class used across the library. Is a substitute for C# System.String when translating code....
Definition: string.h:122
String ToString() const
Wrapper for handling String class in contexts where ToString() is being called on value type objects.
Definition: string.h:504
Represents a particular type and provides information about it.
Definition: type_info.h:109
Definition: db_command.h:9
System::MulticastDelegate< void(SharedPtr< IAsyncResult >)> AsyncCallback
A delegate type that represents a method to be called when asynchronous operation completes.
Definition: async_callback.h:13
bool operator!=(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:156
Decimal operator+(const T &x, const Decimal &d)
Returns a new instance of Decimal class that represents a value that is a sum of the specified value ...
Definition: decimal.h:542
auto operator-(DayOfWeek a, DayOfWeek b)
Calculates the number of days between two days of week.
Definition: day_of_week.h:25
std::enable_if< std::is_scalar< T >::value, int >::type GetHashCode(const T &obj)
Returns a hash code for the specified scalar value.
Definition: get_hash_code.h:21
bool operator==(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:150
Represents a pointer to TypeInfo object that contains information about MulticastDelegate class.
Definition: multicast_delegate.h:35
MulticastDelegateTypeInfo()
Constructs an instance of MulticastDelegateTypeInfo class.
Definition: multicast_delegate.h:37
Wrapper for a pointer to an instance of TypeInfo class. This type should be allocated on stack and pa...
Definition: type_info.h:72