diff --git a/src/blackcore/airspace_monitor.cpp b/src/blackcore/airspace_monitor.cpp index e915aa301..fac3dad8c 100644 --- a/src/blackcore/airspace_monitor.cpp +++ b/src/blackcore/airspace_monitor.cpp @@ -149,10 +149,10 @@ namespace BlackCore QList CAirspaceMonitor::connectRemoteAircraftProviderSignals( QObject *receiver, - std::function situationSlot, + std::function situationSlot, std::function partsSlot, - std::function removedAircraftSlot, - std::function aircraftSnapshotSlot + std::function removedAircraftSlot, + std::function aircraftSnapshotSlot ) { Q_ASSERT_X(receiver, Q_FUNC_INFO, "Missing receiver"); diff --git a/src/blackcore/simulator_common.cpp b/src/blackcore/simulator_common.cpp index 866c4023a..cedab5675 100644 --- a/src/blackcore/simulator_common.cpp +++ b/src/blackcore/simulator_common.cpp @@ -35,12 +35,14 @@ namespace BlackCore this->setObjectName("Simulator:" + info.getIdentifier()); // provider signals - m_remoteAircraftProviderConnections = this->m_remoteAircraftProvider->connectRemoteAircraftProviderSignals( + m_remoteAircraftProviderConnections.append( + this->m_remoteAircraftProvider->connectRemoteAircraftProviderSignals( this, // receiver must match object in bind std::bind(&CSimulatorCommon::ps_remoteProviderAddAircraftSituation, this, std::placeholders::_1), std::bind(&CSimulatorCommon::ps_remoteProviderAddAircraftParts, this, std::placeholders::_1, std::placeholders::_2), std::bind(&CSimulatorCommon::ps_remoteProviderRemovedAircraft, this, std::placeholders::_1), - std::bind(&CSimulatorCommon::ps_recalculateRenderedAircraft, this, std::placeholders::_1)); + std::bind(&CSimulatorCommon::ps_recalculateRenderedAircraft, this, std::placeholders::_1)) + ); // timer this->m_oneSecondTimer.setObjectName(this->objectName().append(":m_oneSecondTimer")); @@ -219,14 +221,7 @@ namespace BlackCore void CSimulatorCommon::unload() { this->disconnectFrom(); // disconnect from simulator - - // disconnect as many signals as possible - for (const QMetaObject::Connection &c : m_remoteAircraftProviderConnections) - { - QObject::disconnect(c); - } - m_remoteAircraftProviderConnections.clear(); - this->disconnect(); + this->m_remoteAircraftProviderConnections.disconnectAll(); CLogHandler::instance()->disconnect(); } diff --git a/src/blackcore/simulator_common.h b/src/blackcore/simulator_common.h index 2106ae653..e6eb1357b 100644 --- a/src/blackcore/simulator_common.h +++ b/src/blackcore/simulator_common.h @@ -27,6 +27,7 @@ #include "blackmisc/network/textmessage.h" #include "blackmisc/network/client.h" #include "blackmisc/pixmap.h" +#include "blackmisc/connectionguard.h" #include namespace BlackCore @@ -137,7 +138,7 @@ namespace BlackCore bool setInitialAircraftSituation(BlackMisc::Simulation::CSimulatedAircraft &aircraft) const; protected: - IInterpolator *m_interpolator = nullptr; //!< interpolator instance + IInterpolator *m_interpolator = nullptr; //!< interpolator instance bool m_pausedSimFreezesInterpolation = false; //!< paused simulator will also pause interpolation (so AI aircraft will hold) private: @@ -152,7 +153,7 @@ namespace BlackCore BlackMisc::Aviation::CCallsignSet m_callsignsToBeRendered; //!< callsigns which will be rendered int m_maxRenderedAircraft = MaxAircraftInfinite; //!< max.rendered aircraft BlackMisc::PhysicalQuantities::CLength m_maxRenderedDistance { 0.0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()}; //!< max.distance for rendering - QList m_remoteAircraftProviderConnections; //!< connected signal/slots + BlackMisc::CConnectionGuard m_remoteAircraftProviderConnections; //!< connected signal/slots }; } // namespace diff --git a/src/blackgui/components/enablefordockwidgetinfoarea.cpp b/src/blackgui/components/enablefordockwidgetinfoarea.cpp index 1a978d6e2..f15a2c525 100644 --- a/src/blackgui/components/enablefordockwidgetinfoarea.cpp +++ b/src/blackgui/components/enablefordockwidgetinfoarea.cpp @@ -42,6 +42,7 @@ namespace BlackGui this->m_parentDockableInfoArea = nullptr; }); Q_ASSERT_X(con, Q_FUNC_INFO, "Connection failed"); + this->m_connections.append(con); return true; } diff --git a/src/blackgui/components/enablefordockwidgetinfoarea.h b/src/blackgui/components/enablefordockwidgetinfoarea.h index 2ec7af859..a606aec4e 100644 --- a/src/blackgui/components/enablefordockwidgetinfoarea.h +++ b/src/blackgui/components/enablefordockwidgetinfoarea.h @@ -16,7 +16,7 @@ #include "blackgui/dockwidgetinfoarea.h" #include "blackgui/infoarea.h" #include "blackgui/enableforframelesswindow.h" -#include "blackmisc/qtconnectionlist.h" +#include "blackmisc/connectionguard.h" #include namespace BlackGui @@ -69,6 +69,7 @@ namespace BlackGui private: BlackGui::CDockWidgetInfoArea *m_parentDockableInfoArea = nullptr; //!< my parent dockable widget + BlackMisc::CConnectionGuard m_connections; }; } } // namespace diff --git a/src/blackmisc/connectionguard.cpp b/src/blackmisc/connectionguard.cpp new file mode 100644 index 000000000..228e3bb56 --- /dev/null +++ b/src/blackmisc/connectionguard.cpp @@ -0,0 +1,45 @@ +/* Copyright (C) 2015 + * 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. + */ + +#include "connectionguard.h" + +namespace BlackMisc +{ + CConnectionGuard::CConnectionGuard(const QMetaObject::Connection &connection) + { + this->m_connections.append(connection); + } + + void CConnectionGuard::append(const QMetaObject::Connection &connection) + { + this->m_connections.append(connection); + } + + void CConnectionGuard::append(const QList &connections) + { + this->m_connections.append(connections); + } + + CConnectionGuard::~CConnectionGuard() + { + disconnectAll(); + } + + int CConnectionGuard::disconnectAll() + { + if (this->m_connections.isEmpty()) { return 0; } + int c = 0; + for (const QMetaObject::Connection &con : this->m_connections) + { + if (QObject::disconnect(con)) { c++; } + } + this->m_connections.clear(); + return c; + } +} // ns diff --git a/src/blackmisc/connectionguard.h b/src/blackmisc/connectionguard.h new file mode 100644 index 000000000..e56950e65 --- /dev/null +++ b/src/blackmisc/connectionguard.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2015 + * 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_CONNECTIONGUARD_H +#define BLACKMISC_CONNECTIONGUARD_H + +#include "blackmisc/blackmiscexport.h" +#include +#include + +namespace BlackMisc +{ + /*! + * List of QMetaObject::Connection. The trick here is that those connections will + * be disconnected when the object is destroyed. So it can be used with lambdas or bind which feature + * non QObjects, if those might be destroyed before the signaling QObject. + */ + class BLACKMISC_EXPORT CConnectionGuard : public QObject + { + Q_OBJECT + + public: + //! Constructor + CConnectionGuard() = default; + + //! Constructor + CConnectionGuard(const QMetaObject::Connection &connection); + + //! Destructor + ~CConnectionGuard(); + + //! Add connection + void append(const QMetaObject::Connection &connection); + + //! Add connections + void append(const QList &connections); + + //! Disconnect all + int disconnectAll(); + + private: + QList m_connections; + }; +} // BlackMisc + +#endif diff --git a/src/blackmisc/network/webdataservicesprovider.cpp b/src/blackmisc/network/webdataservicesprovider.cpp index 59916169b..850916c67 100644 --- a/src/blackmisc/network/webdataservicesprovider.cpp +++ b/src/blackmisc/network/webdataservicesprovider.cpp @@ -21,7 +21,7 @@ namespace BlackMisc { CWebDataServicesAware::~CWebDataServicesAware() { - disconnectSignals(); + this->m_swiftConnections.disconnectAll(); } CServerList CWebDataServicesAware::getVatsimFsdServers() const @@ -264,7 +264,7 @@ namespace BlackMisc void CWebDataServicesAware::setProvider(IWebDataServicesProvider *webDataReaderProvider) { Q_ASSERT_X(webDataReaderProvider, Q_FUNC_INFO, "missing provider"); - disconnectSignals(); + this->m_swiftConnections.disconnectAll(); m_webDataReaderProvider = webDataReaderProvider; } @@ -275,7 +275,7 @@ namespace BlackMisc void CWebDataServicesAware::gracefulShutdown() { - disconnectSignals(); + this->m_swiftConnections.disconnectAll(); this->m_webDataReaderProvider = nullptr; } @@ -317,13 +317,5 @@ namespace BlackMisc return this->m_webDataReaderProvider->readDbDataFromDisk(dir, inBackround); } - void CWebDataServicesAware::disconnectSignals() - { - for (QMetaObject::Connection &c : m_swiftConnections) - { - QObject::disconnect(c); - } - m_swiftConnections.clear(); - } } // namespace } // namespace diff --git a/src/blackmisc/network/webdataservicesprovider.h b/src/blackmisc/network/webdataservicesprovider.h index fe750985b..ce415e553 100644 --- a/src/blackmisc/network/webdataservicesprovider.h +++ b/src/blackmisc/network/webdataservicesprovider.h @@ -26,6 +26,7 @@ #include "blackmisc/simulation/simulatedaircraft.h" #include "blackmisc/weather/metarset.h" #include "blackmisc/countrylist.h" +#include "blackmisc/connectionguard.h" #include @@ -343,8 +344,8 @@ namespace BlackMisc CWebDataServicesAware(IWebDataServicesProvider *webDataReaderProvider = nullptr) : m_webDataReaderProvider(webDataReaderProvider) { } private: - IWebDataServicesProvider *m_webDataReaderProvider = nullptr; //!< access to object - QList m_swiftConnections; //!< signal connection with swift + IWebDataServicesProvider *m_webDataReaderProvider = nullptr; //!< access to object + BlackMisc::CConnectionGuard m_swiftConnections; //!< signal connection with swift //! Disconnect all signals void disconnectSignals(); diff --git a/src/blackmisc/simulation/remoteaircraftprovider.h b/src/blackmisc/simulation/remoteaircraftprovider.h index 9dd6d9e43..ba9e41691 100644 --- a/src/blackmisc/simulation/remoteaircraftprovider.h +++ b/src/blackmisc/simulation/remoteaircraftprovider.h @@ -110,7 +110,7 @@ namespace BlackMisc virtual QList connectRemoteAircraftProviderSignals( QObject *receiver, std::function addedSituationSlot, - std::function addedPartsSlot, + std::function addedPartsSlot, std::function removedAircraftSlot, std::function aircraftSnapshot ) = 0; diff --git a/src/blackmisc/simulation/remoteaircraftproviderdummy.cpp b/src/blackmisc/simulation/remoteaircraftproviderdummy.cpp index b40357522..e11fd0c7f 100644 --- a/src/blackmisc/simulation/remoteaircraftproviderdummy.cpp +++ b/src/blackmisc/simulation/remoteaircraftproviderdummy.cpp @@ -72,10 +72,10 @@ namespace BlackMisc QList CRemoteAircraftProviderDummy::connectRemoteAircraftProviderSignals( QObject *receiver, - std::function situationSlot, - std::function partsSlot, - std::function removedAircraftSlot, - std::function aircraftSnapshotSlot + std::function situationSlot, + std::function partsSlot, + std::function removedAircraftSlot, + std::function aircraftSnapshotSlot ) { Q_ASSERT_X(receiver, Q_FUNC_INFO, "Missing receiver");