Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+956
View File
@@ -0,0 +1,956 @@
/**
* Handler for all exercise objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-03
*/
#include "handler_effect_show.h"
#include "handler_ppm_data.h"
#include "handler_tab_data.h"
#include "handler_mdm_data.h"
#include "object_effect_show.h"
#include "effect_show_explosion_area.h"
#include "effect_show_explosion_cluster.h"
#include "effect_show_effect_cluster.h"
#include "effect_show_mine_area.h"
#include "initialization.h"
#include <EffectShowManagement/esm_db.h>
#include <random>
namespace EffectShowManagement
{
//=============================================================================
HandlerEffectShow::HandlerEffectShow(Initialization *mainHandler,
QObject *parent)
: QObject(parent)
, EffectShowModifyRequestHandler(mainHandler->dds()->fts())
, EffectShowRemoveRequestHandler(mainHandler->dds()->fts())
, m_cleanupTimer(new QTimer(this))
, m_timerMeteoData(new QTimer(this))
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerEffectShow"))
{} // end of ctor()
//=============================================================================
HandlerEffectShow::~HandlerEffectShow()
{
qDeleteAll(m_effectShowObjMap);
m_effectShowObjMap.clear();
} // end of dtor()
//=============================================================================
bool HandlerEffectShow::init()
{
bool bRet = true;
// create Effect Show Objects
auto cbEffectShow = [this, &bRet](const Database::EsmEffectShow & data)
{
ObjectEffectShow *ifs(new ObjectEffectShow(m_mainHandler, this));
Core::FunctionReplyObject ret = ifs->createObject(data);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
m_effectShowObjMap.insert(ifs->getId(), ifs);
};
if (!m_mainHandler->db()->select(cbEffectShow) || !bRet)
{
ERROR_LOG(m_logger) << "Error reading data from database 'esm_effect_show!";
return false;
}
// provision of timer for meteo data
connect(m_timerMeteoData, &QTimer::timeout, this, &HandlerEffectShow::onSendMeteoData);
m_timerMeteoData->start(HandlerEffectShow::meteoDataSendInterval);
//cleanupTimer
connect(m_cleanupTimer, &QTimer::timeout, this, &HandlerEffectShow::onCleanUp);
m_cleanupTimer->start(CLEANUPTIME); //10 minutes
DEBUG_LOG(m_logger) << "m_effectShowObjMap.size() = " << m_effectShowObjMap.size();
return true;
} // end of init()
//=============================================================================
void HandlerEffectShow::onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, KindOfModification_e kindOfModification)
{
INFO_LOG(m_logger) << "onExplosionAreaChanged: " << data << ", kindOfModification: " << enumToString(kindOfModification);
switch (kindOfModification)
{
case KindOfModification_e::Added:
createEffectShowsRelatedToExplosionArea(data);
break;
case KindOfModification_e::ModifiedArea:
modifyEffectShowsRelatedToExplosionArea(data);
break;
case KindOfModification_e::ModifiedData:
updateEffectShowsRelatedToExplosionArea(data);
updateEffectShowOrdersRelatedToAes(data.id());
break;
case KindOfModification_e::Removed:
if(data.effectStateId() == AreaEffectSimulation::AesEffectState::EsRemoved)
removeEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::Paused:
updateEffectShowsRelatedToExplosionArea(data);
updateEffectShowOrdersRelatedToAes(data.id());
//pauseEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::Continued:
updateEffectShowsRelatedToExplosionArea(data);
updateEffectShowOrdersRelatedToAes(data.id());
//continueEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::None:
break;
}
}
void HandlerEffectShow::onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, HandlerEffectShow::KindOfModification_e kindOfModification)
{
INFO_LOG(m_logger) << "onExplosionClusterChanged: " << data << ", kindOfModification: " << enumToString(kindOfModification);
switch (kindOfModification)
{
case KindOfModification_e::Added:
createEffectShowsRelatedToExplosionCluster(data);
break;
case KindOfModification_e::ModifiedArea:
modifyEffectShowsRelatedToExplosionCluster(data);
break;
case KindOfModification_e::ModifiedData:
updateEffectShowsRelatedToExplosionCluster(data);
updateEffectShowOrdersRelatedToAes(data.id());
break;
case KindOfModification_e::Removed:
if(data.effectStateId() == AreaEffectSimulation::AesEffectState::EsRemoved)
removeEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::Paused:
updateEffectShowsRelatedToExplosionCluster(data);
updateEffectShowOrdersRelatedToAes(data.id());
//pauseEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::Continued:
updateEffectShowsRelatedToExplosionCluster(data);
updateEffectShowOrdersRelatedToAes(data.id());
//continueEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::None:
break;
}
}
void HandlerEffectShow::onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &data, KindOfModification_e kindOfModification)
{
INFO_LOG(m_logger) << "onEffectClusterChanged: " << data << ", kindOfModification: " << enumToString(kindOfModification);
switch (kindOfModification)
{
case KindOfModification_e::Added:
createEffectShowsRelatedToEffectCluster(data);
break;
case KindOfModification_e::ModifiedArea:
modifyEffectShowsRelatedToEffectCluster(data);
break;
case KindOfModification_e::ModifiedData:
updateEffectShowsRelatedToEffectCluster(data);
updateEffectShowOrdersRelatedToAes(data.id());
break;
case KindOfModification_e::Removed:
if(data.effectStateId() == AreaEffectSimulation::AesEffectState::EsRemoved)
removeEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::Paused:
updateEffectShowsRelatedToEffectCluster(data);
updateEffectShowOrdersRelatedToAes(data.id());
//pauseEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::Continued:
updateEffectShowsRelatedToEffectCluster(data);
updateEffectShowOrdersRelatedToAes(data.id());
//continueEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::None:
break;
}
} // end of onExplosionClusterChanged()
//=============================================================================
void HandlerEffectShow::onMineAreaChanged(const AreaEffectSimulation::MineArea &data, KindOfModification_e kindOfModification)
{
INFO_LOG(m_logger) << "onMineAreaChanged: " << data << ", kindOfModification: " << enumToString(kindOfModification);
switch (kindOfModification)
{
case KindOfModification_e::Added:
createEffectShowsRelatedToMineArea(data);
break;
case KindOfModification_e::ModifiedArea:
modifyEffectShowsRelatedToMineArea(data);
break;
case KindOfModification_e::ModifiedData:
updateEffectShowsRelatedToMineArea(data);
updateEffectShowOrdersRelatedToAes(data.id());
break;
case KindOfModification_e::Removed:
if(data.effectStateId() == AreaEffectSimulation::AesEffectState::EsRemoved)
removeEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::Paused:
updateEffectShowsRelatedToMineArea(data);
updateEffectShowOrdersRelatedToAes(data.id());
// pauseEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::Continued:
updateEffectShowsRelatedToMineArea(data);
updateEffectShowOrdersRelatedToAes(data.id());
//continueEffectShowsRelatedToAes(data.id());
break;
case KindOfModification_e::None:
break;
}
} // end of onMineAreaChanged()
//=============================================================================
void HandlerEffectShow::effectShowOrderConfirmationReceived(const ConvertFromTab::OrderConfirmation_t &orderConfirmation)
{
DEBUG_LOG(m_logger) << "onEffectShowConfirmationReceived()";
ObjectEffectShow *ifs = m_effectShowObjMap.value(orderConfirmation.orderId);
if (ifs == nullptr)
{
WARNING_LOG(m_logger) << "Error receiving effect show ID not known: " << orderConfirmation.orderId;
return;
}
const auto oldId = ifs->getData().orderConfirmation;
// add confirmation data
ifs->updateObject(orderConfirmation);
if (oldId != ifs->getData().orderConfirmation && ifs->getData().orderConfirmation == EffectShowManagement::OrderConfirmation_e::FiringReadiness)
{
DEBUG_LOG(m_logger) << "effectShowOrderConfirmationReceived Got Fire Readyness, send to aes for " << ifs->getId();
AreaEffectSimulation::SetAesItemEffectorStateRequest req;
req.aesId(ifs->getIdAES());
req.newEffectorState(AreaEffectSimulation::AesEffectorState::EsReadyToFire);
req.participantId(ifs->getData().esmParticipantId);
m_mainHandler->dds()->ftcAes()->setAesItemEffectorStateRequest(req, this);
}
switch (orderConfirmation.confirmation.underlying())
{
case EffectShowManagement::OrderConfirmation_e_def::DriveOff:
case EffectShowManagement::OrderConfirmation_e_def::FiringReadiness:
case EffectShowManagement::OrderConfirmation_e_def::InterruptExecution:
case EffectShowManagement::OrderConfirmation_e_def::PositionReached:
{
triggerMeteoData(ifs); // send meteo data for effect show position
break;
}
default:
break;
}
} // end of onEffectShowConfirmationReceived()
//=============================================================================
void HandlerEffectShow::createEffectShow(const Database::EsmEffectShow &data, bool bForceUpdateDb)
{
ObjectEffectShow *ifs(new ObjectEffectShow(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(data, bForceUpdateDb);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
}
else
{
m_effectShowObjMap.insert(ifs->getId(), ifs);
triggerEffectShowOrder(ifs);
}
} // end of createEffectShow
//-----------------------------------------------------------------------------
void HandlerEffectShow::onEffectShowModifyRequest(
const rti::core::SampleIdentity &cookie,
const EffectShow &request)
{
DEBUG_LOG(m_logger) << "onEffectShowModifyRequest: " << request.id();
if (request.id() <= 0)
{
ERROR_LOG(m_logger) << "Illegal Effect Show Id: " << request.id();
return;
}
// Sende Feuerbereitschaft zum SAA
// m_mainHandler->handlerTabData()->sendAdlerFqFb(request.idAreaEffectSimulation());
auto ret = effectShowModifyRequest(request);
if (ret.error())
ERROR_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->effectShowModifyReply(cookie, ret);
} // end of onEffectShowModifyRequest()
//-------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerEffectShow::effectShowModifyRequest(const EffectShow &request)
{
ObjectEffectShow *ifs = m_effectShowObjMap.value(request.id());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "EffectShow with id %1 not found")).arg(request.id());
Core::FunctionReplyObject ret;
auto idCurrent = ifs->getData().esmParticipantId;
if ((idCurrent != -1) && (request.esmParticipantId() != idCurrent))
{
triggerRetractOrder(ifs); // trigger retract order to current effect show actor, if needed
ret = ifs->updateObject(request); // update effect show
if (!ret.error())
ifs->resetOrderConfirmation(); // reset confirmation status
}
else
{
ret = ifs->updateObject(request); // update effect show
}
if (!ret.error() && ifs->getData().esmParticipantId != -1)
triggerEffectShowOrder(ifs); // trigger effect show order to effect show actor
if (ret.error())
WARNING_LOG(m_logger) << ret();
return ret;
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::onEffectShowRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request)
{
DEBUG_LOG(m_logger) << "onEffectShowRemoveRequest: " << request.id();
ObjectEffectShow *ifs = m_effectShowObjMap.value(request.id());
Core::FunctionReplyObject ret;
if (ifs == nullptr)
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "EffectShow id %1 is not valid")).arg(request.id());
m_mainHandler->dds()->fts()->effectShowRemoveReply(cookie, ret);
return;
}
EffectShowManagement::EffectShow ddsData;
ddsData.id(ifs->getId());
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ddsData, m_mainHandler->exerciseId()))
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "EffectShow '%1' is used by another user!")).arg(ifs->getName());
m_mainHandler->dds()->fts()->effectShowRemoveReply(cookie, ret);
return;
}
ret = removeEffectShow(ifs); // trigger retract order if needed, before object remove
m_mainHandler->dds()->fts()->effectShowRemoveReply(cookie, ret);
}
//-------------------------------------------------------------------------------
static std::string toString(const Database::EsmEffectShow &esmEffectShow)
{
std::ostringstream oss;
oss << "Created Effect Show "
<< "\n ID: " << esmEffectShow.id
<< "\n Name: " << esmEffectShow.name
<< "\n Start time: " << esmEffectShow.startTime
<< "\n Duration: " << esmEffectShow.duration
<< "\n ID AES: " << esmEffectShow.idAreaEffectSimulation
<< "\n ID Effect Show Actor: " << esmEffectShow.esmParticipantId
<< "\n numOfVOlley" << esmEffectShow.numOfVolley
<< "\n shotsPervolley" << esmEffectShow.shotsPerVolley;
return oss.str();
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::createEffectShowsRelatedToMineArea(const AreaEffectSimulation::MineArea &data)
{
const auto esmEffectShows = createEffectShowDbDataRelatedToMineArea(data);
for (const auto &esmEffectShow : esmEffectShows)
{
createEffectShow(esmEffectShow);
DEBUG_LOG(m_logger) << toString(esmEffectShow);
}
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::createEffectShowsRelatedToExplosionArea(const AreaEffectSimulation::ExplosionArea &data)
{
const auto esmEffectShows = createEffectShowDbDataRelatedToExplosionArea(data);
for (const auto &esmEffectShow : esmEffectShows)
{
createEffectShow(esmEffectShow);
DEBUG_LOG(m_logger) << toString(esmEffectShow);
}
}
void HandlerEffectShow::createEffectShowsRelatedToExplosionCluster(const AreaEffectSimulation::ExplosionCluster &data)
{
const auto esmEffectShows = createEffectShowDbDataRelatedToExplosionCluster(data);
for (const auto &esmEffectShow : esmEffectShows)
{
createEffectShow(esmEffectShow);
DEBUG_LOG(m_logger) << toString(esmEffectShow);
}
}
void HandlerEffectShow::createEffectShowsRelatedToEffectCluster(const AreaEffectSimulation::EffectCluster &data)
{
const auto esmEffectShows = createEffectShowDbDataRelatedToEffectCluster(data);
for (const auto &esmEffectShow : esmEffectShows)
{
createEffectShow(esmEffectShow);
DEBUG_LOG(m_logger) << toString(esmEffectShow);
}
}
//-------------------------------------------------------------------------------
QVector<Database::EsmEffectShow> HandlerEffectShow::createEffectShowDbDataRelatedToMineArea(const AreaEffectSimulation::MineArea &data)
{
QVector<Database::EsmEffectShow> ret;
DEBUG_LOG(m_logger) << "createEffectShowDbDataRelatedToExplosionArea: ";
EffectShowMineArea effectShowMineArea(data);
Database::EsmEffectShow esmEffectShow = effectShowMineArea.getEffectShow();
ret.push_back(esmEffectShow);
return ret;
}
//-------------------------------------------------------------------------------
QVector<Database::EsmEffectShow> HandlerEffectShow::createEffectShowDbDataRelatedToExplosionArea(const AreaEffectSimulation::ExplosionArea &data)
{
QVector<Database::EsmEffectShow> ret;
DEBUG_LOG(m_logger) << "createEffectShowDbDataRelatedToExplosionArea: ";
EffectShowExplosionArea effectShowExplosionArea(data, m_mainHandler->handlerPdmData());
if (m_mainHandler->handlerPdmData()->isSmoke(data.chargeStruct()))
{
//create exact 1
ret.reserve(1);
Database::EsmEffectShow esmEffectShow = effectShowExplosionArea.getEffectShow(0);
DEBUG_LOG(m_logger) << toString(esmEffectShow);
ret.push_back(std::move(esmEffectShow));
}
else
{
int max = effectShowExplosionArea.getNumOfEffectShows() > MAX_EFFECT_SHOWS ? MAX_EFFECT_SHOWS : effectShowExplosionArea.getNumOfEffectShows();
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd());
std::uniform_int_distribution<uint32_t> dist(0, effectShowExplosionArea.getNumOfEffectShows() - 1);
QSet<int> taken;
// only create MAX_EFFECT_SHOWS orders even there are more needed for this area
ret.reserve(max);
for (int i = 0; i < max; ++i)
{
int randomNr = dist(gen);
Database::EsmEffectShow esmEffectShow = effectShowExplosionArea.getEffectShow(randomNr);
while (taken.contains(randomNr))
{
randomNr = dist(gen);
esmEffectShow = effectShowExplosionArea.getEffectShow(randomNr);
}
taken.insert(randomNr);
int shootsPerArea = effectShowExplosionArea.getShotsPerArea(max);
esmEffectShow.numOfVolley = effectShowExplosionArea.getNumberOfVolley(shootsPerArea);
esmEffectShow.shotsPerVolley = effectShowExplosionArea.getShotsPerArea();
if (esmEffectShow.shotsPerVolley < esmEffectShow.numOfVolley)
esmEffectShow.shotsPerVolley = esmEffectShow.numOfVolley; // set minimum shots per volley
DEBUG_LOG(m_logger) << toString(esmEffectShow);
ret.push_back(std::move(esmEffectShow));
}
}
return ret;
}
QVector<Database::EsmEffectShow> HandlerEffectShow::createEffectShowDbDataRelatedToExplosionCluster(const AreaEffectSimulation::ExplosionCluster &data)
{
EffectShowExplosionCluster effectShowExplosionCluster(data, m_mainHandler->handlerPdmData());
QVector<Database::EsmEffectShow> ret;
if (m_mainHandler->handlerPdmData()->isSmoke(data.chargeStruct()))
{
//create exact 1
ret.reserve(1);
Database::EsmEffectShow esmEffectShow = effectShowExplosionCluster.getEffectShow(0);
if(data.esmParticipantIds().size() > 0)
esmEffectShow.esmParticipantId = data.esmParticipantIds().at(0); // TODO handle vector
DEBUG_LOG(m_logger) << toString(esmEffectShow);
ret.push_back(std::move(esmEffectShow));
}
else
{
int max = effectShowExplosionCluster.getNumOfEffectShows() > MAX_EFFECT_SHOWS ? MAX_EFFECT_SHOWS : effectShowExplosionCluster.getNumOfEffectShows();
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd());
std::uniform_int_distribution<uint32_t> dist(0, effectShowExplosionCluster.getNumOfEffectShows() - 1);
QSet<int> taken;
// only create MAX_EFFECT_SHOWS orders even there are more needed for this area
ret.reserve(max);
for (int i = 0; i < max; ++i)
{
int randomNr = dist(gen);
Database::EsmEffectShow esmEffectShow = effectShowExplosionCluster.getEffectShow(randomNr);
while (taken.contains(randomNr))
{
randomNr = dist(gen);
esmEffectShow = effectShowExplosionCluster.getEffectShow(randomNr);
}
taken.insert(randomNr);
int shootsPerArea = effectShowExplosionCluster.getShotsPerArea(max);
esmEffectShow.numOfVolley = effectShowExplosionCluster.getNumberOfVolley(shootsPerArea);
esmEffectShow.shotsPerVolley = effectShowExplosionCluster.getShotsPerArea();
if (esmEffectShow.shotsPerVolley < esmEffectShow.numOfVolley)
esmEffectShow.shotsPerVolley = esmEffectShow.numOfVolley; // set minimum shots per volley
DEBUG_LOG(m_logger) << toString(esmEffectShow);
// Evlt. nicht bei DM42 (dann ist max > 1)
if(data.esmParticipantIds().size() > 0)
esmEffectShow.esmParticipantId = data.esmParticipantIds().at(0); // TODO handle vector
ret.push_back(std::move(esmEffectShow));
}
}
return ret;
}
QVector<Database::EsmEffectShow> HandlerEffectShow::createEffectShowDbDataRelatedToEffectCluster(const AreaEffectSimulation::EffectCluster &data)
{
EffectShowEffectCluster effectShowEffectCluster(data, m_mainHandler->handlerPdmData());
QVector<Database::EsmEffectShow> ret;
if (m_mainHandler->handlerPdmData()->isSmoke(data.chargeStruct()))
{
//create exact 1
ret.reserve(1);
Database::EsmEffectShow esmEffectShow = effectShowEffectCluster.getEffectShow(0);
if(data.esmParticipantIds().size() > 0)
esmEffectShow.esmParticipantId = data.esmParticipantIds().at(0); // TODO handle vector
DEBUG_LOG(m_logger) << toString(esmEffectShow);
ret.push_back(std::move(esmEffectShow));
}
else
{
int max = effectShowEffectCluster.getNumOfEffectShows() > MAX_EFFECT_SHOWS ? MAX_EFFECT_SHOWS : effectShowEffectCluster.getNumOfEffectShows();
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd());
std::uniform_int_distribution<uint32_t> dist(0, effectShowEffectCluster.getNumOfEffectShows() - 1);
QSet<int> taken;
// only create MAX_EFFECT_SHOWS orders even there are more needed for this area
ret.reserve(max);
for (int i = 0; i < max; ++i)
{
int randomNr = dist(gen);
Database::EsmEffectShow esmEffectShow = effectShowEffectCluster.getEffectShow(randomNr);
while (taken.contains(randomNr))
{
randomNr = dist(gen);
esmEffectShow = effectShowEffectCluster.getEffectShow(randomNr);
}
taken.insert(randomNr);
int shootsPerArea = effectShowEffectCluster.getShotsPerArea(max);
esmEffectShow.numOfVolley = effectShowEffectCluster.getNumberOfVolley(shootsPerArea);
esmEffectShow.shotsPerVolley = effectShowEffectCluster.getShotsPerArea();
if (esmEffectShow.shotsPerVolley < esmEffectShow.numOfVolley)
esmEffectShow.shotsPerVolley = esmEffectShow.numOfVolley; // set minimum shots per volley
//DEBUG_LOG(m_logger) << toString(esmEffectShow);
// Evlt. nicht bei DM42 (dann ist max > 1)
if(data.esmParticipantIds().size() > (size_t)i)
esmEffectShow.esmParticipantId = data.esmParticipantIds().at(i); // TODO handle vector
DEBUG_LOG(m_logger) << toString(esmEffectShow);
ret.push_back(std::move(esmEffectShow));
}
}
return ret;
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::removeEffectShowsRelatedToAes(int idAes, bool retract)
{
DEBUG_LOG(m_logger) << "removeEffectShowsRelatedToAes(" << idAes << ")";
auto it = m_effectShowObjMap.begin();
while (it != m_effectShowObjMap.end())
{
bool remove = false;
if (it.value()->getIdAES() == idAes)
{
if ((it.value()->getData().orderConfirmation != EffectShowManagement::OrderConfirmation_e_def::Execution) &&
(it.value()->getData().orderConfirmation != EffectShowManagement::OrderConfirmation_e_def::OrderCarriedOut))
remove = true;
else
INFO_LOG(m_logger) << "Effect Show: " << it.value()->getId() << " not removed due to EXECUTION / ORDER CARRIED OUT";
}
if (remove)
{
ObjectEffectShow *objToDelete = it.value();
++it;
removeEffectShow(objToDelete, true, retract); // trigger retract order if needed, before object remove
}
else
++it;
}
} // end of removeEffectShowsRelatedToAes()
//-------------------------------------------------------------------------------
void HandlerEffectShow::updateEffectShowsRelatedToMineArea(const AreaEffectSimulation::MineArea &data)
{
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
if (obj->getIdAES() == data.id())
{
Database::EsmEffectShow esmEffectShow = obj->getData();
EffectShowMineArea effectShowMineArea(data);
effectShowMineArea.updateEffectShow(esmEffectShow);
obj->updateObject(esmEffectShow);
}
}
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::updateEffectShowsRelatedToExplosionArea(const AreaEffectSimulation::ExplosionArea &data)
{
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
if (obj->getIdAES() == data.id())
{
Database::EsmEffectShow esmEffectShow = obj->getData();
EffectShowExplosionArea effectShowExplosionArea(data, m_mainHandler->handlerPdmData());
effectShowExplosionArea.updateEffectShow(esmEffectShow);
obj->updateObject(esmEffectShow);
}
}
}
void HandlerEffectShow::updateEffectShowsRelatedToExplosionCluster(const AreaEffectSimulation::ExplosionCluster &data)
{
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
if (obj->getIdAES() == data.id())
{
Database::EsmEffectShow esmEffectShow = obj->getData();
EffectShowExplosionCluster effectShowExplosionCluster(data, m_mainHandler->handlerPdmData());
effectShowExplosionCluster.updateEffectShow(esmEffectShow);
obj->updateObject(esmEffectShow);
}
}
}
void HandlerEffectShow::updateEffectShowsRelatedToEffectCluster(const AreaEffectSimulation::EffectCluster &data)
{
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
if (obj->getIdAES() == data.id())
{
Database::EsmEffectShow esmEffectShow = obj->getData();
EffectShowEffectCluster effectShowEffectCluster(data, m_mainHandler->handlerPdmData());
effectShowEffectCluster.updateEffectShow(esmEffectShow);
obj->updateObject(esmEffectShow);
}
}
}
static void copyOldActorData(Database::EsmEffectShow &newData, const Database::EsmEffectShow &oldData)
{
newData.id = oldData.id;
newData.orderConfirmation = oldData.orderConfirmation;
newData.answerText = oldData.answerText;
newData.esmParticipantId = oldData.esmParticipantId;
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::modifyEffectShowsRelatedToMineArea(const AreaEffectSimulation::MineArea &data)
{
// even there can currently only be one object we use the same logic as for
// modifyEffectShowsRelatedToExplosionArea for convenience
modifyEffectShows(createEffectShowDbDataRelatedToMineArea(data), data.id());
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::modifyEffectShowsRelatedToExplosionArea(const AreaEffectSimulation::ExplosionArea &data)
{
modifyEffectShows(createEffectShowDbDataRelatedToExplosionArea(data), data.id());
}
void HandlerEffectShow::modifyEffectShowsRelatedToExplosionCluster(const AreaEffectSimulation::ExplosionCluster &data)
{
modifyEffectShows(createEffectShowDbDataRelatedToExplosionCluster(data), data.id());
}
void HandlerEffectShow::modifyEffectShowsRelatedToEffectCluster(const AreaEffectSimulation::EffectCluster &data)
{
modifyEffectShows(createEffectShowDbDataRelatedToEffectCluster(data), data.id());
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::modifyEffectShows(const QVector<Database::EsmEffectShow> &esmEffectShows, int aesId)
{
// a lot of stuff might have changed - therefore we recalculate the effect shows,
// use the old ids and send out a complete update
// first retrieve all objects for the area
QVector<ObjectEffectShow * > objects = removeFromEffectShowMapByAesId(aesId);
// fewer objects than before -> remove the superfluous ones
while (objects.size() > esmEffectShows.size())
removeEffectShow(objects.takeLast(), false, false);
// update all for the existing objects, create new ones if needed
for (int i = 0; i < esmEffectShows.size(); ++i)
{
auto esmEffectShow = esmEffectShows.at(i);
if (objects.size() > i)
{
auto oldObj = objects.at(i);
copyOldActorData(esmEffectShow, oldObj->getData());
oldObj->setRemoveFromDdsOnDestruction(false);
delete oldObj;
}
createEffectShow(esmEffectShow, true);
}
updateEffectShowOrdersRelatedToAes(aesId);
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::updateEffectShowOrdersRelatedToAes(int idAes)
{
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
if (obj->getIdAES() == idAes)
triggerEffectShowOrder(obj);
}
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::pauseEffectShowsRelatedToAes(int idAes)
{
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
if (obj->getIdAES() == idAes)
triggerEffectShowStop(obj);
}
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::continueEffectShowsRelatedToAes(int idAes)
{
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
if (obj->getIdAES() == idAes)
triggerEffectShowContinue(obj);
}
}
//-------------------------------------------------------------------------------
QVector<ObjectEffectShow * > HandlerEffectShow::removeFromEffectShowMapByAesId(int aesId)
{
QVector<ObjectEffectShow * > ret;
for (auto it = m_effectShowObjMap.begin(); it != m_effectShowObjMap.end();)
{
ObjectEffectShow *obj = it.value();
if (obj->getIdAES() == aesId)
{
ret += obj;
it = m_effectShowObjMap.erase(it);
}
else
++it;
}
// in modifyEffectShowsRelatedToFOO we want to remove the last objects first when no longer needed
std::sort(ret.begin(), ret.end(), [](const ObjectEffectShow * a, const ObjectEffectShow * b) { return a->getId() < b->getId();});
return ret;
}
//-------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerEffectShow::removeEffectShow(ObjectEffectShow *ifs, bool bWarnWhenNotInMap, bool retract)
{
const int effectShowId = ifs->getId();
// retract order if needed
if (retract)
triggerRetractOrder(ifs);
// remove from data base
Core::FunctionReplyObject ret = ifs->removeObject();
if (ret.error())
{
ERROR_LOG(m_logger) << ret();
return ret;
}
// delete object and remove from data distribution
delete ifs;
// remove from map
if (!m_effectShowObjMap.remove(effectShowId) && bWarnWhenNotInMap)
WARNING_LOG(m_logger) << "Remove of EffectShow(" << effectShowId << ") failed.";
else
DEBUG_LOG(m_logger) << "EffectShow(" << effectShowId << ") removed.";
return ret;
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::triggerEffectShowOrder(const ObjectEffectShow *ifs)
{
const Database::EsmEffectShow &effectShow = ifs->getData();
INFO_LOG(m_logger) << "triggerEffectShowOrder for id " << ifs->getId()
<< ", aesId: " << ifs->getIdAES()
<< ", actor: " << effectShow.esmParticipantId;
if (effectShow.esmParticipantId == -1)
return; // no effect show actor allocated
// trigger effect show order
int equipmentNumber = m_mainHandler->handlerPpmData()->getEquipmentNumber(effectShow.esmParticipantId);
m_mainHandler->handlerTabData()->effectShowOrder(equipmentNumber, effectShow.esmParticipantId, ifs->getEffectShowOrder());
}
//-------------------------------------------------------------------------------
void HandlerEffectShow::triggerRetractOrder(const ObjectEffectShow *ifs)
{
const Database::EsmEffectShow &effectShow = ifs->getData();
INFO_LOG(m_logger) << "triggerRetractOrder for id " << ifs->getId()
<< ", aesId: " << ifs->getIdAES()
<< ", actor: " << effectShow.esmParticipantId;
if (effectShow.esmParticipantId == -1)
return; // up to now no actor allocated
if (effectShow.orderConfirmation >= EffectShowManagement::OrderConfirmation_e_def::OrderCarriedOut)
return; // order obsolete
// trigger retract order
int equipmentNumber = m_mainHandler->handlerPpmData()->getEquipmentNumber(effectShow.esmParticipantId);
m_mainHandler->handlerTabData()->retractOrder(equipmentNumber, effectShow.esmParticipantId, ifs->getRetractOrder());
}
//-----------------------------------------------------------------------------
void HandlerEffectShow::triggerEffectShowStop(const ObjectEffectShow *ifs)
{
const Database::EsmEffectShow &effectShow = ifs->getData();
INFO_LOG(m_logger) << "triggerEffectShowStop for id " << ifs->getId()
<< ", aesId: " << ifs->getIdAES()
<< ", actor: " << effectShow.esmParticipantId;
if (effectShow.esmParticipantId == -1)
return; // up to now no actor allocated
// trigger effect show stop
int equipmentNumber = m_mainHandler->handlerPpmData()->getEquipmentNumber(effectShow.esmParticipantId);
m_mainHandler->handlerTabData()->effectShowStop(equipmentNumber, effectShow.esmParticipantId, ifs->getId());
}
//-----------------------------------------------------------------------------
void HandlerEffectShow::triggerEffectShowContinue(const ObjectEffectShow *ifs)
{
const Database::EsmEffectShow &effectShow = ifs->getData();
INFO_LOG(m_logger) << "triggerEffectShowContinue for id " << ifs->getId()
<< ", aesId: " << ifs->getIdAES()
<< ", actor: " << effectShow.esmParticipantId;
if (effectShow.esmParticipantId == -1)
return; // up to now no actor allocated
// trigger retract order
int equipmentNumber = m_mainHandler->handlerPpmData()->getEquipmentNumber(effectShow.esmParticipantId);
m_mainHandler->handlerTabData()->effectShowContinue(equipmentNumber, effectShow.esmParticipantId, ifs->getContinueOrder());
}
//-----------------------------------------------------------------------------
void HandlerEffectShow::triggerMeteoData(const ObjectEffectShow *ifs)
{
const Database::EsmEffectShow &effectShow = ifs->getData();
// get weather near to the effect show position
Core::GeoPosition2D pos(effectShow.centerPosition.x(), effectShow.centerPosition.y());
MeteoDataManagement::MeteoData meteoData;
if (m_mainHandler->handlerMdmData()->getNearestWeather(pos, meteoData))
{
if (!meteoData.windOk() && !meteoData.climateOk())
{
WARNING_LOG(m_logger) << "Found MeteoStation but no weather Data available, try again in 1 minute";
QTimer::singleShot(6000, this, &HandlerEffectShow::onSendMeteoData);
return;
}
// trigger meteo data to effect show vehicle
int equipmentNumber = m_mainHandler->handlerPpmData()->getEquipmentNumber(effectShow.esmParticipantId);
m_mainHandler->handlerTabData()->meteoData(equipmentNumber, effectShow.esmParticipantId, meteoData);
// meteo data available
qint64 deltaTime = m_mainHandler->dds()->currentPartitionTime() - meteoData.timeStamp();
if (deltaTime > (60 * 15 * 1000))
WARNING_LOG(m_logger) << "Age of meteo data=" << (deltaTime / 60000) << "min for vehicle: " << equipmentNumber;
}
else
{
int equipmentNumber = m_mainHandler->handlerPpmData()->getEquipmentNumber(effectShow.esmParticipantId);
WARNING_LOG(m_logger) << "Meteo data not available for effect show vehicle: " << equipmentNumber;
}
}
//-----------------------------------------------------------------------------
void HandlerEffectShow::onSendMeteoData()
{
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
const Database::EsmEffectShow &effectShow = obj->getData();
if (effectShow.esmParticipantId == -1)
continue; // no actor allocated
if ((effectShow.orderConfirmation < EffectShowManagement::OrderConfirmation_e_def::DriveOff) ||
(effectShow.orderConfirmation >= EffectShowManagement::OrderConfirmation_e_def::OrderCarriedOut))
continue; // effect show not processed
triggerMeteoData(obj);
}
}
void HandlerEffectShow::onCleanUp()
{
DEBUG_LOG(m_logger) << "Start Cleanup ";
QVector<ObjectEffectShow * > objects;
for (ObjectEffectShow *obj : qAsConst(m_effectShowObjMap))
{
const Database::EsmEffectShow &effectShow = obj->getData();
if (effectShow.orderConfirmation == OrderConfirmation_e::OrderCarriedOut || effectShow.startTime <= 0 || effectShow.id <= 0)
continue;
DEBUG_LOG(m_logger) << "Effect show with ID " << effectShow.id << " will expire at: " << QDateTime::fromMSecsSinceEpoch(effectShow.startTime + effectShow.duration + CLEANUPTIME).toString() << " current time: " << QDateTime::fromMSecsSinceEpoch(m_mainHandler->dds()->currentPartitionTime()).toString();
if ((effectShow.startTime + effectShow.duration + CLEANUPTIME) < m_mainHandler->dds()->currentPartitionTime())
{
//remove object
DEBUG_LOG(m_logger) << "Remove Effect Show " << effectShow.id ;
objects.append(obj);
}
}
while (objects.size() > 0)
removeEffectShow(objects.takeLast(), false, true);
}
QString HandlerEffectShow::enumToString(HandlerEffectShow::KindOfModification_e mod)
{
switch (mod)
{
case HandlerEffectShow::KindOfModification_e::Added:
return QLatin1String("KindOfModification_e::Added");
case HandlerEffectShow::KindOfModification_e::ModifiedArea:
return QLatin1String("KindOfModification_e::ModifiedArea");
case HandlerEffectShow::KindOfModification_e::ModifiedData:
return QLatin1String("KindOfModification_e::ModifiedData");
case HandlerEffectShow::KindOfModification_e::Removed:
return QLatin1String("KindOfModification_e::Removed");
case HandlerEffectShow::KindOfModification_e::Paused:
return QLatin1String("KindOfModification_e::Paused");
case HandlerEffectShow::KindOfModification_e::Continued:
return QLatin1String("KindOfModification_e::Continued");
case HandlerEffectShow::KindOfModification_e::None:
return QLatin1String("KindOfModification_e::None");
}
Q_ASSERT(false);
return QStringLiteral("Unknown KindOfModification_e (%1)").arg(int(mod));
}
//-----------------------------------------------------------------------------
} // namespace EffectShowManagement