diff --git a/Modules/MitkExt/DataManagement/mitkSet.h b/Modules/MitkExt/DataManagement/mitkSet.h index c9683718e5..cbadd621f2 100644 --- a/Modules/MitkExt/DataManagement/mitkSet.h +++ b/Modules/MitkExt/DataManagement/mitkSet.h @@ -1,242 +1,242 @@ #ifndef mitkSet_H #define mitkSet_H #include #include #include #include #include #include "mitkSetObserver.h" namespace mitk { /// /// A class that acts like a weak pointer /// but for a list of itk objects /// template -class Set: public itk::DataObject +class Set: virtual public itk::Object { public: typedef mitk::SetObserver Observer; mitkClassMacro(Set, itk::Object); itkFactorylessNewMacro(Set); Set() { } /// /// clears this set, copies over all elements from otherSet /// void Copy( mitk::Set* otherSet ) { this->Clear(); for(unsigned int i=0; i< otherSet->GetSize(); ++i) { this->Add( otherSet->Get(i) ); } } bool Add ( const T& obj ) { if(this->Has(obj)) // this is a set! do not add twice return false; // add it now m_Objects.push_back(obj); // if index is not valid any more, just add // the element // subscribe for modified event typename itk::MemberCommand >::Pointer _modifiedCommand = itk::MemberCommand >::New(); _modifiedCommand->SetCallbackFunction(this , &Set::OnObjectModified); m_ObjectModifiedTags[obj] = obj->AddObserver(itk::ModifiedEvent(), _modifiedCommand); // subscribe for delete event typename itk::MemberCommand >::Pointer _DeleteCommand = itk::MemberCommand >::New(); _DeleteCommand->SetCallbackFunction(this , &Set::OnObjectModified); m_ObjectDeleteTags[obj] = obj->AddObserver(itk::DeleteEvent(), _DeleteCommand); for(typename std::set*>::iterator it = m_SetObserver.begin(); it != m_SetObserver.end(); ++it) (*it)->OnAdded(obj); this->Modified(); return true; } bool Remove ( const T& obj ) { return this->Remove(this->IndexOf(obj)); } bool Remove ( int index ) { if( !this->IsValid(index) ) // element must exist to be removed return false; typename std::vector::iterator it = m_Objects.begin(); std::advance(it, index); T& obj = *it; for(typename std::set*>::iterator it2 = m_SetObserver.begin(); it2 != m_SetObserver.end(); ++it2) (*it2)->OnRemove(*it); // remove it now obj->RemoveObserver(m_ObjectModifiedTags[obj]); obj->RemoveObserver(m_ObjectDeleteTags[obj]); m_ObjectModifiedTags.erase(obj); m_ObjectDeleteTags.erase(obj); m_Objects.erase(it); this->Modified(); return true; } void Clear () { while(m_Objects.size() > 0) this->Remove(m_Objects.size()-1); } unsigned int GetSize() const { return m_Objects.size(); } int IndexOf(const T& obj) const { int index = -1; typename std::vector::const_iterator it = m_Objects.begin(); for(unsigned int i=0; iIndexOf(obj) != -1; } bool IsEmpty() const { return m_Objects.empty(); } bool IsValid( int index ) const { if(index >= 0) { return m_Objects.size() > 0 && static_cast< unsigned int > (index) < m_Objects.size(); } return false; } T& Front() { return m_Objects.front(); } T& Back() { return m_Objects.back(); } T& Get( unsigned int index ) { return m_Objects.at(index); } const T& Front() const { return m_Objects.front(); } const T& Back() const { return m_Objects.back(); } const T& Get( unsigned int index ) const { return m_Objects.at(index); } void AddObserver( SetObserver* observer ) const { m_SetObserver.insert( observer ); } void RemoveObserver( SetObserver* observer ) const { m_SetObserver.erase( observer ); } void OnObjectModified(const itk::Object* caller , const itk::EventObject &event) { unsigned int i=0; for(; i(m_Objects.at(i)) == caller ) break; const itk::DeleteEvent* delEvent = dynamic_cast(&event); // inform listeners for(typename std::set*>::iterator it = m_SetObserver.begin(); it != m_SetObserver.end(); ++it) delEvent ? (*it)->OnDelete( this->Get(i) ) : (*it)->OnModified( this->Get(i) ); // remove from list if object was deleted (no dangling pointers) if(delEvent) { this->Remove(i); } } Set(const Set& other) { *this = other; } Set& operator= (const Set& other) { // do not simply copy -> because of observer objects // instead: use add method for each element of the other List for(int i=0; iAdd( other.Get(i) ); return *this; } virtual ~Set() { this->Clear(); } protected: /// /// Holds all objects /// std::vector m_Objects; /// /// holds the list of observed itk objects (will be updated in setat()) /// mutable std::set*> m_SetObserver; /// /// \brief Holds all tags of Modified Event Listeners. /// std::map m_ObjectModifiedTags; /// /// \brief Holds all tags of Modified Event Listeners. /// std::map m_ObjectDeleteTags; }; } // namespace mitk #endif // mitkSet_H