OpendTect  6.3
monitorable.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
8  Date: April 2016
9 ________________________________________________________________________
10 
11 -*/
12 
13 #include "notify.h"
14 #include "ptrman.h"
15 #include "refcount.h"
16 
17 
77 {
78 public:
79 
80  class ChangeData;
81 
82  typedef int ChangeType;
83  typedef od_int64 IDType;
86 
87  Monitorable(const Monitorable&);
88  virtual ~Monitorable();
89  Monitorable& operator =(const Monitorable&);
90  bool operator ==(const Monitorable&) const;
91  virtual Monitorable* clone() const { return getClone(); }
92 
93  virtual ChangeDataNotifier& objectChanged() const
94  { return const_cast<Monitorable*>(this)->chgnotif_; }
96  { return const_cast<Monitorable*>(this)->delnotif_; }
99 
100  virtual void touch() const { dirtycount_++; }
101  virtual DirtyCountType dirtyCount() const { return dirtycount_; }
102  virtual ChangeType compareWith(const Monitorable&) const;
103 
104  static inline ChangeType cEntireObjectChange()
105  { return ChangeData::cEntireObjectChgType(); }
106  static inline ChangeType cNoChange()
107  { return ChangeData::cNoChgType(); }
108  static IDType cUnspecChgID()
109  { return ChangeData::cUnspecChgID(); }
110  static IDType cEntireObjectChgID()
111  { return ChangeData::cUnspecChgID(); }
112 
113  mExpClass(Basic) ChangeData : public std::pair<ChangeType,IDType>
114  {
115  public:
116 
117  ChangeData( ChangeType typ, IDType id )
118  : std::pair<ChangeType,IDType>(typ,id)
119  , auxdata_(0) {}
120  ChangeData(const ChangeData&);
121  virtual ~ChangeData() {}
122  ChangeData& operator =(const ChangeData&);
123 
124  ChangeType changeType() const { return first; }
125  IDType ID() const { return second; }
126  bool isEntireObject() const { return first == -1; }
127  bool isNoChange() const { return mIsUdf(first); }
128  bool hasUnspecID() const { return second == -1; }
129  bool includes( ChangeType ct ) const
130  { return ct == first || isEntireObject(); }
131 
132  static inline ChangeType cEntireObjectChgType() { return -1; }
133  static inline ChangeType cNoChgType() { return 0; }
134  static inline IDType cUnspecChgID() { return -1; }
135  static inline ChangeData AllChanged() { return ChangeData(-1,-1); }
136  static inline ChangeData NoChange() { return ChangeData(0,-1); }
137 
138  mExpClass(Basic) AuxData : public RefCount::Referenced
139  {
140  protected:
141  virtual ~AuxData() {}
142  };
143 
145  template<class T> inline
147  { return static_cast<T*>( auxdata_.ptr() ); }
148  };
149  static ChangeType changeNotificationTypeOf(CallBacker*);
150  void sendChangeNotification(const ChangeData&) const;
151  void sendEntireObjectChangeNotification() const;
152  void transferNotifsTo(const Monitorable&,
153  const CallBacker* onlyfor=0) const;
154 
155  mExpClass(Basic) AccessLocker : public Threads::Locker
156  {
157  public:
158  AccessLocker(const Monitorable&,bool forread=true);
159  inline bool convertToWrite() { return convertToWriteLock(); }
160  };
161 
162 protected:
163 
164  Monitorable();
165  virtual Monitorable* getClone() const = 0;
166 
168 
169  void copyAll(const Monitorable&);
170  void sendChgNotif(AccessLocker&,const ChangeData&) const;
172  void sendChgNotif(AccessLocker&,ChangeType,IDType) const;
174  void sendDelNotif() const;
176  { chgnotifblocklevel_++; }
177  void resumeChangeNotifications() const;
178 
179  template <class T>
180  inline T getMemberSimple(const T&) const;
181  template <class TMember,class TSetTo>
182  inline void setMemberSimple(TMember&,TSetTo,ChangeType,IDType);
183 
185 
186 private:
187 
188  mutable DirtyCounter dirtycount_;
190 
191  mutable ChangeDataNotifier chgnotif_;
193  mutable bool delalreadytriggered_;
194 
195  friend class MonitorLock;
196  friend class ChangeNotifyBlocker;
197 
198  ChangeType compareClassData(const Monitorable&) const;
199 
200 };
201 
202 
203 #define mGetMonitoredChgData(cb,chgdata) \
204  mCBCapsuleUnpack( Monitorable::ChangeData, chgdata, cb )
205 
206 #define mGetMonitoredChgDataWithAux(cb,chgdata,T,auxvar) \
207  mCBCapsuleUnpack( Monitorable::ChangeData, chgdata, cb ); \
208  T* auxvar = chgdata.auxDataAs<T>()
209 
210 #define mGetMonitoredChgDataWithCaller(cb,chgdata,caller) \
211  mCBCapsuleUnpackWithCaller( Monitorable::ChangeData, chgdata, caller, cb )
212 
213 #define mGetMonitoredChgDataWithAuxAndCaller(cb,chgdata,T,auxvar,caller) \
214  mGetMonitoredChgDataWithCaller(cb,chgdata,caller); \
215  T* auxvar = chgdata.auxDataAs<T>()
216 
217 #define mGetMonitoredChgDataDoAll(cb,chgdata,doallact) \
218  mGetMonitoredChgData(chgdata,cb); \
219  if ( chgdata.changeType() == Monitored::cEntireObjectChange() ) \
220  { doallact; }
221 
222 #define mGetIDFromChgData( typ, var, chgdata ) \
223  const typ var = typ::get( (typ::IDType)chgdata.ID() )
224 
225 
253 {
254 public:
255  MonitorLock(const Monitorable&);
256  ~MonitorLock();
257 
258  void unlockNow();
259  void reLock();
260 
261 protected:
262 
264  bool unlocked_;
265 
266 };
267 
268 
278 {
279 public:
281  bool send_notif=true);
283 
284  void unBlockNow();
285  void reBlock();
286 
287 protected:
288 
292 
293 };
294 
295 
296 
316 template <class Mon> inline
318  const Mon* newptr, CallBacker* only_for )
319 {
320  const Mon* curptr = ref.ptr();
321  if ( curptr == newptr )
322  return false;
323 
325  if ( (newptr && !curptr) || (!newptr && curptr) )
327  else if ( curptr && newptr )
328  {
329  ct = curptr->compareWith( *newptr );
330  curptr->transferNotifsTo( *newptr, only_for );
331  }
332 
333  ref = newptr;
334  return ct;
335 }
336 
337 template <class Mon> inline
339  const Mon& newref, CallBacker* only_for )
340 {
341  return replaceMonitoredRef( ref, &newref, only_for );
342 }
343 
344 template <class Mon> inline
346  ConstRefMan<Mon>& newref, CallBacker* only_for )
347 {
348  return replaceMonitoredRef( ref, newref.ptr(), only_for );
349 }
350 
351 template <class Mon> inline
353  CallBacker* only_for )
354 {
355  return replaceMonitoredRef( (ConstRefMan<Mon>&)ref, (const Mon*)newptr,
356  only_for );
357 }
358 
359 template <class Mon> inline
361  CallBacker* only_for )
362 {
363  return replaceMonitoredRef( ref, &newref, only_for );
364 }
365 
366 template <class Mon> inline
368  CallBacker* only_for )
369 {
370  return replaceMonitoredRef( ref, newref.ptr(), only_for );
371 }
#define mExpClass(module)
Definition: commondefs.h:157
Object that can be MT-safely monitored from cradle to grave.
Definition: monitorable.h:76
bool convertToWrite()
Definition: monitorable.h:159
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:285
Inherit from this class to be able to send and/or receive CallBacks.
Definition: callback.h:182
int ChangeType
Definition: monitorable.h:80
int64_t DirtyCountType
Definition: monitorable.h:84
A lock of a type that (hopefully) suits your needs. To use it, you need the Locker class...
Definition: threadlock.h:51
IDType ID() const
Definition: monitorable.h:125
bool operator==(const ArrayNDInfo &a1, const ArrayNDInfo &a2)
Definition: arrayndinfo.h:51
RefMan< AuxData > auxdata_
Definition: monitorable.h:144
virtual ~ChangeData()
Definition: monitorable.h:121
T * auxDataAs()
Definition: monitorable.h:146
virtual Monitorable * clone() const
Definition: monitorable.h:91
Monitorable::ChangeType replaceMonitoredRef(ConstRefMan< Mon > &ref, const Mon *newptr, CallBacker *only_for)
replaces a ref to a Monitorable with a new one.
Definition: monitorable.h:317
#define od_int64
Definition: plftypes.h:34
void stopChangeNotifications() const
Definition: monitorable.h:175
bool hasUnspecID() const
Definition: monitorable.h:128
bool isEntireObject() const
Definition: monitorable.h:126
static ChangeData NoChange()
Definition: monitorable.h:136
bool delalreadytriggered_
Definition: monitorable.h:193
Definition: fixedstreambuf.h:18
int64_t IDType
Definition: monitorable.h:83
protects a Monitorable against change.
Definition: monitorable.h:252
bool unblocked_
Definition: monitorable.h:290
ChangeData(ChangeType typ, IDType id)
Definition: monitorable.h:117
bool sendnotif_
Definition: monitorable.h:291
static IDType cUnspecChgID()
Definition: monitorable.h:108
#define mDeclInstanceCreatedNotifierAccess(clss)
Definition: notify.h:235
interface to threads that should be portable.
Definition: atomic.h:24
const T * ptr() const
Definition: ptrman.h:77
static ChangeType cEntireObjectChange()
Definition: monitorable.h:104
virtual Notifier< Monitorable > & objectToBeDeleted() const
Definition: monitorable.h:95
Definition: monitorable.h:138
ChangeType changeType() const
Definition: monitorable.h:124
Monitorable::AccessLocker locker_
Definition: monitorable.h:263
virtual ChangeDataNotifier & objectChanged() const
Definition: monitorable.h:93
static IDType cUnspecChgID()
Definition: monitorable.h:134
ChangeNotifyBlocker(const Monitorable &, bool send_notif=true)
DirtyCounter dirtycount_
Definition: monitorable.h:188
static ChangeType cNoChgType()
Definition: monitorable.h:133
Threads::Lock accesslock_
Definition: monitorable.h:167
virtual DirtyCountType dirtyCount() const
Definition: monitorable.h:101
bool isNoChange() const
Definition: monitorable.h:127
ChangeDataNotifier chgnotif_
Definition: monitorable.h:191
prevents change notifications coming out of a Monitorable.
Definition: monitorable.h:277
virtual void touch() const
Definition: monitorable.h:100
static ChangeData AllChanged()
Definition: monitorable.h:135
bool unlocked_
Definition: monitorable.h:264
Definition: monitorable.h:113
bool includes(ChangeType ct) const
Definition: monitorable.h:129
Definition: monitorable.h:155
const Monitorable & obj_
Definition: monitorable.h:289
Threads::Atomic< int > chgnotifblocklevel_
Definition: monitorable.h:189
static ChangeType cEntireObjectChgType()
Definition: monitorable.h:132
Definition: ptrman.h:227
CNotifier< Monitorable, ChangeData > ChangeDataNotifier
Definition: monitorable.h:85
static IDType cEntireObjectChgID()
Definition: monitorable.h:110
Notifier< Monitorable > delnotif_
Definition: monitorable.h:192
Threads::Atomic< DirtyCountType > DirtyCounter
Definition: monitorable.h:184
const T * ptr() const
Definition: ptrman.h:95
Definition: ptrman.h:200
static ChangeType cNoChange()
Definition: monitorable.h:106
virtual ~AuxData()
Definition: monitorable.h:141

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