/** * Handler for all oc situation data at the server per client * $Id$ * $HeadURL$ * $Author$ * Created by Philipp Dassow, NLST, 27-02-2018 */ #pragma once #include #include #include #include #include #include #include #include #include #include #include "main_handler.h" #include "position_converter.h" #include "oc_situation.h" #include "logger.h" namespace OcSituationServer { class HandlerOcSituationData; class ThreadOcSituationData : public QThread { Q_OBJECT public: explicit ThreadOcSituationData(MainHandler *mainHandler, int equipmentId, int centerEquipmentId, int radius, bool filterActive, QSet partys, QSet typeClasses); public slots: void requestOcSituationData(OcSituation::SituationCenterType centerType, int centerEquipmentId, const Core::GeoPosition2D &position, int radius, bool filterActive, QSet partyList, QSet typeClassList, bool initial); signals: void sendOcData(const TrainingAreaBase::SendOcDataRequest &); protected: virtual void run(); private: OcSituation::SituationCenterType m_centerType = OcSituation::SituationCenterType::Equipment; // which kind of center is used for the situation Core::GeoPosition2D m_position; // center position a situation can be requested around LtsCoordTrans::UtmCoordinate m_baseCoordinate; int m_equipmentId{0}; // id from requesting OC-laptop int m_centerEquipmentId{0}; // equipment in the center of situation int m_radius{0}; // observer radius in meter QSet m_partyList; bool m_filterActive; QSet m_typeClassList; MainHandler *m_mainHandler{nullptr}; // provides TAB FTC and PPM DTC HandlerOcSituationData *m_handler{nullptr}; // OC-Thread-Object QMutex m_accessMutex; // Mutex-Object LOGGER_T &m_logger; // Logger-Object }; class HandlerOcSituationData : public QObject { Q_OBJECT public: explicit HandlerOcSituationData(const std::shared_ptr &dds, const LtsCoordTrans::UtmCoordinate &baseCoordinate, int equipmentId); bool withCompression() const { return m_bWithCompression; } void setWithCompression(bool bOn) { m_bWithCompression = bOn; } bool withVBGTime() const { return m_bWithVBGTime; } void setWithVBGTime(bool bOn) { m_bWithVBGTime = bOn; } private: void fetchParticipantsInRange(); void handleParticipant(const ParticipantManagement::Participant &participant); QVector> createPrioQueue() const; QByteArray createDataStream(int maxSize, const QVector> &participantsPrioQueue); void updatePrioOfNotSendParticipants(); void setModified(int participantId, OcSituation::ModificationBits bits); void clearModified(int participantId); // Building Byte Stream void addParticipantId(QByteArray &buf, const int participantId, OcSituation::ModificationBits modifiedFlags) const; void addPosition2D(QByteArray &buf, const ParticipantManagement::ParticipantPosition &data, bool bAdd) const; void addPosition3D(QByteArray &buf, const ParticipantManagement::ParticipantPosition &data, bool bAdd) const; void addVBG(QByteArray &buf, const ParticipantManagement::DynamicParticipantData &data, bool bAdd) const; void addState(QByteArray &buf, const ParticipantManagement::DynamicParticipantData &data, bool bAdd) const; void addStructure(QByteArray &buf, const ParticipantManagement::Participant &data, bool bAdd) const; void addDesignator(QByteArray &buf, const ParticipantManagement::Participant &data, bool bAdd) const; void addSymbolSidc(QByteArray &buf, const ParticipantManagement::Participant &data, bool bAdd) const; public slots: void setRequestOcSituationData(OcSituation::SituationCenterType centerType, int centerEquipmentId, const Core::GeoPosition2D ¢erPosition, int radius, bool filterActive, QSet partys, QSet typeClasses, bool initial); private slots: void onPartitionTimeChanged(qint64 partitionTime) { m_partitionTime = partitionTime; } void onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType); void onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &data, DataModification modType); void onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &data, DataModification modType); void onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType); void onDusMineStateChanged(const AreaEffectSimulation::DusMineState &data, DataModification modType); void handleSituation(); void resetAliveTimer(); void aliveTimeout(); void onResetInternalData(); signals: void sendOcData(const TrainingAreaBase::SendOcDataRequest &); void resetInternalData(); private: LtsCoordTrans::UtmCoordinate m_baseCoordinate; std::shared_ptr m_ppmDtc; std::shared_ptr m_aesDtc; std::shared_ptr m_gimDtc; // request data OcSituation::SituationCenterType m_centerType{OcSituation::SituationCenterType::Equipment}; // which kind of center is used for the situation Core::GeoPosition2D m_centerPosition; // center position a situation can be requested around int m_equipmentId{0}; // id from requesting OC-laptop int m_centerEquipmentId{0}; // equipment in the center of situation int m_centerParticipantId{0}; int m_radius{0}; // observer radius in meter int m_retryCount{0}; bool m_participantOverloaded{false}; // internal participant data QHash m_participants; QHash m_dynamicParticpantData; QHash m_participantPositions; QHash m_allParticipants; QHash m_allDynamicParticpantData; QHash m_allParticipantPositions; mutable QSet m_participantWithMaybeMissingPartyId; // originatorType==DusMine QHash m_aesId2PartyId; // situation management data QMap m_modifiedFlags; QSet m_participantsToSend; QSet m_outdatedParticipants; QSet m_newlyOutdatedParticipants; QMap m_participantsNotSend; // map QMap m_participantId2EqId; // for debugging purposes QSet m_typeClassList; QSet m_partyList; bool m_filterActive; // options, must be in sync with osc bool m_bWithCompression{true}; bool m_bWithVBGTime{true}; bool m_bInitialDataTransfer{true}; qint64 m_partitionTime; // thread management QMutex m_accessMutex; // Mutex-Object QTimer *m_aliveTimer{nullptr}; // alive timer QTimer *m_txTimer{nullptr}; // tx cycle timer LOGGER_T &m_logger; }; } // namespace OcSituationServer