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

+171
View File
@@ -0,0 +1,171 @@
#
# $Id$
# $HeadURL$
# $Author$
#
INCLUDE(MacroRTIDDSGen)
INCLUDE(MacroCodeGenIdl)
SET(xml_FILE esm_service.xml)
#
# --- Library svcEsmCommon --------------------------------------------------------------------------------
#
SET(SRCS_common
esm_export.h
logger.cpp
logger.h
)
# Generate esm_enums.idl / esm.idl
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
# Generate *.cpp/*.hpp from idl
RTIDDSGEN(SRCS_common esm_enums.idl)
RTIDDSGEN(SRCS_common esm.idl)
# Generate esm_dt[s,c]_types.h, esm_ft[s,c]_types.h
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
# Generate esm_[d|f]tc.h
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
# Generate esm_db_impl.cpp/.h, esm_db.h
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
NGL_ADD_LIBRARY(AAR SV WS svcEsmCommon SHARED ${SRCS_common})
NGL_TARGET_INCLUDE_DIRECTORIES(svcEsmCommon
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcEsmCommon
PRIVATE
RTI::nddscpp2
PUBLIC
Qt5::Core
ddscore
ngldb
NGLLogger
)
NGL_INSTALL_TARGET(svcEsmCommon)
#
# --- Library svcEsmClient --------------------------------------------------------------------------------
#
SET(SRCS_client
esm_export.h
)
# generate esm_[d|f]tc.h, esm_[d|f]tc_impl.[cpp|h]
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
NGL_ADD_LIBRARY(AAR SV WS svcEsmClient SHARED ${SRCS_client})
NGL_TARGET_INCLUDE_DIRECTORIES(svcEsmClient
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcEsmClient
PRIVATE
RTI::nddscpp2
ddsconnector
PUBLIC
svcEsmCommon
ddsftc
)
NGL_INSTALL_TARGET(svcEsmClient)
#
# --- Library svcEsmServer --------------------------------------------------------------------------------
#
SET(SRCS_server
dds_handler.cpp
dds_handler.h
effect_show_explosion_area.cpp
effect_show_explosion_area.h
effect_show_explosion_cluster.cpp
effect_show_explosion_cluster.h
effect_show_effect_cluster.cpp
effect_show_effect_cluster.h
effect_show_mine_area.cpp
effect_show_mine_area.h
esm_convert_from_tab.cpp
esm_convert_from_tab.h
esm_convert_to_tab.cpp
esm_convert_to_tab.h
handler_aes_data.cpp
handler_aes_data.h
handler_effect_show_actor_relocation.cpp
handler_effect_show_actor_relocation.h
handler_effect_show.cpp
handler_effect_show.h
handler_effect_show_vehicle_status.cpp
handler_effect_show_vehicle_status.h
handler_mdm_data.cpp
handler_mdm_data.h
handler_pdm_data.cpp
handler_pdm_data.h
handler_ppm_data.cpp
handler_ppm_data.h
handler_tab_data.cpp
handler_tab_data.h
initialization.cpp
initialization.h
object_aes_data.cpp
object_aes_data.h
object_effect_show_actor_relocation.cpp
object_effect_show_actor_relocation.h
object_effect_show.cpp
object_effect_show.h
object_effect_show_vehicle_status.cpp
object_effect_show_vehicle_status.h
settings.cpp
settings.h
${xml_FILE}
)
# generate esm_[d|f]ts.h, esm_[d|f]ts_impl.[cpp|h]
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE})
# Generate esm.sql, esm.xml
CODEGEN_SQL(SRCS_server ${xml_FILE})
NGL_ADD_SVC_ICON(SRCS_server)
NGL_ADD_LIBRARY(AAR SV svcEsmServer SHARED ${SRCS_server})
NGL_TARGET_INCLUDE_DIRECTORIES(svcEsmServer
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcEsmServer
PRIVATE
RTI::nddscpp2
ddsconnector
ddsfts
LtsCoordTrans
ngldb
nglsettings
ngltools
ProjectConfig
svcAesClient
svcCoreClient
svcPpmClient
svcMdmClient
svcEsmCommon
svcTabClient
svcPdmClient
PUBLIC
Qt5::Core
ddsconnector
NGLLogger
)
NGL_INSTALL_TARGET(svcEsmServer)
#
# --- Topic Type Plugin --------------------------------------------------------------
#
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
# Uncomment if necessary
#ADD_SUBDIRECTORY(UnitTests)
#ADD_SUBDIRECTORY(ModuleTests)
+150
View File
@@ -0,0 +1,150 @@
/**
* DdsHandler for DDS
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-02
*/
#include "dds_handler.h"
#include "esm_dts.h"
#include "esm_fts.h"
namespace EffectShowManagement
{
DdsHandler::DdsHandler(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector)
: m_ddsConnector(ddsConnector)
, m_logger(getLogger("DdsHandler"))
{
DEBUG_LOG(m_logger) << "DdsHandler(" << m_ddsConnector->getDomainId() << ") for partition: " << m_ddsConnector->getDefaultPartition();
}
bool DdsHandler::init(const QStringList &qosFileList)
{
INFO_LOG(m_logger) << "--- StartEffectShowManagement DDSHandler.";
if (!m_ddsConnector->init(qosFileList))
{
ERROR_LOG(m_logger) << "Error initializing dds connections - aborting";
return false;
}
// default initialize Publisher and Subscriber
m_ddsConnector->initPublisherSubscriber();
m_topicLockMaster = std::make_shared<Core::TopicLockMaster>(m_ddsConnector);
m_dtcCore = Core::Interface::Dtc::create(m_ddsConnector);
m_dtcCore->enablePartitionTime();
m_ddsDts = EffectShowManagement::Interface::Dts::create(m_ddsConnector);
m_ddsFts = EffectShowManagement::Interface::Fts::create(m_ddsConnector);
if (!m_ddsDts->enableAll())
{
ERROR_LOG(m_logger) << "Could not Dts enableAll";
return false;
}
if (!m_ddsFts->enableAll())
{
ERROR_LOG(m_logger) << "Could not Fts enableAll";
return false;
}
// Subsribe for AreaEffectSimulation
m_dtcAes = AreaEffectSimulation::Interface::Dtc::create(m_ddsConnector);
if (!m_dtcAes->enableExplosionArea())
{
ERROR_LOG(m_logger) << "Could not initialize enableExplosionArea data topic client";
return false;
}
if (!m_dtcAes->enableExplosionSingle())
{
ERROR_LOG(m_logger) << "Could not initialize enableExplosionArea data topic client";
return false;
}
if (!m_dtcAes->enableMineArea())
{
ERROR_LOG(m_logger) << "Could not initialize enableMineArea data topic client";
return false;
}
// add FTC for AreaEffectSimulation
m_ftcAes = AreaEffectSimulation::Interface::Ftc::create(m_ddsConnector);
if (!m_ftcAes->enableSetAesItemEffectorState(true))
{
ERROR_LOG(m_logger) << "Could not initialize enableSetAesItemEffectorState data topic client";
return false;
}
// Subsribe for Participant Management
m_dtcPpm = ParticipantManagement::Interface::Dtc::create(m_ddsConnector);
if (!m_dtcPpm->enableParticipant())
{
ERROR_LOG(m_logger) << "Could not initialize Participant data topic client";
return false;
}
if (!m_dtcPpm->enableType())
{
ERROR_LOG(m_logger) << "Could not initialize Participant type data topic client";
return false;
}
m_dtcPpm->waitForHistoricalDataType();
// Subscripe for Project Data Management
m_dtcPdm = ProjectDataManagement::Interface::Dtc::create(m_ddsConnector);
if (!m_dtcPdm->enableChargeType())
{
ERROR_LOG(m_logger) << "Error initializing ProjectDataManagement DTC";
return false;
}
// Subscripe for Meteo Data Management
m_dtcMdm = MeteoDataManagement::Interface::Dtc::create(m_ddsConnector);
if (!m_dtcMdm->enableMeteoData())
{
ERROR_LOG(m_logger) << "Error initializing MeteoDataManagement DTC";
return false;
}
// Subscripe for Training Area Base
m_dtcTab = TrainingAreaBase::Interface::Dtc::create(m_ddsConnector);
if (!m_dtcTab->enableFireSmokeMarkerData())
{
ERROR_LOG(m_logger) << "Error initializing TrainingAreaBase DTC";
return false;
}
m_ftcTab = TrainingAreaBase::Interface::Ftc::create(m_ddsConnector);
if (!m_ftcTab->enableSendFireSmokeMarkerData())
{
ERROR_LOG(m_logger) << "Error initializing TrainingAreaBase FTC";
return false;
}
if (!m_ftcTab->enableAdlerFqFb())
{
ERROR_LOG(m_logger) << "Error initializing TrainingAreaBase FTC";
return false;
}
return true;
}
//-----------------------------------------------------------------------------
qint64 DdsHandler::currentPartitionTime() const
{
return m_dtcCore->partitionTime().timeStamp();
}
} // namespace EffectShowManagement
+85
View File
@@ -0,0 +1,85 @@
/**
* DdsHandler for DDS
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-02
*/
#pragma once
#include <DDS/DDSConnector/dds_connector.h>
#include <DDS/Core/topic_lock_master.h>
#include <DDS/Core/core_dtc.h>
#include <DDS/Core/core_dts_types.h>
#include <EffectShowManagement/esm_dts.h>
#include <EffectShowManagement/esm_fts.h>
#include <AreaEffectSimulation/aes_dtc.h>
#include <AreaEffectSimulation/aes_ftc.h>
#include <ParticipantManagement/ppm_dtc.h>
#include <ProjectDataManagement/pdm_dtc.h>
#include <MeteoDataManagement/mdm_dtc.h>
#include <TrainingAreaBase/tab_dtc.h>
#include <TrainingAreaBase/tab_ftc.h>
#include "logger.h"
namespace EffectShowManagement
{
class DdsHandler final
{
public:
explicit DdsHandler(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector);
bool init(const QStringList &qosFileList = QStringList());
std::shared_ptr<DDSConnector::DdsConnector> ddsConnector() const
{
return m_ddsConnector;
}
std::shared_ptr<Core::TopicLockMaster> topicLockMaster() const { return m_topicLockMaster; }
std::shared_ptr<EffectShowManagement::Interface::Dts> dts() const
{
return m_ddsDts;
}
std::shared_ptr<EffectShowManagement::Interface::Fts> fts() const
{
return m_ddsFts;
}
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> dtcAes() const { return m_dtcAes; }
std::shared_ptr<AreaEffectSimulation::Interface::Ftc> ftcAes() const { return m_ftcAes; }
std::shared_ptr<ParticipantManagement::Interface::Dtc> dtcPpm() const { return m_dtcPpm; }
std::shared_ptr<ProjectDataManagement::Interface::Dtc> dtcPdm() const { return m_dtcPdm; }
std::shared_ptr<MeteoDataManagement::Interface::Dtc> dtcMdm() const { return m_dtcMdm; }
std::shared_ptr<TrainingAreaBase::Interface::Dtc> dtcTab() const { return m_dtcTab; }
std::shared_ptr<TrainingAreaBase::Interface::Ftc> ftcTab() const { return m_ftcTab; }
int exerciseId() const { return m_ddsConnector->getPartitionId(); }
qint64 currentPartitionTime() const;
private:
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<Core::TopicLockMaster> m_topicLockMaster;
std::shared_ptr<Core::Interface::Dtc> m_dtcCore;
std::shared_ptr<EffectShowManagement::Interface::Dts> m_ddsDts;
std::shared_ptr<EffectShowManagement::Interface::Fts> m_ddsFts;
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_dtcAes;
std::shared_ptr<AreaEffectSimulation::Interface::Ftc> m_ftcAes;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_dtcPpm;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_dtcPdm;
std::shared_ptr<MeteoDataManagement::Interface::Dtc> m_dtcMdm;
std::shared_ptr<TrainingAreaBase::Interface::Dtc> m_dtcTab;
std::shared_ptr<TrainingAreaBase::Interface::Ftc> m_ftcTab;
NGL::INGLLogger &m_logger;
};
} // namespace EffectShowManagement
@@ -0,0 +1,315 @@
/**
* Handler for the HMI language
* $Id$
* $HeadURL$
* $Author$
*/
#include "effect_show_effect_cluster.h"
#include <QJsonDocument>
#include <QObject>
#include "settings.h"
const static int DEFAULT_EFFECT_DURATION = 777777;
namespace EffectShowManagement
{
EffectShowEffectCluster::EffectShowEffectCluster(const AreaEffectSimulation::EffectCluster &effectCluster,
const std::shared_ptr<HandlerPdmData> &handlerPdmData)
: m_effectCluster(effectCluster)
, m_handlerPdmData(handlerPdmData)
, m_numOfEffectShows(0)
, m_logger(getLogger("EffectShowEffectCluster"))
{
}
//=============================================================================
int EffectShowEffectCluster::getNumOfEffectShows()
{
if (m_numOfEffectShows == 0)
calculateSquare();
return m_numOfEffectShows;
}
//=============================================================================
Database::EsmEffectShow EffectShowEffectCluster::getEffectShow(int idx)
{
if (m_numOfEffectShows == 0)
calculateSquare();
Database::EsmEffectShow esmEffectShow;
if (!m_handlerPdmData->isSmoke(m_effectCluster.chargeStruct()))
{
int indX = idx % m_areasWidth.numOfAreas;
int indY = idx / m_areasWidth.numOfAreas;
// calculate lower left position
double x_off = 0.0;
for (int i = 0; i < indX; ++i)
x_off += m_areasWidth.side(i);
double y_off = 0.0;
for (int i = 0; i < indY; ++i)
y_off += m_areasDepth.side(i);
LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos;
lowerLeftPos.x = lowerLeftPos.x + x_off;
lowerLeftPos.y = lowerLeftPos.y + y_off;
LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad());
// calculate center position
LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPos;
centerPos.x = centerPos.x + m_areasWidth.side(indX) / 2.;
centerPos.y = centerPos.y + m_areasDepth.side(indY) / 2.;
LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad());
esmEffectShow.id = 0;
esmEffectShow.name = QStringLiteral("EXP");
esmEffectShow.startTime = m_effectCluster.effectStart().is_set() ? m_effectCluster.effectStart().get() : 0;
esmEffectShow.centerPosition = centerPosRotated.geographic();
esmEffectShow.idAreaEffectSimulation = m_effectCluster.id();
esmEffectShow.esmParticipantId = -1;
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_effectCluster.name());
esmEffectShow.numOfVolley = getNumberOfVolley();
esmEffectShow.shotsPerVolley = getShotsPerArea() / esmEffectShow.numOfVolley;
esmEffectShow.typeOfAmmunition = m_effectCluster.chargeStruct().chargeTypeId();
// can there be more then 48 shoots?
if (esmEffectShow.shotsPerVolley > 48)
esmEffectShow.shotsPerVolley = 48;// (48 / esmEffectShow.numOfVolley);
if (esmEffectShow.shotsPerVolley <= 0)
esmEffectShow.shotsPerVolley = 1;
DEBUG_LOG(m_logger) << "recalc effectDuration ";
if (m_effectCluster.effectDuration() == DEFAULT_EFFECT_DURATION)
{
QJsonObject probObject = QJsonDocument::fromJson(QByteArray::fromStdString(m_effectCluster.properties())).object();
AreaEffectSimulation::FiringType firingType = AreaEffectSimulation::FiringType::ReportReadyToFire;
if (probObject.contains(QStringLiteral("abfeuerungsArt")))
firingType = static_cast<AreaEffectSimulation::FiringType::inner_enum>(probObject[QStringLiteral("abfeuerungsArt")].toInt());
if (firingType == AreaEffectSimulation::FiringType::FireOnCommand)
{
//use default
esmEffectShow.duration = Settings::getDefaultCadence() * esmEffectShow.shotsPerVolley;
DEBUG_LOG(m_logger) << " recalc effectDuration use default value as fireoncommand " << esmEffectShow.duration ;
}
else
{
// use cadence
if (m_effectCluster.effectors().size()) //should always be there!
{
esmEffectShow.duration = m_effectCluster.effectors().at(0).chargeAmount() * m_handlerPdmData.get()->getCadence(m_effectCluster.effectors().at(0).chargeStruct().chargeTypeId());
DEBUG_LOG(m_logger) << " recalc effectDuration use cadence value " << esmEffectShow.duration << " effector shots: " << m_effectCluster.effectors().at(0).chargeAmount() << " cadence " << m_handlerPdmData.get()->getCadence(m_effectCluster.effectors().at(0).chargeStruct().chargeTypeId());
}
}
}
else
{
DEBUG_LOG(m_logger) << "Use effectDuration directly ";
esmEffectShow.duration = m_effectCluster.effectDuration();
}
esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic();
esmEffectShow.areaWidth = m_areasWidth.side(indX);
esmEffectShow.areaDepth = m_areasDepth.side(indY);
esmEffectShow.areaRotation = m_effectCluster.area().rotation() + 90;
DEBUG_LOG(m_logger) << "\nWidth: " << m_effectCluster.area().width() << " Height: " << m_effectCluster.area().height()
<< "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs()
<< "\nduration: " << esmEffectShow.duration
<< "\nRotated Center Pos: " << centerPosRotated.mgrs()
<< "\nOffset x,y: " << x_off << " , " << y_off
<< "\nSide x,y: " << m_areasWidth.side(indX) << " , " << m_areasDepth.side(indY)
<< "\nindX: " << indX << " grid " << m_areasWidth.numSideLength1 << ' ' << m_areasWidth.sideLength1 << ' ' << m_areasWidth.numSideLength2 << ' ' << m_areasWidth.sideLength2
<< "\nindY: " << indY << " grid " << m_areasDepth.numSideLength1 << ' ' << m_areasDepth.sideLength1 << ' ' << m_areasDepth.numSideLength2 << ' ' << m_areasDepth.sideLength2;
}
else
{
LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos; //unnötig?
LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad());
// calculate center position
LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPosRotated;
centerPos.x = centerPos.x + m_effectCluster.area().width() / 2.;
centerPos.y = centerPos.y + m_effectCluster.area().height() / 2.;
LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad());
esmEffectShow.id = 0;
esmEffectShow.name = QStringLiteral("EXP");
esmEffectShow.startTime = m_effectCluster.effectStart().is_set() ? m_effectCluster.effectStart().get() : 0;
esmEffectShow.duration = m_effectCluster.effectDuration();
esmEffectShow.centerPosition = centerPosRotated.geographic();
esmEffectShow.idAreaEffectSimulation = m_effectCluster.id();
esmEffectShow.esmParticipantId = -1;
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_effectCluster.name());
esmEffectShow.typeOfAmmunition = m_effectCluster.chargeStruct().chargeTypeId();
esmEffectShow.numOfVolley = 1;
esmEffectShow.shotsPerVolley = 1;
esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic();
esmEffectShow.areaWidth = m_effectCluster.area().width();
esmEffectShow.areaDepth = m_effectCluster.area().height();
esmEffectShow.areaRotation = m_effectCluster.area().rotation() + 90;
DEBUG_LOG(m_logger) << "\nWidth: " << m_effectCluster.area().width() << " Height: " << m_effectCluster.area().height()
<< "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs()
<< "\nRotated Center Pos: " << centerPosRotated.mgrs()
<< "\nSide x,y: " << m_effectCluster.area().width() << " , " << m_effectCluster.area().height();
}
return esmEffectShow;
}
//=============================================================================
void EffectShowEffectCluster::updateEffectShow(Database::EsmEffectShow &data)
{
DEBUG_LOG(m_logger) << "update EffectSHow for (" << data.id << ")";
data.nameAreaEfffectSimulation = QString::fromStdString(m_effectCluster.name());
data.startTime = m_effectCluster.effectStart().is_set() ? m_effectCluster.effectStart().get() : 0;
DEBUG_LOG(m_logger) << "Recalc effectDuration ";
if (m_effectCluster.effectDuration() == DEFAULT_EFFECT_DURATION)
{
QJsonObject probObject = QJsonDocument::fromJson(QByteArray::fromStdString(m_effectCluster.properties())).object();
AreaEffectSimulation::FiringType firingType = AreaEffectSimulation::FiringType::ReportReadyToFire;
if (probObject.contains(QStringLiteral("abfeuerungsArt")))
firingType = static_cast<AreaEffectSimulation::FiringType::inner_enum>(probObject[QStringLiteral("abfeuerungsArt")].toInt());
if (firingType == AreaEffectSimulation::FiringType::FireOnCommand)
{
//use default
data.duration = Settings::getDefaultCadence() * data.shotsPerVolley;
DEBUG_LOG(m_logger) << " recalc effectDuration use default value as fireoncommand " << data.duration ;
}
else
{
// use cadence
if (m_effectCluster.effectors().size()) //should always be there!
{
data.duration = m_effectCluster.effectors().at(0).chargeAmount() * m_handlerPdmData.get()->getCadence(m_effectCluster.effectors().at(0).chargeStruct().chargeTypeId());
DEBUG_LOG(m_logger) << " recalc effectDuration use cadence value " << data.duration << " effector shots: " << m_effectCluster.effectors().at(0).chargeAmount() << " cadence " << m_handlerPdmData.get()->getCadence(m_effectCluster.effectors().at(0).chargeStruct().chargeTypeId());
}
}
}
else
{
DEBUG_LOG(m_logger) << "Use effectDuration directly ";
data.duration = m_effectCluster.effectDuration();
}
if (data.shotsPerVolley > 48)
data.shotsPerVolley = 48;//(48 / data.numOfVolley);
if (data.shotsPerVolley <= 0)
data.shotsPerVolley = 1;
data.typeOfAmmunition = m_effectCluster.chargeStruct().chargeTypeId();
data.esmParticipantId = (m_effectCluster.esmParticipantIds().size() > 0)
? m_effectCluster.esmParticipantIds().at(0)
: -1;
}
//-----------------------------------------------------------------------------
void EffectShowEffectCluster::calculateSquare()
{
Core::GeoPosition2D geoPos = m_effectCluster.area().cornerBottomLeft();
m_lowerLeftPos = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos.lon(), geoPos.lat());
// Calculate squares.
m_areasWidth = getAreasSideLength(m_effectCluster.area().width()); // Squares in x-direction
m_areasDepth = getAreasSideLength(m_effectCluster.area().height()); // Squares in y-direction
m_numOfEffectShows = m_handlerPdmData->effectShowCount(m_effectCluster.chargeStruct());
}
//static ----------------------------------------------------------------------
LtsCoordTrans::UtmCoordinate EffectShowEffectCluster::rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle)
{
LtsCoordTrans::UtmCoordinate res = p; // copy zone, northp
res.x = ((p.x - c.x) * cos(angle)) - ((p.y - c.y) * sin(angle)) + c.x;
res.y = ((p.x - c.x) * sin(angle)) + ((p.y - c.y) * cos(angle)) + c.y;
return res;
}
//static ----------------------------------------------------------------------
EffectShowEffectCluster::areas_t EffectShowEffectCluster::getAreasSideLength(double sideLength)
{
areas_t res;
int sl = qRound(sideLength + 0.5);
int n50 = (sl < 25) ? 1 : (sl + 25) / 50; // number of 50m squares
int n300 = n50 / 6; // number of 300m squares
int len = n50 * 50; // length to be diveded into squares
res.numOfAreas = ((n300 * 6) == n50) ? n300 : n300 + 1; // number of areas at all
res.sideLength1 = (len / (res.numOfAreas * 50)) * 50;
res.numSideLength2 = (len - (res.numOfAreas * res.sideLength1)) / 50;
res.sideLength2 = res.sideLength1 + 50;
res.numSideLength1 = res.numOfAreas - res.numSideLength2;
//qCritical() << "sl = " << sl << " n50= " << n50 << " n300 = " << n300 << " len = "
// << len << " numOfAreas = " << res.numOfAreas << " sideLength1 = " << res.sideLength1;
return res;
}
//-----------------------------------------------------------------------------
int EffectShowEffectCluster::getNumberOfVolley() const
{
const int v = getShotsPerArea();
return getNumberOfVolley(v);
}
//-----------------------------------------------------------------------------
int EffectShowEffectCluster::getShotsPerArea() const
{
if (!m_numOfEffectShows)
return 0;
int v = 0;
for (const auto &effector: m_effectCluster.effectors())
{
v+= effector.chargeAmount();
}
return v / m_numOfEffectShows; //split even across all effect shows
}
int EffectShowEffectCluster::getShotsPerArea(int areas) const
{
if (areas == 0)
return 0;
int v = 0;
for (const auto &effector: m_effectCluster.effectors())
{
v+= effector.chargeAmount();
}
return v / areas;
}
int EffectShowEffectCluster::getNumberOfVolley(int v)
{
if (v < 3) // <= 0 should not happen but did...
return qMax(1, v);
if (v <= 25)
return 3;
if (v <= 50)
return 6;
if (v <= 100)
return 9;
if (v <= 150)
return 12;
if (v <= 200)
return 15;
return 18;
}
//-----------------------------------------------------------------------------
double EffectShowEffectCluster::rotationRad() const
{
return -m_effectCluster.area().rotation() * LtsCoordTrans::deg2rad();
}
//-----------------------------------------------------------------------------
} // Namespace EffectShowManagement
@@ -0,0 +1,130 @@
/**
* Exercise object
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "logger.h"
#include "handler_pdm_data.h"
#include <AreaEffectSimulation/aes_dtc.h>
#include <EffectShowManagement/esm_db.h>
#include <LtsCoordTrans/lts_coord_trans.h>
namespace EffectShowManagement
{
/**
* @brief Creates the Effect Show data from the Area Effect Simulation data for Explosion Clusters.
*
* For the Effect Show data to be created see ICD GUEZSB60_ICD-0046C.
* For calculations the mathematical x-axis is mapped to east; the y-axis is mapped to north.\n
*
* List of features:\n
* (1)The area effect is limited to one effect show located at the center of the cluster.\n
* (2) Only specific charge types create more than one effect show as configured in the charge type
* (3)The number of volleys depends on the number of shots by the explosion cluster as follows:\n
* Number of shot <= 25 : 3 volleys\n
* Number of shot <= 50 : 6 volleys\n
* Number of shot <= 100 : 9 volleys\n
* Number of shot <= 150 : 12 volleys\n
* Number of shot <= 200 : 15 volleys\n
* else : 18 volleys\n
* (4)The start time for the effect show is overtaken from the start time of the explosion cluster.\n
* (5)The duration for the effect show is overtaken from the duration of the explosion cluster.\n
* (6)The type of ammunition is determined by the chargeType of the explosion cluster and the
* "tas code indirect" of the Project Data Management.\n
*
*/
class EffectShowEffectCluster
{
public:
explicit EffectShowEffectCluster(const AreaEffectSimulation::EffectCluster &explosionCluster,
const std::shared_ptr<HandlerPdmData> &handlerPdmData);
/**
* @brief Returns the number of Effect Shows resulting from Area Effect Simulation.
* @return The number of effect shows
*/
int getNumOfEffectShows();
/**
* @brief Returns the Effect Show with the provided index.
* @param[in] idx The index of the Effect Show [0..@see geNumOfEffectShows()-1]
* @return The Effect Show with the provided index
*/
Database::EsmEffectShow getEffectShow(int idx);
/**
* @brief Updates the following data: startTime, duration, volley, typeOfAmmunition.
* @param[in] data The Effect Show to be updated
* @param[out] data The updated Effect Show
*/
void updateEffectShow(Database::EsmEffectShow &data);
int getShotsPerArea(int areas) const;
static int getNumberOfVolley(int v);
/**
* @brief Returns the number of volley.
* @return The number of volley.
*/
int getNumberOfVolley() const;
int getShotsPerArea() const;
private:
/**
* @brief Calculates the square of the each effect area.
*/
void calculateSquare();
/**
* @brief Turns position p arround position c.
* @param[in] p Point to be rotated
* @param[in] c Center point of rotation
* @param[in] angle Angle of rotation
* @return Depth of the effect area. The resolution of the value is 50m. (Max: 300m)
*/
static LtsCoordTrans::UtmCoordinate rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle);
struct areas_t
{
int side(int i) const
{
return (i < numSideLength1) ? sideLength1 : sideLength2;
}
int numSideLength1 = 0; // number of areas with the side length "sideLength1"
int sideLength1 = 0; // side length of the areas 1
int numSideLength2 = 0; // number of areas with the side length "sideLength2"
int sideLength2 = 0; // side length of the areas 2
int numOfAreas = 0; // number of areas along the side at all
};
/** @brief Calculates the side length of effect shows.
* The side length shall be rounded to a resolution of 50m.
* The maximum side length shall be 300m. If the side length is > 300m, a split into
* more side length shall be made. In this case uniform side length of <= 300m shall be
* calculated. For the rest, a last side length shall be provided.
* @param[in] sideLength Side length of Area Effect Simuilation
* @return Side length of the effect shows
*/
static areas_t getAreasSideLength(double sideLength);
double rotationRad() const;
private:
AreaEffectSimulation::EffectCluster const m_effectCluster;
std::shared_ptr<HandlerPdmData> m_handlerPdmData;
int m_numOfEffectShows;
areas_t m_areasWidth; // squares in x-direction
areas_t m_areasDepth; // squares in y-direction
LtsCoordTrans::UtmCoordinate m_lowerLeftPos;
NGL::INGLLogger &m_logger;
};
}
@@ -0,0 +1,244 @@
/**
* Handler for the HMI language
* $Id$
* $HeadURL$
* $Author$
*/
#include "effect_show_explosion_area.h"
namespace EffectShowManagement
{
EffectShowExplosionArea::EffectShowExplosionArea(const AreaEffectSimulation::ExplosionArea &explosionArea,
const std::shared_ptr<HandlerPdmData> &handlerPdmData)
: m_explosionArea(explosionArea)
, m_handlerPdmData(handlerPdmData)
, m_numOfEffectShows(0)
, m_logger(getLogger("EffectShowExplosionArea"))
{
}
//=============================================================================
int EffectShowExplosionArea::getNumOfEffectShows()
{
if (m_numOfEffectShows == 0)
calculateSquare();
return m_numOfEffectShows;
}
//=============================================================================
Database::EsmEffectShow EffectShowExplosionArea::getEffectShow(int idx)
{
if (m_numOfEffectShows == 0)
calculateSquare();
Database::EsmEffectShow esmEffectShow;
if (!m_handlerPdmData->isSmoke(m_explosionArea.chargeStruct()))
{
int indX = idx % m_areasWidth.numOfAreas;
int indY = idx / m_areasWidth.numOfAreas;
// calculate lower left position
double x_off = 0.0;
for (int i = 0; i < indX; ++i)
x_off += m_areasWidth.side(i);
double y_off = 0.0;
for (int i = 0; i < indY; ++i)
y_off += m_areasDepth.side(i);
LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos;
lowerLeftPos.x = lowerLeftPos.x + x_off;
lowerLeftPos.y = lowerLeftPos.y + y_off;
LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad());
// calculate center position
LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPos;
centerPos.x = centerPos.x + m_areasWidth.side(indX) / 2.;
centerPos.y = centerPos.y + m_areasDepth.side(indY) / 2.;
LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad());
esmEffectShow.id = 0;
esmEffectShow.name = QStringLiteral("EXP");
esmEffectShow.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0;
esmEffectShow.duration = m_explosionArea.effectDuration();
esmEffectShow.centerPosition = centerPosRotated.geographic();
esmEffectShow.idAreaEffectSimulation = m_explosionArea.id();
esmEffectShow.esmParticipantId = -1;
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name());
esmEffectShow.numOfVolley = getNumberOfVolley();
esmEffectShow.shotsPerVolley = getShotsPerArea() / esmEffectShow.numOfVolley;
esmEffectShow.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId();
// can there be more then 48 shoots?
if (esmEffectShow.shotsPerVolley > 48)
esmEffectShow.shotsPerVolley = 48;// (48 / esmEffectShow.numOfVolley);
if (esmEffectShow.shotsPerVolley <= 0)
esmEffectShow.shotsPerVolley = 1;
esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic();
esmEffectShow.areaWidth = m_areasWidth.side(indX);
esmEffectShow.areaDepth = m_areasDepth.side(indY);
esmEffectShow.areaRotation = m_explosionArea.area().rotation() + 90;
DEBUG_LOG(m_logger) << "\nWidth: " << m_explosionArea.area().width() << " Height: " << m_explosionArea.area().height()
<< "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs()
<< "\nRotated Center Pos: " << centerPosRotated.mgrs()
<< "\nOffset x,y: " << x_off << " , " << y_off
<< "\nSide x,y: " << m_areasWidth.side(indX) << " , " << m_areasDepth.side(indY)
<< "\nindX: " << indX << " grid " << m_areasWidth.numSideLength1 << ' ' << m_areasWidth.sideLength1 << ' ' << m_areasWidth.numSideLength2 << ' ' << m_areasWidth.sideLength2
<< "\nindY: " << indY << " grid " << m_areasDepth.numSideLength1 << ' ' << m_areasDepth.sideLength1 << ' ' << m_areasDepth.numSideLength2 << ' ' << m_areasDepth.sideLength2;
}
else
{
LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos; //unnötig?
LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad());
// calculate center position
LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPosRotated;
centerPos.x = centerPos.x + m_explosionArea.area().width() / 2.;
centerPos.y = centerPos.y + m_explosionArea.area().height() / 2.;
LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad());
esmEffectShow.id = 0;
esmEffectShow.name = QStringLiteral("EXP");
esmEffectShow.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0;
esmEffectShow.duration = m_explosionArea.effectDuration();
esmEffectShow.centerPosition = centerPosRotated.geographic();
esmEffectShow.idAreaEffectSimulation = m_explosionArea.id();
esmEffectShow.esmParticipantId = -1;
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name());
esmEffectShow.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId();
esmEffectShow.numOfVolley = 1;
esmEffectShow.shotsPerVolley = 1;
esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic();
esmEffectShow.areaWidth = m_explosionArea.area().width();
esmEffectShow.areaDepth = m_explosionArea.area().height();
esmEffectShow.areaRotation = m_explosionArea.area().rotation() + 90;
DEBUG_LOG(m_logger) << "\nWidth: " << m_explosionArea.area().width() << " Height: " << m_explosionArea.area().height()
<< "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs()
<< "\nRotated Center Pos: " << centerPosRotated.mgrs()
<< "\nSide x,y: " << m_explosionArea.area().width() << " , " << m_explosionArea.area().height();
}
return esmEffectShow;
}
//=============================================================================
void EffectShowExplosionArea::updateEffectShow(Database::EsmEffectShow &data)
{
data.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name());
data.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0;
data.duration = m_explosionArea.effectDuration();
if (data.shotsPerVolley > 48)
data.shotsPerVolley = 48;//(48 / data.numOfVolley);
if (data.shotsPerVolley <= 0)
data.shotsPerVolley = 1;
data.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId();
}
//-----------------------------------------------------------------------------
void EffectShowExplosionArea::calculateSquare()
{
// start position of the area
Core::GeoPosition2D geoPos = m_explosionArea.area().cornerBottomLeft();
m_lowerLeftPos = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos.lon(), geoPos.lat());
// Calculate squares.
m_areasWidth = getAreasSideLength(m_explosionArea.area().width()); // Squares in x-direction
m_areasDepth = getAreasSideLength(m_explosionArea.area().height()); // Squares in y-direction
// Calculate number of squares
if (m_handlerPdmData->isSmoke(m_explosionArea.chargeStruct()))
m_numOfEffectShows = 1;
else
m_numOfEffectShows = m_areasWidth.numOfAreas * m_areasDepth.numOfAreas;
DEBUG_LOG(m_logger) << "Calc Square poslef " << m_lowerLeftPos.x << " " << m_lowerLeftPos.y << " witdh" << m_areasWidth.sideLength1 << " depth " << m_areasDepth.sideLength1 << " num of Effect Shows " << m_numOfEffectShows;
}
//static ----------------------------------------------------------------------
LtsCoordTrans::UtmCoordinate EffectShowExplosionArea::rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle)
{
LtsCoordTrans::UtmCoordinate res = p; // copy zone, northp
res.x = ((p.x - c.x) * cos(angle)) - ((p.y - c.y) * sin(angle)) + c.x;
res.y = ((p.x - c.x) * sin(angle)) + ((p.y - c.y) * cos(angle)) + c.y;
return res;
}
//static ----------------------------------------------------------------------
EffectShowExplosionArea::areas_t EffectShowExplosionArea::getAreasSideLength(double sideLength)
{
areas_t res;
int sl = qRound(sideLength + 0.5);
int n50 = (sl < 25) ? 1 : (sl + 25) / 50; // number of 50m squares
int n300 = n50 / 6; // number of 300m squares
int len = n50 * 50; // length to be diveded into squares
res.numOfAreas = ((n300 * 6) == n50) ? n300 : n300 + 1; // number of areas at all
res.sideLength1 = (len / (res.numOfAreas * 50)) * 50;
res.numSideLength2 = (len - (res.numOfAreas * res.sideLength1)) / 50;
res.sideLength2 = res.sideLength1 + 50;
res.numSideLength1 = res.numOfAreas - res.numSideLength2;
//qCritical() << "sl = " << sl << " n50= " << n50 << " n300 = " << n300 << " len = "
// << len << " numOfAreas = " << res.numOfAreas << " sideLength1 = " << res.sideLength1;
return res;
}
//-----------------------------------------------------------------------------
int EffectShowExplosionArea::getNumberOfVolley() const
{
const int v = getShotsPerArea();
return getNumberOfVolley(v);
}
//-----------------------------------------------------------------------------
int EffectShowExplosionArea::getShotsPerArea() const
{
if (!m_numOfEffectShows)
return 0;
int v = m_explosionArea.cannonCount() * m_explosionArea.cannonRounds();
return v / m_numOfEffectShows; //split even across all effect shows
}
int EffectShowExplosionArea::getShotsPerArea(int areas) const
{
if (areas == 0)
return 0;
int v = m_explosionArea.cannonCount() * m_explosionArea.cannonRounds();
return v / areas;
}
int EffectShowExplosionArea::getNumberOfVolley(int v)
{
if (v < 3) // <= 0 should not happen but did...
return qMax(1, v);
if (v <= 25)
return 3;
if (v <= 50)
return 6;
if (v <= 100)
return 9;
if (v <= 150)
return 12;
if (v <= 200)
return 15;
return 18;
}
//-----------------------------------------------------------------------------
double EffectShowExplosionArea::rotationRad() const
{
return -m_explosionArea.area().rotation() * LtsCoordTrans::deg2rad();
}
//-----------------------------------------------------------------------------
} // Namespace EffectShowManagement
@@ -0,0 +1,132 @@
/**
* Exercise object
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "logger.h"
#include "handler_pdm_data.h"
#include <AreaEffectSimulation/aes_dtc.h>
#include <EffectShowManagement/esm_db.h>
#include <LtsCoordTrans/lts_coord_trans.h>
namespace EffectShowManagement
{
/**
* @brief Creates the Effect Show data from the Area Effect Simulation data for mine areas.
*
* For the Effect Show data to be created see ICD GUEZSB60_ICD-0046C.
* For calculations the mathematical x-axis is mapped to east; the y-axis is mapped to north.\n
*
* List of features:\n
* (1)The area for the effect show is limited to 300m x 300m in a grid of 50m.\n
* (2)If the explosion area exceeds the limit for an effect show area, multi-effect shows
* will be defined in order to cover the explosion area. It is intend to come to nearly
* the same size for each effect show. Each size is defined in a 50m grid.\n
* (3)The number of volleys depends on the number of shots by the explosion area as follows:\n
* Number of shot <= 25 : 3 volleys\n
* Number of shot <= 50 : 6 volleys\n
* Number of shot <= 100 : 9 volleys\n
* Number of shot <= 150 : 12 volleys\n
* Number of shot <= 200 : 15 volleys\n
* else : 18 volleys\n
* (4)The start time for the effect show is overtaken from the start time of the explosion area.\n
* (5)The duration for the effect show is overtaken from the duration of the explosion area.\n
* (6)The type of ammunition is determined by the chargeType of the explosion area and the
* "tas code indirect" of the Project Data Management.\n
*
*/
class EffectShowExplosionArea
{
public:
explicit EffectShowExplosionArea(const AreaEffectSimulation::ExplosionArea &explosionArea,
const std::shared_ptr<HandlerPdmData> &handlerPdmData);
/**
* @brief Returns the number of Effect Shows resulting from Area Effect Simulation.
* @return The number of effect shows
*/
int getNumOfEffectShows();
/**
* @brief Returns the Effect Show with the provided index.
* @param[in] idx The index of the Effect Show [0..@see geNumOfEffectShows()-1]
* @return The Effect Show with the provided index
*/
Database::EsmEffectShow getEffectShow(int idx);
/**
* @brief Updates the following data: startTime, duration, volley, typeOfAmmunition.
* @param[in] data The Effect Show to be updated
* @param[out] data The updated Effect Show
*/
void updateEffectShow(Database::EsmEffectShow &data);
int getShotsPerArea(int areas) const;
static int getNumberOfVolley(int v);
/**
* @brief Returns the number of volley.
* @return The number of volley.
*/
int getNumberOfVolley() const;
int getShotsPerArea() const;
private:
/**
* @brief Calculates the square of the each effect area.
*/
void calculateSquare();
/**
* @brief Turns position p arround position c.
* @param[in] p Point to be rotated
* @param[in] c Center point of rotation
* @param[in] angle Angle of rotation
* @return Depth of the effect area. The resolution of the value is 50m. (Max: 300m)
*/
static LtsCoordTrans::UtmCoordinate rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle);
struct areas_t
{
int side(int i) const
{
return (i < numSideLength1) ? sideLength1 : sideLength2;
}
int numSideLength1 = 0; // number of areas with the side length "sideLength1"
int sideLength1 = 0; // side length of the areas 1
int numSideLength2 = 0; // number of areas with the side length "sideLength2"
int sideLength2 = 0; // side length of the areas 2
int numOfAreas = 0; // number of areas along the side at all
};
/** @brief Calculates the side length of effect shows.
* The side length shall be rounded to a resolution of 50m.
* The maximum side length shall be 300m. If the side length is > 300m, a split into
* more side length shall be made. In this case uniform side length of <= 300m shall be
* calculated. For the rest, a last side length shall be provided.
* @param[in] sideLength Side length of Area Effect Simuilation
* @return Side length of the effect shows
*/
static areas_t getAreasSideLength(double sideLength);
double rotationRad() const;
private:
AreaEffectSimulation::ExplosionArea const m_explosionArea;
std::shared_ptr<HandlerPdmData> m_handlerPdmData;
int m_numOfEffectShows;
areas_t m_areasWidth; // squares in x-direction
areas_t m_areasDepth; // squares in y-direction
LtsCoordTrans::UtmCoordinate m_lowerLeftPos;
NGL::INGLLogger &m_logger;
};
}
@@ -0,0 +1,239 @@
/**
* Handler for the HMI language
* $Id$
* $HeadURL$
* $Author$
*/
#include "effect_show_explosion_cluster.h"
namespace EffectShowManagement
{
EffectShowExplosionCluster::EffectShowExplosionCluster(const AreaEffectSimulation::ExplosionCluster &explosionCluster,
const std::shared_ptr<HandlerPdmData> &handlerPdmData)
: m_explosionCluster(explosionCluster)
, m_handlerPdmData(handlerPdmData)
, m_numOfEffectShows(0)
, m_logger(getLogger("EffectShowExplosionCluster"))
{
}
//=============================================================================
int EffectShowExplosionCluster::getNumOfEffectShows()
{
if (m_numOfEffectShows == 0)
calculateSquare();
return m_numOfEffectShows;
}
//=============================================================================
Database::EsmEffectShow EffectShowExplosionCluster::getEffectShow(int idx)
{
if (m_numOfEffectShows == 0)
calculateSquare();
Database::EsmEffectShow esmEffectShow;
if (!m_handlerPdmData->isSmoke(m_explosionCluster.chargeStruct()))
{
int indX = idx % m_areasWidth.numOfAreas;
int indY = idx / m_areasWidth.numOfAreas;
// calculate lower left position
double x_off = 0.0;
for (int i = 0; i < indX; ++i)
x_off += m_areasWidth.side(i);
double y_off = 0.0;
for (int i = 0; i < indY; ++i)
y_off += m_areasDepth.side(i);
LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos;
lowerLeftPos.x = lowerLeftPos.x + x_off;
lowerLeftPos.y = lowerLeftPos.y + y_off;
LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad());
// calculate center position
LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPos;
centerPos.x = centerPos.x + m_areasWidth.side(indX) / 2.;
centerPos.y = centerPos.y + m_areasDepth.side(indY) / 2.;
LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad());
esmEffectShow.id = 0;
esmEffectShow.name = QStringLiteral("EXP");
esmEffectShow.startTime = m_explosionCluster.effectStart().is_set() ? m_explosionCluster.effectStart().get() : 0;
esmEffectShow.duration = m_explosionCluster.effectDuration();
esmEffectShow.centerPosition = centerPosRotated.geographic();
esmEffectShow.idAreaEffectSimulation = m_explosionCluster.id();
esmEffectShow.esmParticipantId = -1;
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_explosionCluster.name());
esmEffectShow.numOfVolley = getNumberOfVolley();
esmEffectShow.shotsPerVolley = getShotsPerArea() / esmEffectShow.numOfVolley;
esmEffectShow.typeOfAmmunition = m_explosionCluster.chargeStruct().chargeTypeId();
// can there be more then 48 shoots?
if (esmEffectShow.shotsPerVolley > 48)
esmEffectShow.shotsPerVolley = 48;// (48 / esmEffectShow.numOfVolley);
if (esmEffectShow.shotsPerVolley <= 0)
esmEffectShow.shotsPerVolley = 1;
esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic();
esmEffectShow.areaWidth = m_areasWidth.side(indX);
esmEffectShow.areaDepth = m_areasDepth.side(indY);
esmEffectShow.areaRotation = m_explosionCluster.area().rotation() + 90;
DEBUG_LOG(m_logger) << "\nWidth: " << m_explosionCluster.area().width() << " Height: " << m_explosionCluster.area().height()
<< "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs()
<< "\nRotated Center Pos: " << centerPosRotated.mgrs()
<< "\nOffset x,y: " << x_off << " , " << y_off
<< "\nSide x,y: " << m_areasWidth.side(indX) << " , " << m_areasDepth.side(indY)
<< "\nindX: " << indX << " grid " << m_areasWidth.numSideLength1 << ' ' << m_areasWidth.sideLength1 << ' ' << m_areasWidth.numSideLength2 << ' ' << m_areasWidth.sideLength2
<< "\nindY: " << indY << " grid " << m_areasDepth.numSideLength1 << ' ' << m_areasDepth.sideLength1 << ' ' << m_areasDepth.numSideLength2 << ' ' << m_areasDepth.sideLength2;
}
else
{
LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos; //unnötig?
LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad());
// calculate center position
LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPosRotated;
centerPos.x = centerPos.x + m_explosionCluster.area().width() / 2.;
centerPos.y = centerPos.y + m_explosionCluster.area().height() / 2.;
LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad());
esmEffectShow.id = 0;
esmEffectShow.name = QStringLiteral("EXP");
esmEffectShow.startTime = m_explosionCluster.effectStart().is_set() ? m_explosionCluster.effectStart().get() : 0;
esmEffectShow.duration = m_explosionCluster.effectDuration();
esmEffectShow.centerPosition = centerPosRotated.geographic();
esmEffectShow.idAreaEffectSimulation = m_explosionCluster.id();
esmEffectShow.esmParticipantId = -1;
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_explosionCluster.name());
esmEffectShow.typeOfAmmunition = m_explosionCluster.chargeStruct().chargeTypeId();
esmEffectShow.numOfVolley = 1;
esmEffectShow.shotsPerVolley = 1;
esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic();
esmEffectShow.areaWidth = m_explosionCluster.area().width();
esmEffectShow.areaDepth = m_explosionCluster.area().height();
esmEffectShow.areaRotation = m_explosionCluster.area().rotation() + 90;
DEBUG_LOG(m_logger) << "\nWidth: " << m_explosionCluster.area().width() << " Height: " << m_explosionCluster.area().height()
<< "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs()
<< "\nRotated Center Pos: " << centerPosRotated.mgrs()
<< "\nSide x,y: " << m_explosionCluster.area().width() << " , " << m_explosionCluster.area().height();
}
return esmEffectShow;
}
//=============================================================================
void EffectShowExplosionCluster::updateEffectShow(Database::EsmEffectShow &data)
{
DEBUG_LOG(m_logger) << "update EffectSHow for (" << data.id << ")";
data.nameAreaEfffectSimulation = QString::fromStdString(m_explosionCluster.name());
data.startTime = m_explosionCluster.effectStart().is_set() ? m_explosionCluster.effectStart().get() : 0;
data.duration = m_explosionCluster.effectDuration();
if (data.shotsPerVolley > 48)
data.shotsPerVolley = 48;//(48 / data.numOfVolley);
if (data.shotsPerVolley <= 0)
data.shotsPerVolley = 1;
data.typeOfAmmunition = m_explosionCluster.chargeStruct().chargeTypeId();
}
//-----------------------------------------------------------------------------
void EffectShowExplosionCluster::calculateSquare()
{
Core::GeoPosition2D geoPos = m_explosionCluster.area().cornerBottomLeft();
m_lowerLeftPos = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos.lon(), geoPos.lat());
// Calculate squares.
m_areasWidth = getAreasSideLength(m_explosionCluster.area().width()); // Squares in x-direction
m_areasDepth = getAreasSideLength(m_explosionCluster.area().height()); // Squares in y-direction
m_numOfEffectShows = m_handlerPdmData->effectShowCount(m_explosionCluster.chargeStruct());
}
//static ----------------------------------------------------------------------
LtsCoordTrans::UtmCoordinate EffectShowExplosionCluster::rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle)
{
LtsCoordTrans::UtmCoordinate res = p; // copy zone, northp
res.x = ((p.x - c.x) * cos(angle)) - ((p.y - c.y) * sin(angle)) + c.x;
res.y = ((p.x - c.x) * sin(angle)) + ((p.y - c.y) * cos(angle)) + c.y;
return res;
}
//static ----------------------------------------------------------------------
EffectShowExplosionCluster::areas_t EffectShowExplosionCluster::getAreasSideLength(double sideLength)
{
areas_t res;
int sl = qRound(sideLength + 0.5);
int n50 = (sl < 25) ? 1 : (sl + 25) / 50; // number of 50m squares
int n300 = n50 / 6; // number of 300m squares
int len = n50 * 50; // length to be diveded into squares
res.numOfAreas = ((n300 * 6) == n50) ? n300 : n300 + 1; // number of areas at all
res.sideLength1 = (len / (res.numOfAreas * 50)) * 50;
res.numSideLength2 = (len - (res.numOfAreas * res.sideLength1)) / 50;
res.sideLength2 = res.sideLength1 + 50;
res.numSideLength1 = res.numOfAreas - res.numSideLength2;
//qCritical() << "sl = " << sl << " n50= " << n50 << " n300 = " << n300 << " len = "
// << len << " numOfAreas = " << res.numOfAreas << " sideLength1 = " << res.sideLength1;
return res;
}
//-----------------------------------------------------------------------------
int EffectShowExplosionCluster::getNumberOfVolley() const
{
const int v = getShotsPerArea();
return getNumberOfVolley(v);
}
//-----------------------------------------------------------------------------
int EffectShowExplosionCluster::getShotsPerArea() const
{
if (!m_numOfEffectShows)
return 0;
int v = m_explosionCluster.impactCount(); //cannonCount() * m_explosionCluster.cannonRounds();
return v / m_numOfEffectShows; //split even across all effect shows
}
int EffectShowExplosionCluster::getShotsPerArea(int areas) const
{
if (areas == 0)
return 0;
int v = m_explosionCluster.impactCount();//cannonCount() * m_explosionCluster.cannonRounds();
return v / areas;
}
int EffectShowExplosionCluster::getNumberOfVolley(int v)
{
if (v < 3) // <= 0 should not happen but did...
return qMax(1, v);
if (v <= 25)
return 3;
if (v <= 50)
return 6;
if (v <= 100)
return 9;
if (v <= 150)
return 12;
if (v <= 200)
return 15;
return 18;
}
//-----------------------------------------------------------------------------
double EffectShowExplosionCluster::rotationRad() const
{
return -m_explosionCluster.area().rotation() * LtsCoordTrans::deg2rad();
}
//-----------------------------------------------------------------------------
} // Namespace EffectShowManagement
@@ -0,0 +1,130 @@
/**
* Exercise object
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "logger.h"
#include "handler_pdm_data.h"
#include <AreaEffectSimulation/aes_dtc.h>
#include <EffectShowManagement/esm_db.h>
#include <LtsCoordTrans/lts_coord_trans.h>
namespace EffectShowManagement
{
/**
* @brief Creates the Effect Show data from the Area Effect Simulation data for Explosion Clusters.
*
* For the Effect Show data to be created see ICD GUEZSB60_ICD-0046C.
* For calculations the mathematical x-axis is mapped to east; the y-axis is mapped to north.\n
*
* List of features:\n
* (1)The area effect is limited to one effect show located at the center of the cluster.\n
* (2) Only specific charge types create more than one effect show as configured in the charge type
* (3)The number of volleys depends on the number of shots by the explosion cluster as follows:\n
* Number of shot <= 25 : 3 volleys\n
* Number of shot <= 50 : 6 volleys\n
* Number of shot <= 100 : 9 volleys\n
* Number of shot <= 150 : 12 volleys\n
* Number of shot <= 200 : 15 volleys\n
* else : 18 volleys\n
* (4)The start time for the effect show is overtaken from the start time of the explosion cluster.\n
* (5)The duration for the effect show is overtaken from the duration of the explosion cluster.\n
* (6)The type of ammunition is determined by the chargeType of the explosion cluster and the
* "tas code indirect" of the Project Data Management.\n
*
*/
class EffectShowExplosionCluster
{
public:
explicit EffectShowExplosionCluster(const AreaEffectSimulation::ExplosionCluster &explosionCluster,
const std::shared_ptr<HandlerPdmData> &handlerPdmData);
/**
* @brief Returns the number of Effect Shows resulting from Area Effect Simulation.
* @return The number of effect shows
*/
int getNumOfEffectShows();
/**
* @brief Returns the Effect Show with the provided index.
* @param[in] idx The index of the Effect Show [0..@see geNumOfEffectShows()-1]
* @return The Effect Show with the provided index
*/
Database::EsmEffectShow getEffectShow(int idx);
/**
* @brief Updates the following data: startTime, duration, volley, typeOfAmmunition.
* @param[in] data The Effect Show to be updated
* @param[out] data The updated Effect Show
*/
void updateEffectShow(Database::EsmEffectShow &data);
int getShotsPerArea(int areas) const;
static int getNumberOfVolley(int v);
/**
* @brief Returns the number of volley.
* @return The number of volley.
*/
int getNumberOfVolley() const;
int getShotsPerArea() const;
private:
/**
* @brief Calculates the square of the each effect area.
*/
void calculateSquare();
/**
* @brief Turns position p arround position c.
* @param[in] p Point to be rotated
* @param[in] c Center point of rotation
* @param[in] angle Angle of rotation
* @return Depth of the effect area. The resolution of the value is 50m. (Max: 300m)
*/
static LtsCoordTrans::UtmCoordinate rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle);
struct areas_t
{
int side(int i) const
{
return (i < numSideLength1) ? sideLength1 : sideLength2;
}
int numSideLength1 = 0; // number of areas with the side length "sideLength1"
int sideLength1 = 0; // side length of the areas 1
int numSideLength2 = 0; // number of areas with the side length "sideLength2"
int sideLength2 = 0; // side length of the areas 2
int numOfAreas = 0; // number of areas along the side at all
};
/** @brief Calculates the side length of effect shows.
* The side length shall be rounded to a resolution of 50m.
* The maximum side length shall be 300m. If the side length is > 300m, a split into
* more side length shall be made. In this case uniform side length of <= 300m shall be
* calculated. For the rest, a last side length shall be provided.
* @param[in] sideLength Side length of Area Effect Simuilation
* @return Side length of the effect shows
*/
static areas_t getAreasSideLength(double sideLength);
double rotationRad() const;
private:
AreaEffectSimulation::ExplosionCluster const m_explosionCluster;
std::shared_ptr<HandlerPdmData> m_handlerPdmData;
int m_numOfEffectShows;
areas_t m_areasWidth; // squares in x-direction
areas_t m_areasDepth; // squares in y-direction
LtsCoordTrans::UtmCoordinate m_lowerLeftPos;
NGL::INGLLogger &m_logger;
};
}
+132
View File
@@ -0,0 +1,132 @@
/**
* Handler for the HMI language
* $Id$
* $HeadURL$
* $Author$
*/
#include "effect_show_mine_area.h"
#include <QLineF>
namespace EffectShowManagement
{
EffectShowMineArea::EffectShowMineArea(const AreaEffectSimulation::MineArea &mineArea)
: m_mineArea(mineArea)
, m_segment(getEffectShowSegment(mineArea))
, m_utmZone(-1)
, m_rotation(0.0)
, m_logger(getLogger("EffectShowMineArea"))
{
}
//=============================================================================
Database::EsmEffectShow EffectShowMineArea::getEffectShow()
{
calculatePositions();
Database::EsmEffectShow esmEffectShow;
esmEffectShow.id = 0;
esmEffectShow.name = QLatin1String("MIN");
esmEffectShow.startTime = m_mineArea.effectStart().is_set() ? m_mineArea.effectStart().get() : 0;
esmEffectShow.duration = m_mineArea.effectDuration();
esmEffectShow.centerPosition = m_centerPos.geographic();
esmEffectShow.idAreaEffectSimulation = m_mineArea.id();
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_mineArea.name());
esmEffectShow.esmParticipantId = -1;
esmEffectShow.numOfVolley = 1; //Hardcode??
esmEffectShow.shotsPerVolley = 18;
esmEffectShow.lowerLeftPosition = m_lowerLeftPos.geographic();
esmEffectShow.areaWidth = getEffectAreaWidth();
esmEffectShow.areaDepth = getEffectAreaDepth();
esmEffectShow.areaRotation = m_rotation;
updateEffectShow(esmEffectShow);
for (const auto &seg : m_mineArea.segments())
{
const Core::GeoPosition2D &posGeo = seg.positionStart();
LtsCoordTrans::UtmCoordinate pos = LtsCoordTrans::UtmCoordinate::fromGeographic(posGeo.lon(), posGeo.lat(), m_utmZone);
DEBUG_LOG(m_logger) << "Start Pos Segm.: " << pos.mgrs();
}
DEBUG_LOG(m_logger) << "Center Pos Effect Show: " << LtsCoordTrans::mgrsFromGeographic(esmEffectShow.centerPosition.x(), esmEffectShow.centerPosition.y());
return esmEffectShow;
}
//-----------------------------------------------------------------------------
void EffectShowMineArea::updateEffectShow(Database::EsmEffectShow &data)
{
data.nameAreaEfffectSimulation = QString::fromStdString(m_mineArea.name());
data.duration = m_mineArea.effectDuration() / 10;
if (data.duration > (3600 * 1000))
data.duration = 3600 * 1000;
if (m_mineArea.effectStart().is_set())
data.startTime = m_mineArea.effectStart().get() + m_mineArea.effectDuration() - data.duration;
else
data.startTime = 0;
data.typeOfAmmunition = m_mineArea.chargeStruct().chargeTypeId();
}
//-----------------------------------------------------------------------------
void EffectShowMineArea::calculatePositions()
{
// start position of the segment
Core::GeoPosition2D geoPosStart = m_segment.positionStart();
Core::GeoPosition2D geoPosEnd = m_segment.positionEnd();
LtsCoordTrans::UtmCoordinate startPositionUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPosStart.lon(), geoPosStart.lat(), m_utmZone);
if (m_utmZone == -1)
m_utmZone = startPositionUtm.zone;
LtsCoordTrans::UtmCoordinate endPositionUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPosEnd.lon(), geoPosEnd.lat(), m_utmZone);
const QLineF line({startPositionUtm.x, startPositionUtm.y}, {endPositionUtm.x, endPositionUtm.y});
// length/2 of the segment
double halfSegmentLength = line.length() / 2.0;
// rotation angle
m_rotation = 90.0 - line.angle();
double angle = m_rotation * LtsCoordTrans::deg2rad();
// calculation center position
LtsCoordTrans::UtmCoordinate centerPos = startPositionUtm;
centerPos.x = centerPos.x + halfSegmentLength;
m_centerPos = rotate(centerPos, startPositionUtm, angle);
// calculation lower left position
LtsCoordTrans::UtmCoordinate lowerLeftPos = startPositionUtm;
lowerLeftPos.x = lowerLeftPos.x + halfSegmentLength - (getEffectAreaWidth() / 2.0);
lowerLeftPos.y = lowerLeftPos.y - (getEffectAreaDepth() / 2.0);
m_lowerLeftPos = rotate(lowerLeftPos, startPositionUtm, angle);
}
//-----------------------------------------------------------------------------
int EffectShowMineArea::getEffectAreaWidth() const
{
Core::GeoPosition2D geoPosStart = m_segment.positionStart();
Core::GeoPosition2D geoPosEnd = m_segment.positionEnd();
LtsCoordTrans::UtmCoordinate startPositionUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPosStart.lon(), geoPosStart.lat(), m_utmZone);
LtsCoordTrans::UtmCoordinate endPositionUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPosEnd.lon(), geoPosEnd.lat(), m_utmZone);
const QLineF line({startPositionUtm.x, startPositionUtm.y}, {endPositionUtm.x, endPositionUtm.y});
int segmentLength = line.length();
if (segmentLength <= 50) return 50;
if (segmentLength >= 300) return 300;
return (((segmentLength + 25) / 50) * 50);
}
//-----------------------------------------------------------------------------
int EffectShowMineArea::getEffectAreaDepth() const
{
int segmentWidth = qRound(m_mineArea.width());
if (segmentWidth <= 50) return 50;
if (segmentWidth >= 300) return 300;
return (((segmentWidth + 25) / 50) * 50);
}
//static ----------------------------------------------------------------------
LtsCoordTrans::UtmCoordinate EffectShowMineArea::rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle)
{
LtsCoordTrans::UtmCoordinate res = p; // copy zone, northp
res.x = ((p.x - c.x) * cos(angle)) - ((p.y - c.y) * sin(angle)) + c.x;
res.y = ((p.x - c.x) * sin(angle)) + ((p.y - c.y) * cos(angle)) + c.y;
return res;
}
//-----------------------------------------------------------------------------
} // Namespace EffectShowManagement
+101
View File
@@ -0,0 +1,101 @@
/**
* Exercise object
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "logger.h"
#include "handler_pdm_data.h"
#include <AreaEffectSimulation/aes_dtc.h>
#include <EffectShowManagement/esm_db.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <QPointF>
namespace EffectShowManagement
{
/**
* @brief Creates the Effect Show data from the Area Effect Simulation data for mine areas.
*
* For the Effect Show data to be created see ICD GUEZSB60_ICD-0046C.
* For calculations the mathematical x-axis is mapped to east; the y-axis is mapped to north.
*
* List of features:\n
* (1)The area for the effect show is limited to 300m x 300m in a grid of 50m.\n
* (2)One effect show area is mapped to the middle segment of the segments of the mine area.\n
* (3)The number of volleys is fixed to 18 volleys\n
* (4)The duration of the effect show is set to "duration of mine area" / 10.\n
* (5)The start time of the effect show is calculated as follows:\n
* "start time mine area" + "duration mine area" - "duration of the effect show"\n
* (6)The type of ammunition is determined by the chargeType of the mine area and the
* "tas code indirect" of the Project Data Management.\n
*/
class EffectShowMineArea
{
public:
explicit EffectShowMineArea(const AreaEffectSimulation::MineArea &mineArea);
/**
* @brief Returns the Effect Show.
* @return The Effect Show
*/
Database::EsmEffectShow getEffectShow();
/**
* @brief Updates the following data: startTime, duration, typeOfAmmunition.
* @param[in] data The Effect Show to be updated
* @param[out] data The updated Effect Show
*/
void updateEffectShow(Database::EsmEffectShow &data);
/**
* @brief Returns the segment of the mine area to be used for effect show.
* The middle segment shall be used for the effect show.
* @return Segment of the mine area to be used for the effect show
*/
static const AreaEffectSimulation::MineSegment &getEffectShowSegment(const AreaEffectSimulation::MineArea &mineArea)
{
return mineArea.segments().at(mineArea.segments().size() / 2);
}
private:
/**
* @brief Calculates the center position and the lower left position of the effect area.
*/
void calculatePositions();
/**
* @brief Returns the width of the effect area.
* Width is the length of the mine area segment.
* @return Width of the effect area. The resolution of the value is 50m. (Max: 300m)
*/
int getEffectAreaWidth() const;
/**
* @brief Returns the Depth of the effect area.
* Depth is the width of the mine area segment.
* @return Depth of the effect area. The resolution of the value is 50m. (Max: 300m)
*/
int getEffectAreaDepth() const;
/**
* @brief Turns position p arround position c.
* @param[in] p Point to be rotated
* @param[in] c Center point of rotation
* @param[in] angle Angle of rotation
* @return Depth of the effect area. The resolution of the value is 50m. (Max: 300m)
*/
static LtsCoordTrans::UtmCoordinate rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle);
private:
AreaEffectSimulation::MineArea const m_mineArea;
const AreaEffectSimulation::MineSegment &m_segment;
int m_utmZone;
LtsCoordTrans::UtmCoordinate m_centerPos;
LtsCoordTrans::UtmCoordinate m_lowerLeftPos;
double m_rotation; // math angle [degree]
NGL::INGLLogger &m_logger;
};
}
+89
View File
@@ -0,0 +1,89 @@
/**
* @RDE_HEADER@
* MeteoDataManagement - Static Meteo Data Edit Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-10-17
*/
#include "esm_convert_from_tab.h"
#include <LtsUtilsCore/qbytearray_byteaccess.h>
namespace EffectShowManagement
{
namespace ConvertFromTab
{
//=============================================================================
RxTelegram_e isTelegram(const TrainingAreaBase::FireSmokeMarkerData &data)
{
Q_ASSERT(data.payload().size() > 0);
switch (data.payload().at(0))
{
case 120: return RxTelegram_e::OrderConfirmation;
case 121: return RxTelegram_e::VehicleStatus;
}
return (RxTelegram_e::unknown);
}
//=============================================================================
OrderConfirmation_t getOrderConfirmation(const TrainingAreaBase::FireSmokeMarkerData &data)
{
Q_ASSERT(data.payload().size() >= 5);
const QByteArray tele(QByteArray::fromRawData(
reinterpret_cast<const char *>(&data.payload().at(0)),
data.payload().size()));
OrderConfirmation_t res;
size_t k = 1;
quint8 byte;
LtsUtils::get1Byte(tele, k, byte);
res.orderType = OrderType_e(byte);
LtsUtils::get2Byte(tele, k, res.orderId);
LtsUtils::get1Byte(tele, k, byte);
res.confirmation = EffectShowManagement::OrderConfirmation_e::inner_enum(byte);
QByteArray qbArr;
int ie = data.payload().size() - 5;
for (int i = 0; i < ie; ++i)
qbArr.append(data.payload().at(5 + i)); // rationale (text)
res.answerText = QString::fromUtf8(qbArr);
return res;
}
//=============================================================================
VehicleStatus_t getVehicleStatus(const TrainingAreaBase::FireSmokeMarkerData &data)
{
Q_ASSERT(data.payload().size() == 5);
const QByteArray tele(QByteArray::fromRawData(
reinterpret_cast<const char *>(&data.payload().at(0)),
data.payload().size()));
VehicleStatus_t res;
res.equipmentNumber = data.equipmentNumber();
res.timestamp = data.sampleTime();
size_t k = 1;
quint8 byte;
LtsUtils::get1Byte(tele, k, byte);
res.operational = byte != 0;
LtsUtils::get1Byte(tele, k, res.ammunitionMagazine);
LtsUtils::get1Byte(tele, k, res.ammunitionAvailable);
LtsUtils::get1Byte(tele, k, byte);
res.inclinationSensorFail = ((byte & 0x80) != 0);
res.navigationFail = ((byte & 0x40) != 0);
res.airSpeedMeterFail = ((byte & 0x20) != 0);
res.controlComputerFail = ((byte & 0x10) != 0);
res.magazineFail = ((byte & 0x08) != 0);
res.feature = (byte & 0x06) >> 1;
return res;
}
} // namespace ConvertFromTab
} // namespace EffectShowManagement
+80
View File
@@ -0,0 +1,80 @@
/**
* @RDE_HEADER@
* MeteoDataManagement - Static Meteo Data Edit Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-10-17
*/
#pragma once
#include <TrainingAreaBase/tab_dtc.h>
#include <EffectShowManagement/esm_db.h>
#include <QString>
namespace EffectShowManagement
{
/**
* @brief Converts the data telegrams received from Training Area Base proxy.
*
* For the telegram data to be converted see GUEZSB60_ICD-0046C.
*/
namespace ConvertFromTab
{
/**
* @brief Rx Telegram types.
*/
enum class RxTelegram_e { OrderConfirmation, VehicleStatus, unknown };
/**
* @brief Returns the type of telegram related to the received data.
* @return The type of the telegram
*/
RxTelegram_e isTelegram(const TrainingAreaBase::FireSmokeMarkerData &data);
/**
* @brief Order types.
*/
enum class OrderType_e : qint8 { Relocation = 0, EffectShow = 1 };
/**
* @brief Order confirmation data. ICD Tele: DMF-Auftragsbestaetigung; Parameter: Bestaetigung
*/
struct OrderConfirmation_t
{
OrderType_e orderType = OrderType_e::Relocation; // 0=Relocation; 1=Effect Show
qint16 orderId = 0; // Id of relocation or effect show
EffectShowManagement::OrderConfirmation_e confirmation = EffectShowManagement::OrderConfirmation_e::WaitingForAcceptance;
QString answerText;
};
/**
* @brief Returns the order confirmation data.
* @return Order confirmation data.
*/
OrderConfirmation_t getOrderConfirmation(const TrainingAreaBase::FireSmokeMarkerData &data);
/**
* @brief Order confirmation data. ICD Tele: DMF-Auftragsbestaetigung; Parameter: Bestaetigung
*/
struct VehicleStatus_t
{
qint64 timestamp = 0;
int equipmentNumber = 0;
int operational = 0;
int ammunitionMagazine = 0;
int feature = 0;
quint8 ammunitionAvailable = 0;
bool inclinationSensorFail = false;
bool navigationFail = false;
bool airSpeedMeterFail = false;
bool controlComputerFail = false;
bool magazineFail = false;
};
/**
* @brief Returns the effect show vehicle status data.
* @return Effect show vehicle status data.
*/
VehicleStatus_t getVehicleStatus(const TrainingAreaBase::FireSmokeMarkerData &data);
} // namespace ConvertFromTab
} // namespace EffectShowManagement
+143
View File
@@ -0,0 +1,143 @@
/**
* @RDE_HEADER@
* MeteoDataManagement - Static Meteo Data Edit Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-10-17
*/
#include "esm_convert_to_tab.h"
#include <LtsUtilsCore/qbytearray_byteaccess.h>
#include <LtsUtilsCore/dds_vector.h>
#include <QByteArray>
namespace EffectShowManagement
{
namespace ConvertToTab
{
//=============================================================================
std::vector<uint8_t> convertEffectShowOrder(const EffectShowOrder_t &effectShowOrder)
{
QByteArray ba;
ba.reserve(48);
LtsUtils::set1Byte(150, ba);
LtsUtils::set2Byte(effectShowOrder.idEffectShow, ba);
LtsUtils::set4Byte(effectShowOrder.startTime, ba);
LtsUtils::set8Byte(effectShowOrder.centerPosition.lon(), ba);
LtsUtils::set8Byte(effectShowOrder.centerPosition.lat(), ba);
// 50m squares
LtsUtils::set1Byte(effectShowOrder.areaWidth / 50, ba);
LtsUtils::set1Byte(effectShowOrder.areaDepth / 50, ba);
double rotation = fmod(effectShowOrder.rotation, 360.0);
if (rotation < 0.0)
rotation += 360.0;
LtsUtils::set2Byte(qRound(rotation * 100), ba);
LtsUtils::set8Byte(effectShowOrder.lowerLeftPosition.lon(), ba);
LtsUtils::set8Byte(effectShowOrder.lowerLeftPosition.lat(), ba);
LtsUtils::set1Byte(effectShowOrder.numOfVolley, ba);
LtsUtils::set1Byte(effectShowOrder.shotsPerVolley, ba);
LtsUtils::set1Byte(effectShowOrder.typeOfAmmunition, ba);
LtsUtils::set2Byte(static_cast<quint16>(effectShowOrder.duration), ba);
const QByteArray text = effectShowOrder.name.toUtf8().simplified();
for (auto c : text)
LtsUtils::set1Byte(c, ba);
return LtsUtils::convert<std::vector<uint8_t>>(ba);
}
//=============================================================================
std::vector<uint8_t> convertRelocationOrder(const RelocationOrder_t &relocationOrder)
{
QByteArray ba;
ba.reserve(63);
LtsUtils::set1Byte(155, ba);
LtsUtils::set2Byte(relocationOrder.idRelocation, ba);
LtsUtils::set4Byte(relocationOrder.executionTime, ba);
LtsUtils::set8Byte(relocationOrder.centerPosition.lon(), ba);
LtsUtils::set8Byte(relocationOrder.centerPosition.lat(), ba);
const QByteArray text = relocationOrder.infoText.toUtf8().simplified();
for (auto c : text)
LtsUtils::set1Byte(c, ba);
return LtsUtils::convert<std::vector<uint8_t>>(ba);
}
//======================================================================
std::vector<uint8_t> convertEffectShowStop(const qint16 &idEffectShow)
{
QByteArray ba;
ba.reserve(3);
LtsUtils::set1Byte(152, ba);
LtsUtils::set2Byte(idEffectShow, ba);
return LtsUtils::convert<std::vector<uint8_t>>(ba);
}
//======================================================================
std::vector<uint8_t> convertEffectShowContinue(const EffectShowContinue_t &effectShowContinue)
{
QByteArray ba;
ba.reserve(7);
LtsUtils::set1Byte(151, ba);
LtsUtils::set2Byte(effectShowContinue.idEffectShow, ba);
LtsUtils::set4Byte(effectShowContinue.executionTime, ba);
return LtsUtils::convert<std::vector<uint8_t>>(ba);
}
//======================================================================
std::vector<uint8_t> convertOrderRetract(const RetractOrder_t &retractOrder)
{
QByteArray ba;
ba.reserve(4);
LtsUtils::set1Byte(153, ba);
LtsUtils::set1Byte(retractOrder.orderType, ba);
LtsUtils::set2Byte(retractOrder.id, ba);
return LtsUtils::convert<std::vector<uint8_t>>(ba);
}
//=====================================================================
std::vector<uint8_t> convertStatusRequest()
{
std::vector<uint8_t> tele;
tele.resize(1, 154);
return tele;
}
//======================================================================
std::vector<uint8_t> convertMeteoData(const MeteoDataManagement::MeteoData &meteoData)
{
QByteArray ba;
ba.reserve(11);
LtsUtils::set1Byte(156, ba);
LtsUtils::set2Byte(qRound(meteoData.temperature() * 10.0), ba);
LtsUtils::set2Byte(qRound(meteoData.humidity()), ba);
LtsUtils::set2Byte(qRound(meteoData.pressure()), ba);
double dir = fmod(meteoData.windDirection(), 360.0);
if (dir < 0.0)
dir += 360.0;
LtsUtils::set2Byte(qRound(dir * 100), ba);
LtsUtils::set2Byte(qRound(meteoData.windSpeed()), ba);
return LtsUtils::convert<std::vector<uint8_t>>(ba);
}
} // namespace ConvertToTab
} // namespace EffectShowManagement
+112
View File
@@ -0,0 +1,112 @@
/**
* @RDE_HEADER@
* MeteoDataManagement - Static Meteo Data Edit Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-10-17
*/
#pragma once
#include <TrainingAreaBase/tab_dtc.h>
#include <MeteoDataManagement/mdm_dtc.h>
#include <QString>
namespace EffectShowManagement
{
/**
* @brief Converts the data telegrams to be set to Training Area Base proxy.
*
* For the telegram data to be converted see GUEZSB60_ICD-0046C.
*/
namespace ConvertToTab
{
/**
* @brief Order effect show.
*/
struct EffectShowOrder_t
{
qint16 idEffectShow = 0; // ID effect show
qint32 startTime = 0; // GPS time
Core::GeoPosition2D centerPosition; // center pos effect area
int areaWidth = 0; // [0..300]
int areaDepth = 0; // [0..300]
double rotation = 0; // [deg]
Core::GeoPosition2D lowerLeftPosition; // lower left corner effect area
qint8 numOfVolley = 0; // number of volley
qint8 shotsPerVolley = 0; // number of volley
qint8 typeOfAmmunition = 0; // type of ammunition
qint16 duration = 0; // duration of the effect show
QString name;
};
/**
* @brief Returns the telegram to order a effect show.
* @return Telegram to order a effect show.
*/
std::vector<uint8_t> convertEffectShowOrder(const EffectShowOrder_t &effectShowOrder);
/**
* @brief Order Relocation of Effect Show Actor.
*/
struct RelocationOrder_t
{
qint16 idRelocation = 0;
qint64 executionTime = 0; // GPS time [s]
Core::GeoPosition2D centerPosition; // center pos effect area
QString infoText; // max ASCII-char: 40
};
/**
* @brief Returns the telegram to order a relocation of the effect show actor.
* @return Telegram to order a relocation.
*/
std::vector<uint8_t> convertRelocationOrder(const RelocationOrder_t &relocationOrder);
/**
* @brief Returns the telegram to stop the effect show.
* @return Telegram to stop the effect show.
*/
std::vector<uint8_t> convertEffectShowStop(const qint16 &idEffectShow);
/**
* @brief Order continue Effect Show.
*/
struct EffectShowContinue_t
{
qint16 idEffectShow = 0; // ID of effect show
qint64 executionTime = 0; // GPS time [s]
};
/**
* @brief Returns the telegram to continue the effect show.
* @return Telegram to continue the effect show.
*/
std::vector<uint8_t> convertEffectShowContinue(const EffectShowContinue_t &effectShowContinue);
/**
* @brief Retract order.
*/
struct RetractOrder_t
{
qint8 orderType = 0; // 0=Relocation; 1=Effect Show
qint16 id = 0; // Id of Relocation or Effect Show
};
/**
* @brief Returns the telegram to retract the order.
* @return Telegram to retract the order.
*/
std::vector<uint8_t> convertOrderRetract(const RetractOrder_t &retractOrder);
/**
* @brief Returns the telegram to request the status.
* @return Telegram to request the status.
*/
std::vector<uint8_t> convertStatusRequest();
/**
* @brief Returns the telegram to provide meteo data.
* @return Telegram to to provide meteo data.
*/
std::vector<uint8_t> convertMeteoData(const MeteoDataManagement::MeteoData &meteoData);
}
} //namespace EffectShowManagement
+56
View File
@@ -0,0 +1,56 @@
/**
* Export definitions
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-08-04
*/
#pragma once
#include <QtCore/qglobal.h>
#ifndef ESM_COMMON_EXPORT
# undef ESM_ENUM_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define ESM_COMMON_EXPORT
# define ESM_ENUM_EXPORT
# else
# if defined(MAKE_SVCESMCOMMON_LIB)
# define ESM_COMMON_EXPORT Q_DECL_EXPORT
# define ESM_ENUM_EXPORT Q_DECL_EXPORT
# ifndef WIN32
# ifdef NDDSUSERDllExport
# undef NDDSUSERDllExport
# endif
# define NDDSUSERDllExport Q_DECL_EXPORT
# endif
# else
# define ESM_COMMON_EXPORT Q_DECL_IMPORT
# define ESM_ENUM_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef ESM_CLIENT_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define ESM_CLIENT_EXPORT
# else
# if defined(MAKE_SVCESMCLIENT_LIB)
# define ESM_CLIENT_EXPORT Q_DECL_EXPORT
# else
# define ESM_CLIENT_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef ESM_SERVER_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define ESM_SERVER_EXPORT
# else
# if defined(MAKE_SVCESMSERVER_LIB)
# define ESM_SERVER_EXPORT Q_DECL_EXPORT
# else
# define ESM_SERVER_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
+174
View File
@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service namespace="EffectShowManagement" abbreviation="ESM" procNames="EffectShowManagement" exerciseDependency="Exercise">
<rcs>
<Id Id="$Id: ea_export_script.txt 41311 2018-04-23 09:43:45Z ehrlicher $"/>
<HeadURL HeadURL="$HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Common/CodeGen/ea_export_script.txt $"/>
<Author Author="$Author: ehrlicher $"/>
</rcs>
<tables>
<table name="esm_aes_data">
<column name="id_aes" datatype="integer" isPrimaryKey="1"/>
<column name="name_aes" datatype="text"/>
<column name="effect_state_id" datatype="integer"/>
<column name="effect_start" datatype="bigint"/>
<column name="effect_duration" datatype="integer"/>
<column name="charge_type_id" datatype="integer" isForeignKey="1"/>
<column name="volley" datatype="integer"/>
<column name="position" datatype="point_2d"/>
<column name="width" datatype="real"/>
<column name="depth" datatype="real"/>
<column name="rotation_angle" datatype="real"/>
<constraint name="UQ_esm_area_effect_simulation_id_aes" type="unique">
<column name="id_aes"/>
</constraint>
<foreignKey name="FK_esm_aes_data_pdm_charge_type" referential_integrity="DeleteCascade">
<source table="esm_aes_data" column="charge_type_id"/>
<destination service="ProjectDataManagement" serviceAbbr="pdm" schema="pdm" table="pdm_charge_type" column="id"/>
</foreignKey>
</table>
<table name="esm_effect_show">
<column name="id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
<column name="center_position" datatype="point_2d"/>
<column name="id_area_effect_simulation" datatype="integer"/>
<column name="name_area_efffect_simulation" datatype="text"/>
<column name="esm_participant_id" datatype="integer"/>
<column name="num_of_volley" datatype="integer"/>
<column name="shots_per_volley" datatype="integer"/>
<column name="order_confirmation" datatype="integer"/>
<column name="answer_text" datatype="text"/>
<column name="start_time" datatype="bigint"/>
<column name="duration" datatype="integer"/>
<column name="lower_left_position" datatype="point_2d"/>
<column name="area_width" datatype="integer"/>
<column name="area_depth" datatype="integer"/>
<column name="area_rotation" datatype="real"/>
<column name="type_of_ammunition" datatype="integer"/>
<constraint name="UQ_esm_effect_show_id" type="unique">
<column name="id"/>
</constraint>
</table>
<table name="esm_effect_show_actor_relocation">
<column name="id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="position" datatype="point_2d"/>
<column name="arrival_time" datatype="bigint"/>
<column name="info" datatype="text"/>
<column name="esm_participant_id" datatype="integer"/>
<column name="order_confirmation" datatype="integer"/>
<column name="answert_text" datatype="text"/>
<constraint name="UQ_esm_relocation_id" type="unique">
<column name="id"/>
</constraint>
</table>
<table name="esm_effect_show_vehicle_status">
<column name="esm_participant_id" datatype="integer" isPrimaryKey="1"/>
<column name="timestamp" datatype="bigint"/>
<column name="name_effect_show_actor" datatype="text"/>
<column name="operational" datatype="boolean"/>
<column name="ammunition_magazine" datatype="integer"/>
<column name="ammunition_available" datatype="integer"/>
<column name="inclination_sensor_fail" datatype="boolean"/>
<column name="navigation_fail" datatype="boolean"/>
<column name="air_speed_meter_fail" datatype="boolean"/>
<column name="control_computer_fail" datatype="boolean"/>
<column name="magazine_fail" datatype="boolean"/>
<column name="feature" datatype="integer"/>
<constraint name="UQ_esm_effect_show_vehicle_status_esm_participant_id" type="unique">
<column name="esm_participant_id"/>
</constraint>
</table>
</tables>
<views/>
<dbServiceStructs>
<serviceStruct name="EsmAesData" table="esm_aes_data"/>
<serviceStruct name="EsmEffectShow" table="esm_effect_show"/>
<serviceStruct name="EsmEffectShowActorRelocation" table="esm_effect_show_actor_relocation"/>
<serviceStruct name="EsmEffectShowVehicleStatus" table="esm_effect_show_vehicle_status"/>
<table name="esm_aes_data"/>
<table name="esm_effect_show"/>
<table name="esm_effect_show_actor_relocation"/>
<table name="esm_effect_show_vehicle_status"/>
</dbServiceStructs>
<topicTypes>
<topicType name="EffectShow" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="Core::BaseEntity">
<column name="position" idlType="Core::GeoPosition2D"/>
<column name="startTime" idlType="long long" isOptional="1"/>
<column name="idAreaEffectSimulation" idlType="long"/>
<column name="nameAreaEffectSimulation" idlType="string"/>
<column name="esmParticipantId" idlType="long"/>
<column name="duration" idlType="long"/>
<column name="numOfVolley" idlType="long"/>
<column name="shotsPerVolley" idlType="long"/>
<column name="lowerLeftPosition" idlType="Core::GeoPosition2D"/>
<column name="areaDepth" idlType="long"/>
<column name="areaWidth" idlType="long"/>
<column name="areaRotation" idlType="long"/>
<column name="typeOfAmmunition" idlType="long"/>
<column name="orderConfirmation" idlType="OrderConfirmation_e"/>
<column name="answerText" idlType="string"/>
</topicType>
<topicType name="EffectShowActorRelocation" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="Core::BaseEntity">
<column name="position" idlType="Core::GeoPosition2D"/>
<column name="arrival_time" idlType="long long" isOptional="1"/>
<column name="info" idlType="string"/>
<column name="esmParticipantId" idlType="long"/>
<column name="orderConfirmation" idlType="OrderConfirmation_e"/>
<column name="answerText" idlType="string"/>
</topicType>
<topicType name="EffectShowVehicleStatus" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" recordTopic="1">
<column name="esmParticipantId" idlType="long" isKey="1"/>
<column name="nameEffectShowActor" idlType="string"/>
<column name="operational" idlType="boolean"/>
<column name="ammunitionMagazine" idlType="short"/>
<column name="ammunitionAvailable" idlType="short"/>
<column name="inclinationSensorFail" idlType="boolean"/>
<column name="navigationFail" idlType="boolean"/>
<column name="airSpeedMeterFail" idlType="boolean"/>
<column name="controlComputerFail" idlType="boolean"/>
<column name="magazineFail" idlType="boolean"/>
<column name="feature" idlType="Feature_e"/>
<column name="sampleTime" idlType="long long"/>
</topicType>
</topicTypes>
<functionTopics>
<functionTopic name="EffectShowActorRelocationModify" requestTopicType="EffectShowActorRelocation" replyTopicType="Core::FunctionReply" requestTopicName="EffectShowActorRelocationModifyRequest" replyTopicName="EffectShowActorRelocationModifyReply" routeInReplay="0"/>
<functionTopic name="EffectShowActorRelocationRemove" requestTopicType="Core::RemoveElementRequest" replyTopicType="Core::FunctionReply" requestTopicName="EffectShowActorRelocationRemoveRequest" replyTopicName="EffectShowActorRelocationRemoveReply" routeInReplay="0"/>
<functionTopic name="EffectShowModify" requestTopicType="EffectShow" replyTopicType="Core::FunctionReply" requestTopicName="EffectShowModifyRequest" replyTopicName="EffectShowModifyReply" routeInReplay="0"/>
<functionTopic name="EffectShowRemove" requestTopicType="Core::RemoveElementRequest" replyTopicType="Core::FunctionReply" requestTopicName="EffectShowRemoveRequest" replyTopicName="EffectShowRemoveReply" routeInReplay="0"/>
</functionTopics>
<enumerations>
<enumeration name="Feature_e">
<attribute key="NotSpecified" value="0"/>
<attribute key="Smoke" value="1"/>
<attribute key="Explosion24" value="2"/>
<attribute key="Explosion48" value="3"/>
</enumeration>
<enumeration name="OrderConfirmation_e">
<attribute key="WaitingForAcceptance" value="0"/>
<attribute key="OrderAcceptance" value="1"/>
<attribute key="DriveOff" value="2"/>
<attribute key="PositionReached" value="3"/>
<attribute key="FiringReadiness" value="4"/>
<attribute key="Execution" value="5"/>
<attribute key="InterruptExecution" value="6"/>
<attribute key="OrderCarriedOut" value="7"/>
<attribute key="Abort" value="8"/>
<attribute key="Nonacceptance" value="9"/>
<attribute key="InterruptRelocation" value="10"/>
</enumeration>
</enumerations>
<operatorRights offset="49">
<guiPlugin name="EffectShow" offset="1">
<operatorRightGroup name="Effect Show Management" description="Edit Effect Show Elements, Actors, Relocations and show Vehicle Status">
<operatorRight right="EffectShowEdit" value="1" description="Edit Effect Show Elements"/>
<operatorRight right="ActorEdit" value="2" description="Edit Actors"/>
<operatorRight right="RelocationsEdit" value="3" description="Edit Relocations"/>
<operatorRight right="VehicleStatusShow" value="4" description="Show Vehicle Status"/>
</operatorRightGroup>
</guiPlugin>
</operatorRights>
</service>
+596
View File
@@ -0,0 +1,596 @@
/**
* Get notifications about changed AES Explosions/MineAreas
* $Id$
* $HeadURL$
* $Author$
*/
#include <QVector>
#include "handler_aes_data.h"
#include "object_aes_data.h"
#include "handler_effect_show_vehicle_status.h"
#include "effect_show_mine_area.h"
#include "effect_show_explosion_area.h"
#include "effect_show_explosion_cluster.h"
#include "settings.h"
using namespace EffectShowManagement;
HandlerAesData::HandlerAesData(Initialization *mainHandler)
: QObject()
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerAesData"))
{
} // end of ctor()
//=============================================================================
HandlerAesData::~HandlerAesData()
{
qDeleteAll(m_AesDataObjMap);
m_AesDataObjMap.clear();
} // end of dtor()
//=============================================================================
bool HandlerAesData::init()
{
DEBUG_LOG(m_logger) << "Begin HandlerAesData";
// create ObjectAesData
auto cbAes = [this](const Database::EsmAesData & data)
{
ObjectAesData *ifs(new ObjectAesData(m_mainHandler, this));
ifs->setData(data);
m_AesDataObjMap.insert(data.idAes, ifs);
};
if (!m_mainHandler->db()->select(cbAes))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
auto dtcAes = m_mainHandler->dds()->dtcAes();
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::explosionAreaChanged,
this, &HandlerAesData::onExplosionAreaChanged);
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::explosionClusterChanged,
this, &HandlerAesData::onExplosionClusterChanged, Qt::UniqueConnection);
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::effectClusterChanged,
this, &HandlerAesData::onEffectClusterChanged, Qt::UniqueConnection);
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleChanged,
this, &HandlerAesData::onExplosionSingleChanged);
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::mineAreaChanged,
this, &HandlerAesData::onMineAreaChanged);
// Get current data for all ExplosionArea
{
auto cb = [this](const AreaEffectSimulation::ExplosionArea & explosionArea)
{
onExplosionAreaChanged(explosionArea, DataModification::eAdded);
};
if (!dtcAes->explosionAreas(cb))
return false;
}
// Get current data for all ExplosionArea
{
auto cb = [this](const AreaEffectSimulation::ExplosionSingle & explosionSingle)
{
onExplosionSingleChanged(explosionSingle, DataModification::eAdded);
};
if (!dtcAes->explosionSingles(cb))
return false;
}
// Get current data for all ExplosionCluster
{
auto cb = [this](const AreaEffectSimulation::ExplosionCluster & explosionCluster)
{
onExplosionClusterChanged(explosionCluster, DataModification::eAdded);
};
if (!dtcAes->explosionClusters(cb))
return false;
}
// Get current data for all EffectCluster
{
auto cb = [this](const AreaEffectSimulation::EffectCluster & effectCluster)
{
onEffectClusterChanged(effectCluster, DataModification::eAdded);
};
if (!dtcAes->effectClusters(cb))
return false;
}
// Get current data for all MineArea
{
auto cb = [this](const AreaEffectSimulation::MineArea & mineArea)
{
onMineAreaChanged(mineArea, DataModification::eAdded);
};
if (!dtcAes->mineAreas(cb))
return false;
}
DEBUG_LOG(m_logger) << "m_AesDataObjMap.size() = " << m_AesDataObjMap.size();
return true;
} // end of init()
//=============================================================================
void HandlerAesData::onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType)
{
const Core::GeoPosition2D &posLl = data.impactPosition();
AreaEffectSimulation::ExplosionArea areaData;
areaData.altitude(data.altitude());
areaData.cannonCount(1);
areaData.cannonRounds(1);
areaData.chargeStruct().chargeTypeId(data.chargeStruct().chargeTypeId());
areaData.effectDuration(data.effectDuration());
areaData.effectMarkingInTa(data.effectMarkingInTa());
areaData.effectStart(data.effectStart());
areaData.effectStateId(data.effectStateId());
areaData.externalId(data.externalId());
areaData.fireRequestTime(data.fireRequestTime());
areaData.remainExplosionNumber(1);
areaData.id(data.id());
areaData.name(data.name());
areaData.isDeleted(data.isDeleted());
areaData.isUsed(data.isUsed());
AreaEffectSimulation::Area area;
area.cornerBottomLeft(posLl);
area.height(50);
area.width(50);
areaData.area(area);
HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed;
if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa())
kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(areaData), modType);
ObjectAesData *ifs = m_AesDataObjMap.value(data.id());
if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs)
kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData;
DEBUG_LOG(m_logger) << "Got ExplosionArea: "
<< "\n ID: " << data.id()
<< "\n Name: " << data.name()
<< "\n Effect status: " << data.effectStateId()
<< "\n Effect show (y/n): " << data.effectMarkingInTa()
<< "\n Lower left Pos: " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat())
<< "\n Start: " << data.effectStart()
<< "\n Duration: " << data.effectDuration()
<< "\n Modification: " << modType
<< "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification);
switch (kindOfModification)
{
case HandlerEffectShow::KindOfModification_e::Added:
{
ifs = new ObjectAesData(m_mainHandler);
Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(areaData));
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
}
else
{
m_AesDataObjMap.insert(data.id(), ifs);
m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(areaData, kindOfModification);
}
break;
}
case HandlerEffectShow::KindOfModification_e::ModifiedArea:
case HandlerEffectShow::KindOfModification_e::ModifiedData:
case HandlerEffectShow::KindOfModification_e::Paused:
case HandlerEffectShow::KindOfModification_e::Continued:
{
if (ifs != nullptr)
{
const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(areaData));
if (!ret.error())
m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(areaData, kindOfModification);
else
ERROR_LOG(m_logger) << ret();
}
else
WARNING_LOG(m_logger) << "Explosion Area not available for modification: " << data.id();
break;
}
case HandlerEffectShow::KindOfModification_e::Removed:
{
if (ifs != nullptr)
{
if (!m_AesDataObjMap.remove(data.id()))
ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed.";
Core::FunctionReplyObject ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
}
m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(areaData, kindOfModification);
break;
}
case HandlerEffectShow::KindOfModification_e::None:
break;
}
} // onExplosionSingleChanged
//=============================================================================
//=============================================================================
void HandlerAesData::onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType)
{
HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed;
if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa())
kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(data), modType);
ObjectAesData *ifs = m_AesDataObjMap.value(data.id());
if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs)
kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData;
const Core::GeoPosition2D &posLl = data.area().cornerBottomLeft();
DEBUG_LOG(m_logger) << "Got ExplosionArea: "
<< "\n ID: " << data.id()
<< "\n Name: " << data.name()
<< "\n Effect status: " << data.effectStateId()
<< "\n Effect show (y/n): " << data.effectMarkingInTa()
<< "\n Lower left Pos: " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat())
<< "\n Width: " << data.area().width()
<< "\n Height: " << data.area().height()
<< "\n Rotation: " << data.area().rotation()
<< "\n Start: " << data.effectStart()
<< "\n Duration: " << data.effectDuration()
<< "\n Modification: " << modType
<< "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification);
switch (kindOfModification)
{
case HandlerEffectShow::KindOfModification_e::Added:
{
ifs = new ObjectAesData(m_mainHandler);
Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(data));
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
}
else
{
m_AesDataObjMap.insert(ifs->getId(), ifs);
m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(data, kindOfModification);
}
break;
}
case HandlerEffectShow::KindOfModification_e::ModifiedArea:
case HandlerEffectShow::KindOfModification_e::ModifiedData:
case HandlerEffectShow::KindOfModification_e::Paused:
case HandlerEffectShow::KindOfModification_e::Continued:
{
if (ifs != nullptr)
{
const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(data));
if (!ret.error())
m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(data, kindOfModification);
else
ERROR_LOG(m_logger) << ret();
}
else
WARNING_LOG(m_logger) << "Explosion Area not available for modification: " << data.id();
break;
}
case HandlerEffectShow::KindOfModification_e::Removed:
{
if (ifs != nullptr)
{
if (!m_AesDataObjMap.remove(data.id()))
ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed.";
Core::FunctionReplyObject ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
}
m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(data, kindOfModification);
break;
}
case HandlerEffectShow::KindOfModification_e::None:
break;
}
}// onExplosionAreaChanged
//=============================================================================
void HandlerAesData::onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType)
{
HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed;
if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa())
kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(data), modType);
ObjectAesData *ifs = m_AesDataObjMap.value(data.id());
if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs)
kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData;
const Core::GeoPosition2D &posLl = data.area().cornerBottomLeft();
DEBUG_LOG(m_logger) << ">>>> Got Cluster: "
<< "\n ID: " << data.id()
<< "\n Name: " << data.name()
<< "\n Effect status: " << data.effectStateId()
<< "\n Effect show (y/n): " << data.effectMarkingInTa()
<< "\n Lower left Pos: " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat())
<< "\n Width: " << data.area().width()
<< "\n Height: " << data.area().height()
<< "\n Rotation: " << data.area().rotation()
<< "\n Start: " << data.effectStart()
<< "\n Duration: " << data.effectDuration()
<< "\n Modification: " << modType
<< "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification);
switch (kindOfModification)
{
case HandlerEffectShow::KindOfModification_e::Added:
{
ifs = new ObjectAesData(m_mainHandler);
Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(data));
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
}
else
{
m_AesDataObjMap.insert(data.id(), ifs);
m_mainHandler->handlerEffectShow()->onExplosionClusterChanged(data, kindOfModification);
}
break;
}
case HandlerEffectShow::KindOfModification_e::ModifiedArea:
case HandlerEffectShow::KindOfModification_e::ModifiedData:
case HandlerEffectShow::KindOfModification_e::Paused:
case HandlerEffectShow::KindOfModification_e::Continued:
{
if (ifs != nullptr)
{
const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(data));
if (!ret.error())
m_mainHandler->handlerEffectShow()->onExplosionClusterChanged(data, kindOfModification);
else
ERROR_LOG(m_logger) << ret();
}
else
WARNING_LOG(m_logger) << "Explosion Area not available for modification: " << data.id();
break;
}
case HandlerEffectShow::KindOfModification_e::Removed:
{
if (ifs != nullptr)
{
if (!m_AesDataObjMap.remove(data.id()))
ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed.";
Core::FunctionReplyObject ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
}
m_mainHandler->handlerEffectShow()->onExplosionClusterChanged(data, kindOfModification);
break;
}
case HandlerEffectShow::KindOfModification_e::None:
break;
}
}
void HandlerAesData::onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &data, DataModification modType)
{
HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed;
if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa())
kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(data), modType);
ObjectAesData *ifs = m_AesDataObjMap.value(data.id());
if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs)
kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData;
const Core::GeoPosition2D &posLl = data.area().cornerBottomLeft();
DEBUG_LOG(m_logger) << ">>>> Got EffectCluster: "
<< "\n ID: " << data.id()
<< "\n Name: " << data.name()
<< "\n Effect status: " << data.effectStateId()
<< "\n Effect show (y/n): " << data.effectMarkingInTa()
<< "\n Lower left Pos: " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat())
<< "\n Width: " << data.area().width()
<< "\n Height: " << data.area().height()
<< "\n Rotation: " << data.area().rotation()
<< "\n Start: " << data.effectStart()
<< "\n Duration: " << data.effectDuration()
<< "\n Modification: " << modType
<< "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification);
switch (kindOfModification)
{
case HandlerEffectShow::KindOfModification_e::Added:
{
ifs = new ObjectAesData(m_mainHandler);
Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(data));
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
}
else
{
m_AesDataObjMap.insert(data.id(), ifs);
m_mainHandler->handlerEffectShow()->onEffectClusterChanged(data, kindOfModification);
}
break;
}
case HandlerEffectShow::KindOfModification_e::ModifiedArea:
case HandlerEffectShow::KindOfModification_e::ModifiedData:
case HandlerEffectShow::KindOfModification_e::Paused:
case HandlerEffectShow::KindOfModification_e::Continued:
{
if (ifs != nullptr)
{
const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(data));
if (!ret.error())
m_mainHandler->handlerEffectShow()->onEffectClusterChanged(data, kindOfModification);
else
ERROR_LOG(m_logger) << ret();
}
else
WARNING_LOG(m_logger) << "Explosion Area not available for modification: " << data.id();
break;
}
case HandlerEffectShow::KindOfModification_e::Removed:
{
if (ifs != nullptr)
{
if (!m_AesDataObjMap.remove(data.id()))
ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed.";
Core::FunctionReplyObject ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
}
m_mainHandler->handlerEffectShow()->onEffectClusterChanged(data, kindOfModification);
break;
}
case HandlerEffectShow::KindOfModification_e::None:
break;
}
} // onExplosionClusterChanged
//=============================================================================
void HandlerAesData::onMineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType)
{
HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed;
if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa())
kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(data), modType);
ObjectAesData *ifs = m_AesDataObjMap.value(data.id());
if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs)
kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData;
if (data.segments().size() == 0)
return;
const Core::GeoPosition2D &posLl = data.segments().at(data.segments().size() / 2).positionStart();
DEBUG_LOG(m_logger) << "Got MineArea: "
<< "\n ID: " << data.id()
<< "\n Name: " << data.name()
<< "\n Effect status: " << data.effectStateId()
<< "\n Effect show (y/n): " << data.effectMarkingInTa()
<< "\n Start Position " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat())
<< "\n Start: " << data.effectStart()
<< "\n Duration: " << data.effectDuration()
<< "\n Num of segments: " << data.segments().size()
<< "\n Modification: " << modType
<< "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification);
switch (kindOfModification)
{
case HandlerEffectShow::KindOfModification_e::Added:
{
ifs = new ObjectAesData(m_mainHandler);
Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(data));
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
}
else
{
m_AesDataObjMap.insert(data.id(), ifs);
m_mainHandler->handlerEffectShow()->onMineAreaChanged(data, kindOfModification);
}
break;
}
case HandlerEffectShow::KindOfModification_e::ModifiedArea:
case HandlerEffectShow::KindOfModification_e::ModifiedData:
case HandlerEffectShow::KindOfModification_e::Paused:
case HandlerEffectShow::KindOfModification_e::Continued:
{
if (ifs != nullptr)
{
const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(data));
if (!ret.error())
m_mainHandler->handlerEffectShow()->onMineAreaChanged(data, kindOfModification);
else
ERROR_LOG(m_logger) << ret();
}
else
WARNING_LOG(m_logger) << "Mine Area not available for modification: " << data.id();
break;
}
case HandlerEffectShow::KindOfModification_e::Removed:
{
if (ifs != nullptr)
{
if (!m_AesDataObjMap.remove(data.id()))
ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed.";
Core::FunctionReplyObject ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
}
m_mainHandler->handlerEffectShow()->onMineAreaChanged(data, kindOfModification);
break;
}
case HandlerEffectShow::KindOfModification_e::None:
break;
}
} // onMineAreaChanged()
//-----------------------------------------------------------------------------
bool HandlerAesData::takeIntoAccountEffectShow(const AreaEffectSimulation::AesEffectState &effectStateId)
{
return (
(effectStateId == AreaEffectSimulation::AesEffectState::EsCreated)
|| (effectStateId == AreaEffectSimulation::AesEffectState::EsPrepared)
|| (effectStateId == AreaEffectSimulation::AesEffectState::EsActivated)
|| (effectStateId == AreaEffectSimulation::AesEffectState::EsFired)
|| (effectStateId == AreaEffectSimulation::AesEffectState::EsPaused)
);
} // takeIntoAccountEffectShow()
//-----------------------------------------------------------------------------
HandlerEffectShow::KindOfModification_e HandlerAesData::getKindOfModification(const Database::EsmAesData &data, DataModification modType) const
{
auto it = m_AesDataObjMap.find(data.idAes);
DEBUG_LOG(m_logger) << "Check esm " << data.idAes << " modType " << modType;
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
DEBUG_LOG(m_logger) << "Case Added Or Modified";
if (it != m_AesDataObjMap.end())
{
DEBUG_LOG(m_logger) << "Found data";
if (it.value()->areaChanged(data))
return HandlerEffectShow::KindOfModification_e::ModifiedArea;
if (it.value()->dataChanged(data))
return HandlerEffectShow::KindOfModification_e::ModifiedData;
if (it.value()->statusPaused(data))
return HandlerEffectShow::KindOfModification_e::Paused;
if (it.value()->statusContinued(data))
return HandlerEffectShow::KindOfModification_e::Continued;
}
return HandlerEffectShow::KindOfModification_e::Added;
}
case DataModification::eRemoved:
{
if (it != m_AesDataObjMap.end())
return HandlerEffectShow::KindOfModification_e::Removed;
}
break;
}
return HandlerEffectShow::KindOfModification_e::None;
} // getKindOfModification()
//-----------------------------------------------------------------------------
+100
View File
@@ -0,0 +1,100 @@
/**
* Get notifications about changed AES Explosions/MineAreas
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "initialization.h"
#include "logger.h"
#include "handler_effect_show.h"
#include <AreaEffectSimulation/aes_dtc.h>
#include <QMap>
namespace EffectShowManagement
{
class ObjectAesData;
/**
* @brief Handler for area effect simulation.
*
* (1)Fetches the gui-interactions for area effect simulation and triggers effect show activities
* accordingly.\n
* (2)Holds some data of the area effect simulation (AES) within the data base in order to
* check was has been changed in case of AES chagnes.\n
* (3)In case of changes of the AES, it determines the kind of modification
* (see #KindOfModification_e) and informs the "HandlerAesData" about the changes.\n
*
*/
class HandlerAesData : public QObject
{
Q_OBJECT
public:
explicit HandlerAesData(Initialization *mainHandler);
~HandlerAesData();
/**
* @brief Updates area effect simulation data from the data base and the data distributin system.
* @return (true)Initialization was successfull
*/
bool init();
private Q_SLOTS:
/**
* @brief Checks, if the changed single explosion causes administration of related effect shows.
* @param[in] data Single Explosion data
* @param[in] modType Kind of modification of the single explosion
*/
void onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType);
/**
* @brief Checks, if the changed explosion area causes administration of related effect shows.
* @param[in] data Explosion area data
* @param[in] modType Kind of modification of the explosion area
*/
void onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType);
/**
* @brief Checks, if the changed explosion area causes administration of related effect shows.
* @param[in] data Explosion cluster data
* @param[in] modType Kind of modification of the explosion cluster
*/
void onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType);
/**
* @brief Checks, if the changed explosion area causes administration of related effect shows.
* @param[in] data Explosion cluster data
* @param[in] modType Kind of modification of the explosion cluster
*/
void onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &data, DataModification modType);
/**
* @brief Checks, if the changed mine area causes administration of related effect shows.
* @param[in] data Mine area data
* @param[in] modType Kind of modification of the mine area
*/
void onMineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType);
private:
/**
* @brief Checks, if the status of the area effect simulation allows a treatment of its data.
* @param effectStateId Status of the area effect simulatin data.
* @return (true)A Treatment of the data is allowed.
*/
static bool takeIntoAccountEffectShow(const AreaEffectSimulation::AesEffectState &effectStateId);
/**
* @brief Determines what has been changed in the area effect simulation
* @param data Area effect simulation data
* @param modType Kind of modification of the area effect simulation
* @return See #KindOfModification_e of the HandlerEffectShow class
*/
HandlerEffectShow::KindOfModification_e getKindOfModification(const Database::EsmAesData &data, DataModification modType) const;
private: // attributes
QMap<int, ObjectAesData *> m_AesDataObjMap;
Initialization *m_mainHandler;
NGL::INGLLogger &m_logger;
};
} // namespace EffectShowManagement
+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
+188
View File
@@ -0,0 +1,188 @@
/**
* Handler for all Language HMI objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-03
*/
#pragma once
#include <QHash>
#include <QTimer>
#include "dds_handler.h"
#include "initialization.h"
#include "logger.h"
#include <EffectShowManagement/esm_fts.h>
#include <EffectShowManagement/esm_db.h>
#include <AreaEffectSimulation/aes_ftc.h>
#include "esm_convert_from_tab.h"
namespace EffectShowManagement
{
constexpr int MAX_EFFECT_SHOWS = 3;
constexpr int CLEANUPTIME = 10*60*1000;
class Initialization;
class ObjectEffectShow;
/**
* @brief Handler for effect shows.
*
* (1)Fetches the gui-interactions for effect shows and triggers data base administration
* accordingly.\n
* (2)If an effect show was updated and an effect show actor was allocted, the Training Area Base
* Proxy will be triggered to send an effect show order to the allocated effect show actor.
* If needed, a retract order will be sent to the previous allocated effect show actor.\n
* (3)If an effect shall be deleted and an effect show actor is allocated and the status
* is < ORDER CARRIED OUT, the Training Area Base Proxy will be triggered to send a retract
* order to the effect show actor.\n
* (4)If the area of the area effect simulation (AES) was changed, the existing effect shows
* related to the AES will be removed and new effect shows will be created related to the
* new area. Effect Show Actors will not be allocated. This has to be done via Dialog by
* the user.\n
* (5)If the charge type, effect start, effect duration or the number of volley was changed
* by the AES, the related effect shows will be updated accordingly.\n
* (6)Receives the confirmation from the effect show actor via Training Area Base
* Proxy for effect show order and triggers the update of the data base with the new
* confirmation.\n
* (7)If the confirmation indicates: ORDER CARRIED OUT the effect show will be deleted after
* 1min automatically.\n
* (8)If the AES changes into the state EsPaused, the Training Area Base Proxy sill be triggered
* to send a STOP order to the effect show actor.\n
* (9)If the AES changes into the state EsActivated and the previous start time was zero
* (start button was pressed by AES), the Training Area Base Proxy will be triggered to
* send a CONTINUE order to the effect show actor.\n
* (10)Meteo data will be sent to the vehicle every 10 min,
* if the effect show actor has indicated by the order confirmation, that the effect show
* is in processing. Meteo Data will be read from "HandlerMdmData".\n
*/
class HandlerEffectShow : public QObject
, protected Interface::Fts::EffectShowModifyRequestHandler
, protected Interface::Fts::EffectShowRemoveRequestHandler
, protected AreaEffectSimulation::Interface::Ftc::SetAesItemEffectorStateReplyHandler
{
Q_OBJECT
public:
explicit HandlerEffectShow(Initialization *mainHandler,
QObject *parent = nullptr);
~HandlerEffectShow();
/**
* @brief Updates effect shows data from the data base and distributes the data.
* @return (true)Initialization was successfull
*/
bool init();
/**
* @brief The kind of modification of the area effect simulation
*/
enum class KindOfModification_e : int { Added = 0, ModifiedArea, ModifiedData, Removed, Paused, Continued, None };
static QString enumToString(HandlerEffectShow::KindOfModification_e mod);
void onSetAesItemEffectorStateReply(const Core::FunctionReplyObject &replyObject) override {DEBUG_LOG(m_logger) << replyObject.translated();}
/**
* @brief Create, update, remove & create or remove Effect Shows in relation to the changes of the Explosion Area.
* @param[in] data
* @param]in] kindOfModification
*/
void onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, KindOfModification_e kindOfModification);
/**
* @brief Create, update, remove & create or remove Effect Shows in relation to the changes of the Explosion Cluster.
* @param[in] data
* @param]in] kindOfModification
*/
void onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, KindOfModification_e kindOfModification);
/**
* @brief Create, update, remove & create or remove Effect Shows in relation to the changes of the Explosion Cluster.
* @param[in] data
* @param]in] kindOfModification
*/
void onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &data, KindOfModification_e kindOfModification);
/**
* @brief Create, update, remove & create or remove Effect Shows in relation to the changes of the Explosion Area.
* @param[in] data
* @param[in] kindOfModification
*/
void onMineAreaChanged(const AreaEffectSimulation::MineArea &data, KindOfModification_e kindOfModification);
/**
* @brief Updates Effect Show data with #orderConfirmation received from effect show actor via TAB service.
* @param[in] orderConfirmation Order Confirmation received from effect show actor via TAB service.
*/
void effectShowOrderConfirmationReceived(const ConvertFromTab::OrderConfirmation_t &orderConfirmation);
/**
* @brief Creates a new effect show
* @param[in] data Effect Show data
*/
void createEffectShow(const Database::EsmEffectShow &data, bool bForceUpdateDb = false);
private:
void onEffectShowModifyRequest(const rti::core::SampleIdentity &cookie,
const EffectShow &request) override final;
Core::FunctionReplyObject effectShowModifyRequest(const EffectShow &request);
void onEffectShowRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request) override final;
void createEffectShowsRelatedToMineArea(const AreaEffectSimulation::MineArea &data);
void createEffectShowsRelatedToExplosionArea(const AreaEffectSimulation::ExplosionArea &data);
void createEffectShowsRelatedToExplosionCluster(const AreaEffectSimulation::ExplosionCluster &data);
void createEffectShowsRelatedToEffectCluster(const AreaEffectSimulation::EffectCluster &data);
QVector<Database::EsmEffectShow> createEffectShowDbDataRelatedToMineArea(const AreaEffectSimulation::MineArea &data);
QVector<Database::EsmEffectShow> createEffectShowDbDataRelatedToExplosionArea(const AreaEffectSimulation::ExplosionArea &data);
QVector<Database::EsmEffectShow> createEffectShowDbDataRelatedToExplosionCluster(const AreaEffectSimulation::ExplosionCluster &data);
QVector<Database::EsmEffectShow> createEffectShowDbDataRelatedToEffectCluster(const AreaEffectSimulation::EffectCluster &data);
void removeEffectShowsRelatedToAes(int idAes, bool retract = true);
void updateEffectShowsRelatedToMineArea(const AreaEffectSimulation::MineArea &data);
void updateEffectShowsRelatedToExplosionArea(const AreaEffectSimulation::ExplosionArea &data);
void updateEffectShowsRelatedToExplosionCluster(const AreaEffectSimulation::ExplosionCluster &data);
void updateEffectShowsRelatedToEffectCluster(const AreaEffectSimulation::EffectCluster &data);
void modifyEffectShowsRelatedToMineArea(const AreaEffectSimulation::MineArea &data);
void modifyEffectShowsRelatedToExplosionArea(const AreaEffectSimulation::ExplosionArea &data);
void modifyEffectShowsRelatedToExplosionCluster(const AreaEffectSimulation::ExplosionCluster &data);
void modifyEffectShowsRelatedToEffectCluster(const AreaEffectSimulation::EffectCluster &data);
void modifyEffectShows(const QVector<Database::EsmEffectShow> &esmEffectShows, int aesId);
void updateEffectShowOrdersRelatedToAes(int idAes);
void pauseEffectShowsRelatedToAes(int idAes);
void continueEffectShowsRelatedToAes(int idAes);
QVector<ObjectEffectShow* > removeFromEffectShowMapByAesId(int aesId);
private:
Core::FunctionReplyObject removeEffectShow(ObjectEffectShow *ifs, bool bWarnWhenNotInMap = true, bool retract = true);
void triggerEffectShowOrder(const ObjectEffectShow *ifs);
void triggerRetractOrder(const ObjectEffectShow *ifs);
void triggerEffectShowStop(const ObjectEffectShow *ifs);
void triggerEffectShowContinue(const ObjectEffectShow *ifs);
void triggerMeteoData(const ObjectEffectShow *ifs);
private Q_SLOTS:
void onSendMeteoData();
void onCleanUp();
private:
QHash<int, ObjectEffectShow *> m_effectShowObjMap;
static constexpr qint64 meteoDataSendInterval = 600000; // 10 min send time interval for meteo data
QTimer *m_cleanupTimer;
QTimer *m_timerMeteoData;
Initialization *m_mainHandler;
NGL::INGLLogger &m_logger;
};
}
@@ -0,0 +1,166 @@
/**
* Handler for all exercise objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-03
*/
#include "handler_effect_show_actor_relocation.h"
#include "handler_tab_data.h"
#include "handler_ppm_data.h"
#include "object_effect_show_actor_relocation.h"
#include "esm_db.h"
#include "initialization.h"
#include <QTimer>
#include <QCoreApplication>
namespace EffectShowManagement
{
//=============================================================================
HandlerEffectShowActorRelocation::HandlerEffectShowActorRelocation(Initialization *mainHandler,
QObject *parent)
: QObject(parent)
, EffectShowActorRelocationModifyRequestHandler(mainHandler->dds()->fts())
, EffectShowActorRelocationRemoveRequestHandler(mainHandler->dds()->fts())
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerEffectShowActorRelocation"))
{}
//=============================================================================
HandlerEffectShowActorRelocation::~HandlerEffectShowActorRelocation()
{
qDeleteAll(m_effectShowActorRelocationObjMap);
}
//=============================================================================
bool HandlerEffectShowActorRelocation::init()
{
bool bRet = true;
// create EffectShowActorRelocations objects
auto cbActor = [this, &bRet](const Database::EsmEffectShowActorRelocation &data)
{
ObjectEffectShowActorRelocation *ifs(new ObjectEffectShowActorRelocation(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(data);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
m_effectShowActorRelocationObjMap.insert(ifs->getId(), ifs);
};
if (!m_mainHandler->db()->select(cbActor) || !bRet)
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
DEBUG_LOG(m_logger) << "m_effectShowActorRelocationObjMap.size() = " << m_effectShowActorRelocationObjMap.size();
return true;
}
//=============================================================================
void HandlerEffectShowActorRelocation::relocationOrderConfirmationReceived(const ConvertFromTab::OrderConfirmation_t &orderConfirmation)
{
DEBUG_LOG(m_logger) << "relocationOrderConfirmationReceived()";
ObjectEffectShowActorRelocation *ifs = m_effectShowActorRelocationObjMap.value(orderConfirmation.orderId);
if (ifs == nullptr)
{
WARNING_LOG(m_logger) << "Error receiving effect show relocation ID not known.";
return;
}
// add confirmation data
auto data = ifs->getData();
data.orderConfirmation = orderConfirmation.confirmation.underlying();
data.answertText = orderConfirmation.answerText;
ifs->updateObject(data);
}
//-----------------------------------------------------------------------------
void HandlerEffectShowActorRelocation::onEffectShowActorRelocationModifyRequest(
const rti::core::SampleIdentity &cookie,
const EffectShowActorRelocation &request)
{
DEBUG_LOG(m_logger) << "onEffectShowActorRelocationModifyRequest: " << request.id();
auto ret = request.id() > 0 ? effectShowActorRelocationModifyRequest(request) : effectShowActorRelocationCreateRequest(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->effectShowActorRelocationModifyReply(cookie, ret);
}
//-----------------------------------------------------------------------------
Core::FunctionReplyObject HandlerEffectShowActorRelocation::effectShowActorRelocationCreateRequest(const EffectShowActorRelocation &request)
{
ObjectEffectShowActorRelocation *ifs(new ObjectEffectShowActorRelocation(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(ObjectEffectShowActorRelocation::ddsToDb(request));
if (ret.error())
delete ifs;
else
{
m_effectShowActorRelocationObjMap.insert(ifs->getId(), ifs);
// trigger relocation telegram to effect show actor
int participantId = ifs->getIdEffectShowActor();
int equipmentNumber = m_mainHandler->handlerPpmData()->getEquipmentNumber(participantId);
m_mainHandler->handlerTabData()->relocationOrder(equipmentNumber, participantId, ifs->getRelocationOrder());
DEBUG_LOG(m_logger) << "effectShowActorRelocationCreateRequest() - insert";
}
return ret;
}
//-----------------------------------------------------------------------------
Core::FunctionReplyObject HandlerEffectShowActorRelocation::effectShowActorRelocationModifyRequest(const EffectShowActorRelocation &request)
{
ObjectEffectShowActorRelocation *ifs = m_effectShowActorRelocationObjMap.value(request.id());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "EffectShowActorRelocation with id %1 not found")).arg(request.id());
return ifs->updateObject(ObjectEffectShowActorRelocation::ddsToDb(request));
}
//-----------------------------------------------------------------------------
void HandlerEffectShowActorRelocation::onEffectShowActorRelocationRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request)
{
DEBUG_LOG(m_logger) << "onEffectShowActorRelocationRemoveRequest: " << request.id();
Core::FunctionReplyObject ret;
ObjectEffectShowActorRelocation *ifs = m_effectShowActorRelocationObjMap.value(request.id());
if (!ifs)
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "'%1' with id %2 not found")).arg(QStringLiteral("HandlerEffectShowActorRelocation")).arg(request.id());;
m_mainHandler->dds()->fts()->effectShowActorRelocationRemoveReply(cookie, ret);
return;
}
EffectShowActorRelocation ddsData;
ddsData.id(request.id());
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ddsData, m_mainHandler->exerciseId()))
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "EffectShowActorRelocation '%1' is used by another user!")).arg(ifs->getId());
m_mainHandler->dds()->fts()->effectShowActorRelocationRemoveReply(cookie, ret);
return;
}
ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << LOGFUNCTION << ret();
else
{
// trigger relocation telegram to effect show actor
int participantId = ifs->getIdEffectShowActor();
int equipmentNumber = m_mainHandler->handlerPpmData()->getEquipmentNumber(participantId);
m_mainHandler->handlerTabData()->retractOrder(equipmentNumber, participantId, ifs->getRetractOrder());
// remove from map
delete ifs;
m_effectShowActorRelocationObjMap.remove(request.id());
}
m_mainHandler->dds()->fts()->effectShowActorRelocationRemoveReply(cookie, ret);
}
//-----------------------------------------------------------------------------
} // Namespace EffectShowManagement
@@ -0,0 +1,80 @@
/**
* Handler for all Language HMI objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-03
*/
#pragma once
#include <QMap>
#include <QQueue>
#include <QObject>
#include "dds_handler.h"
#include "esm_convert_from_tab.h"
#include "logger.h"
namespace EffectShowManagement
{
class Initialization;
class ObjectEffectShowActorRelocation;
/**
* @brief Handler for effect show actor relocations.
*
* (1)Fetches the gui-interactions for effect show actor relocations and
* triggers data base administration accordingly.\n
* (2)If a effect show actor relocation was created, the Training Area Base Proxy
* will be triggered to send a relocation order to the effect show actor.\n
* (3)If a effect show actor was deleted, the Training Area Base Proxy will be
* triggered to send a retract order to the effect show actor.\n
* (4)Receives the confirmation from the effect show actor via Training Area Base
* Proxy for relocation order.\n
* (5)Triggers the update of the data base with the new confirmation.\n
* (6)If the relocation order is completed, the status will be provided for the
* dialog for 1min. After that the relocation order will be removed.\n
*/
class HandlerEffectShowActorRelocation : public QObject
, protected Interface::Fts::EffectShowActorRelocationModifyRequestHandler
, protected Interface::Fts::EffectShowActorRelocationRemoveRequestHandler
{
Q_OBJECT
public:
explicit HandlerEffectShowActorRelocation(Initialization *mainHandler, QObject *parent = nullptr);
~HandlerEffectShowActorRelocation();
/**
* @brief Update of member variables with data base entries after start.
*/
bool init();
/**
* @brief Updates the handler with the order confirmation from effect show actor
* @param[in] orderConfirmation Order confirmation from effect show actor
*/
void relocationOrderConfirmationReceived(const ConvertFromTab::OrderConfirmation_t &orderConfirmation);
private:
void onEffectShowActorRelocationModifyRequest(const rti::core::SampleIdentity &cookie,
const EffectShowActorRelocation &request) override final;
Core::FunctionReplyObject effectShowActorRelocationModifyRequest(const EffectShowActorRelocation &request);
Core::FunctionReplyObject effectShowActorRelocationCreateRequest(const EffectShowActorRelocation &request);
void onEffectShowActorRelocationRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request) override final;
private:
QMap<int, ObjectEffectShowActorRelocation *> m_effectShowActorRelocationObjMap;
struct Completed_t
{
qint64 timestamp;
int id;
};
QQueue<Completed_t> m_completed; // IDs and timestamp of the completed relocations
Initialization *m_mainHandler;
NGL::INGLLogger &m_logger;
};
}
@@ -0,0 +1,246 @@
/**
* Handler for all exercise objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-03
*/
#include "handler_effect_show.h"
#include "handler_effect_show_vehicle_status.h"
#include "handler_tab_data.h"
#include "handler_mdm_data.h"
#include "object_effect_show_vehicle_status.h"
#include "esm_db.h"
#include "initialization.h"
#include <QCoreApplication>
namespace EffectShowManagement
{
//=============================================================================
HandlerEffectShowVehicleStatus::HandlerEffectShowVehicleStatus(Initialization *mainHandler,
QObject *parent)
: QObject(parent)
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerEffectShowVehicleStatus"))
{
m_timerVehicleStatus.setSingleShot(true);
}
//=============================================================================
HandlerEffectShowVehicleStatus::~HandlerEffectShowVehicleStatus()
{
qDeleteAll(m_effectShowVehicleStatusObjMap);
}
//=============================================================================
bool HandlerEffectShowVehicleStatus::init()
{
DEBUG_LOG(m_logger) << "Begin HandlerEffectShowVehicleStatus";
// create EffectShowVehicleStatuss objects
auto cbEsvs = [this] (const Database::EsmEffectShowVehicleStatus &data)
{
ObjectEffectShowVehicleStatus *ifs(new ObjectEffectShowVehicleStatus(m_mainHandler));
ifs->set(data);
DEBUG_LOG(m_logger) << "HandlerEffectShowVehicleStatus::init getParticipantId :" << ifs->getParticipantId();
m_effectShowVehicleStatusObjMap.insert(ifs->getParticipantId(), ifs);
};
if (!m_mainHandler->db()->select(cbEsvs))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
// check status from data base after statusRequestInterval
QTimer::singleShot(HandlerEffectShowVehicleStatus::delayAfterStart, this, &HandlerEffectShowVehicleStatus::onStatusRequest);
// provision of timer for timeout vehicle status
connect(&m_timerVehicleStatus, &QTimer::timeout, this, &HandlerEffectShowVehicleStatus::onTimeoutVehicleStatus);
m_timerVehicleStatus.setSingleShot(true);
if (m_effectShowVehicleStatusObjMap.size() != 0)
onTimeoutVehicleStatus();
DEBUG_LOG(m_logger) << "m_effectShowVehicleStatusObjMap.size() = " << m_effectShowVehicleStatusObjMap.size();
return true;
}
//=============================================================================
int HandlerEffectShowVehicleStatus::getNumOfEffectShowActors() const
{
int res = 0;
auto it = m_effectShowVehicleStatusObjMap.begin();
while (it != m_effectShowVehicleStatusObjMap.end())
{
if (it.value()->getOperational())
res++;
}
return res;
}
//=============================================================================
int HandlerEffectShowVehicleStatus::getIdOfEffectShowActor(int seq)
{
int num = 0;
auto it = m_effectShowVehicleStatusObjMap.begin();
while (it != m_effectShowVehicleStatusObjMap.end())
{
if (it.value()->getOperational())
{
if (seq == num) return it.value()->getIdOfEffectShowActor();
num++;
}
}
return -1; // illegal seq-number
}
//=============================================================================
bool HandlerEffectShowVehicleStatus::isOperational(int id) const
{
for (auto it = m_effectShowVehicleStatusObjMap.begin();
it != m_effectShowVehicleStatusObjMap.end(); ++it)
{
if (it.value()->getIdOfEffectShowActor() == id)
return it.value()->getOperational();
}
return false;
}
//=============================================================================
void HandlerEffectShowVehicleStatus::vehicleStatusReceived(const ConvertFromTab::VehicleStatus_t &vehicleStatus)
{
DEBUG_LOG(m_logger) << "vehicleStatusReceived: " << vehicleStatus.equipmentNumber
<< ' ' << vehicleStatus.timestamp << ' ' << m_mainHandler->dds()->currentPartitionTime();
HandlerPpmData::Participant_t actor = m_mainHandler->handlerPpmData()->getIdAndNameOfEffectShowActor(vehicleStatus.equipmentNumber);
if (actor.id == -1)
return;
ObjectEffectShowVehicleStatus *ifs = m_effectShowVehicleStatusObjMap.value(actor.id);
if (ifs == nullptr)
{
// create new object
ifs = new ObjectEffectShowVehicleStatus(m_mainHandler);
ifs->set(vehicleStatus);
ifs->set(actor);
ifs->createObject(); // write into db and publish data
m_effectShowVehicleStatusObjMap.insert(ifs->getParticipantId(), ifs); // insert object into map
}
else
{
// update object
ifs->set(vehicleStatus);
ifs->set(actor);
ifs->updateObject(); // update db and publish data
}
onTimeoutVehicleStatus();
}
//=============================================================================
void HandlerEffectShowVehicleStatus::effectShowActorChanged(const HandlerPpmData::Participant_t &data, DataModification modType)
{
DEBUG_LOG(m_logger) << "onEffectShowActorChanged: " << data.equipmentNumber;
auto it = m_effectShowVehicleStatusObjMap.find(data.id);
if (it == m_effectShowVehicleStatusObjMap.end()) return; // participant not allocated to any order
if (modType == DataModification::eRemoved)
{
it.value()->removeObject(); // remove vehicle status object
}
else
{
it.value()->set(data);
it.value()->updateObject(); // update and publish Object
}
}
//=============================================================================
void HandlerEffectShowVehicleStatus::onStatusRequest()
{
qint64 currentTime = m_mainHandler->dds()->currentPartitionTime();
if (currentTime == 0)
{
QTimer::singleShot(HandlerEffectShowVehicleStatus::statusRequestInterval, this, &HandlerEffectShowVehicleStatus::onStatusRequest);
return; // wait for the clock
}
if (m_statusRequest.size() == 0)
{
// check timestamp after init() one time
for (auto it = m_effectShowVehicleStatusObjMap.begin(); it != m_effectShowVehicleStatusObjMap.end(); ++it)
{
if ((currentTime - it.value()->getTimestamp()) > HandlerEffectShowVehicleStatus::statusTimeout)
{
it.value()->setOperational(false); // reset operational status
m_statusRequest.append(it.value()->getParticipantId()); // order status request
}
}
}
if (m_statusRequest.size() != 0)
{
// sent status request
int equipmentNumber = m_statusRequest[m_statusRequest.size() - 1];
HandlerPpmData::Participant_t actor = m_mainHandler->handlerPpmData()->getIdAndNameOfEffectShowActor(equipmentNumber);
auto it = m_effectShowVehicleStatusObjMap.find(actor.id);
if (it != m_effectShowVehicleStatusObjMap.end())
{
DEBUG_LOG(m_logger) << "Status Request equipment number: " << equipmentNumber << ' ' << it.value()->getIdOfEffectShowActor();
m_mainHandler->handlerTabData()->effectShowVehicleStatusRequest(equipmentNumber, it.value()->getIdOfEffectShowActor());
}
// remove request order
m_statusRequest.removeLast();
}
// activate timer, if further vehicle status requests to be done
if (m_statusRequest.size() != 0)
QTimer::singleShot(HandlerEffectShowVehicleStatus::statusRequestInterval, this, &HandlerEffectShowVehicleStatus::onStatusRequest);
}
//=============================================================================
void HandlerEffectShowVehicleStatus::onTimeoutVehicleStatus()
{
if (m_timerVehicleStatus.isActive())
return; // timeout already active
qint64 currentTime = m_mainHandler->dds()->currentPartitionTime();
if (currentTime == 0)
{
m_timerVehicleStatus.start(HandlerEffectShowVehicleStatus::delayAfterStart);
return; // wait for partition time
}
bool activateTimer = false;
qint64 maxAge = 0;
// determine the next vehicle status for timeout observation
for (auto it = m_effectShowVehicleStatusObjMap.begin(); it != m_effectShowVehicleStatusObjMap.end(); ++it)
{
if (it.value()->getOperational())
{
qint64 age = currentTime - it.value()->getTimestamp();
DEBUG_LOG(m_logger) << currentTime << ' ' << it.value()->getTimestamp();
if ((age + 1000) >= HandlerEffectShowVehicleStatus::statusTimeout)
{
it.value()->setOperational(false); // reset operational status
}
else
{
activateTimer = true;
if (age > maxAge)
maxAge = age;
}
}
}
// activate timer for timeout observation, if needed
if (activateTimer)
m_timerVehicleStatus.start(HandlerEffectShowVehicleStatus::statusTimeout - maxAge);
DEBUG_LOG(m_logger) << "onTimeoutVehicleStatus(): " << activateTimer << ' ' << maxAge;
}
} // Namespace EffectShowManagement
@@ -0,0 +1,102 @@
/**
* Handler for all Language HMI objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-03
*/
#pragma once
#include <QMap>
#include <QTimer>
#include <QObject>
#include "dds_handler.h"
#include "esm_convert_from_tab.h"
#include "handler_ppm_data.h"
#include "logger.h"
namespace EffectShowManagement
{
class Initialization;
class ObjectEffectShowVehicleStatus;
/**
* @brief Handler for the status of the effect show vehicle.
*
* (1)Receives the status from the effect show vehicle.\n
* (2)Adds name and ID of the allocated effect show actor to the status.\n
* (3)Updates both informations into the data base.\n
* (4)In case of obsolete data base entries at start time,
* a sequential status request will be sent to the effect
* show vehicles in time intervals of 5 seconds in succession.\n
* (5)It is expected that an effect show vehicle sends its
* status every 10 minutes. If any status information is
* older than 30 minutes, its status will be set to
* "not operational" by the handler.\n
*/
class HandlerEffectShowVehicleStatus : public QObject
{
Q_OBJECT
public:
explicit HandlerEffectShowVehicleStatus(Initialization *mainHandler,
QObject *parent = nullptr);
~HandlerEffectShowVehicleStatus();
/**
* @brief Update of member variables after start.
*/
bool init();
/**
* @brief Returns the number of operational effect show actors
* @return Number of operational effect show actors
*/
int getNumOfEffectShowActors() const;
/**
* @brief Returns the ID of the effect show actor with the sequential number #seq
* @param[in] seq ID's are numbered from [0..*]
* @return ID of the effect show actor with the sequential number #seq
*/
int getIdOfEffectShowActor(int seq);
/**
* @brief Requests, if the effect show vehicle is operational
* @param[in] id ID of the allocated effect show actor
* @return (true)The effect show vehicle is operational
*/
bool isOperational(int id) const;
/**
* @brief Updates the handler with the new status received from effect show vehicle
* @param[in] vehicleStatus Status receied from effect show vehicle
*/
void vehicleStatusReceived(const ConvertFromTab::VehicleStatus_t &vehicleStatus);
/**
* @brief Updates Name and Id of effect show acter
* @param[in] data Name and Id of effect show actor
* @param[in] modType Type of modification
*/
void effectShowActorChanged(const HandlerPpmData::Participant_t &data, DataModification modType);
public Q_SLOTS:
void onStatusRequest();
void onTimeoutVehicleStatus();
private:
static const qint64 statusTimeout = 1800000; // 30 min timeout effect show vehicle status
static const qint64 delayAfterStart = 20000; // 20 seconds delay for status requests after service start
static const qint64 statusRequestInterval = 5000; // Status request time interval of 5 seconds
private:
QMap<int, ObjectEffectShowVehicleStatus *> m_effectShowVehicleStatusObjMap; // key = equipment number
QVector<int> m_statusRequest; // List of equipment numbers; Order List for request of vehicle status.
QTimer m_timerVehicleStatus;
Initialization *m_mainHandler;
NGL::INGLLogger &m_logger;
};
}
+81
View File
@@ -0,0 +1,81 @@
/**
* Subscribe to MeteoDataManagement and provide the correct weather for the given position
* $Id$
* $HeadURL$
* $Author$
*/
#include "handler_mdm_data.h"
#include "initialization.h"
#include <LtsCoordTrans/lts_coord_trans.h>
#include "settings.h"
using namespace EffectShowManagement;
//=============================================================================
HandlerMdmData::HandlerMdmData(const std::shared_ptr<DdsHandler> &ddsHandler,
QObject *parent)
: QObject(parent)
, m_ddsHandler(ddsHandler)
, m_logger(getLogger("HandlerMdmData"))
{
}
//=============================================================================
bool HandlerMdmData::init()
{
DEBUG_LOG(m_logger) << "init() HandlerMdmData";
auto dtcMdm = m_ddsHandler->dtcMdm();
connect(dtcMdm.get(), &MeteoDataManagement::Interface::Dtc::meteoDataChanged,
this, &HandlerMdmData::onMeteoDataChanged);
// Get current data for all weather data
{
auto cb = [this](const MeteoDataManagement::MeteoData & meteoData)
{
onMeteoDataChanged(meteoData, DataModification::eAdded);
};
if (!dtcMdm->meteoDatas(cb))
return false;
}
return true;
}
//=============================================================================
bool HandlerMdmData::getNearestWeather(const Core::GeoPosition2D &pos,
MeteoDataManagement::MeteoData &data) const
{
const LtsCoordTrans::UtmCoordinate utm(LtsCoordTrans::UtmCoordinate::fromGeographic(pos.lon(), pos.lat()));
double nearestDistanceSquared = std::numeric_limits<double>::max();
bool found = false;
for (const auto &md : qAsConst(m_meteoData))
{
if (md.isStaticMeteoData())
continue;
const double distanceSquared = LtsCoordTrans::squareDistance(utm, md.pos().lon(), md.pos().lat());
if (distanceSquared < nearestDistanceSquared)
{
found = true;
data = md;
nearestDistanceSquared = distanceSquared;
}
}
return found;
}
//-----------------------------------------------------------------------------
void HandlerMdmData::onMeteoDataChanged(const MeteoDataManagement::MeteoData &data, DataModification modType)
{
switch (modType)
{
case DataModification::eRemoved:
m_meteoData.remove(data.id());
break;
case DataModification::eAdded:
case DataModification::eModified:
m_meteoData[data.id()] = data;
break;
}
}
+47
View File
@@ -0,0 +1,47 @@
/**
* Subscribe to MeteoDataManagement and provide the correct weather for the given position
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "dds_handler.h"
#include "logger.h"
#include <QHash>
#include <MeteoDataManagement/mdm_dtc.h>
namespace EffectShowManagement
{
/**
* @brief Handler for the provision of meto data for the effect shows
*/
class HandlerMdmData : public QObject
{
Q_OBJECT
public:
explicit HandlerMdmData(const std::shared_ptr<DdsHandler> &ddsHandler,
QObject *parent = nullptr);
/**
* @brief Initialize the handler to manage information from Meteo Data Management
*/
bool init();
/**
* @brief Returns the weather data from the station nearest to the provided position.
* @param[in] pos Position of the effect show
* @param[out] data Weather data from the station nearest to the position #pos
* @return (false)No Weather data provided
*/
bool getNearestWeather(const Core::GeoPosition2D &pos, MeteoDataManagement::MeteoData &data) const;
private Q_SLOTS:
void onMeteoDataChanged(const MeteoDataManagement::MeteoData &data, DataModification modType);
private:
QHash<int, MeteoDataManagement::MeteoData> m_meteoData;
std::shared_ptr<DdsHandler> m_ddsHandler;
NGL::INGLLogger &m_logger;
};
} // namespace EffectShowManagement
+47
View File
@@ -0,0 +1,47 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2017-02-20
*/
#include "handler_pdm_data.h"
namespace EffectShowManagement
{
//=============================================================================
HandlerPdmData::HandlerPdmData(const std::shared_ptr<DdsHandler> &ddsHandler,
QObject *parent)
: QObject(parent)
, m_ddsHandler(ddsHandler)
, m_logger(getLogger("HandlerPdmData"))
{
} // end of ctor()
//=============================================================================
bool HandlerPdmData::isSmoke(const AreaEffectSimulation::ChargeStruct &chargeStruct) const
{
return m_ddsHandler->dtcPdm()->isSmoke(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId());
} // end of isSmoke()
int HandlerPdmData::effectShowCount(const AreaEffectSimulation::ChargeStruct &chargeStruct) const
{
return m_ddsHandler->dtcPdm()->maxEffectShows(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId());
}
int HandlerPdmData::getCadence(const int chargeId) const
{
const auto &gearTypeIds = m_ddsHandler->dtcPdm()->gearTypeIdFromChargeTypeId(chargeId);
int cadence = 35000;
if (gearTypeIds.size())
cadence = m_ddsHandler->dtcPdm()->cadence(gearTypeIds.at(0));
return cadence;
}
} // namespace EffectShowManagement
+42
View File
@@ -0,0 +1,42 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2017-02-20
*/
#pragma once
#include "dds_handler.h"
#include "logger.h"
#include <QHash>
#include <ProjectDataManagement/pdm_dtc.h>
// Project Data Management - Handling for Effect Show Actors
namespace EffectShowManagement
{
/**
* @brief Handler for the determination of the type of ammunition.
*
* (1)Receives the charge type from the Project Data Management service.\n
* (2)Retrieves the type of ammunition via charge type id from Area Effect Simulation.\n
*/
class HandlerPdmData : public QObject
{
Q_OBJECT
public:
explicit HandlerPdmData(const std::shared_ptr<DdsHandler> &ddsHandler,
QObject *parent = nullptr);
bool isSmoke(const AreaEffectSimulation::ChargeStruct &chargeStruct) const;
int effectShowCount(const AreaEffectSimulation::ChargeStruct &chargeStruct) const;
int getCadence(const int chargeId) const;
private: // attributes
std::shared_ptr<DdsHandler> m_ddsHandler;
NGL::INGLLogger &m_logger;
};
} // namespace EffectShowManagement
+126
View File
@@ -0,0 +1,126 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2017-02-20
*/
#include "handler_ppm_data.h"
#include "handler_effect_show_vehicle_status.h"
#include "settings.h"
using namespace EffectShowManagement;
//=============================================================================
HandlerPpmData::HandlerPpmData(Initialization *mainHandler,
QObject *parent)
: QObject(parent)
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerPpmData"))
{
} // end of ctor()
//=============================================================================
bool HandlerPpmData::init()
{
DEBUG_LOG(m_logger) << "Begin HandlerPpmData";
auto dtcPpm = m_mainHandler->dds()->dtcPpm();
connect(dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
this, &HandlerPpmData::onParticipantChanged);
// Get current data for all Participants
{
auto cb = [this](const ParticipantManagement::Participant & participant)
{
onParticipantChanged(participant, DataModification::eAdded);
};
if (!dtcPpm->participants(cb))
return false;
}
DEBUG_LOG(m_logger) << "End HandlerPpmData";
return true;
} // end of init()
//-----------------------------------------------------------------------------
HandlerPpmData::Participant_t HandlerPpmData::getIdAndNameOfEffectShowActor(int equipmentNum) const
{
for (const HandlerPpmData::Participant_t &p : m_participant)
{
if (p.equipmentNumber == equipmentNum)
return p;
}
WARNING_LOG(m_logger) << LOGFUNCTION << " Equipment Number not found: " << equipmentNum;
return Participant_t(); // participant not available
} // end of getIdAndNameOfEffectShowActor()
//-----------------------------------------------------------------------------
int HandlerPpmData::getEquipmentNumber(int id) const
{
auto it = m_participant.find(id);
if (it == m_participant.end())
{
WARNING_LOG(m_logger) << LOGFUNCTION << " Participant(" << id << ") not found. ";
return -1; // participant not available
}
return it.value().equipmentNumber;
} // end of getIdAndNameOfEffectShowActor()
//-----------------------------------------------------------------------------
void HandlerPpmData::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType)
{
if (modType != DataModification::eRemoved)
{
auto m_ppmDtc = m_mainHandler->dds()->dtcPpm();
ParticipantManagement::TypeClass typeClass = m_ppmDtc->type(data.typeId()).typeClass();
DEBUG_LOG(m_logger) << "support entity / equipment number set " << (typeClass == ParticipantManagement::TypeClass::SupportEntity)
<< " / " << data.equipmentNumber().is_set() << ", typeId: " << data.typeId()
<< ", cnt: " << m_ppmDtc->types().size();
if (typeClass != ParticipantManagement::TypeClass::SupportEntity)
{
// type class does not match, make sure we don't handle it (now)
modType = DataModification::eRemoved;
}
else
{
// does not exists or has no longer an equipment number -> remove
if (!data.equipmentNumber().is_set())
modType = DataModification::eRemoved;
}
}
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
auto &val = m_participant[data.id()];
val = Participant_t(data);
m_mainHandler->handlerEffectShowVehicleStatus()->effectShowActorChanged(val, modType);
break;
}
case DataModification::eRemoved:
{
// remove if participant exists
auto it = m_participant.constFind(data.id());
if (it != m_participant.constEnd())
{
m_mainHandler->handlerEffectShowVehicleStatus()->effectShowActorChanged(it.value(), modType);
m_participant.remove(data.id());
}
break;
}
}
DEBUG_LOG(m_logger) << "onParticipantChanged: " << data.id() << ' ' << data.name() << ' ' << modType;
} // end of onParticipantChanged()
+80
View File
@@ -0,0 +1,80 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2017-02-20
*/
#pragma once
#include "initialization.h"
#include "logger.h"
#include <QMap>
#include <ParticipantManagement/ppm_dtc.h>
// Participand Management-Handling for Effect Show Actors
namespace EffectShowManagement
{
/**
* @brief Handler for the provision of effect show actor data.
*
* (1)Receives participant data from Participant Management service.\n
* (2)Retrieves the effect show actor information from participant data.\n
*/
class HandlerPpmData : public QObject
{
Q_OBJECT
public:
explicit HandlerPpmData(Initialization *mainHandler,
QObject *parent = nullptr);
/**
* @brief Connects to Participant Management service in order to access Participant data.
*/
bool init();
/**
* @brief ID, name and equipment number of effect show actor
*/
struct Participant_t
{
Participant_t() = default;
explicit Participant_t(const ParticipantManagement::Participant &data)
: id(data.id())
, equipmentNumber(data.equipmentNumber().is_set() ? data.equipmentNumber().get() : 0)
, name(QString::fromStdString(data.name()))
{}
int id = -1;
int equipmentNumber = 0;
QString name;
};
/**
* @brief Returns ID, name and equipment number of the effect show actor. (-1, if not available).
* @param[in] equipmentNum Equipment number
* @return ID, name and equipment number of the effect show actor.
*/
Participant_t getIdAndNameOfEffectShowActor(int equipmentNum) const;
/**
* @brief Returns the equipment number of the allocated effect show actor. (-1, if not available).
* @param[in] id ID of effect show actor
* @return Equipment number of the allocated effect show actor.
*/
int getEquipmentNumber(int id) const;
private Q_SLOTS:
void onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType);
private:
QMap<int, Participant_t> m_participant; // key = ID
Initialization *m_mainHandler;
NGL::INGLLogger &m_logger;
};
} // namespace EffectShowManagement
+252
View File
@@ -0,0 +1,252 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2017-02-20
*/
#include <QVector>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include "initialization.h"
#include "handler_tab_data.h"
#include "handler_effect_show.h"
#include "handler_effect_show_vehicle_status.h"
#include "handler_effect_show_actor_relocation.h"
#include "esm_convert_to_tab.h"
#include "settings.h"
namespace EffectShowManagement
{
static inline QString plText(const std::vector<uint8_t> &pl)
{
return QString::fromLatin1(LtsUtils::toQByteArray(pl).toHex());
}
//=============================================================================
HandlerTabData::HandlerTabData(Initialization *mainHandler,
QObject *parent)
: QObject(parent)
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerTabData"))
{
} // end of ctor()
//=============================================================================
bool HandlerTabData::init()
{
DEBUG_LOG(m_logger) << "Begin HandlerTabData";
auto dtcTab = m_mainHandler->dds()->dtcTab();
connect(dtcTab.get(), &TrainingAreaBase::Interface::Dtc::fireSmokeMarkerDataChanged,
this, &HandlerTabData::onFireSmokeMarkerDataChanged);
// Get current data for all Fire Smoke Marker
{
auto cb = [this](const TrainingAreaBase::FireSmokeMarkerData & fireSmokeMarker)
{
onFireSmokeMarkerDataChanged(fireSmokeMarker, DataModification::eAdded);
};
if (!dtcTab->fireSmokeMarkerDatas(cb))
return false;
}
DEBUG_LOG(m_logger) << "End HandlerTabData";
return true;
} // end of init()
//=============================================================================
void HandlerTabData::effectShowVehicleStatusRequest(int equipmentNumber, int participantId)
{
DEBUG_LOG(m_logger) << "Trigger Status Request " << equipmentNumber << ' ' << participantId;
TrainingAreaBase::SendFireSmokeMarkerDataRequest out;
out.equipmentNumber(equipmentNumber);
out.participantId(participantId);
out.payload(ConvertToTab::convertStatusRequest());
m_mainHandler->dds()->ftcTab()->sendFireSmokeMarkerDataRequest(out, this);
} // end of onVehicleStatusStatusRequest()
//=============================================================================
void HandlerTabData::relocationOrder(int equipmentNumber, int participantId, const ConvertToTab::RelocationOrder_t &relocationOrder)
{
DEBUG_LOG(m_logger) << "Trigger Relocation Order " << equipmentNumber << ' ' << participantId;
TrainingAreaBase::SendFireSmokeMarkerDataRequest out;
out.equipmentNumber(equipmentNumber);
out.participantId(participantId);
out.payload(ConvertToTab::convertRelocationOrder(relocationOrder));
m_mainHandler->dds()->ftcTab()->sendFireSmokeMarkerDataRequest(out, this);
} // end of relocationOrder()
//=============================================================================
void HandlerTabData::effectShowOrder(int equipmentNumber, int participantId, const ConvertToTab::EffectShowOrder_t &effectShowOrder)
{
TrainingAreaBase::SendFireSmokeMarkerDataRequest out;
out.equipmentNumber(equipmentNumber);
out.participantId(participantId);
out.payload(ConvertToTab::convertEffectShowOrder(effectShowOrder));
Core::GeoPosition2D posCenter = effectShowOrder.centerPosition;
Core::GeoPosition2D posLl = effectShowOrder.lowerLeftPosition;
DEBUG_LOG(m_logger) << "Trigger Effect Show Order " << equipmentNumber << ' ' << participantId
<< "\n idEffectShow " << effectShowOrder.idEffectShow
<< "\n startTime " << effectShowOrder.startTime
<< "\n centerPosition " << LtsCoordTrans::mgrsFromGeographic(posCenter.lon(), posCenter.lat())
<< "\n areaDepth " << effectShowOrder.areaDepth
<< "\n areaWidth " << effectShowOrder.areaWidth
<< "\n rotation " << effectShowOrder.rotation
<< "\n lowerLeftPosition " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat())
<< "\n numOfVolley " << int(effectShowOrder.numOfVolley)
<< "\n shotsPerVolley " << int(effectShowOrder.shotsPerVolley)
<< "\n typeOfAmmunition " << int(effectShowOrder.typeOfAmmunition)
<< "\n duration " << effectShowOrder.duration
<< "\n name " << effectShowOrder.name
<< "\n payload" << plText(out.payload());
m_mainHandler->dds()->ftcTab()->sendFireSmokeMarkerDataRequest(out, this);
} // end of effetShowOrder()
//=============================================================================
void HandlerTabData::effectShowStop(int equipmentNumber, int participantId, const qint16 &idEffectShow)
{
DEBUG_LOG(m_logger) << "Trigger Effect Show Stop " << equipmentNumber << ' ' << participantId;
TrainingAreaBase::SendFireSmokeMarkerDataRequest out;
out.equipmentNumber(equipmentNumber);
out.participantId(participantId);
out.payload(ConvertToTab::convertEffectShowStop(idEffectShow));
m_mainHandler->dds()->ftcTab()->sendFireSmokeMarkerDataRequest(out, this);
} // end of effectShowStop()
//=============================================================================
void HandlerTabData::effectShowContinue(int equipmentNumber, int participantId, const ConvertToTab::EffectShowContinue_t &effectShowContinue)
{
TrainingAreaBase::SendFireSmokeMarkerDataRequest out;
out.equipmentNumber(equipmentNumber);
out.participantId(participantId);
out.payload(ConvertToTab::convertEffectShowContinue(effectShowContinue));
DEBUG_LOG(m_logger) << "Trigger Effect Show Continue " << equipmentNumber << ' ' << participantId
<< "\n idEffectShow " << effectShowContinue.idEffectShow
<< "\n executionTime " << effectShowContinue.executionTime
<< "\n payload" << plText(out.payload());
m_mainHandler->dds()->ftcTab()->sendFireSmokeMarkerDataRequest(out, this);
} // end of effectShowContinue()
//=============================================================================
void HandlerTabData::retractOrder(int equipmentNumber, int participantId, const ConvertToTab::RetractOrder_t &retractOrder)
{
TrainingAreaBase::SendFireSmokeMarkerDataRequest out;
out.equipmentNumber(equipmentNumber);
out.participantId(participantId);
out.payload(ConvertToTab::convertOrderRetract(retractOrder));
DEBUG_LOG(m_logger) << "Trigger Retract Order " << equipmentNumber << ' ' << participantId
<< "\n orderType " << retractOrder.orderType
<< "\n id " << retractOrder.id
<< "\n payload" << plText(out.payload());
m_mainHandler->dds()->ftcTab()->sendFireSmokeMarkerDataRequest(out, this);
} // end of retractOrder()
//=============================================================================
void HandlerTabData::meteoData(int equipmentNumber, int participantId, const MeteoDataManagement::MeteoData &meteoData)
{
TrainingAreaBase::SendFireSmokeMarkerDataRequest out;
out.equipmentNumber(equipmentNumber);
out.participantId(participantId);
out.payload(ConvertToTab::convertMeteoData(meteoData));
DEBUG_LOG(m_logger) << "Trigger Meteo data " << equipmentNumber << ' ' << participantId
<< "\n temperature " << meteoData.temperature()
<< "\n humidity " << meteoData.humidity()
<< "\n pressure " << meteoData.pressure()
<< "\n windDirection " << meteoData.windDirection()
<< "\n payload" << plText(out.payload());
m_mainHandler->dds()->ftcTab()->sendFireSmokeMarkerDataRequest(out, this);
} // end of
//=============================================================================
void HandlerTabData::onSendFireSmokeMarkerDataReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Fire Smoke Marker Data could not be send: " << reply.str();
else
DEBUG_LOG(m_logger) << "Fire Smoke Marker Data send successfully to TAB!";
} // end of onSendFireSmokeMarkerDataReply()
//-----------------------------------------------------------------------------
void HandlerTabData::onFireSmokeMarkerDataChanged(const TrainingAreaBase::FireSmokeMarkerData &data, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
DEBUG_LOG(m_logger) << "Got Fire Smoke Marker " << data.sampleTime();
switch (ConvertFromTab::isTelegram(data))
{
case ConvertFromTab::RxTelegram_e::VehicleStatus:
{
DEBUG_LOG(m_logger) << "Got Vehicle Status";
m_mainHandler->handlerEffectShowVehicleStatus()->vehicleStatusReceived(ConvertFromTab::getVehicleStatus(data));
break;
}
case ConvertFromTab::RxTelegram_e::OrderConfirmation:
{
DEBUG_LOG(m_logger) << "Got Order Confirmation ";
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
const ConvertFromTab::OrderConfirmation_t orderConfirmation = ConvertFromTab::getOrderConfirmation(data);
if (orderConfirmation.orderType == ConvertFromTab::OrderType_e::Relocation)
{
DEBUG_LOG(m_logger) << "relocationOrderConfirmationReceived(orderConfirmation)";
m_mainHandler->handlerEffectShowActorRelocation()->relocationOrderConfirmationReceived(orderConfirmation);
}
else
{
DEBUG_LOG(m_logger) << "effectShowOrderConfirmationReceived(orderConfirmation)";
m_mainHandler->handlerEffectShow()->effectShowOrderConfirmationReceived(orderConfirmation);
}
break;
}
case DataModification::eRemoved:
break;
}
break;
}
case ConvertFromTab::RxTelegram_e::unknown:
break;
}
} // end of onFireSmokeMarkerDataChanged()
//-----------------------------------------------------------------------------
void HandlerTabData::publishVehicleStatus(const EffectShowManagement::EffectShowVehicleStatus &vehicleStatus)
{
DEBUG_LOG(m_logger) << "Vehicle Status published esmParticipantId: " << vehicleStatus.esmParticipantId() << ' ' << vehicleStatus.operational();
m_mainHandler->dds()->dts()->publish(vehicleStatus);
} // end of publishVehicleStatus()
//-----------------------------------------------------------------------------
void HandlerTabData::sendAdlerFqFb(const int aesId)
{
DEBUG_LOG(m_logger) << "Send Adler Feuerbereitschaft";
TrainingAreaBase::AdlerFqFbRequest out;
out.aesItemId(aesId);
m_mainHandler->dds()->ftcTab()->adlerFqFbRequest(out, this);
}
//=============================================================================
void HandlerTabData::onAdlerFqFbReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
ERROR_LOG(m_logger) << "Adler Feuerbereitschaft could not be send: " << reply.str()
<< ", id:" << reply.id();
else
DEBUG_LOG(m_logger) << "Adler Feuerbereitschaft successfully to TAB!";
}
} // namespace EffectShowManagement
+121
View File
@@ -0,0 +1,121 @@
/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2017-02-20
*/
#pragma once
#include "dds_handler.h"
#include "logger.h"
#include "esm_convert_from_tab.h"
#include "esm_convert_to_tab.h"
#include <TrainingAreaBase/tab_dtc.h>
// AES-Handling for Mine Fields
namespace EffectShowManagement
{
class Initialization;
/**
* @brief Handler for data exchange with the Training Aeria Base (TAB) Proxy.
*
* (1)Receives the telegrams from the effect show vehicle via Training Area Base proxy.
* (2)Sends Telegrams to effect show actor/vehicle via Training Area Base proxy.
*/
class HandlerTabData : public QObject
, protected TrainingAreaBase::Interface::Ftc::SendFireSmokeMarkerDataReplyHandler
, protected TrainingAreaBase::Interface::Ftc::AdlerFqFbReplyHandler
{
Q_OBJECT
public:
explicit HandlerTabData(Initialization *mainHandler,
QObject *parent = nullptr);
/**
* @brief Receives the relevant telegrams from TAB after service start
*/
bool init();
/**
* @brief Sends order for effect show vehicle status request to TAB.
* @param[in] equipmentNumber Equipment number for request target
* @param[in] participantId Effect Show Acter Id allocated to the effect show vehicle
*/
void effectShowVehicleStatusRequest(int equipmentNumber, int participantId);
/**
* @brief Triggers TAB to send an effect show actor relocation order telegramm to effect show actor.
* @param[in] equipmentNumber Equipment number for telegram target
* @param[in] participantId Effect Show Acter Id allocated to the effect show vehicle
* @param[in] relocationOrder Effect Show Actor Relocation Order telegram data
*/
void relocationOrder(int equipmentNumber, int participantId, const ConvertToTab::RelocationOrder_t &relocationOrder);
/**
* @brief Triggers TAB to send an effect show stop telegramm to effect show actor.
* @param[in] equipmentNumber Equipment number for telegram target
* @param[in] participantId Effect Show Acter Id allocated to the effect show vehicle
* @param[in] idEffectShow ID of effect show
*/
void effectShowStop(int equipmentNumber, int participantId, const qint16 &idEffectShow);
/**
* @brief Triggers TAB to send an effect show continue telegramm to effect show actor.
* @param[in] equipmentNumber Equipment number for telegram target
* @param[in] participantId Effect Show Acter Id allocated to the effect show vehicle
* @param[in] effectShowOrder Effect Show Continue telegram data
*/
void effectShowContinue(int equipmentNumber, int participantId, const ConvertToTab::EffectShowContinue_t &effectShowContinue);
/**
* @brief Triggers TAB to send a effect show order telegramm to effect show actor.
* @param[in] equipmentNumber Equipment number for telegram target
* @param[in] participantId Effect Show Acter Id allocated to the effect show vehicle
* @param[in] effectShowOrder Effect Show Order telegram data
*/
void effectShowOrder(int equipmentNumber, int participantId, const ConvertToTab::EffectShowOrder_t &effectShowOrder);
/**
* @brief Triggers TAB to send a retract order telegramm to effect show actor.
* @param[in] equipmentNumber Equipment number for telegram target
* @param[in] participantId Effect Show Acter Id allocated to the effect show vehicle
* @param[in] retractOrder Retract Order telegram data
*/
void retractOrder(int equipmentNumber, int participantId, const ConvertToTab::RetractOrder_t &retractOrder);
/**
* @brief Triggers TAB to send meteo data to effect show actor.
* @param[in] equipmentNumber Equipment number for telegram target
* @param[in] participantId Effect Show Acter Id allocated to the effect show vehicle
* @param[in] meteoData Meteo data
*/
void meteoData(int equipmentNumber, int participantId, const MeteoDataManagement::MeteoData &meteoData);
/**
* @brief Triggers TAB to send AdlerFqFb to SAA
* @param[in] aesId of AeraEffectSimulation
*/
void sendAdlerFqFb(const int aesId);
protected:
void onSendFireSmokeMarkerDataReply(const Core::FunctionReplyObject &reply) override final;
void onAdlerFqFbReply(const Core::FunctionReplyObject &reply) override final;
private Q_SLOTS:
void onFireSmokeMarkerDataChanged(const TrainingAreaBase::FireSmokeMarkerData &data, DataModification modType);
private:
void publishVehicleStatus(const EffectShowManagement::EffectShowVehicleStatus &vehicleStatus);
private: // attributes
Initialization *m_mainHandler;
NGL::INGLLogger &m_logger;
QMap<int, EffectShowManagement::EffectShowVehicleStatus> m_effectShowVehicleStatus;
};
} // namespace EffectShowManagement
+156
View File
@@ -0,0 +1,156 @@
/**
* MainHandler for AssetManagement
* $Id$
* $HeadURL$
* $Author$
*/
#include "initialization.h"
#include "handler_aes_data.h"
#include "handler_ppm_data.h"
#include "handler_pdm_data.h"
#include "handler_mdm_data.h"
#include "handler_tab_data.h"
#include "handler_effect_show.h"
#include "handler_effect_show_actor_relocation.h"
#include "handler_effect_show_vehicle_status.h"
#include "settings.h"
#include <ngldb/db_service_handler.h>
namespace EffectShowManagement
{
Initialization::Initialization()
: m_logger(getLogger("MainHandler"))
{}
Initialization::~Initialization()
{
m_handlerAesData = nullptr;
m_handlerPpmData = nullptr;
m_handlerTabData = nullptr;
m_handlerMdmData = nullptr;
m_handlerEffectShow = nullptr;
m_handlerEffectShowActorRelocation = nullptr;
m_handlerEffectShowVehicleStatus = nullptr;
m_ddsHandler = nullptr;
m_dbHandler = nullptr;
}
bool Initialization::initialize(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector, const QSqlDatabase &sqlDb)
{
INFO_LOG(m_logger) << "Start EffectShowManagement Initialization.";
// initialize DDS
m_ddsHandler = std::make_shared<DdsHandler>(ddsConnector);
if (!m_ddsHandler->init())
{
ERROR_LOG(m_logger) << "Initialisation DdsHandler failed.";
return false;
}
// initialize database
m_dbHandler = std::make_shared<DbHandler>();
if (!m_dbHandler->init(ddsConnector->getPartitionId(), sqlDb))
{
ERROR_LOG(m_logger) << "Initialisation DbHandler failed.";
return false;
}
// initialize handlerEffectShow
m_handlerEffectShow = std::make_shared<HandlerEffectShow>(this);
// initialize handler EffectShowActorRelocation
m_handlerEffectShowActorRelocation = std::make_shared<HandlerEffectShowActorRelocation>(this);
// initialize handler VehicleStatus
m_handlerEffectShowVehicleStatus = std::make_shared<HandlerEffectShowVehicleStatus>(this);
// initialize handlerPpmData
m_handlerPpmData = std::make_shared<HandlerPpmData>(this);
// initialize handlerPdmData
m_handlerPdmData = std::make_shared<HandlerPdmData>(m_ddsHandler);
// initialize handlerMdmData
m_handlerMdmData = std::make_shared<HandlerMdmData>(m_ddsHandler);
// initialize handlerTabData
m_handlerTabData = std::make_shared<HandlerTabData>(this);
// initialize handlerAesData
m_handlerAesData = std::make_shared<HandlerAesData>(this);
INFO_LOG(m_logger) << "EffectShowManagement initialized.";
return true;
}
bool Initialization::loadFromDatabase()
{
if (!m_ddsHandler ||
!m_dbHandler ||
!m_handlerAesData ||
!m_handlerPpmData ||
!m_handlerPdmData ||
!m_handlerMdmData ||
!m_handlerTabData ||
!m_handlerEffectShow ||
!m_handlerEffectShowActorRelocation ||
!m_handlerEffectShowVehicleStatus)
return false;
if (!m_handlerEffectShow->init())
{
ERROR_LOG(m_logger) << "Initialisation handlerEffectShow failed.";
return false;
}
if (!m_handlerEffectShowActorRelocation->init())
{
ERROR_LOG(m_logger) << "Initialisation handlerEffectShowActorRelocation failed.";
return false;
}
if (!m_handlerEffectShowVehicleStatus->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerEffectShowVehicleStatus failed.";
return false;
}
if (!m_handlerPpmData->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerPpmData failed.";
return false;
}
if (!m_handlerMdmData->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerMdmData failed.";
return false;
}
if (!m_handlerTabData->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerTabData failed.";
return false;
}
if (!m_handlerAesData->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerAesData failed.";
return false;
}
return true;
}
std::shared_ptr<DatabaseInterface> Initialization::db() const
{
return m_dbHandler->db();
}
int Initialization::exerciseId() const
{
if (dds() && dds()->ddsConnector())
return dds()->ddsConnector()->getPartitionId();
return -1;
}
} // namespace EffectShowManagement
+71
View File
@@ -0,0 +1,71 @@
/**
* MainHandler for AereaEffectSimulation
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <memory>
#include <EffectShowManagement/esm_db.h>
#include "dds_handler.h"
#include "esm_export.h"
#include "logger.h"
namespace NGLDB
{
template <typename DB> class DbServiceHandler;
}
namespace EffectShowManagement
{
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
class HandlerAesData;
class HandlerPpmData;
class HandlerPdmData;
class HandlerMdmData;
class HandlerTabData;
class HandlerEffectShow;
class HandlerEffectShowActorRelocation;
class HandlerEffectShowVehicleStatus;
class HandlerPosition;
class ESM_SERVER_EXPORT Initialization
{
public:
Initialization();
~Initialization();
bool initialize(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector, const QSqlDatabase &sqlDb);
bool loadFromDatabase();
std::shared_ptr<DdsHandler> dds() const { return m_ddsHandler; }
std::shared_ptr<DatabaseInterface> db() const;
std::shared_ptr<HandlerPpmData> handlerPpmData() const { return m_handlerPpmData; }
std::shared_ptr<HandlerPdmData> handlerPdmData() const { return m_handlerPdmData; }
std::shared_ptr<HandlerMdmData> handlerMdmData() const { return m_handlerMdmData; }
std::shared_ptr<HandlerTabData> handlerTabData() const { return m_handlerTabData; }
std::shared_ptr<HandlerEffectShow> handlerEffectShow() const { return m_handlerEffectShow; }
std::shared_ptr<HandlerEffectShowVehicleStatus> handlerEffectShowVehicleStatus() const { return m_handlerEffectShowVehicleStatus; }
std::shared_ptr<HandlerEffectShowActorRelocation> handlerEffectShowActorRelocation() const { return m_handlerEffectShowActorRelocation; }
int exerciseId() const;
private:
std::shared_ptr<DdsHandler> m_ddsHandler;
std::shared_ptr<DbHandler> m_dbHandler;
std::shared_ptr<HandlerAesData> m_handlerAesData;
std::shared_ptr<HandlerPpmData> m_handlerPpmData;
std::shared_ptr<HandlerPdmData> m_handlerPdmData;
std::shared_ptr<HandlerMdmData> m_handlerMdmData;
std::shared_ptr<HandlerTabData> m_handlerTabData;
std::shared_ptr<HandlerEffectShow> m_handlerEffectShow;
std::shared_ptr<HandlerEffectShowActorRelocation> m_handlerEffectShowActorRelocation;
std::shared_ptr<HandlerEffectShowVehicleStatus> m_handlerEffectShowVehicleStatus;
NGL::INGLLogger &m_logger;
};
} // namespace EffectShowManagement
+37
View File
@@ -0,0 +1,37 @@
/**
* @RDE_HEADER@
* Building Config - logging facility
* $Id$
* $HeadURL$
* $Author$
*/
#include "logger.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
namespace EffectShowManagement
{
LOGGER_T getLogger(const char *name)
{
static const char ns[] = "ESM.";
std::string loggerName;
const size_t len = strlen(name);
loggerName.reserve(sizeof(ns) + len);
loggerName.append(ns, sizeof(ns) - 1);
loggerName.append(name, len);
try
{
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
getNGLLogger(loggerName);
}
catch (const std::exception &ex)
{
fprintf(stderr, "Error retrieving logger: %s", ex.what());
abort();
}
}
} // namespace EffectShowManagement
+23
View File
@@ -0,0 +1,23 @@
/**
* @RDE_HEADER@
* Logging for EffectShowManagement
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <NGLLogger/INGLLogger.h>
#include "esm_export.h"
namespace EffectShowManagement
{
using LOGGER_T = NGL::INGLLogger&;
ESM_COMMON_EXPORT LOGGER_T getLogger(const char *name);
inline LOGGER_T getLogger(const QString &loggerName)
{
return getLogger(loggerName.toUtf8().constData());
}
} // namespace EffectShowManagement
+178
View File
@@ -0,0 +1,178 @@
/**
* Handler for the HMI language
* $Id$
* $HeadURL$
* $Author$
*/
#include "object_aes_data.h"
#include "effect_show_mine_area.h"
#include "initialization.h"
#include <QLineF>
namespace EffectShowManagement
{
//=============================================================================
ObjectAesData::ObjectAesData(Initialization *mainHandler,
QObject *parent)
: QObject(parent)
, m_mainHandler(mainHandler)
, m_logger(getLogger("ObjectAesData"))
{
}
//=============================================================================
Core::FunctionReplyObject ObjectAesData::createObject(const Database::EsmAesData &data)
{
m_data = data;
if (!m_mainHandler->db()->insert(m_data))
return Core::FunctionReplyObject(m_data.idAes, tr_lts("dds", "Error inserting EsmAesData into database."));
DEBUG_LOG(m_logger) << "New EsmAesData Id: " << m_data.idAes;
return Core::FunctionReplyObject(m_data.idAes);
}
//=============================================================================
Core::FunctionReplyObject ObjectAesData::updateObject(const Database::EsmAesData &data)
{
m_data = data;
if (!m_mainHandler->db()->update(m_data))
return Core::FunctionReplyObject(m_data.idAes, tr_lts("dds", "Error updating EsmAesData into database"));
DEBUG_LOG(m_logger) << "Data changed for EsmAesData Id: " << m_data.idAes;
return Core::FunctionReplyObject(m_data.idAes);
}
//=============================================================================
Core::FunctionReplyObject ObjectAesData::removeObject()
{
if (!m_mainHandler->db()->removeEsmAesData(m_data.idAes))
return Core::FunctionReplyObject(m_data.idAes, tr_lts("dds", "EsmAesData %1 can not be removed")).arg(m_data.idAes);
return Core::FunctionReplyObject(m_data.idAes);
}
//=============================================================================
bool ObjectAesData::areaChanged(const Database::EsmAesData &data) const
{
return (!qFuzzyCompare(m_data.position.x(), data.position.x()) ||
!qFuzzyCompare(m_data.position.y(), data.position.y()) ||
!qFuzzyCompare(m_data.width, data.width) ||
!qFuzzyCompare(m_data.depth, data.depth) ||
!qFuzzyCompare(m_data.rotationAngle, data.rotationAngle) ||
(m_data.volley != data.volley)); //shots change rewrite ?
}
//=============================================================================
bool ObjectAesData::dataChanged(const Database::EsmAesData &data) const
{
if (statusPaused(data) || statusContinued(data) || statusExpired(data))
return false;
if (m_data.nameAes != data.nameAes)
return true;
DEBUG_LOG(m_logger) << "Data Volley: " << data.volley << " old: " << m_data.volley;
return (m_data.chargeTypeId != data.chargeTypeId)
|| (m_data.effectStart != data.effectStart)
|| (m_data.effectStateId == AreaEffectSimulation::AesEffectState::EsFired)
|| (m_data.effectDuration != data.effectDuration);
}
//=============================================================================
bool ObjectAesData::statusPaused(const Database::EsmAesData &data) const
{
return (m_data.effectStateId != AreaEffectSimulation::AesEffectState_def::EsPaused) &&
(data.effectStateId == AreaEffectSimulation::AesEffectState_def::EsPaused);
}
//=============================================================================
bool ObjectAesData::statusContinued(const Database::EsmAesData &data) const
{
return (data.effectStateId == AreaEffectSimulation::AesEffectState_def::EsActivated) &&
(m_data.effectStart != data.effectStart); // false, if the scheduled start time reached
}
bool ObjectAesData::statusExpired(const Database::EsmAesData &data) const
{
return (data.effectStateId == AreaEffectSimulation::AesEffectState_def::EsExpired);
}
//=============================================================================
Database::EsmAesData ObjectAesData::asEsmAesData(const AreaEffectSimulation::ExplosionArea &data)
{
Database::EsmAesData res;
res.idAes = data.id();
res.nameAes = QString::fromStdString(data.name());
res.effectStateId = data.effectStateId().underlying();
res.position = QPointF(data.area().cornerBottomLeft().lon(), data.area().cornerBottomLeft().lat());
res.rotationAngle = data.area().rotation();
res.depth = data.area().height();
res.width = data.area().width();
res.effectStart = data.effectStart().is_set() ? data.effectStart().get() : 0;
res.effectDuration = data.effectDuration();
res.chargeTypeId = data.chargeStruct().chargeTypeId();
res.volley = data.cannonCount() * data.cannonRounds();
return res;
}
Database::EsmAesData ObjectAesData::asEsmAesData(const AreaEffectSimulation::ExplosionCluster &data)
{
Database::EsmAesData res;
res.idAes = data.id();
res.nameAes = QString::fromStdString(data.name());
res.effectStateId = data.effectStateId().underlying();
res.position = QPointF(data.area().cornerBottomLeft().lon(), data.area().cornerBottomLeft().lat());
res.rotationAngle = data.area().rotation();
res.depth = data.area().height();
res.width = data.area().width();
res.effectStart = data.effectStart().is_set() ? data.effectStart().get() : 0;
res.effectDuration = data.effectDuration();
res.chargeTypeId = data.chargeStruct().chargeTypeId();
res.volley = data.impactCount(); //cannonCount() * data.cannonRounds();
return res;
}
Database::EsmAesData ObjectAesData::asEsmAesData(const AreaEffectSimulation::EffectCluster &data)
{
Database::EsmAesData res;
res.idAes = data.id();
res.nameAes = QString::fromStdString(data.name());
res.effectStateId = data.effectStateId().underlying();
res.position = QPointF(data.area().cornerBottomLeft().lon(), data.area().cornerBottomLeft().lat());
res.rotationAngle = data.area().rotation();
res.depth = data.area().height();
res.width = data.area().width();
res.effectStart = data.effectStart().is_set() ? data.effectStart().get() : 0;
res.effectDuration = data.effectDuration();
res.chargeTypeId = data.chargeStruct().chargeTypeId();
res.volley = 0;
for (const auto &effector : data.effectors())
{
res.volley += effector.chargeAmount();
}
return res;
}
//=============================================================================
Database::EsmAesData ObjectAesData::asEsmAesData(const AreaEffectSimulation::MineArea &data)
{
Database::EsmAesData res;
const AreaEffectSimulation::MineSegment &segment = EffectShowManagement::EffectShowMineArea::getEffectShowSegment(data);
LtsCoordTrans::UtmCoordinate startPositionUtm = LtsCoordTrans::UtmCoordinate::fromGeographic({segment.positionStart().lon(), segment.positionStart().lat()});
LtsCoordTrans::UtmCoordinate endPositionUtm = LtsCoordTrans::UtmCoordinate::fromGeographic({segment.positionEnd().lon(), segment.positionEnd().lat()}, startPositionUtm.zone);
const QLineF line({startPositionUtm.x, startPositionUtm.y}, {endPositionUtm.x, endPositionUtm.y});
res.width = line.length();
res.idAes = data.id();
res.nameAes = QString::fromStdString(data.name());
res.effectStateId = data.effectStateId().underlying();
res.position = QPointF(segment.positionStart().lon(), segment.positionStart().lat());
res.depth = data.width();
res.effectStart = data.effectStart().is_set() ? data.effectStart().get() : 0;
res.effectDuration = data.effectDuration();
res.chargeTypeId = data.chargeStruct().chargeTypeId();
res.volley = 18;
return res;
}
//=============================================================================
} // Namespace EffectShowManagement
+101
View File
@@ -0,0 +1,101 @@
/**
* Exercise object
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QObject>
#include "dds_handler.h"
#include "logger.h"
#include <DDS/Core/function_reply_object.h>
// Generated
#include <EffectShowManagement/esm_db.h>
namespace EffectShowManagement
{
class Initialization;
class ObjectAesData : public QObject
{
Q_OBJECT
public:
explicit ObjectAesData(Initialization *mainHandler,
QObject *parent = nullptr);
Core::FunctionReplyObject createObject(const Database::EsmAesData &data);
Core::FunctionReplyObject updateObject(const Database::EsmAesData &data);
Core::FunctionReplyObject removeObject();
int getId() const { return m_data.idAes; }
void setData(const Database::EsmAesData &data) { m_data = data; }
/**
* @brief Checks if the area related to the effect show has been changed.
* @param data Area related to the effect show has been changed
* @return (true)Data has been chanbed
*/
bool areaChanged(const Database::EsmAesData &data) const;
/**
* @brief Checks if only the data related to the effect show has been changed, but the area has not been changed.
* @param data Current area simulation data extract
* @return (true)The data related to the effect show has been changed
*/
bool dataChanged(const Database::EsmAesData &data) const;
/**
* @brief Checks if the area simulation has been paused.
* @param data Current area simulation data extract
* @return (true)Area simulation has been paused
*/
bool statusPaused(const Database::EsmAesData &data) const;
/**
* @brief Checks if the area simulatin has been restarted.
* @param data Current area simulation data extract
* @return (true)The Area simulation has been restarted.
*/
bool statusContinued(const Database::EsmAesData &data) const;
/**
* @brief Checks if the area simulatin has been ended.
* @param data Current area simulation data extract
* @return (true)The Area simulation has been ended.
*/
bool statusExpired(const Database::EsmAesData &data) const;
/**
* @brief Reduces the data of the explosion area effect simulation to the data needed by the effect show.
* @param data Current area simulation data
* @return Extract needed from the area simulation data
*/
static Database::EsmAesData asEsmAesData(const AreaEffectSimulation::ExplosionArea &data);
/**
* @brief Reduces the data of the min area effect simulation to the data needed by the effect show.
* @param data Current area simulation data
* @return Extract needed from the area simulation data
*/
static Database::EsmAesData asEsmAesData(const AreaEffectSimulation::MineArea &data);
/**
* @brief Reduces the data of the min area effect simulation to the data needed by the effect show.
* @param data Current area simulation data
* @return Extract needed from the area simulation data
*/
static Database::EsmAesData asEsmAesData(const AreaEffectSimulation::ExplosionCluster &data);
/**
* @brief Reduces the data of the min area effect simulation to the data needed by the effect show.
* @param data Current area simulation data
* @return Extract needed from the area simulation data
*/
static Database::EsmAesData asEsmAesData(const AreaEffectSimulation::EffectCluster &data);
private:
Initialization *m_mainHandler;
Database::EsmAesData m_data;
NGL::INGLLogger &m_logger;
};
}
+298
View File
@@ -0,0 +1,298 @@
/**
* Handler for the HMI language
* $Id$
* $HeadURL$
* $Author$
*/
#include "object_effect_show.h"
#include "initialization.h"
#include <LtsCoordTrans/lts_coord_trans.h>
namespace EffectShowManagement
{
//=============================================================================
ObjectEffectShow::ObjectEffectShow(Initialization *mainHandler, QObject *parent)
: QObject(parent)
, m_mainHandler(mainHandler)
, m_logger(getLogger("ObjectEffectShow"))
{
} // end of ctor()
//=============================================================================
ObjectEffectShow::~ObjectEffectShow()
{
if (m_bRemoveFromDdsOnDestruction && m_data.id > 0)
m_mainHandler->dds()->dts()->removeEffectShowByKey(m_data.id);
} // end of dtor()
//=============================================================================
Core::FunctionReplyObject ObjectEffectShow::createObject(const Database::EsmEffectShow &data, bool bForceUpdateDb)
{
m_data = data;
if (m_data.id <= 0)
{
if (!m_mainHandler->db()->insert(m_data))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting Effect Show into database."));
}
else
{
if (bForceUpdateDb && !m_mainHandler->db()->update(m_data))
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error updating EffectShow into database"));
}
DEBUG_LOG(m_logger) << "createObject(db) complete ->"
<< "\n id " << m_data.id
<< "\n centerPosition " << LtsCoordTrans::mgrsFromGeographic(m_data.centerPosition.x(), m_data.centerPosition.y())
<< "\n idAreaEffectSimulation " << m_data.idAreaEffectSimulation
<< "\n esmParticipantId " << m_data.esmParticipantId
<< "\n numOfVolley " << m_data.numOfVolley
<< "\n shotsPerVolley " << m_data.shotsPerVolley
<< "\n orderConfirmation " << m_data.orderConfirmation
<< "\n answerText " << m_data.answerText
<< "\n startTime " << m_data.startTime
<< "\n duration " << m_data.duration
<< "\n lowerLeftPosition " << LtsCoordTrans::mgrsFromGeographic(m_data.lowerLeftPosition.x(), m_data.lowerLeftPosition.y())
<< "\n areaWidth " << m_data.areaWidth
<< "\n areaDepth " << m_data.areaDepth
<< "\n areaRotation " << m_data.areaRotation
<< "\n typeOfAmmunition " << (int)m_data.typeOfAmmunition;
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_data.id);
} // end of createObject()
//=============================================================================
Core::FunctionReplyObject ObjectEffectShow::removeObject()
{
if (!m_mainHandler->db()->removeEsmEffectShow(m_data.id))
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "EffectShow %1 can not be removed")).arg(m_data.id);
return Core::FunctionReplyObject(m_data.id);
} // end of removeObject()
//=============================================================================
Core::FunctionReplyObject ObjectEffectShow::updateObject(const EffectShowManagement::EffectShow &data)
{
if (data.id() <= 0)
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Object not valid/blocked"));
if (m_data.orderConfirmation == EffectShowManagement::OrderConfirmation_e_def::Execution)
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Changes rejected due to Effect Show in execution."));
DEBUG_LOG(m_logger) << "updateObject(data topic) complete ->"
<< "\n id " << m_data.id << " new: " << data.id()
<< "\n centerPosition x " << m_data.centerPosition.x() << " new: " << data.position().lon()
<< "\n centerPosition y " << m_data.centerPosition.y() << " new: " << data.position().lat()
<< "\n idAreaEffectSimulation " << m_data.idAreaEffectSimulation << " new: " << data.idAreaEffectSimulation()
<< "\n esmParticipantId " << m_data.esmParticipantId << " new: " << data.esmParticipantId()
<< "\n numOfVolley " << m_data.numOfVolley << " new: " << data.numOfVolley()
<< "\n shotsPerVolley " << m_data.shotsPerVolley << " new: " << data.shotsPerVolley()
<< "\n orderConfirmation " << m_data.orderConfirmation << " new: " << data.orderConfirmation().underlying()
<< "\n answerText " << m_data.answerText << " new: " << QString::fromStdString((data.answerText()))
<< "\n startTime " << m_data.startTime
<< "\n duration " << m_data.duration
<< "\n lowerLeftPosition x " << m_data.lowerLeftPosition.x()
<< "\n lowerLeftPosition y " << m_data.lowerLeftPosition.y()
<< "\n areaWidth " << m_data.areaWidth
<< "\n areaDepth " << m_data.areaDepth
<< "\n areaRotation " << m_data.areaRotation
<< "\n typeOfAmmunition " << m_data.typeOfAmmunition;
m_data.id = data.id();
m_data.name = QString::fromStdString(data.name());
m_data.startTime = data.startTime().is_set() ? data.startTime().get() : 0;
m_data.duration = data.duration();
m_data.idAreaEffectSimulation = data.idAreaEffectSimulation();
m_data.nameAreaEfffectSimulation = QString::fromStdString(data.nameAreaEffectSimulation());
m_data.esmParticipantId = data.esmParticipantId();
m_data.centerPosition.setX(data.position().lon());
m_data.centerPosition.setY(data.position().lat());
m_data.numOfVolley = data.numOfVolley();
m_data.shotsPerVolley = data.shotsPerVolley();
m_data.lowerLeftPosition.setX(data.lowerLeftPosition().lon());
m_data.lowerLeftPosition.setY(data.lowerLeftPosition().lat());
m_data.areaDepth = data.areaDepth();
m_data.areaWidth = data.areaWidth();
m_data.areaRotation = data.areaRotation();
m_data.orderConfirmation = data.orderConfirmation().underlying();
m_data.answerText = QString::fromStdString((data.answerText()));
if (!m_mainHandler->db()->update(m_data))
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error updating EffectShow into database"));
DEBUG_LOG(m_logger) << "Data changed for EffectShow Id: " << m_data.id;
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_data.id);
} // end of updateObject()
//=============================================================================
bool ObjectEffectShow::updateObject(const ConvertFromTab::OrderConfirmation_t &data)
{
DEBUG_LOG(m_logger) << "updateObject() partly ->"
<< "\n orderConfirmation " << m_data.orderConfirmation << " new: " << data.confirmation.underlying()
<< "\n answerText " << m_data.answerText << " new: " << data.answerText;
m_data.orderConfirmation = data.confirmation.underlying();
m_data.answerText = data.answerText;
if (!m_mainHandler->db()->update(m_data))
{
ERROR_LOG(m_logger) << "Effect Show Order Confirmation can_t be updated Id: " << m_data.id;
return false;
}
// Publish Data via DTS
onPublishData();
return true;
} // end of updateObject()
//=============================================================================
bool ObjectEffectShow::updateObject(const Database::EsmEffectShow &data)
{
DEBUG_LOG(m_logger) << "updateObject(db) complete ->"
<< "\n id " << m_data.id << " new: " << data.id
<< "\n centerPosition x " << m_data.centerPosition.x() << " new: " << data.centerPosition.x()
<< "\n centerPosition y " << m_data.centerPosition.y() << " new: " << data.centerPosition.y()
<< "\n idAreaEffectSimulation " << m_data.idAreaEffectSimulation << " new: " << data.idAreaEffectSimulation
<< "\n esmParticipantId " << m_data.esmParticipantId << " new: " << data.esmParticipantId
<< "\n numOfVolley " << m_data.numOfVolley << " new: " << data.numOfVolley
<< "\n shotsPerVolley " << m_data.shotsPerVolley << " new: " << data.shotsPerVolley
<< "\n orderConfirmation " << m_data.orderConfirmation << " new: " << data.orderConfirmation
<< "\n answerText " << m_data.answerText << " new: " << data.answerText
<< "\n startTime " << m_data.startTime << " new: " << data.startTime
<< "\n duration " << m_data.duration << " new: " << data.duration
<< "\n lowerLeftPosition x " << m_data.lowerLeftPosition.x() << " new: " << data.lowerLeftPosition.x()
<< "\n lowerLeftPosition y " << m_data.lowerLeftPosition.y() << " new: " << data.lowerLeftPosition.y()
<< "\n areaWidth " << m_data.areaWidth << " new: " << data.areaWidth
<< "\n areaDepth " << m_data.areaDepth << " new: " << data.areaDepth
<< "\n areaRotation " << m_data.areaRotation << " new: " << data.areaRotation
<< "\n typeOfAmmunition " << m_data.typeOfAmmunition << " new: " << data.typeOfAmmunition;
qint64 id = m_data.id; // ID must be unchanged
m_data = data;
m_data.id = id;
if (!m_mainHandler->db()->update(m_data))
{
ERROR_LOG(m_logger) << "Failed effect Show updated Id: " << m_data.id;
return false;
}
// Publish Data via DTS
onPublishData();
return true;
} // end of updateObject()
//=============================================================================
bool ObjectEffectShow::resetOrderConfirmation()
{
m_data.orderConfirmation = EffectShowManagement::OrderConfirmation_e_def::WaitingForAcceptance;
m_data.answerText.clear();
if (!m_mainHandler->db()->update(m_data))
{
ERROR_LOG(m_logger) << "Effect Show Order Confirmation can_t be updated Id: " << m_data.id;
return false;
}
// Publish Data via DTS
onPublishData();
return true;
} // end of resetOrderConfirmation()
//=============================================================================
ConvertToTab::EffectShowOrder_t ObjectEffectShow::getEffectShowOrder() const
{
ConvertToTab::EffectShowOrder_t order;
order.idEffectShow = m_data.id;
order.areaDepth = m_data.areaDepth;
order.areaWidth = m_data.areaWidth;
order.centerPosition = Core::GeoPosition2D(m_data.centerPosition.x(), m_data.centerPosition.y());
order.duration = m_data.duration / 1000; // [ms] -> [s]
order.lowerLeftPosition = Core::GeoPosition2D(m_data.lowerLeftPosition.x(), m_data.lowerLeftPosition.y());
order.numOfVolley = m_data.numOfVolley;
order.shotsPerVolley = m_data.shotsPerVolley;
order.rotation = m_data.areaRotation;
order.startTime = m_data.startTime / 1000; // [ms] -> [s]
order.typeOfAmmunition = m_data.typeOfAmmunition;
order.name = m_data.nameAreaEfffectSimulation;
DEBUG_LOG(m_logger) << "getEffectShowOrder():"
<< "\n idEffectShow " << order.idEffectShow
<< "\n areaDepth " << order.areaDepth
<< "\n areaWidth " << order.areaWidth
<< "\n centerPosition " << order.centerPosition
<< "\n duration " << (int)order.duration
<< "\n lowerLeftPosition " << order.lowerLeftPosition
<< "\n numOfVolley " << (int)order.numOfVolley
<< "\n shotsPerVolely " << (int)order.shotsPerVolley
<< "\n rotation " << order.rotation
<< "\n startTime " << (int)order.startTime
<< "\n typeOfAmmunition " << order.typeOfAmmunition;
return order;
}
//=============================================================================
ConvertToTab::RetractOrder_t ObjectEffectShow::getRetractOrder() const
{
ConvertToTab::RetractOrder_t order;
order.id = m_data.id;
order.orderType = 1;
DEBUG_LOG(m_logger) << "getRetractOrder():"
<< "\n id " << order.id
<< "\n orderType " << (int)order.orderType;
return order;
}
//=============================================================================
ConvertToTab::EffectShowContinue_t ObjectEffectShow::getContinueOrder() const
{
ConvertToTab::EffectShowContinue_t order;
order.idEffectShow = m_data.id;
order.executionTime = m_data.startTime / 1000; // [ms] -> [s]
DEBUG_LOG(m_logger) << "getContinueOrder():"
<< "\n id " << order.idEffectShow
<< "\n orderType " << order.executionTime;
return order;
}
//=============================================================================
void ObjectEffectShow::onPublishData()
{
EffectShowManagement::EffectShow ddsData;
ddsData.id(m_data.id);
ddsData.name(m_data.name.toStdString());
ddsData.startTime(m_data.startTime);
ddsData.duration(m_data.duration);
ddsData.idAreaEffectSimulation(m_data.idAreaEffectSimulation);
ddsData.nameAreaEffectSimulation(m_data.nameAreaEfffectSimulation.toStdString());
ddsData.esmParticipantId(m_data.esmParticipantId);
ddsData.position() = Core::GeoPosition2D(m_data.centerPosition.x(), m_data.centerPosition.y());
ddsData.numOfVolley(m_data.numOfVolley);
ddsData.shotsPerVolley(m_data.shotsPerVolley);
//we need this for the smoke type
ddsData.lowerLeftPosition() = Core::GeoPosition2D(m_data.lowerLeftPosition.x(), m_data.lowerLeftPosition.y());
ddsData.areaDepth(m_data.areaDepth);
ddsData.areaWidth(m_data.areaWidth);
ddsData.areaRotation(m_data.areaRotation);
ddsData.typeOfAmmunition(m_data.typeOfAmmunition);
ddsData.orderConfirmation(EffectShowManagement::OrderConfirmation_e::inner_enum(m_data.orderConfirmation));
ddsData.answerText(m_data.answerText.toStdString());
ddsData.isDeleted(false);
ddsData.isUsed(false);
INFO_LOG(m_logger) << "Publish EsmEffectShow-data to dds (" << m_data.id << ") ...";
if (!m_mainHandler->dds()->dts()->publish(ddsData))
ERROR_LOG(m_logger) << "Error publishing EsmEffectShow-data to dds";
} // end of onPublishData()
//-----------------------------------------------------------------------------
} // Namespace EffectShowManagement
+70
View File
@@ -0,0 +1,70 @@
/**
* Exercise object
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QObject>
#include "dds_handler.h"
#include "esm_convert_to_tab.h"
#include "esm_convert_from_tab.h"
#include "logger.h"
#include <DDS/Core/function_reply_object.h>
#include <EffectShowManagement/esm_db.h>
#include <EffectShowManagement/esm_dts.h>
namespace EffectShowManagement
{
class Initialization;
class ObjectEffectShow : QObject
{
Q_OBJECT
public:
explicit ObjectEffectShow(Initialization *mainHandler, QObject *parent = nullptr);
~ObjectEffectShow();
Core::FunctionReplyObject createObject(const Database::EsmEffectShow &data, bool bForceUpdateDb = false);
Core::FunctionReplyObject removeObject();
Core::FunctionReplyObject updateObject(const EffectShowManagement::EffectShow &data);
bool updateObject(const ConvertFromTab::OrderConfirmation_t &data);
bool updateObject(const Database::EsmEffectShow &data);
bool resetOrderConfirmation();
int getId() const { return m_data.id; }
QString getName() const { return m_data.name; }
int getIdAES() const { return m_data.idAreaEffectSimulation; }
const Database::EsmEffectShow &getData() const { return m_data; }
void setRemoveFromDdsOnDestruction(bool remove) { m_bRemoveFromDdsOnDestruction = remove; }
/**
* @brief Creates the data needed for the effect show order telegram from the effect show data.
* @return Data needed for the effect show order telegram from the effect show data
*/
ConvertToTab::EffectShowOrder_t getEffectShowOrder() const;
/**
* @brief Creates the data needed for the effect show retract order telegram from the effect show data.
* @return Data needed for the effect show retract order telegram from the effect show data
*/
ConvertToTab::RetractOrder_t getRetractOrder() const;
/**
* @brief Creates the data needed for the effect show continue telegram from the effect show data.
* @return Data needed for the effect show continue telegram from the effect show data
*/
ConvertToTab::EffectShowContinue_t getContinueOrder() const;
public Q_SLOTS:
void onPublishData();
private:
Initialization *m_mainHandler;
Database::EsmEffectShow m_data;
bool m_bRemoveFromDdsOnDestruction = true;
NGL::INGLLogger &m_logger;
};
}
@@ -0,0 +1,122 @@
/**
* Handler for the HMI language
* $Id$
* $HeadURL$
* $Author$
*/
#include "object_effect_show_actor_relocation.h"
#include "initialization.h"
namespace EffectShowManagement
{
ObjectEffectShowActorRelocation::ObjectEffectShowActorRelocation(Initialization *mainHandler)
: m_mainHandler(mainHandler)
, m_logger(getLogger("ObjectEffectShowActorRelocation"))
{
}
//=============================================================================
ObjectEffectShowActorRelocation::~ObjectEffectShowActorRelocation()
{
if (m_data.id > 0)
m_mainHandler->dds()->dts()->removeEffectShowActorRelocationByKey(m_data.id);
}
//=============================================================================
Core::FunctionReplyObject ObjectEffectShowActorRelocation::createObject(const Database::EsmEffectShowActorRelocation &data)
{
m_data = data;
if (m_data.id <= 0)
{
if (!m_mainHandler->db()->insert(m_data))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting Effect Show Actor Relocation into database."));
DEBUG_LOG(m_logger) << "New Effect Show Actor Relocation Id: " << m_data.id;
}
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_data.id);
}
//=============================================================================
Core::FunctionReplyObject ObjectEffectShowActorRelocation::updateObject(const Database::EsmEffectShowActorRelocation &data)
{
if (data.id <= 0)
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Object not valid/blocked"));
m_data = data;
if (!m_mainHandler->db()->update(m_data))
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error updating EffectShowActorRelocation into database"));
DEBUG_LOG(m_logger) << "Data changed for EffectShowActorRelocation Id: " << m_data.id;
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_data.id);
}
//=============================================================================
Core::FunctionReplyObject ObjectEffectShowActorRelocation::removeObject()
{
if (!m_mainHandler->db()->removeEsmEffectShowActorRelocation(m_data.id))
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "EffectShowActorRelocation %1 can not be removed")).arg(m_data.id);
return Core::FunctionReplyObject(m_data.id);
}
//=============================================================================
void ObjectEffectShowActorRelocation::onPublishData()
{
EffectShowManagement::EffectShowActorRelocation ddsData;
ddsData.id(m_data.id);
ddsData.esmParticipantId(m_data.esmParticipantId);
ddsData.arrival_time(m_data.arrivalTime);
ddsData.position(Core::GeoPosition2D(m_data.position.x(), m_data.position.y()));
ddsData.info(m_data.info.toStdString());
ddsData.orderConfirmation(EffectShowManagement::OrderConfirmation_e::inner_enum(m_data.orderConfirmation));
ddsData.answerText(m_data.answertText.toStdString());
ddsData.isDeleted(false);
ddsData.isUsed(false);
INFO_LOG(m_logger) << "Publish EsmEffectShowActorRelocation-data to dds (" << m_data.id << ") ...";
if (!m_mainHandler->dds()->dts()->publish(ddsData))
ERROR_LOG(m_logger) << "Error publishing EsmEffectShowActorRelocation-data to dds";
}
//=============================================================================
ConvertToTab::RelocationOrder_t ObjectEffectShowActorRelocation::getRelocationOrder() const
{
ConvertToTab::RelocationOrder_t order;
order.centerPosition = Core::GeoPosition2D(m_data.position.x(), m_data.position.y());
order.executionTime = m_data.arrivalTime / 1000; // ms -> seconds
order.infoText = m_data.info;
order.idRelocation = m_data.id;
return order;
}
//=============================================================================
ConvertToTab::RetractOrder_t ObjectEffectShowActorRelocation::getRetractOrder() const
{
ConvertToTab::RetractOrder_t order;
order.id = m_data.id; // ID effect show actor relocation
order.orderType = 0; // relocation order
return order;
}
//=============================================================================
Database::EsmEffectShowActorRelocation ObjectEffectShowActorRelocation::ddsToDb(const EffectShowManagement::EffectShowActorRelocation &ddsData)
{
Database::EsmEffectShowActorRelocation dbData;
dbData.id = ddsData.id();
dbData.esmParticipantId = ddsData.esmParticipantId();
dbData.arrivalTime = ddsData.arrival_time().get();
dbData.position = QPointF(ddsData.position().lon(), ddsData.position().lat());
dbData.info = QString::fromStdString(ddsData.info());
dbData.orderConfirmation = ddsData.orderConfirmation().underlying();
dbData.answertText = QString::fromStdString(ddsData.answerText());
return dbData;
}
//=============================================================================
} // Namespace EffectShowManagement
@@ -0,0 +1,63 @@
/**
* Exercise object
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "dds_handler.h"
#include "esm_convert_to_tab.h"
#include "logger.h"
#include <DDS/Core/function_reply_object.h>
#include <EffectShowManagement/esm_db.h>
#include <EffectShowManagement/esm_dts.h>
namespace EffectShowManagement
{
class Initialization;
class ObjectEffectShowActorRelocation final
{
public:
explicit ObjectEffectShowActorRelocation(Initialization *mainHandler);
~ObjectEffectShowActorRelocation();
Core::FunctionReplyObject createObject(const Database::EsmEffectShowActorRelocation &data);
Core::FunctionReplyObject updateObject(const Database::EsmEffectShowActorRelocation &data);
Core::FunctionReplyObject removeObject();
int getId() const { return m_data.id; }
int getIdEffectShowActor() const { return m_data.esmParticipantId; }
Database::EsmEffectShowActorRelocation getData() const { return m_data; }
/**
* @brief Creates the data needed for the effect show actor relocation telegram from the effect show actor relocation data.
* @return Data needed for the effect show actor relocation telegram from the effect show actor relocation data
*/
ConvertToTab::RelocationOrder_t getRelocationOrder() const;
/**
* @brief Creates the data needed for the effect show actor relocation retract telegram from the effect show actor relocation data.
* @return Data needed for the effect show actor relocation retract telegram from the effect show actor relocation data
*/
ConvertToTab::RetractOrder_t getRetractOrder() const;
/**
* @brief Converts Effect Show Actor Relocation DDS data to DB data.
* @param ddsData Effect Show Actor Relocation DDS data
* @return Effect Show Actor Relocation DB data
*/
static Database::EsmEffectShowActorRelocation ddsToDb(const EffectShowManagement::EffectShowActorRelocation &ddsData);
protected:
void onPublishData();
private:
Initialization *m_mainHandler;
Database::EsmEffectShowActorRelocation m_data;
NGL::INGLLogger &m_logger;
};
}
@@ -0,0 +1,120 @@
/**
* Handler for the HMI language
* $Id$
* $HeadURL$
* $Author$
*/
#include "object_effect_show_vehicle_status.h"
#include "initialization.h"
namespace EffectShowManagement
{
ObjectEffectShowVehicleStatus::ObjectEffectShowVehicleStatus(Initialization *mainHandler)
: m_mainHandler(mainHandler)
, m_logger(getLogger("ObjectEffectShowVehicleStatus"))
{
}
ObjectEffectShowVehicleStatus::~ObjectEffectShowVehicleStatus()
{
if (m_data.esmParticipantId > 0)
m_mainHandler->dds()->dts()->removeEffectShowActorRelocationByKey(m_data.esmParticipantId);
}
void ObjectEffectShowVehicleStatus::set(const ConvertFromTab::VehicleStatus_t &vehicleStatus)
{
m_data.esmParticipantId = m_mainHandler->dds()->dtcPpm()->participantIdByEquipmentNumber( vehicleStatus.equipmentNumber);
m_data.timestamp = vehicleStatus.timestamp;
m_data.airSpeedMeterFail = vehicleStatus.airSpeedMeterFail;
m_data.ammunitionAvailable = vehicleStatus.ammunitionAvailable;
m_data.ammunitionMagazine = vehicleStatus.ammunitionMagazine;
m_data.controlComputerFail = vehicleStatus.controlComputerFail;
m_data.feature = vehicleStatus.feature;
m_data.inclinationSensorFail = vehicleStatus.inclinationSensorFail;
m_data.magazineFail = vehicleStatus.magazineFail;
m_data.navigationFail = vehicleStatus.navigationFail;
m_data.operational = vehicleStatus.operational;
}
void ObjectEffectShowVehicleStatus::set(const HandlerPpmData::Participant_t &participant)
{
m_data.esmParticipantId = participant.id;
m_data.nameEffectShowActor = participant.name;
}
void ObjectEffectShowVehicleStatus::set(const Database::EsmEffectShowVehicleStatus &data)
{
m_data = data;
}
void ObjectEffectShowVehicleStatus::createObject()
{
if (!m_mainHandler->db()->insert(m_data))
{
ERROR_LOG(m_logger) << "Error inserting EsmEffectShowVehicleStatus into database. esmParticipantId" << m_data.esmParticipantId;
return;
}
DEBUG_LOG(m_logger) << "New Effect Show Vehicle Status esmParticipantId: " << m_data.esmParticipantId;
// Publish Data via DTS
onPublishData();
}
void ObjectEffectShowVehicleStatus::updateObject()
{
if (m_data.esmParticipantId <= 0)
{
ERROR_LOG(m_logger) << "Update object illegal esmParticipantId: " << m_data.esmParticipantId;
return;
}
if (!m_mainHandler->db()->update(m_data))
{
ERROR_LOG(m_logger) << "Error updating EsmEffectShowVehicleStatus into database esmParticipantId: " << m_data.esmParticipantId;
return;
}
DEBUG_LOG(m_logger) << "Data changed for EsmEffectShowVehicleStatus esmParticipantId: " << m_data.esmParticipantId;
// Publish Data via DTS
onPublishData();
}
void ObjectEffectShowVehicleStatus::removeObject()
{
if (!m_mainHandler->db()->removeEsmEffectShowVehicleStatus(m_data.esmParticipantId))
{
ERROR_LOG(m_logger) << "EsmEffectShowVehicleStatus can not be removed eqpNum: " << m_data.esmParticipantId;
return;
}
}
void ObjectEffectShowVehicleStatus::onPublishData()
{
EffectShowManagement::EffectShowVehicleStatus ddsData;
//ddsData.equipmentNumber(m_data.equipmentNumber);
ddsData.airSpeedMeterFail(m_data.airSpeedMeterFail);
ddsData.ammunitionAvailable(m_data.ammunitionAvailable);
ddsData.ammunitionMagazine(m_data.ammunitionMagazine);
ddsData.controlComputerFail(m_data.controlComputerFail);
ddsData.feature(EffectShowManagement::Feature_e_def::type(m_data.feature));
ddsData.esmParticipantId(m_data.esmParticipantId);
ddsData.inclinationSensorFail(m_data.inclinationSensorFail);
ddsData.magazineFail(m_data.magazineFail);
ddsData.nameEffectShowActor(m_data.nameEffectShowActor.toStdString());
ddsData.operational(m_data.operational);
ddsData.sampleTime(m_data.timestamp);
INFO_LOG(m_logger) << "Publish EsmEffectShowVehicleStatus-data to dds (" << m_data.esmParticipantId << ") ...";
if (!m_mainHandler->dds()->dts()->publish(ddsData))
ERROR_LOG(m_logger) << "Error publishing EsmEffectShowVehicleStatus-data to dds";
}
} // Namespace EffectShowManagement
@@ -0,0 +1,73 @@
/**
* Exercise object
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "dds_handler.h"
#include "esm_convert_from_tab.h"
#include "handler_ppm_data.h"
#include "logger.h"
#include <DDS/Core/function_reply_object.h>
// Generated
#include <EffectShowManagement/esm_db.h>
namespace EffectShowManagement
{
class Initialization;
class ObjectEffectShowVehicleStatus final
{
public:
explicit ObjectEffectShowVehicleStatus(Initialization *mainHandler);
~ObjectEffectShowVehicleStatus();
/**
* @brief Updates the object with the status of the vehicle
* @param[in] vehicleStatus Status of the vehicle
*/
void set(const ConvertFromTab::VehicleStatus_t &vehicleStatus);
/**
* @brief Updates the object with participant data
* @param[in] participant Participant data
*/
void set(const HandlerPpmData::Participant_t &participant);
/**
* @brief Updates the object completely
* @param data Object data
*/
void set(const Database::EsmEffectShowVehicleStatus &data);
void createObject();
void updateObject();
void removeObject();
int getParticipantId() const { return m_data.esmParticipantId; }
qint64 getTimestamp() const { return m_data.timestamp; }
bool getOperational() const { return m_data.operational; }
void setOperational(bool val)
{
bool publish = m_data.operational != val;
m_data.operational = val;
if (publish) onPublishData();
}
int getIdOfEffectShowActor() const { return m_data.esmParticipantId; }
QString getNameOfEffectShowActor() const { return m_data.nameEffectShowActor; }
protected:
void onPublishData();
private:
Initialization *m_mainHandler;
Database::EsmEffectShowVehicleStatus m_data;
NGL::INGLLogger &m_logger;
};
}
+48
View File
@@ -0,0 +1,48 @@
/**
* Settings for EffectShowManagement
* $Id$
* $HeadURL$
* $Author$
*/
#include "settings.h"
#include <QtCore/QSettings>
#include <nglsettings/nglsettings_settings.h>
#include <ngltools/ngltools_filesystem.h>
#include <settings.h>
namespace EffectShowManagement
{
class NGLSettingsClass : public NGL::Settings
{
public:
NGLSettingsClass()
: NGL::Settings(s_iniFile.isEmpty() ? NGL::findProjectConfigFile() : s_iniFile)
{}
static void setIniFile(const QString &fn)
{
s_iniFile = fn;
}
static QString s_iniFile;
};
QString NGLSettingsClass::s_iniFile;
Q_GLOBAL_STATIC(NGLSettingsClass, s)
//-----------------------------------------------------------------------------
NGL::Settings *Settings::settings()
{
return s();
}
//-----------------------------------------------------------------------------
void Settings::setIniFile(const QString &ini)
{
NGLSettingsClass::setIniFile(ini);
}
int Settings::getDefaultCadence()
{
return settings()->settings()->value(QStringLiteral("ESM/defaultCadence"), 10 * 1000).toInt();
}
} // namespace EffectShowManagement
+25
View File
@@ -0,0 +1,25 @@
/**
* Settings for EffectShowManagement
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QString>
namespace NGL
{
class Settings;
}
namespace EffectShowManagement
{
namespace Settings
{
NGL::Settings *settings();
void setIniFile(const QString &ini);
int getDefaultCadence();
}
} // namespace EffectShowManagement