14 #if VARIABLE_NUM_ARGS == VARIABLE_MAX_ARGS
18 template <
bool>
struct _CriticalSectionWrapper
22 template <
bool enabled>
struct _Lock
24 _Lock( _CriticalSectionWrapper<enabled>& cs ) : mLck( cs.mSC )
29 std::scoped_lock<std::mutex> mLck;
31 template <>
struct _CriticalSectionWrapper<false>
35 template <>
struct _Lock<false>
37 _Lock( _CriticalSectionWrapper<false>& cs ) {}
41 template <
class ThreadingPolicy, VARIABLE_ARGS>
50 std::shared_ptr<CallbackType> cb;
53 CallbackInfo( std::shared_ptr<CallbackType> acb,
int aId )
54 : cb( acb ), id( aId )
69 SubscriptionEmplacement emplacement;
72 std::deque<PendingOperation> mPendingOperation;
76 typedef list<CallbackInfo> CallbackListType;
79 inline size_t getNumCallbacks()
const {
return mCallbacks.size(); }
80 void removeCallbacks()
82 _private::_Lock<mpl::isSame<
88 int subscribeCallback( U&& callback,
89 SubscriptionEmplacement se = SE_BACK )
92 new CallbackType( std::forward<U>( callback ),
93 ::mel::core::use_functor ),
96 int subscribeCallback(
98 SubscriptionEmplacement se = SE_BACK )
101 new CallbackType( std::move( callback ),
102 ::mel::core::use_function ),
105 int subscribeCallback(
108 SubscriptionEmplacement se = SE_BACK )
111 new CallbackType( callback, ::mel::core::use_function ),
114 int subscribeCallback(
116 SubscriptionEmplacement se = SE_BACK )
119 new CallbackType( callback, ::mel::core::use_function ),
136 ::std::forward<U>( callback ), ::mel::core::use_functor );
138 std::shared_ptr<CallbackType>( auxiliar ) );
151 for (
typename CallbackListType::iterator
152 i = mCallbacks.begin(),
153 j = mCallbacks.end();
160 PendingOperation::EOperation::O_UNSUBSCRIPTION;
161 po.info = std::move( CallbackInfo(
nullptr,
id ) );
162 mPendingOperation.push_back( std::move( po ) );
170 for (
typename CallbackListType::iterator
171 i = mCallbacks.begin(),
172 j = mCallbacks.end();
177 mCallbacks.erase( i );
190 SubscriptionEmplacement se = SE_BACK )
202 po.op = PendingOperation::EOperation::O_SUBSCRIPTION;
204 std::shared_ptr<CallbackType>( cb ), result ) );
206 mPendingOperation.push_back( std::move( po ) );
213 std::shared_ptr<CallbackType>( cb ), result ) );
218 std::shared_ptr<CallbackType>( cb ), result ) );
240 typename CallbackListType::iterator i = mCallbacks.begin();
241 while ( i != mCallbacks.end() )
247 PendingOperation::EOperation::O_UNSUBSCRIPTION;
249 std::shared_ptr<CallbackType>( cb ), -1 ) );
250 mPendingOperation.push_back( std::move( po ) );
262 typename CallbackListType::iterator i = mCallbacks.begin();
263 while ( i != mCallbacks.end() )
267 mCallbacks.erase( i );
268 i = mCallbacks.end();
282 VARIABLE_ARGS_DECL>& ob2 )
284 for (
auto& cb : ob2.mCallbacks )
285 mCallbacks.push_back( cb );
287 void append( CallbackSubscriptor_Base<ThreadingPolicy,
288 VARIABLE_ARGS_DECL>&& ob2 )
290 for (
auto& cb : ob2.mCallbacks )
291 mCallbacks.push_back( std::move( cb ) );
293 inline CallbackListType& getCallbacks() {
return mCallbacks; }
294 inline const CallbackListType& getCallbacks()
const
300 CallbackListType mCallbacks;
301 _private::_CriticalSectionWrapper<mpl::isSame<
305 CallbackSubscriptor_Base(
const CallbackSubscriptor_Base& o2 )
306 : mTriggering( false )
308 _private::_Lock<mpl::isSame<
311 for (
typename CallbackListType::iterator
312 i = o2.mCallbacks.begin(),
313 j = o2.mCallbacks.end();
315 mCallbacks.push_back(
316 CallbackInfo( ( *i ).cb->clone(), ++mCurrId ) );
318 void _applyPendingOperations()
320 for (
auto& p : mPendingOperation )
324 case PendingOperation::EOperation::O_SUBSCRIPTION:
325 if ( p.emplacement == SE_BACK )
327 mCallbacks.push_back( p.info );
331 mCallbacks.push_front( p.info );
334 case PendingOperation::EOperation::O_UNSUBSCRIPTION:
335 if ( p.info.cb ==
nullptr )
345 mPendingOperation.clear();
348 template <
class ThreadingPolicy, VARIABLE_ARGS_NODEFAULT>
349 int CallbackSubscriptor_Base<ThreadingPolicy,
350 VARIABLE_ARGS_DECL>::mCurrId = 0;
352 template <
class ThreadingPolicy, VARIABLE_ARGS>
362 void triggerCallbacks( VARIABLE_ARGS_IMPL )
364 if ( BaseType::mTriggering )
372 lck( BaseType::mSC );
373 BaseType::mTriggering =
true;
374 typename BaseType::CallbackListType::iterator i =
375 BaseType::mCallbacks.begin();
376 auto j = BaseType::mCallbacks.end();
379 if ( ( *i->cb )( VARIABLE_ARGS_USE ) ==
380 ECallbackResult::UNSUBSCRIBE )
382 i = BaseType::mCallbacks.erase( i );
389 BaseType::mTriggering =
false;
390 if ( !BaseType::mPendingOperation.empty() )
391 BaseType::_applyPendingOperations();
403 template <
class ThreadingPolicy>
410 void triggerCallbacks()
414 lck( BaseType::mSC );
415 if ( BaseType::mTriggering )
421 BaseType::mTriggering =
true;
423 typename BaseType::CallbackListType::iterator i =
424 BaseType::mCallbacks.begin();
425 auto j = BaseType::mCallbacks.end();
428 if ( ( *i->cb )() == ECallbackResult::UNSUBSCRIBE )
430 i = BaseType::mCallbacks.erase( i );
437 BaseType::mTriggering =
false;
438 if ( !BaseType::mPendingOperation.empty() )
439 BaseType::_applyPendingOperations();
450 template <
class ThreadingPolicy, VARIABLE_ARGS>
467 template <
class ThreadingPolicy>
480 SubscriptionEmplacement se = SE_BACK )
484 std::move( callback ), ::mel::core::use_function ),
489 SubscriptionEmplacement se = SE_BACK )
493 callback, ::mel::core::use_function ),
497 SubscriptionEmplacement se )
501 callback, ::mel::core::use_function ),
505 int subscribeCallback( U&& callback,
506 SubscriptionEmplacement se = SE_BACK )
508 return BaseType::subscribeCallback(
509 ::std::forward<U>( callback ), se );
521 ::std::forward<U>( callback ) );
530 template <
class ThreadingPolicy, VARIABLE_ARGS>
531 class CallbackSubscriptor_Base<ThreadingPolicy, VARIABLE_ARGS_DECL,
535 typedef Callback<ECallbackResult, VARIABLE_ARGS_DECL> CallbackType;
540 std::shared_ptr<CallbackType> cb;
543 CallbackInfo( std::shared_ptr<CallbackType> acb,
int aId )
544 : cb( acb ), id( aId )
547 CallbackInfo() : cb( nullptr ), id( -1 ) {}
552 struct PendingOperation
554 enum class EOperation
559 SubscriptionEmplacement emplacement;
562 std::deque<PendingOperation> mPendingOperation;
565 typedef list<CallbackInfo> CallbackListType;
566 CallbackSubscriptor_Base() : mTriggering( false ){};
567 virtual ~CallbackSubscriptor_Base() { removeCallbacks(); }
568 inline size_t getNumCallbacks()
const {
return mCallbacks.size(); }
569 void removeCallbacks()
571 _private::_Lock<mpl::isSame<
578 int subscribeCallback( U&& callback,
579 SubscriptionEmplacement se = SE_BACK )
582 new CallbackType( ::std::forward<U>( callback ),
583 ::mel::core::use_functor ),
593 SubscriptionEmplacement se = SE_BACK )
596 _private::_Lock<mpl::isSame<
606 po.op = PendingOperation::EOperation::O_SUBSCRIPTION;
607 po.info = std::move( CallbackInfo(
608 std::shared_ptr<CallbackType>( cb ), result ) );
610 mPendingOperation.push_back( std::move( po ) );
616 mCallbacks.push_back( CallbackInfo(
617 std::shared_ptr<CallbackType>( cb ), result ) );
621 mCallbacks.push_front( CallbackInfo(
622 std::shared_ptr<CallbackType>( cb ), result ) );
631 _private::_Lock<mpl::isSame<
634 CallbackType* auxiliar =
new CallbackType(
635 std::forward<U>( callback ), ::mel::core::use_functor );
637 std::shared_ptr<CallbackType>( auxiliar ) );
643 _private::_Lock<mpl::isSame<
651 for (
typename CallbackListType::iterator
652 i = mCallbacks.begin(),
653 j = mCallbacks.end();
660 PendingOperation::EOperation::O_UNSUBSCRIPTION;
661 po.info = std::move( CallbackInfo(
nullptr,
id ) );
662 mPendingOperation.push_back( std::move( po ) );
670 for (
typename CallbackListType::iterator
671 i = mCallbacks.begin(),
672 j = mCallbacks.end();
677 mCallbacks.erase( i );
693 _private::_Lock<mpl::isSame<
700 typename CallbackListType::iterator i = mCallbacks.begin();
701 while ( i != mCallbacks.end() )
707 PendingOperation::EOperation::O_UNSUBSCRIPTION;
708 po.info = std::move( CallbackInfo(
709 std::shared_ptr<CallbackType>( cb ), -1 ) );
710 mPendingOperation.push_back( std::move( po ) );
722 typename CallbackListType::iterator i = mCallbacks.begin();
723 while ( i != mCallbacks.end() )
727 mCallbacks.erase( i );
728 i = mCallbacks.end();
741 append(
const CallbackSubscriptor_Base<ThreadingPolicy,
742 VARIABLE_ARGS_DECL>& ob2 )
744 for (
auto& cb : ob2.mCallbacks )
745 mCallbacks.push_back( cb );
747 void append( CallbackSubscriptor_Base<ThreadingPolicy,
748 VARIABLE_ARGS_DECL>&& ob2 )
750 for (
auto& cb : ob2.mCallbacks )
751 mCallbacks.push_back( std::move( cb ) );
753 inline CallbackListType& getCallbacks() {
return mCallbacks; }
754 inline const CallbackListType& getCallbacks()
const
760 CallbackListType mCallbacks;
761 _private::_CriticalSectionWrapper<mpl::isSame<
765 CallbackSubscriptor_Base(
const CallbackSubscriptor_Base& o2 )
766 : mTriggering( false )
768 _private::_Lock<mpl::isSame<
771 typename CallbackListType::const_iterator i, j;
772 for ( i = o2.mCallbacks.begin(), j = o2.mCallbacks.end();
774 mCallbacks.push_back( CallbackInfo(
775 std::shared_ptr<CallbackType>( ( *i ).cb->clone() ),
778 void _applyPendingOperations()
780 for (
auto& p : mPendingOperation )
784 case PendingOperation::EOperation::O_SUBSCRIPTION:
785 if ( p.emplacement == SE_BACK )
787 mCallbacks.push_back( p.info );
791 mCallbacks.push_front( p.info );
794 case PendingOperation::EOperation::O_UNSUBSCRIPTION:
795 if ( p.info.cb ==
nullptr )
805 mPendingOperation.clear();
808 template <
class ThreadingPolicy, VARIABLE_ARGS>
809 int CallbackSubscriptor_Base<ThreadingPolicy,
810 VARIABLE_ARGS_DECL>::mCurrId = 0;
812 template <
class ThreadingPolicy, VARIABLE_ARGS>
813 class CallbackSubscriptorNotTyped<ThreadingPolicy, VARIABLE_ARGS_DECL>
814 :
public CallbackSubscriptor_Base<ThreadingPolicy,
817 typedef CallbackSubscriptor_Base<ThreadingPolicy,
822 void triggerCallbacks( VARIABLE_ARGS_IMPL )
824 if ( BaseType::mTriggering )
826 mel::text::error(
"CallbackSubscriptor Callbacks are being "
827 "triggered while triggering again!!" );
830 _private::_Lock<mpl::isSame<
832 lck( BaseType::mSC );
833 BaseType::mTriggering =
true;
834 typename BaseType::CallbackListType::iterator i =
835 BaseType::mCallbacks.begin();
836 while ( i != BaseType::mCallbacks.end() )
838 if ( ( *i->cb )( VARIABLE_ARGS_USE ) ==
839 ECallbackResult::UNSUBSCRIBE )
841 i = BaseType::mCallbacks.erase( i );
848 BaseType::mTriggering =
false;
849 if ( !BaseType::mPendingOperation.empty() )
850 BaseType::_applyPendingOperations();
854 CallbackSubscriptorNotTyped() : BaseType() {}
855 CallbackSubscriptorNotTyped(
const CallbackSubscriptorNotTyped& o2 )
861 template <
class ThreadingPolicy, VARIABLE_ARGS>
862 class CallbackSubscriptor<ThreadingPolicy, VARIABLE_ARGS_DECL, void>
863 :
public CallbackSubscriptorNotTyped<ThreadingPolicy,
864 VARIABLE_ARGS_DECL, void>
866 typedef CallbackSubscriptorNotTyped<ThreadingPolicy,
867 VARIABLE_ARGS_DECL,
void>
871 CallbackSubscriptor() : BaseType() {}
872 CallbackSubscriptor(
const CallbackSubscriptor& o2 )
876 int subscribeCallback(
878 SubscriptionEmplacement se = SE_BACK )
881 new typename BaseType::CallbackType(
882 std::move( callback ), ::mel::core::use_function ),
885 int subscribeCallback(
888 SubscriptionEmplacement se = SE_BACK )
891 new typename BaseType::CallbackType(
892 callback, ::mel::core::use_function ),
895 int subscribeCallback(
897 SubscriptionEmplacement se = SE_BACK )
900 new typename BaseType::CallbackType(
901 callback, ::mel::core::use_function ),
906 int subscribeCallback( U&& functor,
907 SubscriptionEmplacement se = SE_BACK )
909 return BaseType::subscribeCallback( std::forward<U>( functor ),
create Callback from callable
Definition: Callback_Impl.h:142
bool unsubscribeCallback(std::function< ECallbackResult()> &&callback)=delete
callback subscription functionalit
Definition: CallbackSubscriptor_Impl.h:43
bool unsubscribeCallback(std::function< ECallbackResult(VARIABLE_ARGS_DECL)> &&callback)=delete
bool unsubscribeCreatedCallback(std::shared_ptr< CallbackType > cb)
Definition: CallbackSubscriptor_Impl.h:229
int subscribeCreatedCallback(CallbackType *cb, SubscriptionEmplacement se=SE_BACK)
Definition: CallbackSubscriptor_Impl.h:189
Definition: CallbackSubscriptor_Impl.h:454
Definition: CallbackSubscriptor_Impl.h:406
Definition: CallbackSubscriptor_Impl.h:356
ECallbackResult
Type resturned by callbacks subscribed to CallbackSubscriptors.
Definition: CallbackSubscriptor.h:32
Definition: Callback_Impl.h:11
Definition: CallbackSubscriptor.h:37
Definition: CallbackSubscriptor_Impl.h:49
Definition: CallbackSubscriptor_Impl.h:63