From a4d09405b0be32848413f49a871c2796f92ace45 Mon Sep 17 00:00:00 2001 From: Valentin Platzgummer Date: Sun, 31 Jan 2021 19:36:05 +0100 Subject: [PATCH] temp --- .../MeasurementComplexItem.cc | 31 +- .../MeasurementComplexItem.h | 15 + src/MeasurementComplexItem/NemoInterface.cpp | 442 ++++++++++-------- src/MeasurementComplexItem/NemoInterface.h | 40 +- .../MeasurementComplexItem.SettingsGroup.json | 7 + src/QGCApplication.cc | 2 +- 6 files changed, 324 insertions(+), 213 deletions(-) diff --git a/src/MeasurementComplexItem/MeasurementComplexItem.cc b/src/MeasurementComplexItem/MeasurementComplexItem.cc index 76948c5ea..c66dd8cc3 100644 --- a/src/MeasurementComplexItem/MeasurementComplexItem.cc +++ b/src/MeasurementComplexItem/MeasurementComplexItem.cc @@ -41,6 +41,7 @@ const char *variantNamesKey = "VariantNames"; const char *generatorArrayKey = "GeneratorArray"; const char *variantArrayKey = "VariantArray"; const char *generatorIndexKey = "GeneratorIndex"; +const char *connectionsStringKey = "ConnectionString"; } // namespace MeasurementComplexItem::MeasurementComplexItem( @@ -55,7 +56,8 @@ MeasurementComplexItem::MeasurementComplexItem( _variantIndex(settingsGroup, _metaDataMap[variantIndexKey]), _pAreaData(new AreaData(this)), _pEditorData(new AreaData(this)), _pCurrentData(_pAreaData), _holdProgress(false), _pGenerator(nullptr), - _pWorker(new RoutingThread(this)) { + _pWorker(new RoutingThread(this)), + _nemoCString(settingsGroup, _metaDataMap[connectionsStringKey]) { // Setup altitude. _altitude.setRawValue(qgcApp() @@ -91,17 +93,17 @@ MeasurementComplexItem::MeasurementComplexItem( &MeasurementComplexItem::_storeRoutingData); // Connect coordinate and exitCoordinate. - connect(this, &MeasurementComplexItem::routeChanged, + connect(this, &MeasurementComplexItem::routeChanged, this, [this] { emit this->coordinateChanged(this->coordinate()); }); - connect(this, &MeasurementComplexItem::routeChanged, + connect(this, &MeasurementComplexItem::routeChanged, this, [this] { emit this->exitCoordinateChanged(this->exitCoordinate()); }); - connect(this, &MeasurementComplexItem::routeChanged, [this] { + connect(this, &MeasurementComplexItem::routeChanged, this, [this] { emit this->exitCoordinateSameAsEntryChanged( this->exitCoordinateSameAsEntry()); }); // Connect isIncomplete. - connect(this, &MeasurementComplexItem::idleChanged, [this] { + connect(this, &MeasurementComplexItem::idleChanged, this, [this] { if (this->idle()) { if (this->route().size() > 0 && this->_isIncomplete == true) { this->_isIncomplete = false; @@ -124,14 +126,14 @@ MeasurementComplexItem::MeasurementComplexItem( &MeasurementComplexItem::_updateFlightpathSegments); // Connect complexDistance. - connect(this, &MeasurementComplexItem::routeChanged, + connect(this, &MeasurementComplexItem::routeChanged, this, [this] { emit this->complexDistanceChanged(); }); resetGenerators(); startEditing(); // connect to nemo interface - connect(pNemoInterface, &NemoInterface::progressChanged, this, + connect(pNemoInterface, &Nemointerface::progressChanged, this, &MeasurementComplexItem::_onNewProgress); } @@ -773,6 +775,17 @@ void MeasurementComplexItem::_onAltitudeChanged() { } } +QString MeasurementComplexItem::nemoError() const { return _nemoError; } + +void MeasurementComplexItem::_setNemoError(const QString &nemoError) { + if (_nemoError != nemoError) { + _nemoError = nemoError; + emit nemoErrorChanged(); + } +} + +Fact *MeasurementComplexItem::nemoCString() { return &_nemoCString; } + bool MeasurementComplexItem::holdProgress() const { return _holdProgress; } void MeasurementComplexItem::setHoldProgress(bool holdProgress) { @@ -781,10 +794,10 @@ void MeasurementComplexItem::setHoldProgress(bool holdProgress) { emit holdProgressChanged(); if (_holdProgress) { - disconnect(pNemoInterface, &NemoInterface::progressChanged, this, + disconnect(pNemoInterface, &Nemointerface::progressChanged, this, &MeasurementComplexItem::_onNewProgress); } else { - connect(pNemoInterface, &NemoInterface::progressChanged, this, + connect(pNemoInterface, &Nemointerface::progressChanged, this, &MeasurementComplexItem::_onNewProgress); _onNewProgress(pNemoInterface->getProgress()); } diff --git a/src/MeasurementComplexItem/MeasurementComplexItem.h b/src/MeasurementComplexItem/MeasurementComplexItem.h index f3ec040bc..ea58ac437 100644 --- a/src/MeasurementComplexItem/MeasurementComplexItem.h +++ b/src/MeasurementComplexItem/MeasurementComplexItem.h @@ -14,6 +14,7 @@ class RoutingThread; class RoutingResult; +class Nemointerface; namespace routing { class GeneratorBase; @@ -51,6 +52,8 @@ public: Q_PROPERTY(int generatorIndex READ generatorIndex NOTIFY generatorChanged) Q_PROPERTY(AreaData *areaData READ areaData NOTIFY areaDataChanged) Q_PROPERTY(QVariantList route READ route NOTIFY routeChanged) + Q_PROPERTY(QString nemoError READ nemoError NOTIFY nemoErrorChanged) + Q_PROPERTY(Fact *nemoCString READ nemoCString CONSTANT) Q_INVOKABLE void reverseRoute(void); @@ -224,6 +227,10 @@ public: bool holdProgress() const; void setHoldProgress(bool holdProgress); + QString nemoError() const; + + Fact *nemoCString(); + signals: void variantNamesChanged(); @@ -238,6 +245,8 @@ signals: void routeChanged(); void holdProgressChanged(); + void nemoErrorChanged(); + private slots: // Worker functions. @@ -257,6 +266,7 @@ private: static bool _idle(STATE state); void _updateFlightpathSegments(); void _onAltitudeChanged(); + void _setNemoError(const QString &nemoError); // Hirarcical stuff. int _sequenceNumber; @@ -285,4 +295,9 @@ private: QVector _variantVector; Variant _route; PtrWorker _pWorker; + + // NemoInterface + std::shared_ptr _pNemointerface; + QString _nemoError; + SettingsFact _nemoCString; }; diff --git a/src/MeasurementComplexItem/NemoInterface.cpp b/src/MeasurementComplexItem/NemoInterface.cpp index 4d2c4477d..5ff8973b7 100644 --- a/src/MeasurementComplexItem/NemoInterface.cpp +++ b/src/MeasurementComplexItem/NemoInterface.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -52,7 +53,7 @@ Q_DECLARE_METATYPE(ProgressArray) -QGC_LOGGING_CATEGORY(NemoInterfaceLog, "NemoInterfaceLog") +QGC_LOGGING_CATEGORY(NemointerfaceLog, "NemointerfaceLog") #define NO_HEARTBEAT_TIMEOUT 5000 // ms #define RESTART_INTERVAl 600000 // ms == 10 min @@ -98,7 +99,7 @@ typedef ros_bridge::messages::nemo_msgs::heartbeat::Heartbeat Heartbeat; typedef nemo_interface::TaskDispatcher Dispatcher; typedef std::unique_lock Lock; -class NemoInterface::Impl { +class Nemointerface::Impl { enum class STATE { STOPPED, START_BRIDGE, @@ -113,7 +114,7 @@ class NemoInterface::Impl { }; public: - Impl(NemoInterface *p); + Impl(const QString &connectionString, Nemointerface *p); ~Impl(); void start(); @@ -136,12 +137,13 @@ public: ProgressArray getProgress() const; ProgressArray getProgress(const IDArray &idArray) const; - NemoInterface::STATUS status() const; + Nemointerface::STATUS status() const; bool running() const; // thread safe bool ready() const; // thread safe const QString &infoString() const; const QString &warningString() const; + const QString &connectionString() const; private: void _doSetup(); @@ -167,9 +169,9 @@ private: static bool _userSyncNotSafe(STATE s); static bool _sysSyncNotSafe(STATE s); static bool _runningNotSafe(STATE s); - static NemoInterface::STATUS _status(STATE state); + static Nemointerface::STATUS _status(STATE state); static QString _toString(STATE s); - static QString _toString(NemoInterface::STATUS s); + static QString _toString(Nemointerface::STATUS s); // impl functions bool _addTilesImpl( @@ -201,10 +203,11 @@ private: // static and const members static const char *_localVersion; - NemoInterface *const _parent; + Nemointerface *const _parent; + const QString _connectionString; // thread safe members - ROSBridgePtr _pRosbridge; + Rosbridge _rosbridge; Dispatcher _dispatcher; // protected by mutex @@ -221,51 +224,33 @@ private: QTimer _restartTimer; }; -const char *NemoInterface::Impl::_localVersion("V_1.0"); +const char *Nemointerface::Impl::_localVersion("V_1.0"); -using StatusMap = std::map; +using StatusMap = std::map; static StatusMap statusMap{ - std::make_pair( - NemoInterface::STATUS::NOT_CONNECTED, "Not Connected"), - std::make_pair(NemoInterface::STATUS::ERROR, + std::make_pair( + Nemointerface::STATUS::NOT_CONNECTED, "Not Connected"), + std::make_pair(Nemointerface::STATUS::ERROR, "ERROR"), - std::make_pair(NemoInterface::STATUS::SYNC, + std::make_pair(Nemointerface::STATUS::SYNC, "Synchronizing"), - std::make_pair(NemoInterface::STATUS::READY, + std::make_pair(Nemointerface::STATUS::READY, "Ready"), - std::make_pair( - NemoInterface::STATUS::TIMEOUT, "Timeout"), - std::make_pair( - NemoInterface::STATUS::WEBSOCKET_DETECTED, "Websocket Detected")}; - -NemoInterface::Impl::Impl(NemoInterface *p) - : _parent(p), _state(STATE::STOPPED) { - - // ROS Bridge. - WimaSettings *wimaSettings = - qgcApp()->toolbox()->settingsManager()->wimaSettings(); - auto connectionStringFact = wimaSettings->rosbridgeConnectionString(); - auto setConnectionString = [connectionStringFact, this] { - auto connectionString = connectionStringFact->rawValue().toString(); - - bool wasRunning = this->running(); - this->stop(); - this->_pRosbridge = std::make_shared( - QUrl(QString("ws://") + connectionString.toLocal8Bit().data())); - if (wasRunning) { - this->start(); - } - }; + std::make_pair( + Nemointerface::STATUS::TIMEOUT, "Timeout"), + std::make_pair( + Nemointerface::STATUS::WEBSOCKET_DETECTED, "Websocket Detected")}; - connect(connectionStringFact, &SettingsFact::rawValueChanged, - setConnectionString); - setConnectionString(); +Nemointerface::Impl::Impl(const QString &connectionString, Nemointerface *p) + : _parent(p), _connectionString(connectionString), + _rosbridge(QUrl(QString("ws://") + connectionString)), + _state(STATE::STOPPED) { // Heartbeat timeout. connect(&this->_timeoutTimer, &QTimer::timeout, std::bind(&Impl::_onHeartbeatTimeout, this)); - connect(this->_pRosbridge.get(), &Rosbridge::stateChanged, this->_parent, + connect(&this->_rosbridge, &Rosbridge::stateChanged, this->_parent, [this] { this->_onRosbridgeStateChanged(); }); connect(&this->_restartTimer, &QTimer::timeout, this->_parent, @@ -278,9 +263,9 @@ NemoInterface::Impl::Impl(NemoInterface *p) std::call_once(flag, [] { qRegisterMetaType(); }); } -NemoInterface::Impl::~Impl() { this->_pRosbridge->stop(); } +Nemointerface::Impl::~Impl() { this->_rosbridge.stop(); } -void NemoInterface::Impl::start() { +void Nemointerface::Impl::start() { Lock lk(this->_m); if (!_runningNotSafe(this->_state)) { this->_setStateNotSafe(STATE::START_BRIDGE); @@ -288,7 +273,7 @@ void NemoInterface::Impl::start() { } } -void NemoInterface::Impl::stop() { +void Nemointerface::Impl::stop() { Lock lk(this->_m); if (_runningNotSafe(this->_state)) { this->_setStateNotSafe(STATE::STOPPED); @@ -297,7 +282,7 @@ void NemoInterface::Impl::stop() { } std::shared_future -NemoInterface::Impl::addTiles(const TilePtrArray &tileArray) { +Nemointerface::Impl::addTiles(const TilePtrArray &tileArray) { using namespace nemo_interface; // qDebug() << "addTiles called"; @@ -320,7 +305,7 @@ NemoInterface::Impl::addTiles(const TilePtrArray &tileArray) { pTileArray->push_back(pTileCopy); pIdArray->push_back(id); } else { - qCDebug(NemoInterfaceLog) + qCDebug(NemointerfaceLog) << "addTiles(): tile with id: " << pTile->id() << "already added."; } } @@ -364,7 +349,7 @@ NemoInterface::Impl::addTiles(const TilePtrArray &tileArray) { } std::shared_future -NemoInterface::Impl::removeTiles(const IDArray &idArray) { +Nemointerface::Impl::removeTiles(const IDArray &idArray) { using namespace nemo_interface; // qDebug() << "removeTiles called"; @@ -382,7 +367,7 @@ NemoInterface::Impl::removeTiles(const IDArray &idArray) { _localTiles.erase(it); pIdArray->push_back(id); } else { - qCDebug(NemoInterfaceLog) << "removeTiles(): unknown id: " << id << "."; + qCDebug(NemointerfaceLog) << "removeTiles(): unknown id: " << id << "."; } } if (pIdArray->size() > 0) { @@ -426,7 +411,7 @@ NemoInterface::Impl::removeTiles(const IDArray &idArray) { return p.get_future(); } -std::shared_future NemoInterface::Impl::clearTiles() { +std::shared_future Nemointerface::Impl::clearTiles() { using namespace nemo_interface; // qDebug() << "clearTiles called"; @@ -472,7 +457,7 @@ std::shared_future NemoInterface::Impl::clearTiles() { } } -TileArray NemoInterface::Impl::getTiles(const IDArray &idArray) const { +TileArray Nemointerface::Impl::getTiles(const IDArray &idArray) const { TileArray tileArray; Lock lk(this->_m); @@ -503,7 +488,7 @@ TileArray NemoInterface::Impl::getTiles(const IDArray &idArray) const { return tileArray; } -TileArray NemoInterface::Impl::getAllTiles() const { +TileArray Nemointerface::Impl::getAllTiles() const { TileArray tileArray; Lock lk(this->_m); @@ -531,7 +516,7 @@ TileArray NemoInterface::Impl::getAllTiles() const { return tileArray; } -LogicalArray NemoInterface::Impl::containsTiles(const IDArray &idArray) const { +LogicalArray Nemointerface::Impl::containsTiles(const IDArray &idArray) const { LogicalArray logicalArray; Lock lk(this->_m); @@ -543,18 +528,18 @@ LogicalArray NemoInterface::Impl::containsTiles(const IDArray &idArray) const { return logicalArray; } -std::size_t NemoInterface::Impl::size() const { +std::size_t Nemointerface::Impl::size() const { Lock lk(this->_m); return _localTiles.size(); } -bool NemoInterface::Impl::empty() const { +bool Nemointerface::Impl::empty() const { Lock lk(this->_m); return _localTiles.empty(); } -ProgressArray NemoInterface::Impl::getProgress() const { +ProgressArray Nemointerface::Impl::getProgress() const { ProgressArray progressArray; Lock lk(this->_m); @@ -573,7 +558,7 @@ ProgressArray NemoInterface::Impl::getProgress() const { return progressArray; } -ProgressArray NemoInterface::Impl::getProgress(const IDArray &idArray) const { +ProgressArray Nemointerface::Impl::getProgress(const IDArray &idArray) const { ProgressArray progressArray; Lock lk(this->_m); @@ -598,34 +583,34 @@ ProgressArray NemoInterface::Impl::getProgress(const IDArray &idArray) const { return progressArray; } -NemoInterface::STATUS NemoInterface::Impl::status() const { +Nemointerface::STATUS Nemointerface::Impl::status() const { Lock lk(this->_m); return _status(this->_state); } -bool NemoInterface::Impl::running() const { +bool Nemointerface::Impl::running() const { Lock lk1(this->_m); return _runningNotSafe(this->_state); } -bool NemoInterface::Impl::ready() const { +bool Nemointerface::Impl::ready() const { Lock lk1(this->_m); return _readyNotSafe(this->_state); } -bool NemoInterface::Impl::_sysSync() const { +bool Nemointerface::Impl::_sysSync() const { Lock lk1(this->_m); return _sysSyncNotSafe(this->_state); } -void NemoInterface::Impl::_onHeartbeatTimeout() { +void Nemointerface::Impl::_onHeartbeatTimeout() { Lock lk1(this->_m); this->_setStateNotSafe(STATE::HEARTBEAT_TIMEOUT); this->_doActionNotSafe(); } -void NemoInterface::Impl::_onRosbridgeStateChanged() { - auto rbState = this->_pRosbridge->state(); +void Nemointerface::Impl::_onRosbridgeStateChanged() { + auto rbState = this->_rosbridge.state(); if (rbState == Rosbridge::STATE::CONNECTED) { Lock lk1(this->_m); if (this->_state == STATE::START_BRIDGE || @@ -644,22 +629,26 @@ void NemoInterface::Impl::_onRosbridgeStateChanged() { } } -bool NemoInterface::Impl::_userSync() const { +bool Nemointerface::Impl::_userSync() const { Lock lk1(this->_m); return _userSyncNotSafe(this->_state); } -const QString &NemoInterface::Impl::infoString() const { +const QString &Nemointerface::Impl::infoString() const { Lock lk1(this->_m); return _infoString; } -const QString &NemoInterface::Impl::warningString() const { +const QString &Nemointerface::Impl::warningString() const { Lock lk1(this->_m); return _warningString; } -bool NemoInterface::Impl::_updateProgress(const ProgressArray &pArray) { +const QString &Nemointerface::Impl::connectionString() const { + return this->_connectionString; +} + +bool Nemointerface::Impl::_updateProgress(const ProgressArray &pArray) { ProgressArray copy; bool error = false; @@ -673,7 +662,7 @@ bool NemoInterface::Impl::_updateProgress(const ProgressArray &pArray) { it->second->setProgress(itLP->progress()); copy.push_back(*itLP); } else { - qCDebug(NemoInterfaceLog) + qCDebug(NemointerfaceLog) << "_updateProgress(): tile with id " << itLP->id() << " not found."; error = true; } @@ -687,7 +676,7 @@ bool NemoInterface::Impl::_updateProgress(const ProgressArray &pArray) { return !error; } -void NemoInterface::Impl::_onHeartbeatReceived(const QNemoHeartbeat &) { +void Nemointerface::Impl::_onHeartbeatReceived(const QNemoHeartbeat &) { INVM(this->_parent, ([this]() mutable { this->_timeoutTimer.start(NO_HEARTBEAT_TIMEOUT); })) @@ -699,7 +688,7 @@ void NemoInterface::Impl::_onHeartbeatReceived(const QNemoHeartbeat &) { } } -void NemoInterface::Impl::_setInfoStringNotSafe(const QString &info) { +void Nemointerface::Impl::_setInfoStringNotSafe(const QString &info) { if (_infoString != info) { _infoString = info; @@ -709,7 +698,7 @@ void NemoInterface::Impl::_setInfoStringNotSafe(const QString &info) { } } -void NemoInterface::Impl::_setWarningStringNotSafe(const QString &warning) { +void Nemointerface::Impl::_setWarningStringNotSafe(const QString &warning) { if (_warningString != warning) { _warningString = warning; @@ -719,20 +708,20 @@ void NemoInterface::Impl::_setWarningStringNotSafe(const QString &warning) { } } -void NemoInterface::Impl::_setInfoString(const QString &info) { +void Nemointerface::Impl::_setInfoString(const QString &info) { Lock lk(this->_m); _setInfoStringNotSafe(info); } -void NemoInterface::Impl::_setWarningString(const QString &warning) { +void Nemointerface::Impl::_setWarningString(const QString &warning) { Lock lk(this->_m); _setWarningStringNotSafe(warning); } -void NemoInterface::Impl::_doSetup() { +void Nemointerface::Impl::_doSetup() { // create task auto pTask = std::make_unique([this] { - auto rb = this->_pRosbridge; + auto &rb = this->_rosbridge; auto &disp = this->_dispatcher; // check if required services are available @@ -742,7 +731,7 @@ void NemoInterface::Impl::_doSetup() { this->_setInfoString("Waiting for required service " + s); - auto available = rb->waitForService(cc, cond); + auto available = rb.waitForService(cc, cond); if (!available) { return QVariant(false); } @@ -750,7 +739,7 @@ void NemoInterface::Impl::_doSetup() { // check if version is compatible{ this->_setInfoString("Checking version."); - auto version = _callGetVersion(disp, *rb); + auto version = _callGetVersion(disp, rb); if (version != _localVersion) { this->_setWarningString( "Version checking failed. Local protocol version (" + @@ -763,14 +752,14 @@ void NemoInterface::Impl::_doSetup() { for (const auto &cc : requiredTopics) { QString s(cc); this->_setInfoString("Waiting for required topic " + s); - auto available = rb->waitForTopic(cc, cond); + auto available = rb.waitForTopic(cc, cond); if (!available) { return QVariant(false); } } // subscribe topics - rb->subscribeTopic(progressTopic, [this](const QJsonObject &o) { + rb.subscribeTopic(progressTopic, [this](const QJsonObject &o) { ros_bridge::messages::nemo_msgs::progress_array::ProgressArray progressArray; if (ros_bridge::messages::nemo_msgs::progress_array::fromJson( @@ -789,7 +778,7 @@ void NemoInterface::Impl::_doSetup() { } if (rangeError) { - qCWarning(NemoInterfaceLog) << progressTopic + qCWarning(NemointerfaceLog) << progressTopic << " progress out " "of range, value was set to: " << lp.progress(); @@ -799,7 +788,7 @@ void NemoInterface::Impl::_doSetup() { if (!ret) this->_setWarningString("Progress update failed."); } else { - qCWarning(NemoInterfaceLog) << progressTopic + qCWarning(NemointerfaceLog) << progressTopic << " not able to " "create ProgressArray form json: " << o; @@ -807,12 +796,12 @@ void NemoInterface::Impl::_doSetup() { }); using namespace ros_bridge::messages; - rb->subscribeTopic(heartbeatTopic, [this](const QJsonObject &o) { + rb.subscribeTopic(heartbeatTopic, [this](const QJsonObject &o) { nemo_msgs::heartbeat::Heartbeat heartbeat; if (nemo_msgs::heartbeat::fromJson(o, heartbeat)) { this->_onHeartbeatReceived(heartbeat); } else { - qCWarning(NemoInterfaceLog) << heartbeatTopic + qCWarning(NemointerfaceLog) << heartbeatTopic << " not able to " "create Heartbeat form json: " << o; @@ -832,7 +821,7 @@ void NemoInterface::Impl::_doSetup() { Q_UNUSED(f); } -void NemoInterface::Impl::_synchronize() { +void Nemointerface::Impl::_synchronize() { Lock lk(this->_m); if (this->_state == STATE::READY || this->_state == STATE::SYNC_ERROR) { @@ -848,11 +837,11 @@ void NemoInterface::Impl::_synchronize() { // create cmd. auto pTask = std::make_unique([this, pTileArray] { - auto rb = this->_pRosbridge; + auto &rb = this->_rosbridge; auto &disp = this->_dispatcher; // are _localTiles and _remoteTiles synced? - auto remoteTiles = this->_callGetAllTiles(disp, *rb); + auto remoteTiles = this->_callGetAllTiles(disp, rb); // create tile map; std::map> tempMap; @@ -861,7 +850,7 @@ void NemoInterface::Impl::_synchronize() { if (Q_LIKELY(it == tempMap.end())) { tempMap.insert(std::make_pair(pTile->id(), pTile)); } else { - qCDebug(NemoInterfaceLog) + qCDebug(NemointerfaceLog) << "_synchronizeIfNeccessary(): remoteTiles contains " "duplicate id"; } @@ -918,7 +907,7 @@ void NemoInterface::Impl::_synchronize() { this->_doActionNotSafe(); lk.unlock(); this->_setWarningString("Getting progress failed."); - qCDebug(NemoInterfaceLog) + qCDebug(NemointerfaceLog) << "_addTilesImpl(): _updateProgress failed: unknown id."; return QVariant(false); } @@ -947,7 +936,7 @@ void NemoInterface::Impl::_synchronize() { } } -void NemoInterface::Impl::_tryRestart() { +void Nemointerface::Impl::_tryRestart() { if (this->running()) { if (_dispatcher.idle()) { qDebug() << "_tryRestart: restarting"; @@ -960,19 +949,19 @@ void NemoInterface::Impl::_tryRestart() { } } -bool NemoInterface::Impl::_isSynchronizedNotSafe() const { +bool Nemointerface::Impl::_isSynchronizedNotSafe() const { return _localTiles.size() == _remoteTiles.size() && std::equal( _localTiles.begin(), _localTiles.end(), _remoteTiles.begin(), [](const auto &a, const auto &b) { return a.first == b.first; }); } -bool NemoInterface::Impl::_isSynchronized() const { +bool Nemointerface::Impl::_isSynchronized() const { Lock lk(this->_m); return _isSynchronizedNotSafe(); } -void NemoInterface::Impl::_doActionNotSafe() { +void Nemointerface::Impl::_doActionNotSafe() { static bool resetDone = false; switch (this->_state) { case STATE::STOPPED: { @@ -983,8 +972,8 @@ void NemoInterface::Impl::_doActionNotSafe() { this->_syncTimer.stop(); })) - if (this->_pRosbridge->state() != Rosbridge::STATE::STOPPED) { - this->_pRosbridge->stop(); + if (this->_rosbridge.state() != Rosbridge::STATE::STOPPED) { + this->_rosbridge.stop(); } _dispatcher.stop(); _dispatcher.clear(); @@ -998,7 +987,7 @@ void NemoInterface::Impl::_doActionNotSafe() { INVM(this->_parent, ([this]() mutable { this->_restartTimer.start(RESTART_INTERVAl); })) - this->_pRosbridge->start(); + this->_rosbridge.start(); } break; case STATE::WEBSOCKET_DETECTED: resetDone = false; @@ -1036,8 +1025,8 @@ void NemoInterface::Impl::_doActionNotSafe() { if (!resetDone) { resetDone = true; - this->_pRosbridge->stop(); - this->_pRosbridge->start(); + this->_rosbridge.stop(); + this->_rosbridge.start(); } _dispatcher.stop(); _dispatcher.clear(); @@ -1048,7 +1037,7 @@ void NemoInterface::Impl::_doActionNotSafe() { }; } -bool NemoInterface::Impl::_callAddTiles( +bool Nemointerface::Impl::_callAddTiles( const QVector> &tileArray, Dispatcher &d, Rosbridge &rb) { @@ -1060,7 +1049,7 @@ bool NemoInterface::Impl::_callAddTiles( using namespace ros_bridge::messages; QJsonObject jsonTile; if (!nemo_msgs::tile::toJson(*tile, jsonTile)) { - qCDebug(NemoInterfaceLog) + qCDebug(NemointerfaceLog) << "addTiles(): not able to create json object: tile id: " << tile->id() << " progress: " << tile->progress() << " points: " << tile->tile(); @@ -1079,7 +1068,7 @@ bool NemoInterface::Impl::_callAddTiles( if (o.contains("success") && o["success"].isBool()) { promise_response->set_value(o["success"].toBool()); } else { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << addTilesService << " no \"success\" key or wrong type: " << o; promise_response->set_value(false); } @@ -1101,7 +1090,7 @@ bool NemoInterface::Impl::_callAddTiles( d.isInterruptionRequested()); if (abort) { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << "addTiles(): Websocket not responding to request."; return false; } @@ -1115,7 +1104,7 @@ bool NemoInterface::Impl::_callAddTiles( return true; } -bool NemoInterface::Impl::_callRemoveTiles(const IDArray &pIdArray, +bool Nemointerface::Impl::_callRemoveTiles(const IDArray &pIdArray, Dispatcher &disp, Rosbridge &rb) { // qDebug() << "_callRemoveTiles called"; @@ -1137,7 +1126,7 @@ bool NemoInterface::Impl::_callRemoveTiles(const IDArray &pIdArray, if (o.contains("success") && o["success"].isBool()) { promise_response->set_value(o["success"].toBool()); } else { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << removeTilesService << " no \"success\" key or wrong type: " << msg; promise_response->set_value(false); } @@ -1159,7 +1148,7 @@ bool NemoInterface::Impl::_callRemoveTiles(const IDArray &pIdArray, disp.isInterruptionRequested()); if (abort) { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << "remove_tiles(): Websocket not responding to request."; return false; } @@ -1172,7 +1161,7 @@ bool NemoInterface::Impl::_callRemoveTiles(const IDArray &pIdArray, return true; } -bool NemoInterface::Impl::_callClearTiles(Dispatcher &disp, Rosbridge &rb) { +bool Nemointerface::Impl::_callClearTiles(Dispatcher &disp, Rosbridge &rb) { // create response handler. auto promise_response = std::make_shared>(); @@ -1198,7 +1187,7 @@ bool NemoInterface::Impl::_callClearTiles(Dispatcher &disp, Rosbridge &rb) { disp.isInterruptionRequested()); if (abort) { - qCWarning(NemoInterfaceLog) << "Websocket not responding to request."; + qCWarning(NemointerfaceLog) << "Websocket not responding to request."; return false; } @@ -1210,7 +1199,7 @@ bool NemoInterface::Impl::_callClearTiles(Dispatcher &disp, Rosbridge &rb) { return true; } -ProgressArray NemoInterface::Impl::_callGetProgress(const IDArray &pIdArray, +ProgressArray Nemointerface::Impl::_callGetProgress(const IDArray &pIdArray, Dispatcher &disp, Rosbridge &rb) { // qDebug() << "_callGetProgress called"; @@ -1238,7 +1227,7 @@ ProgressArray NemoInterface::Impl::_callGetProgress(const IDArray &pIdArray, *pArray = std::move(progressArrayMsg.progress_array()); promise_response->set_value(pArray); } else { - qCWarning(NemoInterfaceLog) << getProgressService + qCWarning(NemointerfaceLog) << getProgressService << " error while creating ProgressArray " "from json."; promise_response->set_value(nullptr); @@ -1261,7 +1250,7 @@ ProgressArray NemoInterface::Impl::_callGetProgress(const IDArray &pIdArray, disp.isInterruptionRequested()); if (abort) { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << "all_remove_tiles(): Websocket not responding to request."; return ProgressArray(); } @@ -1270,7 +1259,7 @@ ProgressArray NemoInterface::Impl::_callGetProgress(const IDArray &pIdArray, return *future_response.get(); } -ProgressArray NemoInterface::Impl::_callGetAllProgress(Dispatcher &disp, +ProgressArray Nemointerface::Impl::_callGetAllProgress(Dispatcher &disp, Rosbridge &rb) { // qDebug() << "_callGetAllProgress called"; @@ -1288,7 +1277,7 @@ ProgressArray NemoInterface::Impl::_callGetAllProgress(Dispatcher &disp, *pArray = std::move(progressArrayMsg.progress_array()); promise_response->set_value(pArray); } else { - qCWarning(NemoInterfaceLog) << getAllProgressService + qCWarning(NemointerfaceLog) << getAllProgressService << " error while creating ProgressArray " "from json. msg: " << o; @@ -1312,7 +1301,7 @@ ProgressArray NemoInterface::Impl::_callGetAllProgress(Dispatcher &disp, disp.isInterruptionRequested()); if (abort) { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << "_callGetAllProgress(): Websocket not responding to request."; return ProgressArray(); } @@ -1322,7 +1311,7 @@ ProgressArray NemoInterface::Impl::_callGetAllProgress(Dispatcher &disp, } QVector> -NemoInterface::Impl::_callGetAllTiles(Dispatcher &disp, Rosbridge &rb) { +Nemointerface::Impl::_callGetAllTiles(Dispatcher &disp, Rosbridge &rb) { // qDebug() << "_callGetAllProgress called"; // create response handler. @@ -1343,12 +1332,12 @@ NemoInterface::Impl::_callGetAllTiles(Dispatcher &disp, Rosbridge &rb) { if (ros_bridge::messages::nemo_msgs::tile::fromJson(o, *tile)) { pArray->push_back(tile); } else { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << getAllTilesService << " error while creating tile."; promise_response->set_value(nullptr); } } else { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << getAllTilesService << " json array does not contain objects."; promise_response->set_value(nullptr); } @@ -1356,7 +1345,7 @@ NemoInterface::Impl::_callGetAllTiles(Dispatcher &disp, Rosbridge &rb) { // success! promise_response->set_value(pArray); } else { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << getAllTilesService << " no tile_array key or wrong type."; promise_response->set_value(nullptr); } @@ -1378,7 +1367,7 @@ NemoInterface::Impl::_callGetAllTiles(Dispatcher &disp, Rosbridge &rb) { disp.isInterruptionRequested()); if (abort) { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << "all_remove_tiles(): Websocket not responding to request."; return QVector>(); } @@ -1386,7 +1375,7 @@ NemoInterface::Impl::_callGetAllTiles(Dispatcher &disp, Rosbridge &rb) { return *future_response.get(); } -QString NemoInterface::Impl::_callGetVersion(Dispatcher &d, Rosbridge &rb) { +QString Nemointerface::Impl::_callGetVersion(Dispatcher &d, Rosbridge &rb) { // create response handler. typedef QString ResponseType; @@ -1400,7 +1389,7 @@ QString NemoInterface::Impl::_callGetVersion(Dispatcher &d, Rosbridge &rb) { const auto version = o[versionKey].toString(); promise_response->set_value(version); } else { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << getVersionService << " no version key or wrong type."; promise_response->set_value("error!"); } @@ -1422,7 +1411,7 @@ QString NemoInterface::Impl::_callGetVersion(Dispatcher &d, Rosbridge &rb) { d.isInterruptionRequested()); if (abort) { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << "all_remove_tiles(): Websocket not responding to request."; return "unknown_version"; } @@ -1437,7 +1426,7 @@ QString NemoInterface::Impl::_callGetVersion(Dispatcher &d, Rosbridge &rb) { return version; } -bool NemoInterface::Impl::_addTilesRemote( +bool Nemointerface::Impl::_addTilesRemote( const QVector> tileArray) { // qDebug() << "_addTilesRemote called"; @@ -1449,7 +1438,7 @@ bool NemoInterface::Impl::_addTilesRemote( return _addTilesRemote(copy); } -bool NemoInterface::Impl::_addTilesRemote( +bool Nemointerface::Impl::_addTilesRemote( const QVector> &tileArray) { bool error = false; @@ -1466,7 +1455,7 @@ bool NemoInterface::Impl::_addTilesRemote( Q_UNUSED(ret); } else { if (pTile->tile() != it->second->tile()) { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << "_addTilesRemote: tiles differ but have the same id."; error = true; } @@ -1481,7 +1470,7 @@ bool NemoInterface::Impl::_addTilesRemote( return !error; } -void NemoInterface::Impl::_removeTilesRemote(const IDArray &idArray) { +void Nemointerface::Impl::_removeTilesRemote(const IDArray &idArray) { // qDebug() << "_removeTilesRemote called"; bool anyChange = false; @@ -1492,7 +1481,7 @@ void NemoInterface::Impl::_removeTilesRemote(const IDArray &idArray) { _remoteTiles.erase(it); anyChange = true; } else { - qCWarning(NemoInterfaceLog) + qCWarning(NemointerfaceLog) << "_removeTilesRemote: tile with unknown id " << id << "."; } } @@ -1502,24 +1491,24 @@ void NemoInterface::Impl::_removeTilesRemote(const IDArray &idArray) { } } -void NemoInterface::Impl::_clearTilesRemote() { +void Nemointerface::Impl::_clearTilesRemote() { Lock lk(this->_m); _clearTilesRemoteNotSafe(); } -void NemoInterface::Impl::_clearTilesRemoteNotSafe() { +void Nemointerface::Impl::_clearTilesRemoteNotSafe() { // qDebug() << "_clearTilesRemote called"; if (_remoteTiles.size() > 0) { _remoteTiles.clear(); } } -bool NemoInterface::Impl::_setStateNotSafe(STATE newState) { +bool Nemointerface::Impl::_setStateNotSafe(STATE newState) { if (newState != this->_state) { auto oldState = this->_state; this->_state = newState; - qCDebug(NemoInterfaceLog) + qCDebug(NemointerfaceLog) << "state: " << _toString(oldState) << " -> " << _toString(newState); auto oldStatus = _status(oldState); auto newStatus = _status(newState); @@ -1541,58 +1530,58 @@ bool NemoInterface::Impl::_setStateNotSafe(STATE newState) { } } -bool NemoInterface::Impl::_readyNotSafe(NemoInterface::Impl::STATE s) { +bool Nemointerface::Impl::_readyNotSafe(Nemointerface::Impl::STATE s) { return s == STATE::READY; } -bool NemoInterface::Impl::_userSyncNotSafe(NemoInterface::Impl::STATE s) { +bool Nemointerface::Impl::_userSyncNotSafe(Nemointerface::Impl::STATE s) { return s == STATE::USER_SYNC; } -bool NemoInterface::Impl::_sysSyncNotSafe(NemoInterface::Impl::STATE s) { +bool Nemointerface::Impl::_sysSyncNotSafe(Nemointerface::Impl::STATE s) { return s == STATE::SYS_SYNC; } -bool NemoInterface::Impl::_runningNotSafe(NemoInterface::Impl::STATE s) { +bool Nemointerface::Impl::_runningNotSafe(Nemointerface::Impl::STATE s) { return s != STATE::STOPPED; } -NemoInterface::STATUS -NemoInterface::Impl::_status(NemoInterface::Impl::STATE state) { - NemoInterface::STATUS status; +Nemointerface::STATUS +Nemointerface::Impl::_status(Nemointerface::Impl::STATE state) { + Nemointerface::STATUS status; switch (state) { case STATE::STOPPED: - status = NemoInterface::STATUS::NOT_CONNECTED; + status = Nemointerface::STATUS::NOT_CONNECTED; break; case STATE::START_BRIDGE: - status = NemoInterface::STATUS::NOT_CONNECTED; + status = Nemointerface::STATUS::NOT_CONNECTED; break; case STATE::WEBSOCKET_DETECTED: - status = NemoInterface::STATUS::WEBSOCKET_DETECTED; + status = Nemointerface::STATUS::WEBSOCKET_DETECTED; break; case STATE::TRY_SETUP: - status = NemoInterface::STATUS::WEBSOCKET_DETECTED; + status = Nemointerface::STATUS::WEBSOCKET_DETECTED; break; case STATE::READY: - status = NemoInterface::STATUS::READY; + status = Nemointerface::STATUS::READY; break; case STATE::USER_SYNC: case STATE::SYS_SYNC: - status = NemoInterface::STATUS::SYNC; + status = Nemointerface::STATUS::SYNC; break; case STATE::SYNC_ERROR: - status = NemoInterface::STATUS::ERROR; + status = Nemointerface::STATUS::ERROR; break; case STATE::WEBSOCKET_TIMEOUT: case STATE::HEARTBEAT_TIMEOUT: - status = NemoInterface::STATUS::TIMEOUT; + status = Nemointerface::STATUS::TIMEOUT; break; } return status; } -QString NemoInterface::Impl::_toString(NemoInterface::Impl::STATE s) { +QString Nemointerface::Impl::_toString(Nemointerface::Impl::STATE s) { switch (s) { case STATE::STOPPED: return QString("STOPPED"); @@ -1618,32 +1607,32 @@ QString NemoInterface::Impl::_toString(NemoInterface::Impl::STATE s) { return "unknown state!"; } -QString NemoInterface::Impl::_toString(NemoInterface::STATUS s) { +QString Nemointerface::Impl::_toString(Nemointerface::STATUS s) { switch (s) { - case NemoInterface::STATUS::NOT_CONNECTED: + case Nemointerface::STATUS::NOT_CONNECTED: return QString("NOT_CONNECTED"); - case NemoInterface::STATUS::ERROR: + case Nemointerface::STATUS::ERROR: return QString("ERROR"); - case NemoInterface::STATUS::READY: + case Nemointerface::STATUS::READY: return QString("READY"); - case NemoInterface::STATUS::TIMEOUT: + case Nemointerface::STATUS::TIMEOUT: return QString("TIMEOUT"); - case NemoInterface::STATUS::WEBSOCKET_DETECTED: + case Nemointerface::STATUS::WEBSOCKET_DETECTED: return QString("WEBSOCKET_DETECTED"); - case NemoInterface::STATUS::SYNC: + case Nemointerface::STATUS::SYNC: return QString("SYNC"); } return "unknown state!"; } -bool NemoInterface::Impl::_addTilesImpl( +bool Nemointerface::Impl::_addTilesImpl( std::shared_ptr>> pTileArray, std::shared_ptr pIdArray) { - auto rb = this->_pRosbridge; + auto &rb = this->_rosbridge; auto &disp = this->_dispatcher; // add tiles - bool success = this->_callAddTiles(*pTileArray, disp, *rb); + bool success = this->_callAddTiles(*pTileArray, disp, rb); if (!success) { this->_setWarningString( "Adding tiles failed. This might indicate a poor connection."); @@ -1657,13 +1646,13 @@ bool NemoInterface::Impl::_addTilesImpl( this->_doActionNotSafe(); lk.unlock(); this->_setWarningString("Adding tiles failed."); - qCDebug(NemoInterfaceLog) << "_addTilesImpl(): _addTilesRemote return " + qCDebug(NemointerfaceLog) << "_addTilesImpl(): _addTilesRemote return " "false: different tiles with same id."; return false; } // fetch progress - auto array = this->_callGetProgress(*pIdArray, disp, *rb); + auto array = this->_callGetProgress(*pIdArray, disp, rb); if (array.size() != pIdArray->size()) { Lock lk(this->_m); this->_setStateNotSafe(STATE::SYNC_ERROR); @@ -1681,7 +1670,7 @@ bool NemoInterface::Impl::_addTilesImpl( this->_doActionNotSafe(); lk.unlock(); this->_setWarningString("Getting progress failed."); - qCDebug(NemoInterfaceLog) + qCDebug(NemointerfaceLog) << "_addTilesImpl(): _updateProgress failed: unknown id."; return false; } @@ -1689,12 +1678,12 @@ bool NemoInterface::Impl::_addTilesImpl( return true; } -bool NemoInterface::Impl::_removeTilesImpl( +bool Nemointerface::Impl::_removeTilesImpl( std::shared_ptr pIdArray) { - auto rb = this->_pRosbridge; + auto &rb = this->_rosbridge; auto &disp = this->_dispatcher; - auto success = this->_callRemoveTiles(*pIdArray, disp, *rb); + auto success = this->_callRemoveTiles(*pIdArray, disp, rb); if (!success) { Lock lk(this->_m); this->_setStateNotSafe(STATE::SYNC_ERROR); @@ -1709,11 +1698,11 @@ bool NemoInterface::Impl::_removeTilesImpl( return true; } -bool NemoInterface::Impl::_clearTilesImpl() { - auto rb = this->_pRosbridge; +bool Nemointerface::Impl::_clearTilesImpl() { + auto &rb = this->_rosbridge; auto &disp = this->_dispatcher; - auto success = this->_callClearTiles(disp, *rb); + auto success = this->_callClearTiles(disp, rb); if (!success) { Lock lk(this->_m); this->_setStateNotSafe(STATE::SYNC_ERROR); @@ -1730,24 +1719,18 @@ bool NemoInterface::Impl::_clearTilesImpl() { // =============================================================== // NemoInterface -NemoInterface::NemoInterface() - : QObject(), pImpl(std::make_unique(this)) {} +Nemointerface::Nemointerface(const QString &connectionString) + : QObject(), + pImpl(std::make_unique(connectionString, this)) {} -NemoInterface *NemoInterface::createInstance() { return new NemoInterface(); } +Nemointerface::~Nemointerface() {} -NemoInterface *NemoInterface::instance() { - return GenericSingelton::instance( - NemoInterface::createInstance); -} - -NemoInterface::~NemoInterface() {} - -void NemoInterface::start() { this->pImpl->start(); } +void Nemointerface::start() { this->pImpl->start(); } -void NemoInterface::stop() { this->pImpl->stop(); } +void Nemointerface::stop() { this->pImpl->stop(); } std::shared_future -NemoInterface::addTiles(const TileArray &tileArray) { +Nemointerface::addTiles(const TileArray &tileArray) { TilePtrArray ptrArray; for (const auto &tile : tileArray) { ptrArray.push_back(const_cast(&tile)); @@ -1756,59 +1739,130 @@ NemoInterface::addTiles(const TileArray &tileArray) { } std::shared_future -NemoInterface::addTiles(const TilePtrArray &tileArray) { +Nemointerface::addTiles(const TilePtrArray &tileArray) { return this->pImpl->addTiles(tileArray); } std::shared_future -NemoInterface::removeTiles(const IDArray &idArray) { +Nemointerface::removeTiles(const IDArray &idArray) { return this->pImpl->removeTiles(idArray); } -std::shared_future NemoInterface::clearTiles() { +std::shared_future Nemointerface::clearTiles() { return this->pImpl->clearTiles(); } -TileArray NemoInterface::getTiles(const IDArray &idArray) const { +TileArray Nemointerface::getTiles(const IDArray &idArray) const { return this->pImpl->getTiles(idArray); } -TileArray NemoInterface::getAllTiles() const { +TileArray Nemointerface::getAllTiles() const { return this->pImpl->getAllTiles(); } -LogicalArray NemoInterface::containsTiles(const IDArray &idArray) const { +LogicalArray Nemointerface::containsTiles(const IDArray &idArray) const { return this->pImpl->containsTiles(idArray); } -std::size_t NemoInterface::size() const { return this->pImpl->size(); } +std::size_t Nemointerface::size() const { return this->pImpl->size(); } -bool NemoInterface::empty() const { return this->pImpl->empty(); } +bool Nemointerface::empty() const { return this->pImpl->empty(); } -ProgressArray NemoInterface::getProgress() const { +ProgressArray Nemointerface::getProgress() const { return this->pImpl->getProgress(); } -ProgressArray NemoInterface::getProgress(const IDArray &idArray) const { +ProgressArray Nemointerface::getProgress(const IDArray &idArray) const { return this->pImpl->getProgress(idArray); } -NemoInterface::STATUS NemoInterface::status() const { +Nemointerface::STATUS Nemointerface::status() const { return this->pImpl->status(); } -QString NemoInterface::statusString() const { +QString Nemointerface::statusString() const { return statusMap.at(this->pImpl->status()); } -QString NemoInterface::infoString() const { return this->pImpl->infoString(); } +QString Nemointerface::infoString() const { return this->pImpl->infoString(); } -QString NemoInterface::warningString() const { +QString Nemointerface::warningString() const { return this->pImpl->warningString(); } -QString NemoInterface::editorQml() { +QString Nemointerface::editorQml() { return QStringLiteral("NemoInterface.qml"); } -bool NemoInterface::running() const { return this->pImpl->running(); } +bool Nemointerface::running() const { return this->pImpl->running(); } + +QString Nemointerface::connectionString() { + return this->pImpl->connectionString(); +} + +NemointerfaceFactory *NemointerfaceFactory::createInstance() { + return new NemointerfaceFactory(); +} + +NemointerfaceFactory *NemointerfaceFactory::instance() { + return GenericSingelton::instance( + NemointerfaceFactory::createInstance); +} + +std::shared_ptr +NemointerfaceFactory::create(const QString &connectionString) { + auto it = _map.find(connectionString); + + // If the interface was cereated, is it still in use? + if (it != _map.end()) { + auto weak = it->second; + if (!weak.expired()) { + // Still in use, can't create an other instance. + return nullptr; + } else { + // Not in use, erase map entry. + it = _map.erase(it); + } + } + + Q_ASSERT(it == _map.end()); + if (it == _map.end()) { + auto p = std::make_shared(connectionString); + + if (p) { + QQmlEngine::setObjectOwnership(p.get(), QQmlEngine::CppOwnership); + auto ret = _map.insert( + std::make_pair(connectionString, std::weak_ptr(p))); + + // insert error? + Q_ASSERT(ret.second == true); + if (ret.second != true) { + qCCritical(NemointerfaceLog) + << "NemointerfaceFactory::create() not able to insert pair."; + return nullptr; + } + } + + return p; + } else { + qCCritical(NemointerfaceLog) + << "NemointerfaceFactory::create() logical error."; + return nullptr; + } +} + +bool NemointerfaceFactory::isCreatable(const QString &connectionString) { + auto it = _map.find(connectionString); + + // if it was creaded, is it still in use? + if (it != _map.end()) { + if (it->second.expired()) { + it = _map.erase(it); + return true; + } else { + return false; + } + } else { + return true; + } +} diff --git a/src/MeasurementComplexItem/NemoInterface.h b/src/MeasurementComplexItem/NemoInterface.h index 93180efca..8f681f8a3 100644 --- a/src/MeasurementComplexItem/NemoInterface.h +++ b/src/MeasurementComplexItem/NemoInterface.h @@ -13,20 +13,20 @@ #include "TilePtrArray.h" #include "geometry/ProgressArray.h" -// Singelton class used to interface measurement devices implementing the nemo -// interface. -class NemoInterface : public QObject { +class NemointerfaceFactory; + +class Nemointerface : public QObject { Q_OBJECT class Impl; using PImpl = std::unique_ptr; - NemoInterface(); - NemoInterface(NemoInterface &other) = delete; - static NemoInterface *createInstance(); + Nemointerface(const QString &connectionString); + Nemointerface(Nemointerface &other) = delete; + + friend class NemointerfaceFactory; public: - ~NemoInterface() override; - static NemoInterface *instance(); + ~Nemointerface() override; enum class STATUS { NOT_CONNECTED, @@ -90,6 +90,7 @@ public: QString infoString() const; QString warningString() const; bool running() const; + QString connectionString(); signals: void statusChanged(); @@ -103,4 +104,25 @@ private: PImpl pImpl; }; -#define pNemoInterface NemoInterface::instance() +// Singelton class used for nemo interface creation. +class NemointerfaceFactory { + NemointerfaceFactory(); + NemointerfaceFactory(const NemointerfaceFactory &other) = delete; + static NemointerfaceFactory *createInstance(); + +public: + ~NemointerfaceFactory(); + static NemointerfaceFactory *instance(); + + // Creates a interface with a connection string connectionString. + // Two different interfaces can't share the same connection string. + std::shared_ptr create(const QString &connectionString); + // Returns true if an interface with connection string connectionString can + // be created (i.e. doesn't exist yet), returns false either. + bool isCreatable(const QString &connectionString); + +private: + std::map> _map; +}; + +#define pNemoInterfaceFactory NemointerfaceFactory::instance() diff --git a/src/MeasurementComplexItem/json/MeasurementComplexItem.SettingsGroup.json b/src/MeasurementComplexItem/json/MeasurementComplexItem.SettingsGroup.json index 924f16581..3cb34588e 100644 --- a/src/MeasurementComplexItem/json/MeasurementComplexItem.SettingsGroup.json +++ b/src/MeasurementComplexItem/json/MeasurementComplexItem.SettingsGroup.json @@ -17,6 +17,13 @@ "min": 1, "decimalPlaces": 1, "default": 10.0 +}, +{ + "name": "ConnectionString", + "shrotDesc": "Nemo Connection String.", + "longDesc": "Nemo Connection String (e.g. host_ip:port).", + "type": "string", + "default": "localhost:9090" } ] } diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 1e79d9d8a..82bba624d 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -672,7 +672,7 @@ void QGCApplication::_initCommon() { qmlRegisterUncreatableType( "MeasurementComplexItem", 1, 0, "LinearGenerator", kRefOnly); qmlRegisterType("MeasurementComplexItem", 1, 0, "AreaData"); - qmlRegisterSingletonType("MeasurementComplexItem", 1, 0, + qmlRegisterSingletonType("MeasurementComplexItem", 1, 0, "NemoInterface", getNemoInterface); qmlRegisterInterface("GeneratorBase"); qmlRegisterUncreatableType( -- 2.22.0