Commit 591d4aa8 authored by finetjul's avatar finetjul
Browse files

ENH: Add Logics observation from vtkMRMLAbstractLogic

vtkMRMLAbstractLogic can now observe other logics.

git-svn-id: http://svn.slicer.org/Slicer4/trunk@21543 3bd1e089-480b-0410-8dfb-8563597acbee
parent 19e12601
......@@ -271,6 +271,10 @@ void vtkEventBroker::DetachObservation ( vtkObservation *observation )
//----------------------------------------------------------------------------
void vtkEventBroker::RemoveObservation ( vtkObservation *observation )
{
if (observation == 0)
{
return;
}
std::vector< vtkObservation *> removeList;
removeList.push_back( observation );
this->RemoveObservations( removeList );
......
......@@ -236,7 +236,7 @@ NewImplicitPlaneWidget()
planeWidget->SetRepresentation(rep.GetPointer());
planeWidget->SetEnabled(0);
// Link widget evenement to the LogicCallbackCommand
// Link widget evenement to the WidgetsCallbackCommand
planeWidget->AddObserver(vtkCommand::StartInteractionEvent,
this->External->GetWidgetsCallbackCommand());
planeWidget->AddObserver(vtkCommand::InteractionEvent,
......
......@@ -48,6 +48,9 @@ public:
vtkObserverManager * MRMLNodesObserverManager;
int InMRMLNodesCallbackFlag;
vtkObserverManager * MRMLLogicsObserverManager;
int InMRMLLogicsCallbackFlag;
bool DisableModifiedEvent;
int ModifiedEventPending;
};
......@@ -68,6 +71,9 @@ vtkMRMLAbstractLogic::vtkInternal::vtkInternal()
this->MRMLNodesObserverManager = vtkObserverManager::New();
this->InMRMLNodesCallbackFlag = false;
this->MRMLLogicsObserverManager = vtkObserverManager::New();
this->InMRMLLogicsCallbackFlag = false;
this->DisableModifiedEvent = false;
this->ModifiedEventPending = 0;
}
......@@ -77,6 +83,7 @@ vtkMRMLAbstractLogic::vtkInternal::~vtkInternal()
{
this->MRMLSceneObserverManager->Delete();
this->MRMLNodesObserverManager->Delete();
this->MRMLLogicsObserverManager->Delete();
}
//----------------------------------------------------------------------------
......@@ -98,6 +105,12 @@ vtkMRMLAbstractLogic::vtkMRMLAbstractLogic()
nodesObserverManager->AssignOwner(this);
nodesObserverManager->GetCallbackCommand()->SetClientData(reinterpret_cast<void *> (this));
nodesObserverManager->GetCallbackCommand()->SetCallback(vtkMRMLAbstractLogic::MRMLNodesCallback);
// Setup MRML logics callback
vtkObserverManager * logicsObserverManager = this->Internal->MRMLLogicsObserverManager;
logicsObserverManager->AssignOwner(this);
logicsObserverManager->GetCallbackCommand()->SetClientData(reinterpret_cast<void *> (this));
logicsObserverManager->GetCallbackCommand()->SetCallback(vtkMRMLAbstractLogic::MRMLLogicsCallback);
}
//----------------------------------------------------------------------------
......@@ -162,7 +175,7 @@ void vtkMRMLAbstractLogic::MRMLSceneCallback(vtkObject*caller, unsigned long eid
//----------------------------------------------------------------------------
// Description:
// the LogicCallback is a static function to relay modified events from the
// the MRMLNodesCallback is a static function to relay modified events from the
// observed mrml node back into the gui layer for further processing
//
void vtkMRMLAbstractLogic::MRMLNodesCallback(vtkObject* caller, unsigned long eid,
......@@ -186,15 +199,33 @@ void vtkMRMLAbstractLogic::MRMLNodesCallback(vtkObject* caller, unsigned long ei
}
//----------------------------------------------------------------------------
vtkMRMLScene * vtkMRMLAbstractLogic::GetMRMLScene()const
void vtkMRMLAbstractLogic
::MRMLLogicsCallback(vtkObject*caller, unsigned long eid,
void* clientData, void* callData)
{
return this->Internal->MRMLScene;
vtkMRMLAbstractLogic *self = reinterpret_cast<vtkMRMLAbstractLogic *>(clientData);
assert("Observed object is not a logic" &&
vtkMRMLAbstractLogic::SafeDownCast(caller));
if (self && !self->EnterMRMLLogicsCallback())
{
#ifdef _DEBUG
vtkWarningWithObjectMacro(self,
"vtkMRMLAbstractLogic ******* MRMLLogicCallback called recursively?");
#endif
return;
}
vtkDebugWithObjectMacro(self, "In vtkMRMLAbstractLogic MRMLLogicsCallback");
self->SetInMRMLLogicsCallbackFlag(self->GetInMRMLLogicsCallbackFlag() + 1);
self->ProcessMRMLLogicsEvents(caller, eid, callData);
self->SetInMRMLLogicsCallbackFlag(self->GetInMRMLLogicsCallbackFlag() - 1);
}
//----------------------------------------------------------------------------
vtkCallbackCommand* vtkMRMLAbstractLogic::GetMRMLSceneCallbackCommand()
vtkMRMLScene * vtkMRMLAbstractLogic::GetMRMLScene()const
{
return this->GetMRMLSceneObserverManager()->GetCallbackCommand();
return this->Internal->MRMLScene;
}
//----------------------------------------------------------------------------
......@@ -203,6 +234,12 @@ vtkObserverManager* vtkMRMLAbstractLogic::GetMRMLSceneObserverManager()const
return this->Internal->MRMLSceneObserverManager;
}
//----------------------------------------------------------------------------
vtkCallbackCommand* vtkMRMLAbstractLogic::GetMRMLSceneCallbackCommand()
{
return this->GetMRMLSceneObserverManager()->GetCallbackCommand();
}
//----------------------------------------------------------------------------
vtkObserverManager* vtkMRMLAbstractLogic::GetMRMLNodesObserverManager()const
{
......@@ -215,6 +252,18 @@ vtkCallbackCommand* vtkMRMLAbstractLogic::GetMRMLNodesCallbackCommand()
return this->GetMRMLNodesObserverManager()->GetCallbackCommand();
}
//----------------------------------------------------------------------------
vtkObserverManager* vtkMRMLAbstractLogic::GetMRMLLogicsObserverManager()const
{
return this->Internal->MRMLLogicsObserverManager;
}
//----------------------------------------------------------------------------
vtkCallbackCommand* vtkMRMLAbstractLogic::GetMRMLLogicsCallbackCommand()
{
return this->GetMRMLLogicsObserverManager()->GetCallbackCommand();
}
//----------------------------------------------------------------------------
void vtkMRMLAbstractLogic::SetMRMLScene(vtkMRMLScene * newScene)
{
......@@ -313,13 +362,6 @@ int vtkMRMLAbstractLogic::GetProcessingMRMLSceneEvent()const
return this->Internal->ProcessingMRMLSceneEvent;
}
//----------------------------------------------------------------------------
// NOTE: Do *NOT* use the SetMacro or it call modified itself and generate even more events !
void vtkMRMLAbstractLogic::SetInMRMLNodesCallbackFlag(int flag)
{
this->Internal->InMRMLNodesCallbackFlag = flag;
}
//----------------------------------------------------------------------------
// NOTE: Do *NOT* use the SetMacro or it call modified itself and generate even more events !
void vtkMRMLAbstractLogic::SetProcessingMRMLSceneEvent(int event)
......@@ -327,11 +369,6 @@ void vtkMRMLAbstractLogic::SetProcessingMRMLSceneEvent(int event)
this->Internal->ProcessingMRMLSceneEvent = event;
}
//----------------------------------------------------------------------------
int vtkMRMLAbstractLogic::GetInMRMLNodesCallbackFlag()const
{
return this->Internal->InMRMLNodesCallbackFlag;
}
//----------------------------------------------------------------------------
// NOTE: Do *NOT* use the SetMacro or it call modified itself and generate even more events !
......@@ -352,12 +389,44 @@ bool vtkMRMLAbstractLogic::EnterMRMLSceneCallback()const
return true;
}
//----------------------------------------------------------------------------
// NOTE: Do *NOT* use the SetMacro or it call modified itself and generate even more events !
void vtkMRMLAbstractLogic::SetInMRMLNodesCallbackFlag(int flag)
{
this->Internal->InMRMLNodesCallbackFlag = flag;
}
//----------------------------------------------------------------------------
int vtkMRMLAbstractLogic::GetInMRMLNodesCallbackFlag()const
{
return this->Internal->InMRMLNodesCallbackFlag;
}
//----------------------------------------------------------------------------
bool vtkMRMLAbstractLogic::EnterMRMLNodesCallback()const
{
return true;
}
//----------------------------------------------------------------------------
// NOTE: Do *NOT* use the SetMacro or it call modified itself and generate even more events !
void vtkMRMLAbstractLogic::SetInMRMLLogicsCallbackFlag(int flag)
{
this->Internal->InMRMLLogicsCallbackFlag = flag;
}
//----------------------------------------------------------------------------
int vtkMRMLAbstractLogic::GetInMRMLLogicsCallbackFlag()const
{
return this->Internal->InMRMLLogicsCallbackFlag;
}
//----------------------------------------------------------------------------
bool vtkMRMLAbstractLogic::EnterMRMLLogicsCallback()const
{
return true;
}
//---------------------------------------------------------------------------
void vtkMRMLAbstractLogic
::ProcessMRMLSceneEvents(vtkObject *caller, unsigned long event, void *callData)
......@@ -452,6 +521,16 @@ void vtkMRMLAbstractLogic
}
}
//---------------------------------------------------------------------------
void vtkMRMLAbstractLogic
::ProcessMRMLLogicsEvents(vtkObject * caller,
unsigned long vtkNotUsed(event),
void *vtkNotUsed(callData))
{
vtkMRMLAbstractLogic* logic = vtkMRMLAbstractLogic::SafeDownCast(caller);
assert(logic);
}
//---------------------------------------------------------------------------
bool vtkMRMLAbstractLogic::GetDisableModifiedEvent()const
{
......
......@@ -53,6 +53,22 @@ class vtkMRMLApplicationLogic;
//----------------------------------------------------------------------------
#ifndef vtkSetAndObserveMRMLNodeMacro
/// \brief Set and observe a MRML node.
/// Replace the existing value of \a node with \a value. Unobserve the old node
/// and observe the ModifiedEvent of the new. When the new node is modified,
/// vtkMRMLAbstractLogic::ProcessMRMLNodesEvents is called which propagate the
/// call to vtkMRMLAbstractLogic::OnMRMLNodeModified(vtkMRMLNode*)
/// automatically.
/// \note Can't be used with objects other than vtkMRMLNodes
/// \code
/// void vtkMRMLMyLogic::SetMyNode(vtkMRMLNode* newNode)
/// {
/// vtkSetAndObserveMRMLNodeMacro(this->MyNode, newNode);
/// this->OnMRMLNodeModified(this->MyNode);
/// }
/// \endcode
/// \sa vtkMRMLAbstractLogic::ProcessMRMLNodesEvents(),
/// vtkMRMLAbstractLogic::OnMRMLNodeModified()
#define vtkSetAndObserveMRMLNodeMacro(node,value) { \
vtkObject *_oldNode = (node); \
this->GetMRMLNodesObserverManager()->SetAndObserveObject( \
......@@ -169,43 +185,54 @@ protected:
/// vtkSet[AndObserve]MRMLNode[Event]Macro
/// ProcessMRMLNodesEvents calls OnMRMLNodeModified when event is
/// vtkCommand::ModifiedEvent.
/// \sa ProcessMRMLSceneEvents, ProcessMRMLLogicsEvents,
/// OnMRMLNodeModified(), vtkSetAndObserveMRMLNodeMacro,
/// vtkSetAndObserveMRMLNodeMacro, vtkSetAndObserveMRMLNodeEventMacro
virtual void ProcessMRMLNodesEvents(vtkObject* caller,
unsigned long event,
void * callData);
/// Get MRML scene callbackCommand
/// Receives all the events fired by the logics.
/// To listen to a logic, you can add an observer using
/// GetMRMLLogicsCallbackCommand().
/// To be reimplemented in subclasses if needed.
/// \sa GetMRMLLogicsCallbackCommand() ,ProcessMRMLSceneEvents(),
/// ProcessMRMLNodesEvents()
virtual void ProcessMRMLLogicsEvents(vtkObject* caller,
unsigned long event,
void * callData);
/// Get MRML scene callbackCommand.
/// You shouldn't have to use it manually, reimplementing
/// SetMRMLSceneInternal and setting the events to listen should be enough.
/// \sa SetMRMLSceneInternal()
vtkCallbackCommand * GetMRMLSceneCallbackCommand();
/// Get the MRML nodes callbackCommand. The Execute function associated
/// the the callback calls ProcessMRMLNodesEvents.
/// Only vtkMRMLNodes can be listened to.
/// \sa ProcessMRMLNodesEvents()
vtkCallbackCommand * GetMRMLNodesCallbackCommand();
/// Get the MRML Logic callback command.
/// \sa GetMRMLSceneCallbackCommand(), GetMRMLNodesCallbackCommand()
vtkCallbackCommand * GetMRMLLogicsCallbackCommand();
/// Get MRML scene observerManager. It points to the scene callback.
/// \sa GetMRMLSceneCallbackCommand()
vtkObserverManager * GetMRMLSceneObserverManager()const;
/// Get MRML nodes observerManager. It points to the noes callback.
/// \sa GetMRMLSceneCallbackCommand()
/// Get MRML nodes observerManager. It points to the nodes callback.
/// \sa GetMRMLNodesCallbackCommand()
vtkObserverManager * GetMRMLNodesObserverManager()const;
/// Return 0 when not processing a MRML scene event, >0 otherwise.
/// Values can be higher than 1 when receiving nested event:
/// processing a MRML scene event fires other scene events.
/// \sa SetInMRMLCallbackFlag()
int GetInMRMLSceneCallbackFlag()const;
/// Get MRML logics observerManager. It points to the logics callback.
/// \sa GetMRMLLogicsCallbackCommand()
vtkObserverManager * GetMRMLLogicsObserverManager()const;
/// Return the event id currently processed or 0 if any.
int GetProcessingMRMLSceneEvent()const;
/// Return 0 when not processing any MRML node event, >0 otherwise.
/// Values can be higher than 1 when receiving nested events:
/// processing a MRML node event fires other node events.
/// \sa SetMRMLNodesCallbackFlag()
int GetInMRMLNodesCallbackFlag()const;
/// Called anytime a scene is not set to the logic anymore (e.g. a new or
/// no scene is set)
/// Reimplement the method to delete all the scene specific information
......@@ -306,34 +333,69 @@ protected:
/// is set. Do nothing by default. Can be reimplemented in derivated classes.
virtual void RegisterNodes(){}
/// Set InMRMLCallbackFlag flag
/// Set MRMLSceneCallback flag
/// True means ProcessMRMLEvent has already been called
/// In MRMLCallback, loop are avoided by checking the value of the flag
/// In MRMLSceneCallback, loop are avoided by checking the value of the flag
/// \sa EnterMRMLSceneCallback()
void SetInMRMLSceneCallbackFlag(int flag);
/// Return 0 when not processing a MRML scene event, >0 otherwise.
/// Values can be higher than 1 when receiving nested event:
/// processing a MRML scene event fires other scene events.
/// \sa SetInMRMLCallbackFlag()
int GetInMRMLSceneCallbackFlag()const;
/// Return true if the MRML callback must be executed, false otherwise.
/// By default, it returns true, you can reimplement it in subclasses
virtual bool EnterMRMLSceneCallback()const;
/// Set InLogicCallbackFlag flag
/// True means ProcesslogicEvent has already been called
/// In LogicCallback, loop are avoided by checking the value of the flag
/// Set event id currently processed or 0 if any.
/// \sa EnterMRMLSceneCallback()
void SetProcessingMRMLSceneEvent(int event);
/// Set InMRMLNodesCallback flag.
/// In InMRMLNodesCallback, loop are avoided by checking the value of the
/// flag.
/// \sa EnterMRMLNodesCallback()
void SetInMRMLNodesCallbackFlag(int flag);
/// Return true if the Logic callback must be executed, false otherwise.
/// By default, it returns true, you can reimplement it in subclasses
/// Return 0 when not processing any MRML node event, >0 otherwise.
/// Values can be higher than 1 when receiving nested events:
/// processing a MRML node event fires other node events.
/// \sa SetMRMLNodesCallbackFlag()
int GetInMRMLNodesCallbackFlag()const;
/// Return true if the MRML Nodes callback must be executed, false otherwise.
/// By default, it returns true, you can reimplement it in subclasses.
/// \sa SetInMRMLNodesCallbackFlag()
virtual bool EnterMRMLNodesCallback()const;
/// Set event id currently processed or 0 if any.
void SetProcessingMRMLSceneEvent(int event);
/// Set InMRMLLogicsCallback flag.
/// In InMRMLLogicsCallback, loop are avoided by checking the value of the
/// flag.
/// \sa EnterMRMLLogicsCallback()
void SetInMRMLLogicsCallbackFlag(int flag);
/// MRMLCallback is a static function to relay modified events from the MRML Scene
/// In subclass, MRMLCallback can also be used to relay event from observe MRML node(s)
/// Return 0 when not processing any MRML logic event, >0 otherwise.
/// Values can be higher than 1 when receiving nested events:
/// processing a MRML logic event fires other node events.
/// \sa SetMRMLLogicsCallbackFlag()
int GetInMRMLLogicsCallbackFlag()const;
/// Return true if the Logics callback must be executed, false otherwise.
/// By default, it returns true, you can reimplement it in subclasses
virtual bool EnterMRMLLogicsCallback()const;
/// MRMLSceneCallback is a static function to relay modified events from the MRML Scene
/// In subclass, MRMLSceneCallback can also be used to relay event from observe MRML node(s)
static void MRMLSceneCallback(vtkObject *caller, unsigned long eid, void *clientData, void *callData);
/// LogicCallback is a static function to relay modified events from the Logic
/// MRMLNodesCallback is a static function to relay modified events from the nodes
static void MRMLNodesCallback(vtkObject *caller, unsigned long eid, void *clientData, void *callData);
/// MRMLLogicCallback is a static function to relay modified events from the logics
static void MRMLLogicsCallback(vtkObject *caller, unsigned long eid, void *clientData, void *callData);
/// Start modifying the logic. Disable Modify events.
/// Returns the previous state of DisableModifiedEvent flag
/// that should be passed to EndModify() method
......
......@@ -68,10 +68,6 @@ vtkStandardNewMacro(vtkMRMLSliceLogic);
//----------------------------------------------------------------------------
vtkMRMLSliceLogic::vtkMRMLSliceLogic()
{
this->MRMLLogicCallbackCommand = vtkCallbackCommand::New();
this->MRMLLogicCallbackCommand->SetClientData(this);
this->MRMLLogicCallbackCommand->SetCallback(vtkMRMLSliceLogic::MRMLLogicCallback);
this->Initialized = false;
this->Name = 0;
this->BackgroundLayer = 0;
......@@ -148,12 +144,6 @@ vtkMRMLSliceLogic::~vtkMRMLSliceLogic()
}
this->DeleteSliceModel();
if (this->MRMLLogicCallbackCommand)
{
this->MRMLLogicCallbackCommand->Delete();
this->MRMLLogicCallbackCommand = 0;
}
}
//----------------------------------------------------------------------------
......@@ -206,7 +196,7 @@ void vtkMRMLSliceLogic::SetMRMLSceneInternal(vtkMRMLScene * newScene)
this->SetAndObserveMRMLSceneEventsInternal(newScene, events.GetPointer());
this->ProcessLogicEvents();
this->ProcessMRMLLogicsEvents();
this->ProcessMRMLSceneEvents(newScene, vtkMRMLScene::EndBatchProcessEvent, 0);
}
......@@ -489,32 +479,16 @@ void vtkMRMLSliceLogic::OnMRMLNodeModified(vtkMRMLNode* node)
}
//----------------------------------------------------------------------------
vtkCallbackCommand* vtkMRMLSliceLogic::GetMRMLLogicCallbackCommand()
{
return this->MRMLLogicCallbackCommand;
}
//----------------------------------------------------------------------------
void vtkMRMLSliceLogic::MRMLLogicCallback(vtkObject*caller, unsigned long eid,
void* clientData, void* callData)
{
assert(vtkMRMLAbstractLogic::SafeDownCast(caller));
vtkMRMLSliceLogic *self = reinterpret_cast<vtkMRMLSliceLogic *>(clientData);
vtkDebugWithObjectMacro(self, "In vtkMRMLSliceLogic MRMLLogicCallback");
self->ProcessLogicEvents(caller, eid, callData);
}
//----------------------------------------------------------------------------
void vtkMRMLSliceLogic::ProcessLogicEvents(vtkObject* vtkNotUsed(caller),
unsigned long vtkNotUsed(event),
void* vtkNotUsed(callData))
void vtkMRMLSliceLogic
::ProcessMRMLLogicsEvents(vtkObject* vtkNotUsed(caller),
unsigned long vtkNotUsed(event),
void* vtkNotUsed(callData))
{
this->ProcessLogicEvents();
this->ProcessMRMLLogicsEvents();
}
//----------------------------------------------------------------------------
void vtkMRMLSliceLogic::ProcessLogicEvents()
void vtkMRMLSliceLogic::ProcessMRMLLogicsEvents()
{
//
......@@ -674,7 +648,7 @@ void vtkMRMLSliceLogic::SetBackgroundLayer(vtkMRMLSliceLayerLogic *backgroundLay
this->BackgroundLayer->SetSliceNode(SliceNode);
vtkEventBroker::GetInstance()->AddObservation(
this->BackgroundLayer, vtkCommand::ModifiedEvent,
this, this->GetMRMLLogicCallbackCommand());
this, this->GetMRMLLogicsCallbackCommand());
}
this->Modified();
......@@ -699,7 +673,7 @@ void vtkMRMLSliceLogic::SetForegroundLayer(vtkMRMLSliceLayerLogic *foregroundLay
this->ForegroundLayer->SetSliceNode(SliceNode);
vtkEventBroker::GetInstance()->AddObservation(
this->ForegroundLayer, vtkCommand::ModifiedEvent,
this, this->GetMRMLLogicCallbackCommand());
this, this->GetMRMLLogicsCallbackCommand());
}
this->Modified();
......@@ -725,7 +699,7 @@ void vtkMRMLSliceLogic::SetLabelLayer(vtkMRMLSliceLayerLogic *labelLayer)
this->LabelLayer->SetSliceNode(SliceNode);
vtkEventBroker::GetInstance()->AddObservation(
this->LabelLayer, vtkCommand::ModifiedEvent,
this, this->GetMRMLLogicCallbackCommand());
this, this->GetMRMLLogicsCallbackCommand());
}
this->Modified();
......
......@@ -343,18 +343,12 @@ protected:
virtual void SetMRMLSceneInternal(vtkMRMLScene * newScene);
/// Get Logic CallbackCommand
vtkCallbackCommand * GetMRMLLogicCallbackCommand();
static void MRMLLogicCallback(vtkObject*caller, unsigned long eid,
void* clientData, void* callData);
///
/// process logic events
virtual void ProcessLogicEvents(vtkObject * caller,
unsigned long event,
void * callData);
void ProcessLogicEvents();
virtual void ProcessMRMLLogicsEvents(vtkObject * caller,
unsigned long event,
void * callData);
void ProcessMRMLLogicsEvents();
virtual void OnMRMLSceneNodeAdded(vtkMRMLNode* node);
virtual void OnMRMLSceneNodeRemoved(vtkMRMLNode* node);
......@@ -368,7 +362,6 @@ protected:
virtual void OnMRMLNodeModified(vtkMRMLNode* node);
vtkCallbackCommand* MRMLLogicCallbackCommand;
bool AddingSliceModelNodes;
bool Initialized;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment