Files
qt5-legatus-legacy/Lts/Services/OcSituationServer/central_aes_data_queue.cpp
T
2026-08-13 18:33:10 +02:00

186 lines
6.8 KiB
C++
Executable File

/**
* Manages central aes data to be sent
* $Id: handler_oc_situation_data.h 57655 2022-07-20 11:38:28Z karwat $
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/3dws_devel/Lts/Services/OcSituationServer/handler_oc_situation_data.h $
* $Author: karwat $
* Created by Hannes Fritsche, SLTE, 16-08-2022
*/
#include "central_aes_data_queue.h"
namespace OcSituationServer
{
CentralAesDataQueue::CentralAesDataQueue(QObject *parent)
: QObject(parent)
, m_logger(getLogger("CentralAesDataQueue"))
{
}
void CentralAesDataQueue::addRemoveMessage(int32_t aesItemId, AreaEffectSimulation::AesType aesType, bool isPrioritized)
{
QMutexLocker locker(&m_accessMutex);
QByteArray data;
clearSpecificMessage(aesItemId, OcSituation::Remove);
using namespace DataBuilder;
addCentralAesChangeType(data, OcSituation::Remove);
addAesItemId(data, aesItemId);
addAesType(data, aesType);
if (isPrioritized)
m_internalPrioritizedQueue.prepend({aesItemId, OcSituation::Remove, data});
else
m_internalQueue.prepend({aesItemId, OcSituation::Remove, data});
DEBUG_LOG(m_logger) << "New remove-message added: Id = " << aesItemId
<< ", aesType = " << aesType << ". "
<< m_internalQueue.size() << " normal, "
<< m_internalPrioritizedQueue.size() << " prioritized and "
<< m_internalQueue.size() + m_internalPrioritizedQueue.size() << " remaining messages in total.";
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::EffectCluster &effectCluster)
{
// we treat EffectClusters as ExplosionClusters for the ABT
addRemoveMessage(effectCluster.id(), AreaEffectSimulation::AesType::inner_enum::AtExplosionCluster);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::NContamination &nContamination)
{
addRemoveMessage(nContamination.id(), AreaEffectSimulation::AesType::inner_enum::AtNContamination);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::BCContamination &bCContamination)
{
addRemoveMessage(bCContamination.id(), AreaEffectSimulation::AesType::inner_enum::AtBCContamination);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::ExplosionArea &explosionArea)
{
addRemoveMessage(explosionArea.id(), AreaEffectSimulation::AesType::inner_enum::AtExplosionArea);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::ExplosionSingle &explosionSingle)
{
addRemoveMessage(explosionSingle.id(), AreaEffectSimulation::AesType::inner_enum::AtExplosionSingle);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::MineArea &mineArea)
{
addRemoveMessage(mineArea.id(), AreaEffectSimulation::AesType::inner_enum::AtMineArea);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::FunctionalArea &functionalArea)
{
addRemoveMessage(functionalArea.id(), AreaEffectSimulation::AesType::inner_enum::AtFunctionalArea);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::BoobyTrap &boobyTrap)
{
addRemoveMessage(boobyTrap.id(), AreaEffectSimulation::AesType::inner_enum::AtBoobyTrap);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::OffRouteMine &offRouteMine)
{
addRemoveMessage(offRouteMine.id(), AreaEffectSimulation::AesType::inner_enum::AtOffRouteMine);
}
void CentralAesDataQueue::addRemoveMessage(const AreaEffectSimulation::ExplosionCluster &explosionCluster)
{
addRemoveMessage(explosionCluster.id(), AreaEffectSimulation::AesType::inner_enum::AtExplosionCluster, explosionCluster.impactCount() == 1); // we prioritize every single fire
}
QByteArray CentralAesDataQueue::getSendingData(qint32 size)
{
QMutexLocker locker(&m_accessMutex);
QByteArray result;
qint32 messageCounter = 0;
while (!m_internalPrioritizedQueue.isEmpty() && ((result.size() + m_internalPrioritizedQueue.head().data.size()) <= size))
{
result.append(m_internalPrioritizedQueue.dequeue().data);
++messageCounter;
}
// if the result is empty and we have messages left, there is no message small enough, to fit size
// so we send the next best message
if (result.isEmpty() && !m_internalPrioritizedQueue.isEmpty())
{
result.append(m_internalPrioritizedQueue.dequeue().data);
++messageCounter;
WARNING_LOG(m_logger) << "Could not build data with max size of " << size << " bytes. Delivering data with " << result.size() << " bytes.";
}
while (!m_internalQueue.isEmpty() && ((result.size() + m_internalQueue.head().data.size()) <= size))
{
result.append(m_internalQueue.dequeue().data);
++messageCounter;
}
// if the result is empty and we have messages left, there is no message small enough, to fit size
// so we send the next best message
if (result.isEmpty() && !m_internalQueue.isEmpty())
{
result.append(m_internalQueue.dequeue().data);
++messageCounter;
WARNING_LOG(m_logger) << "Could not build data with max size of " << size << " bytes. Delivering data with " << result.size() << " bytes.";
}
DEBUG_LOG(m_logger) << "Data with max size = " << size << "requestet. " << result.size() << " bytes delivered.";
DEBUG_LOG(m_logger) << messageCounter << " messages are sent. "
<< m_internalQueue.size() << " normal, "
<< m_internalPrioritizedQueue.size() << " prioritized and "
<< m_internalQueue.size() + m_internalPrioritizedQueue.size() << " remaining messages in total.";
return result;
}
bool CentralAesDataQueue::hasMessages() const
{
return !m_internalQueue.isEmpty() || !m_internalPrioritizedQueue.isEmpty();
}
void CentralAesDataQueue::clear()
{
m_internalQueue.clear();
m_internalPrioritizedQueue.clear();
}
void CentralAesDataQueue::clearSpecificMessage(int32_t aesItemId, OcSituation::CentralAesChangeType changeType)
{
for (qint32 counter = 0; counter < m_internalQueue.size(); ++counter)
{
if (m_internalQueue.at(counter).aesItemId == aesItemId && m_internalQueue.at(counter).changeType == changeType)
{
m_internalQueue.removeAt(counter);
DEBUG_LOG(m_logger) << "Removed already existing message. aesItemId = " << aesItemId << ", changeType = " << changeType;
return;
}
}
for (qint32 counter = 0; counter < m_internalPrioritizedQueue.size(); ++counter)
{
if (m_internalPrioritizedQueue.at(counter).aesItemId == aesItemId && m_internalPrioritizedQueue.at(counter).changeType == changeType)
{
m_internalPrioritizedQueue.removeAt(counter);
DEBUG_LOG(m_logger) << "Removed already existing message. aesItemId = " << aesItemId << ", changeType = " << changeType;
return;
}
}
}
} // namespace OcSituationServer