Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkWeakPointer.h
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #ifndef __mitkWeakPointer_h
18 #define __mitkWeakPointer_h
19 
20 #include "mitkMessage.h"
21 #include <MitkCoreExports.h>
22 
23 #include <iostream>
24 #include <itkCommand.h>
25 
26 namespace mitk
27 {
37  template <class TObjectType>
39  {
40  public:
42  typedef TObjectType ObjectType;
43 
45  //##Documentation
46  //## @brief AddEvent is emitted when the object pointed to gets deleted
47  itkObjectEvent ObjectDelete;
48 
49  //##Documentation
50  //## @brief AddEvent is emitted when the object pointed to gets modified
51  itkObjectEvent ObjectModified;
52 
54  WeakPointer() : m_DeleteObserverTag(-1), m_ModifiedObserverTag(-1), m_Pointer(nullptr) {}
57  : m_DeleteObserverTag(-1), m_ModifiedObserverTag(-1), m_Pointer(p.m_Pointer)
58  {
59  this->AddDeleteAndModifiedObserver();
60  }
61 
63  WeakPointer(ObjectType *p) : m_DeleteObserverTag(-1), m_ModifiedObserverTag(-1), m_Pointer(p)
64  {
65  this->AddDeleteAndModifiedObserver();
66  }
67 
70  {
71  this->RemoveDeleteAndModifiedObserver();
72 
73  m_Pointer = nullptr;
74  }
75 
77  ObjectType *operator->() const { return m_Pointer; }
79  operator ObjectType *() const { return m_Pointer; }
81  template <typename R>
82  bool operator==(R r) const
83  {
84  return (m_Pointer == (ObjectType *)r);
85  }
86  template <typename R>
87  bool operator!=(R r) const
88  {
89  return (m_Pointer != (ObjectType *)r);
90  }
91 
93  ObjectType *GetPointer() const { return m_Pointer; }
95  bool operator<(const WeakPointer &r) const { return (void *)m_Pointer < (void *)r.m_Pointer; }
97  bool operator>(const WeakPointer &r) const { return (void *)m_Pointer > (void *)r.m_Pointer; }
99  bool operator<=(const WeakPointer &r) const { return (void *)m_Pointer <= (void *)r.m_Pointer; }
101  bool operator>=(const WeakPointer &r) const { return (void *)m_Pointer >= (void *)r.m_Pointer; }
103  bool IsNotNull() const { return m_Pointer != nullptr; }
104  bool IsNull() const { return m_Pointer == nullptr; }
106  WeakPointer &operator=(const WeakPointer &r) { return this->operator=(r.GetPointer()); }
108  WeakPointer &operator=(ObjectType *r)
109  {
110  this->RemoveDeleteAndModifiedObserver();
111  m_Pointer = r;
112  this->AddDeleteAndModifiedObserver();
113  return *this;
114  }
115 
117  ObjectType *Print(std::ostream &os) const
118  {
119  // This prints the object pointed to by the pointer
120  (*m_Pointer).Print(os);
121  return m_Pointer;
122  }
123 
127  void OnObjectDelete(const itk::Object *caller, const itk::EventObject &)
128  {
129  // do not unsubscribe from this object. this would invalidate the iterator of the
130  // event listener vector (in itk::Object) and would lead to a crash
131  // instead: do nothing->object is going to be dead soon...
132  // this->RemoveDeleteAndModifiedObserver();
133  m_Pointer = nullptr;
134  m_DeleteObserverTag = -1;
135  m_ModifiedObserverTag = -1;
136  ObjectDelete.Send(caller);
137  }
138 
139  void OnObjectModified(const itk::Object *caller, const itk::EventObject &) { ObjectModified.Send(caller); }
140  private:
141  void AddDeleteAndModifiedObserver()
142  {
143  if (m_DeleteObserverTag == -1 && m_ModifiedObserverTag == -1 && m_Pointer != nullptr)
144  {
145  // add observer for delete event
146  typename itk::MemberCommand<WeakPointer<TObjectType>>::Pointer onObjectDelete =
147  itk::MemberCommand<WeakPointer<TObjectType>>::New();
148 
149  onObjectDelete->SetCallbackFunction(this, &WeakPointer<TObjectType>::OnObjectDelete);
150  m_DeleteObserverTag = m_Pointer->AddObserver(itk::DeleteEvent(), onObjectDelete);
151 
152  // add observer for modified event
153  typename itk::MemberCommand<WeakPointer<TObjectType>>::Pointer onObjectModified =
154  itk::MemberCommand<WeakPointer<TObjectType>>::New();
155 
156  onObjectModified->SetCallbackFunction(this, &WeakPointer<TObjectType>::OnObjectModified);
157  m_ModifiedObserverTag = m_Pointer->AddObserver(itk::ModifiedEvent(), onObjectModified);
158  }
159  }
160 
161  void RemoveDeleteAndModifiedObserver()
162  {
163  if (m_DeleteObserverTag >= 0 && m_ModifiedObserverTag >= 0 && m_Pointer != nullptr)
164  {
165  m_Pointer->RemoveObserver(m_DeleteObserverTag);
166  m_Pointer->RemoveObserver(m_ModifiedObserverTag);
167 
168  m_DeleteObserverTag = -1;
169  m_ModifiedObserverTag = -1;
170  }
171  }
172 
173  long m_DeleteObserverTag;
174  long m_ModifiedObserverTag;
175 
177  ObjectType *m_Pointer;
178  };
179 
180  template <typename T>
181  std::ostream &operator<<(std::ostream &os, WeakPointer<T> p)
182  {
183  p.Print(os);
184  return os;
185  }
186 
187 } // end namespace mitk
188 
189 #endif
bool operator<(const WeakPointer &r) const
Message1< const itk::Object * > itkObjectEvent
bool operator!=(R r) const
ObjectType * Print(std::ostream &os) const
itkObjectEvent ObjectDelete
AddEvent is emitted when the object pointed to gets deleted.
void Send(T t)
Definition: mitkMessage.h:606
bool operator>=(const WeakPointer &r) const
void OnObjectDelete(const itk::Object *caller, const itk::EventObject &)
Gets called when the object is deleted or modified.
DataCollection - Class to facilitate loading/accessing structured data.
bool IsNotNull() const
TObjectType ObjectType
bool operator>(const WeakPointer &r) const
void OnObjectModified(const itk::Object *caller, const itk::EventObject &)
bool operator<=(const WeakPointer &r) const
ObjectType * GetPointer() const
bool operator==(R r) const
WeakPointer & operator=(const WeakPointer &r)
Implements a weak reference to an object.
bool IsNull() const
ObjectType * operator->() const
itkObjectEvent ObjectModified
AddEvent is emitted when the object pointed to gets modified.
WeakPointer(ObjectType *p)
WeakPointer(const WeakPointer< ObjectType > &p)
WeakPointer & operator=(ObjectType *r)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.