OpendTect
6.6
|
Object that can be MT-safely monitored from cradle to grave. More...
Classes | |
class | AccessLocker |
class | ChangeData |
Public Types | |
typedef CNotifier< MonitoredObject, ChangeData > | ChangeDataNotifier |
typedef int | ChangeType |
typedef int64_t | IDType |
typedef Threads ::Locker | Locker |
Public Member Functions | |
MonitoredObject (const MonitoredObject &) | |
virtual | ~MonitoredObject () |
virtual MonitoredObject * | clone () const |
virtual ChangeType | compareWith (const MonitoredObject &) const |
virtual DirtyCountType | dirtyCount () const |
virtual ChangeDataNotifier & | objectChanged () const |
virtual Notifier< MonitoredObject > & | objectToBeDeleted () const |
MonitoredObject & | operator= (const MonitoredObject &) |
bool | operator== (const MonitoredObject &) const |
void | sendChangeNotification (const ChangeData &) const |
void | sendEntireObjectChangeNotification () const |
virtual void | touch () const |
void | transferNotifsTo (const MonitoredObject &, 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 | detachAllNotifiers () const |
Call from the destructor of your inherited object. More... | |
void | detachCB (const NotifierAccess &, const CallBack &) const |
void | detachCB (const NotifierAccess *notif, const CallBack &cb) const |
virtual bool | isCapsule () const |
bool | isNotifierAttached (const NotifierAccess *) const |
Only for debugging purposes, don't use. More... | |
void | stopReceivingNotifications () const |
Static Public Member Functions | |
static ChangeType | cEntireObjectChange () |
static IDType | cEntireObjectChgID () |
static ChangeType | changeNotificationTypeOf (CallBacker *) |
static ChangeType | cNoChange () |
static IDType | cUnspecChgID () |
static Notifier< MonitoredObject > & | instanceCreated () |
defines static instanceCreated() More... | |
Static Public Member Functions inherited from CallBacker | |
static void | createReceiverForCurrentThread () |
static void | removeReceiverForCurrentThread () |
Protected Member Functions | |
MonitoredObject () | |
void | copyAll (const MonitoredObject &) |
virtual MonitoredObject * | getClone () const =0 |
template<class T > | |
T | getMemberSimple (const T &) const |
the get function used by mImplSimpleMonitoredGet More... | |
void | resumeChangeNotifications () const |
void | sendChgNotif (AccessLocker &, ChangeType, IDType) const |
calls objectChanged with released lock More... | |
void | sendChgNotif (AccessLocker &, const ChangeData &) const |
calls objectChanged with released lock More... | |
void | sendDelNotif () const |
template<class TMember , class TSetTo > | |
void | setMemberSimple (TMember &, TSetTo, ChangeType, IDType) |
the set function used by mImplSimpleMonitoredSet More... | |
void | stopChangeNotifications () const |
Protected Attributes | |
Threads::Lock | accesslock_ |
Private Member Functions | |
ChangeType | compareClassData (const MonitoredObject &) const |
Private Attributes | |
ChangeDataNotifier | chgnotif_ |
Threads::Atomic< int > | chgnotifblocklevel_ |
bool | delalreadytriggered_ |
Notifier< MonitoredObject > | delnotif_ |
DirtyCounter | dirtycount_ |
Friends | |
class | ChangeNotifyBlocker |
class | MonitorLock |
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 MonitoredObject 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 MonitoredObject, 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 MonitoredObject 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 NamedMonitoredObject, or Pick::Set. For usage, try visSurvey::LocationDisplay.
<>
typedef int MonitoredObject::ChangeType |
typedef int64_t MonitoredObject::IDType |
typedef Threads :: Locker MonitoredObject::Locker |
MonitoredObject::MonitoredObject | ( | const MonitoredObject & | ) |
|
virtual |
|
protected |
|
inlinestatic |
|
inlinestatic |
|
static |
|
inlinevirtual |
Reimplemented in SharedObject, NamedMonitoredObject, and ChangeRecorder.
|
inlinestatic |
|
private |
|
virtual |
Reimplemented in SharedObject, NamedMonitoredObject, and ChangeRecorder.
|
protected |
|
inlinestatic |
|
inlinevirtual |
|
protectedpure virtual |
Implemented in NamedMonitoredObject.
|
inlineprotected |
the get function used by mImplSimpleMonitoredGet
|
static |
defines static instanceCreated()
|
inlinevirtual |
|
inlinevirtual |
MonitoredObject& MonitoredObject::operator= | ( | const MonitoredObject & | ) |
bool MonitoredObject::operator== | ( | const MonitoredObject & | ) | const |
|
protected |
void MonitoredObject::sendChangeNotification | ( | const ChangeData & | ) | const |
|
protected |
calls objectChanged with released lock
|
protected |
calls objectChanged with released lock
|
protected |
void MonitoredObject::sendEntireObjectChangeNotification | ( | ) | const |
|
inlineprotected |
the set function used by mImplSimpleMonitoredSet
|
inlineprotected |
|
inlinevirtual |
void MonitoredObject::transferNotifsTo | ( | const MonitoredObject & | , |
const CallBacker * | onlyfor = 0 |
||
) | const |
|
friend |
|
friend |
|
mutableprotected |
|
mutableprivate |
|
mutableprivate |
|
mutableprivate |
|
mutableprivate |
|
mutableprivate |
Generated at for the OpendTect seismic interpretation project. Copyright (C): dGB Beheer B.V. 1995-2022