/** * @RDE_HEADER@ * InfrastructureBuilder * $Id$ * $HeadURL$ * $Author$ * Created by Christian Fröbel, SLSE, 2017-11-29 */ #pragma once #include "exercise_context.h" #include "avm_export.h" #include "logger.h" #include #include #include #include #include #include namespace InfrastructureManagement { class MainStructureElement; class StructureElement; class MountingPointAsset; class InstrumentationAsset; namespace Interface { class Dtc; } } // namespace InfrastructureManagement enum class DataModification; namespace AudioVideoManagement { class Exercise; class Asset; class MountingPoint; /** * The AssetAssignmentManager keeps track of whether an Asset is assigned to an Exercise or not. * In AVM we're usually only interested in Assets that are Cameras or AnnouncementUnits. * But here we keep track of all Assets and MountingPoints as this makes it easier * to keep the data model consistent. * * There are two aspects: * 1. An Asset can be mounted * 2. The MountingPoint the Asset is mounted on can be assigned to an Exercise or not. * * From AVM perspective we're only interested in the fact of whether an Asset is assigned * to an exercise or not. * * The difficulty here is to keep the data model consistent despite the fact that * the data published on DDS has no defined ordering. * * The idea here is to have containers for Assets (and MountingPoints): an Exercise. * There exists a "pool" Exercise where all Assets (and MountingPoints) reside that are * not assigned to an Exercise. * And there are concrete Exercise-containers for all existing Exercises. * An Asset (and MountingPoint) will only be moved from the pool Exercise to the concrete * Exercise if and only if the Asset is mounted and assigned to an Exercise. * * Mounting and Assigning are two distinct steps. * Mounting only affects the mounting relation of Asset and MountingPoint but does not move * the Asset (and MountingPoint). Thus the Mounting (and Unmounting) always happens in the pool Exercise. * Assignment can only take place when the Asset is mounted. Assignment then moves the * Asset (and MountingPoint) to the concrete Exercise. * * An Asset can be reassigned from one Exercise to another Exercise. This happens * when the MountingPoint is reassigned while the Asset is mounted. * * @author Christian Fröbel */ class AVM_COMMON_EXPORT AssetAssignmentManager : public QObject { Q_OBJECT public: /** Creates *and* connects the relevant signals. */ static AssetAssignmentManager *create(InfrastructureManagement::Interface::Dtc *ismDtc); /** Don't use! Use create() instead. Only provided to be used in UnitTests. */ AssetAssignmentManager(); ~AssetAssignmentManager(); /** * Implicitly creates an Exercise if it does not yet exist. * The AssetAssignmentManager keeps ownership. */ Exercise *exercise(int id); /** Called by the ExercisesHandler after the corresponding ExerciseHandler was removed. */ void removeExercise(int id); /** For UnitTests only. */ bool hasPending() const; public slots: // public only for use in UnitTests void onAssetChanged(const InfrastructureManagement::InstrumentationAsset &asset, DataModification modType); void onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data, DataModification modType); void onMountingChanged(const InfrastructureManagement::MountingPointAsset &mount, DataModification modType); private: void addAsset(const InfrastructureManagement::InstrumentationAsset &asset); void modifyAsset(const InfrastructureManagement::InstrumentationAsset &asset); void removeAsset(const InfrastructureManagement::InstrumentationAsset &asset); void tryAssignAsset(Asset *asset, Exercise *currentExercise, Exercise *targetExercise, const boost::optional &modifiedData); void unassignAsset(Asset *asset, Exercise *exercise, const boost::optional &modifiedData); void addMount(const InfrastructureManagement::MountingPointAsset &mount); void removeMount(const InfrastructureManagement::MountingPointAsset &mount); void tryUnmount(Asset *asset, Exercise *exercise = nullptr); void processPendingModifications(); void processPendingUnmounts(); void processPendingMounts(); void processPendingRemoves(); template void processPending(Container &pendingSource, Function f); bool hasPendingModifications(int assetId); void logPending(); Exercise *pool() const; std::pair findAsset(int id); std::pair findMountingPoint(int id); private: std::map> m_exercises; std::vector m_pendingModifications; std::vector m_pendingUnmounts; std::vector m_pendingMounts; std::vector m_pendingRemoves; LOGGER_T m_logger; }; } // namespace AudioVideoManagement