OpendTect  6.3
Classes | Public Types | Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | Friends | List of all members
Monitorable Class Referenceabstract

Object that can be MT-safely monitored from cradle to grave. More...

Inheritance diagram for Monitorable:
[legend]

Classes

class  AccessLocker
 
class  ChangeData
 

Public Types

typedef int ChangeType
 
typedef int64_t IDType
 
typedef int64_t DirtyCountType
 
typedef CNotifier< Monitorable, ChangeDataChangeDataNotifier
 

Public Member Functions

 Monitorable (const Monitorable &)
 
virtual ~Monitorable ()
 
Monitorableoperator= (const Monitorable &)
 
bool operator== (const Monitorable &) const
 
virtual Monitorableclone () const
 
virtual ChangeDataNotifierobjectChanged () const
 
virtual Notifier< Monitorable > & objectToBeDeleted () const
 
virtual void touch () const
 
virtual DirtyCountType dirtyCount () const
 
virtual ChangeType compareWith (const Monitorable &) const
 
void sendChangeNotification (const ChangeData &) const
 
void sendEntireObjectChangeNotification () const
 
void transferNotifsTo (const Monitorable &, const CallBacker *onlyfor=0) const
 
- Public Member Functions inherited from CallBacker
 CallBacker ()
 
 CallBacker (const CallBacker &)
 
virtual ~CallBacker ()
 
bool attachCB (const NotifierAccess &, const CallBack &, bool onlyifnew=false) const
 
bool attachCB (const NotifierAccess *notif, const CallBack &cb, bool onlyifnew=false) const
 
void detachCB (const NotifierAccess &, const CallBack &) const
 
void detachCB (const NotifierAccess *notif, const CallBack &cb) const
 
bool isNotifierAttached (const NotifierAccess *) const
 Only for debugging purposes, don't use. More...
 
virtual bool isCapsule () const
 
void stopReceivingNotifications () const
 

Static Public Member Functions

static Notifier< Monitorable > & instanceCreated ()
 defines static instanceCreated() More...
 
static ChangeType cEntireObjectChange ()
 
static ChangeType cNoChange ()
 
static IDType cUnspecChgID ()
 
static IDType cEntireObjectChgID ()
 
static ChangeType changeNotificationTypeOf (CallBacker *)
 
- Static Public Member Functions inherited from CallBacker
static void createReceiverForCurrentThread ()
 
static void removeReceiverForCurrentThread ()
 

Protected Types

typedef Threads::Atomic< DirtyCountTypeDirtyCounter
 

Protected Member Functions

 Monitorable ()
 
virtual MonitorablegetClone () const =0
 
void copyAll (const Monitorable &)
 
void sendChgNotif (AccessLocker &, const ChangeData &) const
 calls objectChanged with released lock More...
 
void sendChgNotif (AccessLocker &, ChangeType, IDType) const
 calls objectChanged with released lock More...
 
void sendDelNotif () const
 
void stopChangeNotifications () const
 
void resumeChangeNotifications () const
 
template<class T >
getMemberSimple (const T &) const
 the get function used by mImplSimpleMonitoredGet More...
 
template<class TMember , class TSetTo >
void setMemberSimple (TMember &, TSetTo, ChangeType, IDType)
 the set function used by mImplSimpleMonitoredSet More...
 
- Protected Member Functions inherited from CallBacker
void detachAllNotifiers () const
 Call from the destructor of your inherited object. More...
 

Protected Attributes

Threads::Lock accesslock_
 

Private Member Functions

ChangeType compareClassData (const Monitorable &) const
 

Private Attributes

DirtyCounter dirtycount_
 
Threads::Atomic< int > chgnotifblocklevel_
 
ChangeDataNotifier chgnotif_
 
Notifier< Monitorabledelnotif_
 
bool delalreadytriggered_
 

Friends

class MonitorLock
 
class ChangeNotifyBlocker
 

Detailed Description

Object that can be MT-safely monitored from cradle to grave.

Traditionally, the MVC concept was all about automatic updates. This can still be done, but nowadays more important seems the integrity for MT.

The instanceCreated() will tell you when any Monitorable is created. To make your class really monitorable, use mDeclInstanceCreatedNotifierAccess for your subclass, too. Note that you'll need to add mTriggerInstanceCreatedNotifier() to the constructor, and add mDefineInstanceCreatedNotifierAccess(YourClassName) to a .cc.

Similarly, you have to trigger the objectToBeDeleted() at the start of your destructor - if you do not have one, make one. For that, use sendDelNotif(), it avoids double notifications; this base class will eventually do such a thing but then it's too late for many purposes: the subclass part of the object is then already dead. Thus, at the beginning of the your destructor, call sendDelNotif().

You can also monitor the object's changes. First of all, a dirtyCount() is maintained. To make more precise event handling possible, the change notifier will deliver an int with a change type. This type can be specific for the Monitorable, and could be available with symbolic constants in that class. The default is 0 - 'General change'.

For simple class variables, there are simple macros for get and set that will lock and unlock right: mImplSimpleMonitoredGet, mImplSimpleMonitoredSet, and the most common mImplSimpleMonitoredGetSet.

Locking for more complex things should be done using macros: mLock4Read, mLock4Write, mLock2Write, and mUnlockAllAccess. After write (i.e. object change) operations, you need to unlock and send the notification. Use mSendChgNotif or mSendEntireObjChgNotif.

To handle change notifications, you'll want to unpack the capsule with one of the macros mGetMonitoredChgData or mGetMonitoredChgDataDoAll. Example:

void MyObj::chgCB( CallBacker* cb ) { mGetMonitoredChgDataDoAll( cb, chgdata, caller, return redrawAll() ); if ( chgdata.changeType() == MonObj::cSomeChange() ) doSomething( chgdata.ID() ); }

The choice of cNoChange being zero is deliberate; the guarantee is that you can use a ChangeType as a boolean to see whether there is any change.

Lastly, copying of Monitorables needs to be done right. For this, you want to use the mDeclMonitorableAssignment and mImplMonitorableAssignment macros: these provide correct handling and even make your task easier than otherwise. To make it work, in the .cc file you have to implement a void copyClassData(const clss&) function. It is called already locked, and should only copy the class' own data.

For typical subclass implementations see NamedMonitorable, or Pick::Set. For usage, try visSurvey::LocationDisplay.

Member Typedef Documentation

typedef int64_t Monitorable::DirtyCountType
typedef int64_t Monitorable::IDType

Constructor & Destructor Documentation

Monitorable::Monitorable ( const Monitorable )
virtual Monitorable::~Monitorable ( )
virtual
Monitorable::Monitorable ( )
protected

Member Function Documentation

static ChangeType Monitorable::cEntireObjectChange ( )
inlinestatic
static IDType Monitorable::cEntireObjectChgID ( )
inlinestatic
static ChangeType Monitorable::changeNotificationTypeOf ( CallBacker )
static
virtual Monitorable* Monitorable::clone ( ) const
inlinevirtual
static ChangeType Monitorable::cNoChange ( )
inlinestatic
ChangeType Monitorable::compareClassData ( const Monitorable ) const
private
virtual ChangeType Monitorable::compareWith ( const Monitorable ) const
virtual
void Monitorable::copyAll ( const Monitorable )
protected
static IDType Monitorable::cUnspecChgID ( )
inlinestatic
virtual DirtyCountType Monitorable::dirtyCount ( ) const
inlinevirtual

Reimplemented in Well::Data.

virtual Monitorable* Monitorable::getClone ( ) const
protectedpure virtual
template<class T >
T Monitorable::getMemberSimple ( const T &  memb) const
inlineprotected

the get function used by mImplSimpleMonitoredGet

static Notifier< Monitorable >& Monitorable::instanceCreated ( )
static

defines static instanceCreated()

virtual ChangeDataNotifier& Monitorable::objectChanged ( ) const
inlinevirtual
virtual Notifier<Monitorable>& Monitorable::objectToBeDeleted ( ) const
inlinevirtual
Monitorable& Monitorable::operator= ( const Monitorable )
bool Monitorable::operator== ( const Monitorable ) const
void Monitorable::resumeChangeNotifications ( ) const
protected
void Monitorable::sendChangeNotification ( const ChangeData ) const
void Monitorable::sendChgNotif ( AccessLocker ,
const ChangeData  
) const
protected

calls objectChanged with released lock

void Monitorable::sendChgNotif ( AccessLocker ,
ChangeType  ,
IDType   
) const
protected

calls objectChanged with released lock

void Monitorable::sendDelNotif ( ) const
protected
void Monitorable::sendEntireObjectChangeNotification ( ) const
template<class TMember , class TSetTo >
void Monitorable::setMemberSimple ( TMember &  memb,
TSetTo  setto,
ChangeType  typ,
IDType  id 
)
inlineprotected

the set function used by mImplSimpleMonitoredSet

void Monitorable::stopChangeNotifications ( ) const
inlineprotected
virtual void Monitorable::touch ( ) const
inlinevirtual

Reimplemented in Well::Data.

void Monitorable::transferNotifsTo ( const Monitorable ,
const CallBacker onlyfor = 0 
) const

Friends And Related Function Documentation

friend class ChangeNotifyBlocker
friend
friend class MonitorLock
friend

Member Data Documentation

Threads::Lock Monitorable::accesslock_
mutableprotected
ChangeDataNotifier Monitorable::chgnotif_
mutableprivate
Threads::Atomic<int> Monitorable::chgnotifblocklevel_
mutableprivate
bool Monitorable::delalreadytriggered_
mutableprivate
Notifier<Monitorable> Monitorable::delnotif_
mutableprivate
DirtyCounter Monitorable::dirtycount_
mutableprivate

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