281 lines
7.6 KiB
C++
Executable File
281 lines
7.6 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* DefaultAvMenus
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Fröbel, NLSE, 2018-03-14
|
|
*/
|
|
|
|
#include "default_av_menus.h"
|
|
#include "exercise.h"
|
|
#include "object_video_team.h"
|
|
#include "audio_video_handler_impl.h"
|
|
#include <AudioVideoManagement/avm.hpp>
|
|
#include <AudioVideoManagement/avm_dts.h>
|
|
#include <AudioVideoManagement/handler_menu_struct.h>
|
|
#include <InfrastructureManagement/ism_dtc.h>
|
|
#include <QTimer>
|
|
#include <QtGlobal>
|
|
#include <set>
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
|
|
|
|
namespace
|
|
{
|
|
|
|
std::set<int32_t> mountingPointsOfInterest(const InfrastructureManagement::MainStructureElement &building)
|
|
{
|
|
std::set<int32_t> mountingPoints;
|
|
|
|
for (const auto &se : building.elements())
|
|
{
|
|
if (se.structureElementTypeId() != InfrastructureManagement::StructureElementType::MountingPoint)
|
|
continue;
|
|
|
|
if (se.mountingPointTypeId() == InfrastructureManagement::MountingPointType::AnnouncementUnit ||
|
|
se.mountingPointTypeId() == InfrastructureManagement::MountingPointType::IndoorCamera ||
|
|
se.mountingPointTypeId() == InfrastructureManagement::MountingPointType::OutdoorCamera)
|
|
mountingPoints.insert(se.id());
|
|
}
|
|
|
|
return mountingPoints;
|
|
}
|
|
|
|
bool isStreamOfInterest(const AudioVideoManagement::Stream &stream, bool isAudio)
|
|
{
|
|
using AudioVideoManagement::StreamType;
|
|
|
|
switch (stream.type().underlying())
|
|
{
|
|
case StreamType::Video:
|
|
return !isAudio;
|
|
|
|
case StreamType::AudioIn:
|
|
return false;
|
|
|
|
case StreamType::AudioOut:
|
|
case StreamType::AudioInOut:
|
|
return isAudio;
|
|
}
|
|
Q_ASSERT(false);
|
|
return false;
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
namespace AudioVideoManagement
|
|
{
|
|
|
|
DefaultAvMenus::DefaultAvMenus(const ExerciseContext &context, Interface::Dts *dts, HandlerVideoTeam *handlerVideoTeams, InfrastructureManagement::Interface::Dtc *ismDtc)
|
|
: m_context(context)
|
|
, m_dts(dts)
|
|
, m_videoTeamHandler(handlerVideoTeams)
|
|
, m_ismDtc(ismDtc)
|
|
, m_timer(new QTimer)
|
|
, m_logger(getLogger("DefaultAvMenus"))
|
|
, m_isInitialized(false)
|
|
{
|
|
Q_ASSERT(dts);
|
|
Q_ASSERT(ismDtc);
|
|
if(!m_ismDtc->isMainStructureElementEnabled())
|
|
m_ismDtc->enableMainStructureElement();
|
|
m_timer->setInterval(1000);
|
|
m_timer->setSingleShot(true);
|
|
connect(m_videoTeamHandler, &HandlerVideoTeam::mvsChanged, this, &DefaultAvMenus::onStreamMvsChanged);
|
|
connect(m_timer.get(), &QTimer::timeout, this, &DefaultAvMenus::updateMenus);
|
|
m_timer->start();
|
|
}
|
|
|
|
DefaultAvMenus::~DefaultAvMenus() = default;
|
|
|
|
void DefaultAvMenus::onStreamChanged(const Stream &stream)
|
|
{
|
|
m_streams[stream.id()] = stream;
|
|
m_timer->start();
|
|
}
|
|
|
|
void DefaultAvMenus::onStreamMvsChanged()
|
|
{
|
|
m_timer->start();
|
|
}
|
|
|
|
void DefaultAvMenus::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data, DataModification modType)
|
|
{
|
|
QString buildingDisplayName = getDisplayNameForBuilding(data);
|
|
|
|
if(modType == DataModification::eRemoved)
|
|
{
|
|
m_buildingDisplayNameForId.remove(data.id());
|
|
m_timer->start();
|
|
}
|
|
else if(modType == DataModification::eAdded)
|
|
{
|
|
m_buildingDisplayNameForId[data.id()] = buildingDisplayName;
|
|
m_timer->start();
|
|
}
|
|
else
|
|
{
|
|
if(m_buildingDisplayNameForId.value(data.id(),buildingDisplayName) == buildingDisplayName)
|
|
return;
|
|
|
|
m_buildingDisplayNameForId[data.id()] = buildingDisplayName;
|
|
m_timer->start();
|
|
}
|
|
}
|
|
|
|
|
|
void DefaultAvMenus::onStreamRemoved(int32_t streamId)
|
|
{
|
|
auto removeCount = m_streams.erase(streamId);
|
|
Q_ASSERT(removeCount == 1);
|
|
m_timer->start();
|
|
}
|
|
|
|
void DefaultAvMenus::updateMenus()
|
|
{
|
|
updateMenu(true); // isAudio
|
|
updateMenu(false); // !isAudio = Video
|
|
}
|
|
|
|
void DefaultAvMenus::removeMenus()
|
|
{
|
|
m_dts->removeMenuStructByKey(menuStructId(true)); // isAudio
|
|
m_dts->removeMenuStructByKey(menuStructId(false)); // !isAudio = Video
|
|
}
|
|
|
|
void DefaultAvMenus::updateMenu(bool isAudio)
|
|
{
|
|
MenuStruct menu;
|
|
menu.id(menuStructId(isAudio));
|
|
menu.isDefault(true);
|
|
menu.name("Default");
|
|
menu.isAudio(isAudio);
|
|
|
|
std::vector<AvMenuEntry> allEntries;
|
|
|
|
const auto &buildings = m_ismDtc->mainStructureElements();
|
|
for (const auto &building : buildings)
|
|
{
|
|
m_buildingDisplayNameForId[building.id()] = getDisplayNameForBuilding(building);
|
|
std::vector<AvMenuEntry> subMenu = subMenuForBuilding(building, isAudio);
|
|
std::move(subMenu.begin(), subMenu.end(), std::back_inserter(allEntries));
|
|
}
|
|
|
|
if (!isAudio)
|
|
{
|
|
bool addMenu = false;
|
|
AvMenuEntry mvsStreams;
|
|
mvsStreams.id(1000000);
|
|
mvsStreams.parentId(menuStructId(isAudio));
|
|
mvsStreams.name().set("MVS");
|
|
mvsStreams.isGroup(true);
|
|
|
|
const auto &videoTeams = m_videoTeamHandler->videoTeams();
|
|
for (const auto &videoTeam : videoTeams)
|
|
{
|
|
if (videoTeam.exerciseId() != m_context.id())
|
|
continue;
|
|
addMenu = true;
|
|
AvMenuEntry streamEntry;
|
|
streamEntry.id(videoTeam.id());
|
|
streamEntry.parentId(mvsStreams.id());
|
|
streamEntry.mountingPointId(-1*videoTeam.id());
|
|
// Also set the stream name which makes it easier for the clients.
|
|
streamEntry.name().set(videoTeam.streamName());
|
|
streamEntry.isGroup(false);
|
|
allEntries.push_back(streamEntry);
|
|
// What about the rowId?
|
|
}
|
|
if (addMenu)
|
|
{
|
|
allEntries.push_back(mvsStreams);
|
|
}
|
|
}
|
|
|
|
menu.menuEntries(allEntries);
|
|
HandlerMenuStruct::sortEntries(menu);
|
|
|
|
m_dts->publish(menu);
|
|
|
|
if(!m_isInitialized)
|
|
{
|
|
connect(m_ismDtc, &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged, this, &DefaultAvMenus::onMainStructureElementChanged);
|
|
m_isInitialized = true;
|
|
}
|
|
}
|
|
|
|
QString DefaultAvMenus::getDisplayNameForBuilding(const InfrastructureManagement::MainStructureElement &data)
|
|
{
|
|
for (auto structure : data.elements()) {
|
|
if(structure.structureElementTypeId() == InfrastructureManagement::StructureElementType::Building)
|
|
return QString::fromStdString(structure.displayName());
|
|
}
|
|
return QString::fromStdString(data.name());
|
|
}
|
|
|
|
std::vector<AvMenuEntry> DefaultAvMenus::subMenuForBuilding(const InfrastructureManagement::MainStructureElement &building, bool isAudio)
|
|
{
|
|
std::vector<AvMenuEntry> entries;
|
|
std::vector<Stream> streams = streamsForBuilding(building, isAudio);
|
|
if (streams.empty())
|
|
return entries;
|
|
|
|
entries.reserve(streams.size() + 1);
|
|
|
|
AvMenuEntry buildingEntry;
|
|
buildingEntry.id(building.id());
|
|
buildingEntry.parentId(menuStructId(isAudio));
|
|
buildingEntry.name(getDisplayNameForBuilding(building).toStdString());
|
|
buildingEntry.isGroup(true);
|
|
// What about the rowId?
|
|
|
|
entries.push_back(buildingEntry);
|
|
|
|
for (const auto &stream : streams)
|
|
{
|
|
AvMenuEntry streamEntry;
|
|
streamEntry.id(stream.mountingPointId());
|
|
streamEntry.parentId(buildingEntry.id());
|
|
streamEntry.mountingPointId(stream.mountingPointId());
|
|
// Also set the stream name which makes it easier for the clients.
|
|
streamEntry.name().set(AudioVideoHandlerImpl::internalStreamName(stream.mountingPointId()).toStdString());
|
|
streamEntry.isGroup(false);
|
|
// What about the rowId?
|
|
|
|
entries.push_back(streamEntry);
|
|
}
|
|
|
|
return entries;
|
|
}
|
|
|
|
std::vector<Stream> DefaultAvMenus::streamsForBuilding(const InfrastructureManagement::MainStructureElement &building, bool isAudio)
|
|
{
|
|
std::set<int32_t> mountingPoints = mountingPointsOfInterest(building);
|
|
std::vector<Stream> streams;
|
|
|
|
for (const auto &keyValue : m_streams)
|
|
{
|
|
const Stream &stream = keyValue.second;
|
|
if (!isStreamOfInterest(stream, isAudio))
|
|
continue;
|
|
|
|
if (!mountingPoints.count(stream.mountingPointId()))
|
|
continue;
|
|
|
|
streams.push_back(stream);
|
|
}
|
|
|
|
return streams;
|
|
}
|
|
|
|
int32_t DefaultAvMenus::menuStructId(bool isAudio)
|
|
{
|
|
return m_context.id() + (isAudio ? 20000000 : 10000000);
|
|
}
|
|
|
|
} // namespace AudioVideoManagement
|