OpendTect  6.6
callback.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*+
4 ________________________________________________________________________
5 
6  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
7  Author: A.H.Bril
8  Date: 8-11-1995
9  Contents: Notification and Callbacks
10  RCS: $Id$
11 ________________________________________________________________________
12 
13 -*/
14 
15 #include "basicmod.h"
16 #include "refcount.h"
17 #include "sets.h"
18 #include "threadlock.h"
19 class NotifierAccess;
20 
35 class CallBacker;
36 
37 
39 #define mCBFn(fn) (static_cast<CallBackFunction>(&fn))
40 
42 #define mCB(obj,clss,fn) CallBack( static_cast<clss*>(obj), mCBFn(clss::fn))
43 
45 #define mSCB(fn) CallBack( (static_cast<StaticCallBackFunction>(&fn)) )
46 
47 
62 {
63 public:
64  static void initClass();
66  : cberobj_(nullptr), fn_(nullptr), sfn_(nullptr)
67  {}
69  : cberobj_(o), fn_(f), sfn_(nullptr)
70  {}
72  : cberobj_(nullptr), fn_(nullptr), sfn_(f)
73  {}
74  bool operator==(const CallBack&) const;
75  bool operator!=(const CallBack&) const;
76 
77  bool willCall() const;
78  void doCall(CallBacker*) const;
79  bool isDisabled() const { return disablecount_;}
80  void disable(bool yn=true) const;
81  void enable() const { disable(false); }
82 
83  inline CallBacker* cbObj() { return cberobj_; }
84  inline const CallBacker* cbObj() const { return cberobj_; }
85  inline CallBackFunction cbFn() const { return fn_; }
86  inline StaticCallBackFunction scbFn() const { return sfn_; }
87 
88  static bool addToMainThread(const CallBack&, CallBacker* =nullptr);
93  CallBacker* = nullptr);
98  static bool callInMainThread(const CallBack&, CallBacker* =nullptr);
107  static void removeFromThreadCalls(const CallBacker*);
108  /* Removes callbacker from all event loops in all threads*/
109 
110 
111  // See also mEnsureExecutedInMainThread macro
112 
113 private:
114 
120 
121 public:
122 
123  // Usually only called from mEnsureExecutedInMainThread:
124 
126  CallBacker* =nullptr);
130  mDeprecated("Use removeFromThreadCalls")
131  static void removeFromMainThread( const CallBacker* cber )
132  { removeFromThreadCalls( cber ); }
133 };
134 
135 #define mMainThreadCall( func ) \
136 CallBack::callInMainThread( CallBack( this, mCBFn(func) ), 0)
137 
138 #define mEnsureExecutedInMainThread( func ) \
139  if ( CallBack::queueIfNotInMainThread( \
140  CallBack( this, mCBFn(func) ), 0 ) ) \
141  return
142 
143 #define mEnsureExecutedInMainThreadWithCapsule( func, caps ) \
144  CallBack cb( this, mCBFn(func) ); \
145  if ( CallBack::queueIfNotInMainThread(cb,caps->clone()) ) \
146  return;
147 
150 mExpClass(Basic) CallBackSet : public RefCount::Referenced
151  , public TypeSet<CallBack>
152 {
153 public:
157 
160  void disableAll(bool yn=true);
161  bool hasAnyDisabled() const;
162 
163  void removeWith(const CallBacker*);
169  void transferTo(CallBackSet& to,const CallBacker* onlyfor=nullptr,
170  const CallBacker* notfor=nullptr);
172 
174 
175 protected:
176 
178 
179 };
180 
181 
185 {
186  friend class NotifierAccess;
187 
188 public:
191  virtual ~CallBacker();
192 
193  bool attachCB(const NotifierAccess&,const CallBack&,
194  bool onlyifnew=false) const;
199  bool attachCB(const NotifierAccess* notif,const CallBack& cb,
200  bool onlyifnew=false) const;
203  void detachCB(const NotifierAccess&,const CallBack&) const;
206  void detachCB( const NotifierAccess* notif,
207  const CallBack& cb ) const
208  { if ( notif ) detachCB( *notif, cb ); }
211  bool isNotifierAttached(const NotifierAccess*) const;
213  virtual bool isCapsule() const { return false; }
214 
215  void detachAllNotifiers() const;
217 private:
218 
219  bool notifyShutdown(const NotifierAccess*,bool wait) const;
225 
226 public:
227 
229  { detachAllNotifiers(); }
230 
240 };
241 
242 
253 template <class T>
254 mClass(Basic) CBCapsule : public CallBacker
255 {
256 public:
258  : data(d), caller(c) {}
259 
260  T data;
262 
264  { return new CBCapsule<T>(data,caller); }
265  virtual bool isCapsule() const { return true; }
266 
267 };
268 
269 
291 #define mCBCapsuleGet(PayLoadType,var,cb) \
292 CBCapsule<PayLoadType>* var = dynamic_cast< CBCapsule<PayLoadType>* >( cb );
293 
294 #define mCBCapsuleUnpack(PayLoadType,var,cb) \
295 mCBCapsuleGet(PayLoadType,cb##caps,cb) \
296 PayLoadType var = cb##caps->data
297 
298 #define mCBCapsuleUnpackWithCaller(PayLoadType,var,cber,cb) \
299 mCBCapsuleGet(PayLoadType,cb##caps,cb) \
300 PayLoadType var = cb##caps->data; \
301 CallBacker* cber = cb##caps->caller
302 
303 #include "notify.h"
CallBacker::detachCB
void detachCB(const NotifierAccess &, const CallBack &) const
CallBack::disable
void disable(bool yn=true) const
CallBack::callInMainThread
static bool callInMainThread(const CallBack &, CallBacker *=nullptr)
CallBacker::stopReceivingNotifications
void stopReceivingNotifications() const
Definition: callback.h:228
CallBackSet::CallBackSet
CallBackSet()
Conv::to
T to(const F &fr)
Definition: convert.h:34
CallBackSet::hasAnyDisabled
bool hasAnyDisabled() const
StaticCallBackFunction
void(*)(CallBacker *) StaticCallBackFunction
Definition: callback.h:44
CallBacker::CallBacker
CallBacker(const CallBacker &)
ObjectSet< NotifierAccess >
CallBacker::attachCB
bool attachCB(const NotifierAccess &, const CallBack &, bool onlyifnew=false) const
notify.h
CBCapsule::caller
CallBacker * caller
Definition: callback.h:261
CallBackSet::removeWith
void removeWith(StaticCallBackFunction)
CallBack::cberobj_
CallBacker * cberobj_
Definition: callback.h:115
CallBack::fn_
CallBackFunction fn_
Definition: callback.h:116
CallBackSet::operator=
CallBackSet & operator=(const CallBackSet &)
CallBack::doCall
void doCall(CallBacker *) const
CallBack::scbFn
StaticCallBackFunction scbFn() const
Definition: callback.h:86
mExpClass
#define mExpClass(module)
Definition: commondefs.h:177
CallBackSet::doCall
void doCall(CallBacker *)
it is possible to remove another callback during the doCall
CallBackSet::removeWith
void removeWith(const CallBacker *)
CBCapsule::data
T data
Definition: callback.h:260
CallBacker::attachCB
bool attachCB(const NotifierAccess *notif, const CallBack &cb, bool onlyifnew=false) const
CallBack::CallBack
CallBack(StaticCallBackFunction f)
Definition: callback.h:71
CallBackFunction
void(CallBacker::*)(CallBacker *) CallBackFunction
Definition: callback.h:38
CallBacker::~CallBacker
virtual ~CallBacker()
CallBack::sfn_
StaticCallBackFunction sfn_
Definition: callback.h:117
CallBackSet
TypeSet of CallBacks with a few extras.
Definition: callback.h:152
CallBack::operator==
bool operator==(const CallBack &) const
CallBacker
Inherit from this class to be able to send and/or receive CallBacks.
Definition: callback.h:185
CallBacker::detachAllNotifiers
void detachAllNotifiers() const
Call from the destructor of your inherited object.
CallBack::queueIfNotInMainThread
static bool queueIfNotInMainThread(CallBack, CallBacker *=nullptr)
CallBacker::removeReceiverForCurrentThread
static void removeReceiverForCurrentThread()
CBCapsule::isCapsule
virtual bool isCapsule() const
Definition: callback.h:265
Threads::ThreadID
void * ThreadID
Definition: thread.h:34
CallBack
CallBacks object-oriented (object + method).
Definition: callback.h:62
CallBackSet::CallBackSet
CallBackSet(const CallBackSet &)
CallBackSet::disableAll
void disableAll(bool yn=true)
CallBack::isDisabled
bool isDisabled() const
Definition: callback.h:79
NotifierAccess
Interface class for Notifier. See comments there.
Definition: notify.h:22
CallBack::CallBack
CallBack(CallBacker *o, CallBackFunction f)
Definition: callback.h:68
mClass
#define mClass(module)
Definition: commondefs.h:181
mDeprecated
#define mDeprecated(msg)
Definition: plfdefs.h:215
CBCapsule::CBCapsule
CBCapsule(T d, CallBacker *c)
Definition: callback.h:257
CallBacker::CallBacker
CallBacker()
CallBacker::attachednotifierslock_
Threads::Lock attachednotifierslock_
Definition: callback.h:224
CallBack::addToThread
static bool addToThread(Threads::ThreadID, const CallBack &, CallBacker *=nullptr)
CallBack::cbObj
CallBacker * cbObj()
Definition: callback.h:83
CallBack::cbFn
CallBackFunction cbFn() const
Definition: callback.h:85
CallBacker::attachednotifiers_
ObjectSet< NotifierAccess > attachednotifiers_
Definition: callback.h:223
CallBack::CallBack
CallBack()
Definition: callback.h:65
CallBacker::createReceiverForCurrentThread
static void createReceiverForCurrentThread()
CallBackSet::~CallBackSet
~CallBackSet()
CallBack::cbObj
const CallBacker * cbObj() const
Definition: callback.h:84
CallBack::operator!=
bool operator!=(const CallBack &) const
CallBack::removeFromThreadCalls
static void removeFromThreadCalls(const CallBacker *)
CallBackSet::lock_
Threads::Lock lock_
Definition: callback.h:173
CallBacker::isNotifierAttached
bool isNotifierAttached(const NotifierAccess *) const
Only for debugging purposes, don't use.
CallBackSet::transferTo
void transferTo(CallBackSet &to, const CallBacker *onlyfor=nullptr, const CallBacker *notfor=nullptr)
threadlock.h
CallBacker::detachCB
void detachCB(const NotifierAccess *notif, const CallBack &cb) const
Definition: callback.h:206
refcount.h
CallBack::willCall
bool willCall() const
CBCapsule::clone
CBCapsule< T > * clone() const
Definition: callback.h:263
CallBacker::notifyShutdown
bool notifyShutdown(const NotifierAccess *, bool wait) const
CallBack::mainthread_
static Threads::ThreadID mainthread_
Definition: callback.h:119
CBCapsule
Capsule class to wrap any class into a CallBacker.
Definition: callback.h:255
CallBack::enable
void enable() const
Definition: callback.h:81
CallBack::addToMainThread
static bool addToMainThread(const CallBack &, CallBacker *=nullptr)
CallBackSet::removeWith
void removeWith(CallBackFunction)
sets.h
CallBack::disablecount_
Threads::Atomic< int > disablecount_
Definition: callback.h:118
CallBack::initClass
static void initClass()
CallBacker::isCapsule
virtual bool isCapsule() const
Definition: callback.h:213
Threads::Lock
A lock of a type that (hopefully) suits your needs. To use it, you need the Locker class.
Definition: threadlock.h:53
Threads::Atomic< int >
TypeSet< CallBack >

Generated at for the OpendTect seismic interpretation project. Copyright (C): dGB Beheer B.V. 1995-2021