Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/AreaEffectSimulation/object_explosion_single.cpp
T
berrux-dev 472f537313 Migrates AreaEffectSimulation to generated rtiddsgen API
Converts accessor calls to plain member access across aes service and plugin.
2026-09-21 02:45:07 +02:00

210 lines
7.1 KiB
C++
Executable File

/**
* Handler for one indirect fire single object
* $Id$
* $HeadURL$
* $Author$
*/
#include "object_explosion_single.h"
#include "special_area_provider.h"
#include "handler_charge_administration.h"
#include "Utils/polygons.h"
#include <QtGui/QPolygonF>
namespace AreaEffectSimulation
{
ObjectExplosionSingle::ObjectExplosionSingle(MainHandler *mainHandler,
QObject *parent)
: ObjectBaseTmpl(mainHandler, QStringLiteral("ExplosionSingle"), parent)
{}
ObjectExplosionSingle::~ObjectExplosionSingle()
{
removeTopics();
}
Core::FunctionReplyObject ObjectExplosionSingle::updateObject(const Database::AesExplosionSingle &data)
{
Core::FunctionReplyObject ret = ObjectBaseTmpl::updateObject(data);
if (ret.error() || (isOnlyObjectNameModifiable() && (data.id > 0))) // data.id > 0 -> negative values from oc always get a full update
return ret;
if (data.id != 0 &&
(data.partyId != m_data.partyId ||
data.chargeTypeId != m_data.chargeTypeId)
)
{
ret = m_mainHandler->chargeAdministrationHandler()->claimPlannedCharge(m_data.chargeTypeId, m_data.partyId, -1);
if (ret.error())
return ret;
ret = m_mainHandler->chargeAdministrationHandler()->claimPlannedCharge(data.chargeTypeId, data.partyId, 1);
if (ret.error())
return ret;
}
// only allow some fields
auto tmpData(m_data);
tmpData.id = std::abs(data.id);
tmpData.name = data.name;
tmpData.effectStart = data.effectStart;
tmpData.impactPosition = data.impactPosition;
tmpData.participantId = data.participantId;
tmpData.partyId = data.partyId;
tmpData.chargeTypeId = data.chargeTypeId;
tmpData.fireRequestTime = data.fireRequestTime;
tmpData.altitude = data.altitude;
tmpData.effectMarkingInTa = data.effectMarkingInTa;
tmpData.firePurpose = data.firePurpose;
tmpData.rotationAngle = data.rotationAngle;
tmpData.effectStateId = data.effectStateId; // overwrite for oc
tmpData.properties = data.properties;
if (!m_mainHandler->db()->update(tmpData))
return Core::FunctionReplyObject(data.id, tr_lts("dds", "Error updating single explosion with id %1 in database.")).arg(m_data.id);
m_data = std::move(tmpData);
m_publishDataTimer->start();
checkEnterNewState();
return Core::FunctionReplyObject(data.id); // data not m_data for the possible negative id in the oc-laptop
}
double ObjectExplosionSingle::chargeRadius() const
{
return m_mainHandler->dds()->pdmDtc()->impactRadius(m_data.chargeTypeId, m_data.igniterTypeId, m_data.igniterFunctionId);
}
Core::FunctionReplyObject ObjectExplosionSingle::createObject(const Database::AesExplosionSingle &data)
{
Core::FunctionReplyObject ret;
// No need to create object, if there is not enough charge left.
if (data.id == 0 && data.externalId == 0) // new, not read from db
ret = m_mainHandler->chargeAdministrationHandler()->claimPlannedCharge(data.chargeTypeId, data.partyId, 1);
if (ret.error())
return ret;
ret = ObjectBaseTmpl::createObject(data);
if (ret.error())
{
if (data.id == 0 && data.externalId == 0)
m_mainHandler->chargeAdministrationHandler()->claimPlannedCharge(data.chargeTypeId, data.partyId, -1);
}
return ret;
}
void ObjectExplosionSingle::setEffectState(AesEffectState newState)
{
if (newState == AesEffectState::EsExpired)
{
Core::FunctionReplyObject ret = m_mainHandler->chargeAdministrationHandler()->consumeCharge(m_data.chargeTypeId,
m_data.partyId,
1);
DEBUG_LOG(m_logger) << "Explosion Single Charge marked used";
if (ret.error())
ERROR_LOG(m_logger) << "Could not consume Charge! " << ret();
}
ObjectBaseTmpl::setEffectState(newState);
}
Core::FunctionReplyObject ObjectExplosionSingle::removeObject()
{
Core::FunctionReplyObject ret = ObjectBaseTmpl::removeObject();
if (ret.error())
return ret;
// If not yet activated, free the charge again.
if (!isActivationTimeReached())
ret = m_mainHandler->chargeAdministrationHandler()->claimPlannedCharge(m_data.chargeTypeId, m_data.partyId, -1);
return ret;
}
bool ObjectExplosionSingle::removeObjectFromDb()
{
return m_mainHandler->db()->removeAesExplosionSingle(m_data.id);
}
void ObjectExplosionSingle::onPublishData()
{
ObjectBaseTmpl::onPublishData();
if (!m_mainHandler->db()->update(m_data))
ERROR_LOG(m_logger) << "Error updating AesIndirectFireSingle-data in database";
ExplosionSingle ddsData(m_data.id,
m_data.name.toStdString(),
effectState() == AesEffectState::EsRemoved,
false,
partitionTimeMSec(),
{m_data.chargeTypeId,0,0},
m_data.effectDuration,
toOptional(toMSec(m_data.effectStart)),
m_data.effectStateId,
m_data.effectSourceId,
toOptional(m_data.partyId),
toOptional(m_data.participantId),
m_data.effectMarkingInTa,
m_data.externalId,
m_data.isCentral,
m_data.properties.toStdString(),
Core::GeoPosition2D(m_data.impactPosition.x(),
m_data.impactPosition.y()),
toMSec(m_data.fireRequestTime),
m_data.altitude,
m_data.firePurpose.toStdString());
m_mainHandler->dds()->dts()->publish(ddsData);
publishAiv();
}
void ObjectExplosionSingle::publishAiv()
{
const double cr = chargeRadius();
const QPolygonF poly = Polygons::explosionSingle(m_data, cr);
const QRectF bounds(poly.boundingRect());
AesItemView aiv(m_aiv);
aiv.aesItemId = m_data.id;
aiv.chargeStruct.chargeTypeId = m_data.chargeTypeId;
ddsVecFromPoly(poly, aiv.form);
aiv.effectStart = toMSec(m_data.effectStart);
aiv.boundingBoxBottomLeft = Core::GeoPosition2D(bounds.bottomLeft().x(), bounds.bottomLeft().y());
aiv.boundingBoxTopRight = Core::GeoPosition2D(bounds.topRight().x(), bounds.topRight().y());
aiv.aesTypeId = AesType::AtExplosionSingle;
aiv.effectStateId = effectState();
aiv.id = 1000 * m_data.id + static_cast<int>(AesType::AtExplosionSingle);
if (m_data.partyId != 0)
aiv.partyId = m_data.partyId;
checkIsCentralAndPublish(aiv.form, m_aiv.form, m_data.isCentral);
if (aiv != m_aiv)
{
aiv.sampleTime = partitionTimeMSec();
m_aiv = aiv;
m_mainHandler->dds()->dts()->publish(aiv);
emit newAiv(aiv);
}
}
void ObjectExplosionSingle::removeTopics()
{
auto dts = m_mainHandler->dds()->dts();
dts->removeExplosionSingleByKey(m_data.id);
dts->removeAesItemViewByKey(1000 * m_data.id + static_cast<int>(AesType::AtExplosionSingle));
emit removeAiv(m_data.id);
}
QPolygonF ObjectExplosionSingle::generateForm()
{
const double cr = chargeRadius();
return Polygons::explosionSingle(m_data, cr);
}
} // Namespace AreaEffectSimulation