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...)>;
108 m_callbacks = std::make_shared<const std::list<Callback>>();
122 : Details::DelegateHoldingVariables(o)
123 , m_callbacks(o.m_callbacks)
128 MulticastDelegate&
operator=(
const MulticastDelegate& o)
133#ifdef ASPOSE_THREADSAFE_DELEGATES
134 std::lock(m_guard, o.m_guard);
135 std::lock_guard<std::recursive_mutex> l1( m_guard, std::adopt_lock );
136 std::lock_guard<std::recursive_mutex> l2(o.m_guard, std::adopt_lock);
138 m_callbacks = o.m_callbacks;
139 Details::DelegateHoldingVariables::operator = (o);
147 : Details::DelegateHoldingVariables(o)
148 , m_callbacks(std::move(o.m_callbacks))
153 MulticastDelegate&
operator=(MulticastDelegate&& o)
noexcept
155 m_callbacks = std::move(o.m_callbacks);
156 Details::DelegateHoldingVariables::operator = (std::move(o));
164 mutable_list()->push_back(std::move(initial));
170 template <class T, typename = decltype(Callback(std::declval<T>()))>
185#ifdef ASPOSE_THREADSAFE_DELEGATES
186 std::lock_guard<std::recursive_mutex> lock(m_guard);
189#ifdef ASPOSE_REMOVE_EMPTY_CALLBACKS
193 for (
auto it = m_callbacks->begin(); it != m_callbacks->end(); ++it)
198 return m_callbacks->empty();
218#ifdef ASPOSE_THREADSAFE_DELEGATES
219 std::lock_guard<std::recursive_mutex> lock(m_guard);
224 bool Equals(
const MulticastDelegate& other)
226 return *
this == other;
248#ifdef ASPOSE_THREADSAFE_DELEGATES
249 std::lock_guard<std::recursive_mutex> lock(m_guard);
252 mutable_list()->push_back(std::move(callback));
262 template <
class R,
class... Args>
263 MulticastDelegate&
connect(std::function<R(Args...)> f)
271 MulticastDelegate&
connect(MulticastDelegate& other)
273 if (other.m_callbacks)
274 for (
auto &callback : *other.m_callbacks)
285 template <
class MemberType,
class ClassType>
286 MulticastDelegate&
connect(MemberType ClassType::* member, ClassType * obj)
288 CODEPORTING_DEBUG_ASSERT( obj !=
nullptr );
289 return connect(
Callback(member, obj));
298 template <
class MemberType,
class ClassType>
301 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
302 return connect(
Callback(member, obj));
310 return connect(std::move(callback));
318#ifdef ASPOSE_THREADSAFE_DELEGATES
319 std::lock_guard<std::recursive_mutex> lock(m_guard);
321 auto callbacks = mutable_list();
322 auto it = std::find_if(callbacks->rbegin(), callbacks->rend(), [&](
const Callback& c){return callback == c;});
323 if (it != callbacks->rend())
324 callbacks->erase(std::next(it).base());
334 template <
class MemberType,
class ClassType>
335 MulticastDelegate&
disconnect(MemberType ClassType::* member, ClassType * obj)
337 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
338 return disconnect(
Callback(member, obj));
347 template <
class MemberType,
class ClassType>
350 CODEPORTING_DEBUG_ASSERT(obj !=
nullptr);
351 return disconnect(
Callback(member, obj));
359 if (other.m_callbacks)
361#ifdef ASPOSE_THREADSAFE_DELEGATES
362 std::lock(m_guard, o.m_guard);
363 std::lock_guard<std::recursive_mutex> l1(m_guard, std::adopt_lock);
364 std::lock_guard<std::recursive_mutex> l2(o.m_guard, std::adopt_lock);
366 for (
auto &callback : *other.m_callbacks)
367 disconnect(callback);
377 return disconnect(std::move(callback));
385 CODEPORTING_DEBUG_ASSERT(m_callbacks !=
nullptr && other.m_callbacks !=
nullptr);
388 if (m_callbacks == other.m_callbacks)
392 return *m_callbacks == *other.m_callbacks;
407#ifdef ASPOSE_THREADSAFE_DELEGATES
408 std::lock_guard<std::recursive_mutex> lock(m_guard);
410 mutable_list()->clear();
418 if (m_callbacks && !m_callbacks->empty())
421 auto* mutable_callbacks =
const_cast<std::list<Callback>*
>(m_callbacks.get());
423 for (
auto it = mutable_callbacks->begin(); it != mutable_callbacks->end();)
426 it = mutable_callbacks->erase(it);
436 ReturnType
invoke(ArgumentTypes... args)
const
438#ifdef ASPOSE_THREADSAFE_DELEGATES
439 std::lock_guard<std::recursive_mutex> lock(m_guard);
442#ifdef ASPOSE_REMOVE_EMPTY_CALLBACKS
443 remove_empty_callbacks();
445 if (m_callbacks && !m_callbacks->empty())
447 auto callbacks_copy = m_callbacks;
448 auto last = std::prev(callbacks_copy->end());
449 for (
auto it = callbacks_copy->begin(); it != last; ++it)
452 return (*last)(args...);
455 throw NullReferenceException(u
"MulticastDelegate: Object reference not set to an instance of an object.");
463 return invoke(args...);
469 return *static_holder<ThisTypeInfo>();
475 template <
typename CallbackArgumentType>
478 throw System::NotImplementedException(ASPOSE_CURRENT_FUNCTION);
485 throw System::NotImplementedException(ASPOSE_CURRENT_FUNCTION);
488#if defined(ASPOSE_GET_SHARED_MEMBERS) || defined(__DBG_FOR_EACH_MEMBER)
490 std::shared_ptr<Details::HeldVariables> GetHeldVariables()
const
492 auto heldVariables = std::make_shared<Details::HeldVariables>();
494 heldVariables->CopyFrom(m_heldVariables);
496 if (m_callbacks && !m_callbacks->empty())
498 for (
auto it = m_callbacks->cbegin(); it != m_callbacks->cend(); ++it)
500 heldVariables->CopyFrom(it->GetHeldVariables());
504 return heldVariables;
511 std::list<Callback>* mutable_list()
513 CODEPORTING_DEBUG_ASSERT(m_callbacks !=
nullptr);
515 if (m_callbacks.use_count() > 1)
516 m_callbacks = std::make_shared<std::list<Callback>>(*m_callbacks);
518 return const_cast<std::list<Callback>*
>(m_callbacks.get());
522 mutable std::shared_ptr<const std::list<Callback>> m_callbacks;
524#ifdef ASPOSE_THREADSAFE_DELEGATES
526 mutable std::recursive_mutex m_guard;
534 template <
typename T>
535 MulticastDelegate<T>
operator+(MulticastDelegate<T> lhv, MulticastDelegate<T> rhv)
537 return lhv.connect(rhv);
544 template <
typename T>
545 MulticastDelegate<T>
operator-(MulticastDelegate<T> lhv, MulticastDelegate<T> rhv)
547 return lhv.disconnect(rhv);
552 template <
typename TTo>
struct CastResult;
556 template <
typename T>
557 struct ASPOSECPP_SHARED_CLASS CastResult<MulticastDelegate<T>>
560 typedef MulticastDelegate<T> type;
564 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:271
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:348
MulticastDelegate(MulticastDelegate &&o) noexcept
Moving constructor.
Definition: multicast_delegate.h:146
bool operator!=(const std::nullptr_t &) const
Determines whether the delegate collection is not empty.
Definition: multicast_delegate.h:238
bool empty() const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:183
ReturnType operator()(ArgumentTypes... args) const
Invokes all delegates currently present in the delegates collection. Delegates are invoked in the sam...
Definition: multicast_delegate.h:461
MulticastDelegate & operator=(const MulticastDelegate &o)
Assigns the collection of delegates represented by the specified object to the current object....
Definition: multicast_delegate.h:128
bool IsNull() const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:204
MulticastDelegate & disconnect(MulticastDelegate &other)
Removes the specified MulticastDelegate object from the delegate collection.
Definition: multicast_delegate.h:357
MulticastDelegate & operator=(MulticastDelegate &&o) noexcept
Moving assignment operator.
Definition: multicast_delegate.h:153
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:299
MulticastDelegate & disconnect(Callback callback)
Removes the specified delegate from the delegate collection.
Definition: multicast_delegate.h:316
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:335
MulticastDelegate(const MulticastDelegate &o)
Performs a shallow copy of the delegate collection.
Definition: multicast_delegate.h:121
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:286
ReturnType EndInvoke(const SharedPtr< IAsyncResult > &)
NOT IMPLEMENTED.
Definition: multicast_delegate.h:483
MulticastDelegate(Callback &&initial)
Constructs an instance and puts the specified delegate to the delegates collection.
Definition: multicast_delegate.h:162
String ToString() const
Definition: multicast_delegate.h:211
MulticastDelegate(T arg)
Constructs an instance and puts the specified value to the delegates collection.
Definition: multicast_delegate.h:171
ReturnType invoke(ArgumentTypes... args) const
Invokes all delegates currently present in the delegates collection. Delegates are invoked in the sam...
Definition: multicast_delegate.h:436
static const TypeInfo & Type()
Returns a reference to the TypeInfo object representing the MulticastDelegate class type information.
Definition: multicast_delegate.h:467
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:263
MulticastDelegate & disconnect_all_slots()
Removes all delegates from the delegate collection.
Definition: multicast_delegate.h:405
~MulticastDelegate()
Destructor.
Definition: multicast_delegate.h:112
MulticastDelegate & connect(Callback callback)
Adds the specified delegate to the collection.
Definition: multicast_delegate.h:246
MulticastDelegate(std::function< ReturnType(ArgumentTypes...)> arg)
Constructs an instance and puts the specified value to the delegates collection.
Definition: multicast_delegate.h:177
const TypeInfo & GetType() const
Definition: multicast_delegate.h:206
MulticastDelegate()
Constructs an empty collection.
Definition: multicast_delegate.h:106
bool Equals(const MulticastDelegate &other)
Definition: multicast_delegate.h:224
int GetHashCode() const
Definition: multicast_delegate.h:216
void remove_empty_callbacks() const
Cleans out contained callbacks that are empty (not actually calling anything).
Definition: multicast_delegate.h:416
bool operator==(const std::nullptr_t &) const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:231
MulticastDelegate(std::nullptr_t)
Equivalent to defalt constructor.
Definition: multicast_delegate.h:116
ReturnType(ArgumentTypes...) Function
The type of the function related to delegate signature.
Definition: multicast_delegate.h:103
SharedPtr< IAsyncResult > BeginInvoke(ArgumentTypes... args, const AsyncCallback &member, const CallbackArgumentType &obj)
NOT IMPLEMENTED.
Definition: multicast_delegate.h:476
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:125
String ToString() const
Wrapper for handling String class in contexts where ToString() is being called on value type objects.
Definition: string.h:512
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