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 <QtCore/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)
|
|
{
|
|
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_logger(getLogger("DefaultAvMenus"))
|
|
, m_isInitialized(false)
|
|
, m_context(context)
|
|
, m_dts(dts)
|
|
, m_videoTeamHandler(handlerVideoTeams)
|
|
, m_ismDtc(ismDtc)
|
|
, m_timer(new QTimer)
|
|
{
|
|
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 = "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 = 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 = 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
|