From 2433b36f70a21f403c7f42eee91d24da210c839a Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 5 Mar 2021 14:53:44 +0100 Subject: [PATCH] Gui: harmonize API of Gui document observer classes with App document observer classes --- src/Gui/DocumentObserver.cpp | 110 ++++++++++++++++++++++++++--------- src/Gui/DocumentObserver.h | 101 +++++++++++++++++++++++++++++--- 2 files changed, 175 insertions(+), 36 deletions(-) diff --git a/src/Gui/DocumentObserver.cpp b/src/Gui/DocumentObserver.cpp index 6959f94b70..04d76299ad 100644 --- a/src/Gui/DocumentObserver.cpp +++ b/src/Gui/DocumentObserver.cpp @@ -124,34 +124,58 @@ ViewProviderT::ViewProviderT() { } -ViewProviderT::ViewProviderT(ViewProviderDocumentObject* obj) +ViewProviderT::ViewProviderT(const ViewProviderT& other) { - object = obj->getObject()->getNameInDocument(); - document = obj->getObject()->getDocument()->getName(); + *this = other; } -ViewProviderT::ViewProviderT(const ViewProviderT& vp) +ViewProviderT::ViewProviderT(ViewProviderT &&other) { - object = vp.object; - document = vp.document; + *this = std::move(other); +} + +ViewProviderT::ViewProviderT(const ViewProviderDocumentObject* obj) +{ + *this = obj; } ViewProviderT::~ViewProviderT() { } -void ViewProviderT::operator=(const ViewProviderT& obj) +ViewProviderT & ViewProviderT::operator=(const ViewProviderT& obj) { if (this == &obj) - return; + return *this; object = obj.object; document = obj.document; + return *this; +} + +ViewProviderT &ViewProviderT::operator=(ViewProviderT&& obj) +{ + if (this == &obj) + return *this; + object = std::move(obj.object); + document = std::move(obj.document); + return *this; } void ViewProviderT::operator=(const ViewProviderDocumentObject* obj) { - object = obj->getObject()->getNameInDocument(); - document = obj->getObject()->getDocument()->getName(); + if (!obj) { + object.clear(); + document.clear(); + } + else { + object = obj->getObject()->getNameInDocument(); + document = obj->getObject()->getDocument()->getName(); + } +} + +bool ViewProviderT::operator==(const ViewProviderT &other) const { + return document == other.document + && object == other.object; } Document* ViewProviderT::getDocument() const @@ -159,7 +183,7 @@ Document* ViewProviderT::getDocument() const return Application::Instance->getDocument(document.c_str()); } -std::string ViewProviderT::getDocumentName() const +const std::string& ViewProviderT::getDocumentName() const { return document; } @@ -186,7 +210,7 @@ ViewProviderDocumentObject* ViewProviderT::getViewProvider() const return obj; } -std::string ViewProviderT::getObjectName() const +const std::string& ViewProviderT::getObjectName() const { return object; } @@ -262,21 +286,7 @@ Gui::Document* DocumentWeakPtrT::operator->() noexcept class ViewProviderWeakPtrT::Private { public: Private(ViewProviderDocumentObject* obj) : object(obj), indocument(false) { - try { - if (obj) { - Gui::Document* doc = obj->getDocument(); - indocument = true; - connectApplicationDeletedDocument = doc->signalDeleteDocument.connect(boost::bind - (&Private::deletedDocument, this, bp::_1)); - connectDocumentCreatedObject = doc->signalNewObject.connect(boost::bind - (&Private::createdObject, this, bp::_1)); - connectDocumentDeletedObject = doc->signalDeletedObject.connect(boost::bind - (&Private::deletedObject, this, bp::_1)); - } - } - catch (const Base::RuntimeError&) { - // getDocument() may raise an exception - } + set(obj); } void deletedDocument(const Gui::Document& doc) { // When deleting document then there is no way to undo it @@ -302,6 +312,26 @@ public: object = nullptr; indocument = false; } + void set(ViewProviderDocumentObject* obj) { + object = obj; + try { + if (obj) { + Gui::Document* doc = obj->getDocument(); + indocument = true; + connectApplicationDeletedDocument = doc->signalDeleteDocument.connect(boost::bind + (&Private::deletedDocument, this, bp::_1)); + connectDocumentCreatedObject = doc->signalNewObject.connect(boost::bind + (&Private::createdObject, this, bp::_1)); + connectDocumentDeletedObject = doc->signalDeletedObject.connect(boost::bind + (&Private::deletedObject, this, bp::_1)); + } + } + catch (const Base::RuntimeError&) { + // getDocument() may raise an exception + object = nullptr; + indocument = false; + } + } ViewProviderDocumentObject* get() const { return indocument ? object : nullptr; } @@ -314,7 +344,7 @@ public: Connection connectDocumentDeletedObject; }; -ViewProviderWeakPtrT::ViewProviderWeakPtrT(ViewProviderDocumentObject* obj) noexcept +ViewProviderWeakPtrT::ViewProviderWeakPtrT(ViewProviderDocumentObject* obj) : d(new Private(obj)) { } @@ -329,7 +359,7 @@ ViewProviderDocumentObject* ViewProviderWeakPtrT::_get() const noexcept return d->get(); } -void ViewProviderWeakPtrT::reset() noexcept +void ViewProviderWeakPtrT::reset() { d->reset(); } @@ -339,17 +369,39 @@ bool ViewProviderWeakPtrT::expired() const noexcept return !d->indocument; } +ViewProviderWeakPtrT& ViewProviderWeakPtrT::operator= (ViewProviderDocumentObject* p) +{ + d->reset(); + d->set(p); + return *this; +} + ViewProviderDocumentObject* ViewProviderWeakPtrT::operator->() noexcept { return d->get(); } +bool ViewProviderWeakPtrT::operator== (const ViewProviderWeakPtrT& p) const noexcept +{ + return d->get() == p.d->get(); +} + +bool ViewProviderWeakPtrT::operator!= (const ViewProviderWeakPtrT& p) const noexcept +{ + return d->get() != p.d->get(); +} + // ----------------------------------------------------------------------------- DocumentObserver::DocumentObserver() { } +DocumentObserver::DocumentObserver(Document* doc) +{ + attachDocument(doc); +} + DocumentObserver::~DocumentObserver() { } diff --git a/src/Gui/DocumentObserver.h b/src/Gui/DocumentObserver.h index 9e4fca62f2..90f84dcd00 100644 --- a/src/Gui/DocumentObserver.h +++ b/src/Gui/DocumentObserver.h @@ -86,20 +86,26 @@ public: /*! Constructor */ ViewProviderT(); /*! Constructor */ - ViewProviderT(ViewProviderDocumentObject*); - /*! Constructor */ ViewProviderT(const ViewProviderT&); + /*! Constructor */ + ViewProviderT(ViewProviderT &&); + /*! Constructor */ + ViewProviderT(const ViewProviderDocumentObject*); /*! Destructor */ ~ViewProviderT(); /*! Assignment operator */ - void operator=(const ViewProviderT&); + ViewProviderT &operator=(const ViewProviderT&); + /*! Assignment operator */ + ViewProviderT &operator=(ViewProviderT &&); /*! Assignment operator */ void operator=(const ViewProviderDocumentObject*); + /*! Equality operator */ + bool operator==(const ViewProviderT&) const; /*! Get a pointer to the document or 0 if it doesn't exist any more. */ Document* getDocument() const; /*! Get the name of the document. */ - std::string getDocumentName() const; + const std::string &getDocumentName() const; /*! Get the Gui::Document as Python command. */ std::string getGuiDocumentPython() const; /*! Get the App::Document as Python command. */ @@ -107,7 +113,7 @@ public: /*! Get a pointer to the document object or 0 if it doesn't exist any more. */ ViewProviderDocumentObject* getViewProvider() const; /*! Get the name of the document object. */ - std::string getObjectName() const; + const std::string &getObjectName() const; /*! Get the document object as Python command. */ std::string getObjectPython() const; /*! Get a pointer to the document or 0 if it doesn't exist any more or the type doesn't match. */ @@ -162,24 +168,39 @@ private: class AppExport ViewProviderWeakPtrT { public: - ViewProviderWeakPtrT(ViewProviderDocumentObject*) noexcept; + ViewProviderWeakPtrT(ViewProviderDocumentObject*); ~ViewProviderWeakPtrT(); /*! * \brief reset * Releases the reference to the managed object. After the call *this manages no object. */ - void reset() noexcept; + void reset(); /*! * \brief expired * \return true if the managed object has already been deleted, false otherwise. */ bool expired() const noexcept; + /*! + * \brief operator = + * Assignment operator + */ + ViewProviderWeakPtrT& operator= (ViewProviderDocumentObject* p); /*! * \brief operator -> * \return pointer to the document */ ViewProviderDocumentObject* operator->() noexcept; + /*! + * \brief operator == + * \return true if both objects are equal, false otherwise + */ + bool operator== (const ViewProviderWeakPtrT& p) const noexcept; + /*! + * \brief operator != + * \return true if both objects are inequal, false otherwise + */ + bool operator!= (const ViewProviderWeakPtrT& p) const noexcept; /*! Get a pointer to the object or 0 if it doesn't exist any more or the type doesn't match. */ template inline T* get() const noexcept @@ -198,6 +219,71 @@ private: std::unique_ptr d; }; +/** + * @brief The WeakPtrT class + */ +template +class WeakPtrT +{ +public: + WeakPtrT(T* t) : ptr(t) { + } + ~WeakPtrT() { + } + + /*! + * \brief reset + * Releases the reference to the managed object. After the call *this manages no object. + */ + void reset() { + ptr.reset(); + } + /*! + * \brief expired + * \return true if the managed object has already been deleted, false otherwise. + */ + bool expired() const { + return ptr.expired(); + } + /*! + * \brief operator = + * Assignment operator + */ + WeakPtrT& operator= (T* p) { + ptr = p; + return *this; + } + /*! + * \brief operator -> + * \return pointer to the document + */ + T* operator->() { + return ptr.get(); + } + /*! + * \brief operator == + * \return true if both objects are equal, false otherwise + */ + bool operator== (const WeakPtrT& p) const { + return ptr == p.ptr; + } + /*! + * \brief operator != + * \return true if both objects are inequal, false otherwise + */ + bool operator!= (const WeakPtrT& p) const { + return ptr != p.ptr; + } + +private: + // disable + WeakPtrT(const WeakPtrT&); + WeakPtrT& operator=(const WeakPtrT&); + +private: + ViewProviderWeakPtrT ptr; +}; + /** * The DocumentObserver class simplifies the step to write classes that listen * to what happens inside a document. @@ -211,6 +297,7 @@ class GuiExport DocumentObserver public: /// Constructor DocumentObserver(); + DocumentObserver(Document*); virtual ~DocumentObserver(); /** Attaches to another document, the old document