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);
241#ifdef ASPOSE_THREADSAFE_DELEGATES
242 std::lock_guard<std::recursive_mutex> lock(m_guard);
245 mutable_list()->push_back(std::move(callback));
255 template <
class R,
class... Args>
256 MulticastDelegate&
connect(std::function<R(Args...)> f)
264 MulticastDelegate&
connect(MulticastDelegate& other)
266 if (other.m_callbacks)
267 for (
auto &callback : *other.m_callbacks)
278 template <
class MemberType,
class ClassType>
279 MulticastDelegate&
connect(MemberType ClassType::* member, ClassType * obj)
281 CODEPORTING_DEBUG_ASSERT( obj !=
nullptr );
282 return connect(
Callback(member, obj));
291 template <
class MemberType,
class ClassType>
294 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
295 return connect(
Callback(member, obj));
303 return connect(std::move(callback));
311#ifdef ASPOSE_THREADSAFE_DELEGATES
312 std::lock_guard<std::recursive_mutex> lock(m_guard);
314 auto callbacks = mutable_list();
315 auto it = std::find_if(callbacks->rbegin(), callbacks->rend(), [&](
const Callback& c){return callback == c;});
316 if (it != callbacks->rend())
317 callbacks->erase(std::next(it).base());
327 template <
class MemberType,
class ClassType>
328 MulticastDelegate&
disconnect(MemberType ClassType::* member, ClassType * obj)
330 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
331 return disconnect(
Callback(member, obj));
340 template <
class MemberType,
class ClassType>
343 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
344 return disconnect(
Callback(member, obj));
352 if (other.m_callbacks)
354#ifdef ASPOSE_THREADSAFE_DELEGATES
355 std::lock(m_guard, o.m_guard);
356 std::lock_guard<std::recursive_mutex> l1(m_guard, std::adopt_lock);
357 std::lock_guard<std::recursive_mutex> l2(o.m_guard, std::adopt_lock);
359 for (
auto &callback : *other.m_callbacks)
360 disconnect(callback);
370 return disconnect(std::move(callback));
378 CODEPORTING_DEBUG_ASSERT(m_callbacks !=
nullptr && other.m_callbacks !=
nullptr);
381 if (m_callbacks == other.m_callbacks)
385 return *m_callbacks == *other.m_callbacks;
400#ifdef ASPOSE_THREADSAFE_DELEGATES
401 std::lock_guard<std::recursive_mutex> lock(m_guard);
403 mutable_list()->clear();
411 if (m_callbacks && !m_callbacks->empty())
414 auto* mutable_callbacks =
const_cast<std::list<Callback>*
>(m_callbacks.get());
416 for (
auto it = mutable_callbacks->begin(); it != mutable_callbacks->end();)
419 it = mutable_callbacks->erase(it);
429 ReturnType
invoke(ArgumentTypes... args)
const
431#ifdef ASPOSE_THREADSAFE_DELEGATES
432 std::lock_guard<std::recursive_mutex> lock(m_guard);
435#ifdef ASPOSE_REMOVE_EMPTY_CALLBACKS
436 remove_empty_callbacks();
438 if (m_callbacks && !m_callbacks->empty())
440 auto callbacks_copy = m_callbacks;
441 auto last = std::prev(callbacks_copy->end());
442 for (
auto it = callbacks_copy->begin(); it != last; ++it)
445 return (*last)(args...);
448 throw NullReferenceException(u
"MulticastDelegate: Object reference not set to an instance of an object.");
456 return invoke(args...);
462 return *static_holder<ThisTypeInfo>();
468 template <
typename CallbackArgumentType>
471 throw System::NotImplementedException(ASPOSE_CURRENT_FUNCTION);
478 throw System::NotImplementedException(ASPOSE_CURRENT_FUNCTION);
481#if defined(ASPOSE_GET_SHARED_MEMBERS) || defined(__DBG_FOR_EACH_MEMBER)
483 std::shared_ptr<Details::HeldVariables> GetHeldVariables()
const
485 auto heldVariables = std::make_shared<Details::HeldVariables>();
487 heldVariables->CopyFrom(m_heldVariables);
489 if (m_callbacks && !m_callbacks->empty())
491 for (
auto it = m_callbacks->cbegin(); it != m_callbacks->cend(); ++it)
493 heldVariables->CopyFrom(it->GetHeldVariables());
497 return heldVariables;
504 std::list<Callback>* mutable_list()
506 CODEPORTING_DEBUG_ASSERT(m_callbacks !=
nullptr);
508 if (m_callbacks.use_count() > 1)
509 m_callbacks = std::make_shared<std::list<Callback>>(*m_callbacks);
511 return const_cast<std::list<Callback>*
>(m_callbacks.get());
515 mutable std::shared_ptr<const std::list<Callback>> m_callbacks;
517#ifdef ASPOSE_THREADSAFE_DELEGATES
519 mutable std::recursive_mutex m_guard;
527 template <
typename T>
528 MulticastDelegate<T>
operator+(MulticastDelegate<T> lhv, MulticastDelegate<T> rhv)
530 return lhv.connect(rhv);
537 template <
typename T>
538 MulticastDelegate<T>
operator-(MulticastDelegate<T> lhv, MulticastDelegate<T> rhv)
540 return lhv.disconnect(rhv);
545 template <
typename TTo>
struct CastResult;
549 template <
typename T>
550 struct ASPOSECPP_SHARED_CLASS CastResult<MulticastDelegate<T>>
553 typedef MulticastDelegate<T> type;
557 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:264
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:341
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:231
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:454
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:350
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:292
MulticastDelegate & disconnect(Callback callback)
Removes the specified delegate from the delegate collection.
Definition: multicast_delegate.h:309
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:328
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:279
ReturnType EndInvoke(const SharedPtr< IAsyncResult > &)
NOT IMPLEMENTED.
Definition: multicast_delegate.h:476
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:429
static const TypeInfo & Type()
Returns a reference to the TypeInfo object representing the MulticastDelegate class type information.
Definition: multicast_delegate.h:460
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:256
MulticastDelegate & disconnect_all_slots()
Removes all delegates from the delegate collection.
Definition: multicast_delegate.h:398
~MulticastDelegate()
Destructor.
Definition: multicast_delegate.h:110
MulticastDelegate & connect(Callback callback)
Adds the specified delegate to the collection.
Definition: multicast_delegate.h:239
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
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:409
bool operator==(const std::nullptr_t &) const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:224
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:469
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:494
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:157
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:151
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