From d99a1cac875820d1ab7abde8eee8a0f1b7336e32 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Mon, 12 Mar 2018 17:57:52 +0100 Subject: [PATCH] Ref T259, Ref T243 base class for providers/aware classes * disable aware classes when provider is destroyed * unified base class --- src/blackmisc/provider.h | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/blackmisc/provider.h diff --git a/src/blackmisc/provider.h b/src/blackmisc/provider.h new file mode 100644 index 000000000..b559a9f93 --- /dev/null +++ b/src/blackmisc/provider.h @@ -0,0 +1,77 @@ +/* Copyright (C) 2018 + * Swift Project Community / Contributors + * + * This file is part of Swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_PROVIDER_H +#define BLACKMISC_PROVIDER_H + +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/connectionguard.h" +#include +#include + +namespace BlackMisc +{ + //! Base class for providers + class IProvider + { + public: + //! Return as QObject + virtual QObject *asQObject() { return nullptr; } + }; + + //! Base class of provider aware classes + template class BLACKMISC_EXPORT IProviderAware + { + protected: + //! Ctor + IProviderAware(PROVIDER *provider = nullptr) { this->setProvider(provider); } + + //! Has provider? + bool hasProvider() const { return m_provider; } + + //! Set the provider + //! \remark use individual names to disambiguate + void setProvider(PROVIDER *provider) + { + if (m_provider) { m_lastProviderConnections.disconnectAll(); } + m_provider = provider; // new provider + IProvider *iProvider = dynamic_cast(provider); + if (iProvider && iProvider->asQObject()) + { + QMetaObject::Connection con = QObject::connect(iProvider->asQObject(), &QObject::destroyed, [ = ](QObject * obj) { this->onProviderDestroyed(obj); }); + m_lastProviderConnections.append(con); + } + } + + //! Provider + PROVIDER *provider() { return m_provider; } + + //! Const provider + const PROVIDER *provider() const { return m_provider; } + + private: + CConnectionGuard m_lastProviderConnections; //!< provider signal connections + PROVIDER *m_provider = nullptr; //!< access to provider object + + //! Provider was deleted + virtual void onProviderDestroyed(QObject *obj) + { + if (!m_provider) { return; } // already cleaned relationship + PROVIDER *provider = qobject_cast(obj); // provider is implemented by a QObject + if (provider != m_provider) { return; } // not our business + m_provider = nullptr; + } + }; +} // namespace + +Q_DECLARE_INTERFACE(BlackMisc::IProvider, "org.swift-project.blackmisc.iprovider") + +#endif // guard