OpendTect  6.3
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: Bert / Kris
8  Date: Nov 1995 / End 2015 / April 2016
9  Contents: Notification and Callbacks
10 ________________________________________________________________________
11 
12 -*/
13 
14 #include "basicmod.h"
15 #include "refcount.h"
16 #include "sets.h"
17 #include "threadlock.h"
18 class NotifierAccess;
19 
34 class CallBacker;
35 
36 
38 #define mCBFn(fn) (static_cast<CallBackFunction>(&fn))
39 
41 #define mCB(obj,clss,fn) CallBack( static_cast<clss*>(obj), mCBFn(clss::fn))
42 
44 #define mSCB(fn) CallBack( (static_cast<StaticCallBackFunction>(&fn)) )
45 
46 class QCallBackEventReceiver;
47 
48 
63 {
64 public:
65  static void initClass();
67  : cberobj_(0), fn_(0), sfn_(0) {}
69  : cberobj_(o), fn_(f), sfn_(0) {}
71  : cberobj_(0), fn_(0), sfn_(f) {}
72  bool operator==(const CallBack&) const;
73  inline bool operator!=( const CallBack& cb ) const
74  { return !(*this==cb); }
75 
76  inline bool willCall() const
77  { return disablecount_ == 0
78  && ((cberobj_ && fn_) || sfn_); }
79  void doCall(CallBacker*) const;
80  bool isDisabled() const { return disablecount_;}
81  void disable(bool yn=true) const;
82  void enable() const { disable(false); }
83 
84  inline CallBacker* cbObj() { return cberobj_; }
85  inline const CallBacker* cbObj() const { return cberobj_; }
86  inline CallBackFunction cbFn() const { return fn_; }
87  inline StaticCallBackFunction scbFn() const { return sfn_; }
88 
89  static bool addToMainThread(const CallBack&, CallBacker* =0);
93  static bool addToThread(Threads::ThreadID,const CallBack&,
94  CallBacker* = 0);
99  static bool callInMainThread(const CallBack&, CallBacker* =0);
108  static void removeFromThreadCalls(const CallBacker*);
109  /* Removes callbacker from all event loops in all threads*/
110 
111 
112  // See also mEnsureExecutedInMainThread macro
113 
114 private:
115 
121 
122 public:
123 
124  // Usually only called from mEnsureExecutedInMainThread:
125 
126  static bool queueIfNotInMainThread(CallBack,
127  CallBacker* =0);
130  static mDeprecated void removeFromMainThread(const CallBacker* cber)
131  { removeFromThreadCalls(cber); }
132 };
133 
134 #define mMainThreadCall( func ) \
135 CallBack::callInMainThread( CallBack( this, mCBFn(func) ), 0)
136 
137 #define mEnsureExecutedInMainThread( func ) \
138  if ( CallBack::queueIfNotInMainThread( \
139  CallBack( this, mCBFn(func) ), 0 ) ) \
140  return
141 
142 #define mEnsureExecutedInMainThreadWithCapsule( func, caps ) \
143  CallBack cb( this, mCBFn(func) ); \
144  if ( CallBack::queueIfNotInMainThread(cb,caps->clone()) ) \
145  return;
146 
149 mExpClass(Basic) CallBackSet : public RefCount::Referenced
150  , public TypeSet<CallBack>
151 {
152 public:
153  CallBackSet();
154  CallBackSet(const CallBackSet&);
155  CallBackSet& operator=(const CallBackSet&);
156 
157  void doCall(CallBacker*);
159  void disableAll(bool yn=true);
160  bool hasAnyDisabled() const;
161 
162  void removeWith(const CallBacker*);
164  void removeWith(CallBackFunction);
166  void removeWith(StaticCallBackFunction);
168  void transferTo(CallBackSet& to,const CallBacker* onlyfor=0);
170 
172 
173 protected:
174 
175  ~CallBackSet();
176 
177 };
178 
179 
183 {
184  friend class NotifierAccess;
185 
186 public:
187  CallBacker();
188  CallBacker(const CallBacker&);
189  virtual ~CallBacker();
190 
191  bool attachCB(const NotifierAccess&,const CallBack&,
192  bool onlyifnew=false) const;
197  bool attachCB(const NotifierAccess* notif,const CallBack& cb,
198  bool onlyifnew=false) const;
201  void detachCB(const NotifierAccess&,const CallBack&) const;
204  void detachCB( const NotifierAccess* notif,
205  const CallBack& cb) const
206  { if ( notif ) detachCB( *notif, cb ); }
209  bool isNotifierAttached(const NotifierAccess*) const;
211  virtual bool isCapsule() const { return false; }
212 
213 protected:
214 
215  void detachAllNotifiers() const;
217 private:
218 
219  bool notifyShutdown(const NotifierAccess*,bool wait) const;
225 
228 
229 public:
230 
232  { detachAllNotifiers(); }
233 
234  static void createReceiverForCurrentThread();
237  static void removeReceiverForCurrentThread();
243 };
244 
245 
256 template <class PLT>
257 mClass(Basic) CBCapsule : public CallBacker
258 {
259 public:
260 
261  typedef PLT PayLoadType;
262 
263  CBCapsule( PLT d, CallBacker* c )
264  : data(d), caller(c) {}
265 
266  PLT data;
267  CallBacker* caller;
268 
270  { return new CBCapsule<PLT>(data,caller); }
271  virtual bool isCapsule() const { return true; }
272 
273 };
274 
275 
297 #define mCBCapsuleGet(PayLoadType,var,cb) \
298 CBCapsule<PayLoadType>* var = dynamic_cast< CBCapsule<PayLoadType>* >( cb );
299 
300 #define mCBCapsuleUnpack(PayLoadType,var,cb) \
301 mCBCapsuleGet(PayLoadType,cb##caps,cb) \
302 PayLoadType var = cb##caps->data
303 
304 #define mCBCapsuleUnpackWithCaller(PayLoadType,var,cber,cb) \
305 mCBCapsuleGet(PayLoadType,cb##caps,cb) \
306 PayLoadType var = cb##caps->data; \
307 CallBacker* cber = cb##caps->caller
#define mExpClass(module)
Definition: commondefs.h:157
Capsule class to wrap any class into a CallBacker.
Definition: callback.h:257
Inherit from this class to be able to send and/or receive CallBacks.
Definition: callback.h:182
CBCapsule(PLT d, CallBacker *c)
Definition: callback.h:263
CallBack(CallBacker *o, CallBackFunction f)
Definition: callback.h:68
A lock of a type that (hopefully) suits your needs. To use it, you need the Locker class...
Definition: threadlock.h:51
T to(const F &fr)
Definition: convert.h:31
bool operator==(const ArrayNDInfo &a1, const ArrayNDInfo &a2)
Definition: arrayndinfo.h:51
CallBacker * caller
Definition: callback.h:267
void(* StaticCallBackFunction)(CallBacker *)
Definition: callback.h:43
virtual bool isCapsule() const
Definition: callback.h:211
Interface class for Notifier. See comments there.
Definition: notify.h:20
friend class CallBacker
Definition: notify.h:24
void detachCB(const NotifierAccess *notif, const CallBack &cb) const
Definition: callback.h:204
void(CallBacker::* CallBackFunction)(CallBacker *)
Definition: callback.h:37
bool willCall() const
Definition: callback.h:76
void stopReceivingNotifications() const
Definition: callback.h:231
static Threads::ThreadID mainthread_
Definition: callback.h:120
Set of (small) copyable elements.
Definition: commontypes.h:26
CallBacker * cberobj_
Definition: callback.h:116
void * ThreadID
Definition: thread.h:33
bool operator!=(const CallBack &cb) const
Definition: callback.h:73
Threads::Atomic< int > disablecount_
Definition: callback.h:119
CallBack()
Definition: callback.h:66
StaticCallBackFunction scbFn() const
Definition: callback.h:87
ObjectSet< NotifierAccess > attachednotifiers_
Definition: callback.h:226
PLT data
Definition: callback.h:266
bool isDisabled() const
Definition: callback.h:80
CallBack(StaticCallBackFunction f)
Definition: callback.h:70
CBCapsule< PLT > * clone() const
Definition: callback.h:269
StaticCallBackFunction sfn_
Definition: callback.h:118
#define mDeprecated
Definition: plfdefs.h:213
CallBacker * cbObj()
Definition: callback.h:84
Threads::Lock attachednotifierslock_
Definition: callback.h:227
CallBackFunction cbFn() const
Definition: callback.h:86
CallBackFunction fn_
Definition: callback.h:117
TypeSet of CallBacks with a few extras.
Definition: callback.h:149
static void removeFromMainThread(const CallBacker *cber)
Definition: callback.h:130
void enable() const
Definition: callback.h:82
#define mClass(module)
Definition: commondefs.h:161
ObjectSet< QCallBackEventReceiver > receivers_
Definition: callback.h:223
PLT PayLoadType
Definition: callback.h:261
CallBacks object-oriented (object + method).
Definition: callback.h:62
Threads::Lock receiverslock_
Definition: callback.h:224
Threads::Lock lock_
Definition: callback.h:171
virtual bool isCapsule() const
Definition: callback.h:271
static void initClass()
const CallBacker * cbObj() const
Definition: callback.h:85

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