From 949110d73d104309e522c3d5564c43a8ecb41a4b Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 16 Mar 2020 15:11:11 +0100 Subject: [PATCH] App: [skip ci] implement WekPtrT to simplify using DocumentObjectWeakPtrT --- src/App/DocumentObserver.cpp | 57 ++++++++++++++++-------- src/App/DocumentObserver.h | 84 +++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 20 deletions(-) diff --git a/src/App/DocumentObserver.cpp b/src/App/DocumentObserver.cpp index 789386ba8e..299527d838 100644 --- a/src/App/DocumentObserver.cpp +++ b/src/App/DocumentObserver.cpp @@ -447,16 +447,7 @@ App::Document* DocumentWeakPtrT::operator->() noexcept class DocumentObjectWeakPtrT::Private { public: Private(App::DocumentObject* obj) : object(obj), indocument(false) { - if (obj) { - indocument = true; - connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind - (&Private::deletedDocument, this, _1)); - App::Document* doc = obj->getDocument(); - connectDocumentCreatedObject = doc->signalNewObject.connect(boost::bind - (&Private::createdObject, this, _1)); - connectDocumentDeletedObject = doc->signalDeletedObject.connect(boost::bind - (&Private::deletedObject, this, _1)); - } + set(obj); } void deletedDocument(const App::Document& doc) { // When deleting document then there is no way to undo it @@ -464,13 +455,13 @@ public: reset(); } } - void createdObject(const App::DocumentObject& obj) { + void createdObject(const App::DocumentObject& obj) noexcept { // When undoing the removal if (object == &obj) { indocument = true; } } - void deletedObject(const App::DocumentObject& obj) { + void deletedObject(const App::DocumentObject& obj) noexcept { if (object == &obj) { indocument = false; } @@ -482,7 +473,20 @@ public: object = nullptr; indocument = false; } - App::DocumentObject* get() const { + void set(App::DocumentObject* obj) { + object = obj; + if (obj) { + indocument = true; + connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind + (&Private::deletedDocument, this, _1)); + App::Document* doc = obj->getDocument(); + connectDocumentCreatedObject = doc->signalNewObject.connect(boost::bind + (&Private::createdObject, this, _1)); + connectDocumentDeletedObject = doc->signalDeletedObject.connect(boost::bind + (&Private::deletedObject, this, _1)); + } + } + App::DocumentObject* get() const noexcept { return indocument ? object : nullptr; } @@ -494,7 +498,7 @@ public: Connection connectDocumentDeletedObject; }; -DocumentObjectWeakPtrT::DocumentObjectWeakPtrT(App::DocumentObject* obj) noexcept +DocumentObjectWeakPtrT::DocumentObjectWeakPtrT(App::DocumentObject* obj) : d(new Private(obj)) { } @@ -509,7 +513,7 @@ App::DocumentObject* DocumentObjectWeakPtrT::_get() const noexcept return d->get(); } -void DocumentObjectWeakPtrT::reset() noexcept +void DocumentObjectWeakPtrT::reset() { d->reset(); } @@ -519,14 +523,31 @@ bool DocumentObjectWeakPtrT::expired() const noexcept return !d->indocument; } +DocumentObjectWeakPtrT& DocumentObjectWeakPtrT::operator= (App::DocumentObject* p) +{ + d->reset(); + d->set(p); + return *this; +} + App::DocumentObject* DocumentObjectWeakPtrT::operator->() noexcept { return d->get(); } +bool DocumentObjectWeakPtrT::operator== (const DocumentObjectWeakPtrT& p) const noexcept +{ + return d->get() == p.d->get(); +} + +bool DocumentObjectWeakPtrT::operator!= (const DocumentObjectWeakPtrT& p) const noexcept +{ + return d->get() != p.d->get(); +} + // ----------------------------------------------------------------------------- -DocumentObserver::DocumentObserver() : _document(0) +DocumentObserver::DocumentObserver() : _document(nullptr) { this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(boost::bind (&DocumentObserver::slotCreatedDocument, this, _1)); @@ -534,7 +555,7 @@ DocumentObserver::DocumentObserver() : _document(0) (&DocumentObserver::slotDeletedDocument, this, _1)); } -DocumentObserver::DocumentObserver(Document* doc) : _document(0) +DocumentObserver::DocumentObserver(Document* doc) : _document(nullptr) { // Connect to application and given document this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(boost::bind @@ -579,7 +600,7 @@ void DocumentObserver::attachDocument(Document* doc) void DocumentObserver::detachDocument() { if (this->_document) { - this->_document = 0; + this->_document = nullptr; this->connectDocumentCreatedObject.disconnect(); this->connectDocumentDeletedObject.disconnect(); this->connectDocumentChangedObject.disconnect(); diff --git a/src/App/DocumentObserver.h b/src/App/DocumentObserver.h index 53dea56df7..3fa6329dc2 100644 --- a/src/App/DocumentObserver.h +++ b/src/App/DocumentObserver.h @@ -249,24 +249,39 @@ private: class AppExport DocumentObjectWeakPtrT { public: - DocumentObjectWeakPtrT(App::DocumentObject*) noexcept; + DocumentObjectWeakPtrT(App::DocumentObject*); ~DocumentObjectWeakPtrT(); /*! * \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 + */ + DocumentObjectWeakPtrT& operator= (App::DocumentObject* p); /*! * \brief operator -> * \return pointer to the document */ App::DocumentObject* operator->() noexcept; + /*! + * \brief operator == + * \return true if both objects are equal, false otherwise + */ + bool operator== (const DocumentObjectWeakPtrT& p) const noexcept; + /*! + * \brief operator != + * \return true if both objects are inequal, false otherwise + */ + bool operator!= (const DocumentObjectWeakPtrT& 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 @@ -285,6 +300,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: + DocumentObjectWeakPtrT ptr; +}; + /** * The DocumentObserver class simplfies the step to write classes that listen * to what happens inside a document.