/** * @RDE_HEADER@ * ExerciseManager * $Id$ * $HeadURL$ * $Author$ * Created by Christian Fröbel, NLE, 2019-08-02 */ #pragma once #include "WebSocketInterface/Messages/reply_message.h" #include #include #include #include #include #include #include #include #include #include "logger.h" namespace AudioVideoManagement { class CnrConfig; } namespace CombatNetRadio { class ActiveExercises; class DdsHandler; class TrainingArea; /** * Observes ActiveExercises for active Exercises that have an active FrequencyPlanning. * For those it sets up the neccessary parts. * * @author Christian Fröbel */ class ExerciseManager : public QObject , protected AudioVideoManagement::Interface::Ftc::ModifyFrequencyPlanningStatusReplyHandler , protected AudioVideoManagement::Interface::Ftc::ClearFrequencyPlanningStatusReplyHandler , protected AudioVideoManagement::Interface::Ftc::RemoveFrequencyPlanningStatusByClientReplyHandler { Q_OBJECT public: explicit ExerciseManager(ActiveExercises *activeExercises, DdsHandler *ddsHandler); virtual ~ExerciseManager(); WebSocketInterface::Messages::ReplyMessage trainingAreaData(const QString &uuid) const; std::vector radioStations(const QString &uuid) const; WebSocketInterface::Messages::ReplyMessage configCnr(const QString &uuid); WebSocketInterface::Messages::ReplyMessage positionsCnr(const QString &uuid) const; void onModifyFrequencyPlanningStatusReply(const Core::FunctionReplyObject &replyObject) override final; void onClearFrequencyPlanningStatusReply(const Core::FunctionReplyObject &replyObject) override final; void onRemoveFrequencyPlanningStatusByClientReply(const Core::FunctionReplyObject &replyObject) override final; /** * For a global CnrConfig collect the positions of all Participants from each Exercise. * Will be called by PositionsCnr. */ QVector positionsForGlobal(const AudioVideoManagement::CnrConfig &config) const; public slots: void setPositionsUpdateInterval(std::chrono::milliseconds interval); void stopPositionsUpdate(); void onNewClientConnection(qint64 id); void onClientConnectionClosed(qint64 id); void onClearFrequencyPlanningStatus(); void onConfigCnrSent(qint64 id, const QString &uuid, const QString &requester = {}, bool isActiveClient = false); void onConfigCnrReceived(qint64 id, const QString &uuid); void onConfigCnrProcessed(qint64 id, const QString &uuid, const QJsonObject &configCnrData = {}); signals: void essentialsUpdate(); void positionsUpdate(const WebSocketInterface::Messages::ReplyMessage &positionsCnr); private: void onExerciseActivated(int exerciseId); void onExerciseDeactivated(int exerciseId); void onPositionsUpdateTimeout(); struct ExerciseParts; ActiveExercises *m_activeExercises; DdsHandler *m_ddsHandler; std::map m_parts; //!< exerciseId -> ExerciseParts std::unique_ptr m_trainingArea; //!< set when there is at least one active Exercise QTimer m_positionsUpdateTimer; QTimer m_essentialsUpdateTimer; //!< to cope with repeated updates in a short period of time NGL::INGLLogger &m_logger; }; } // namespace CombatNetRadio