210 lines
7.1 KiB
C++
Executable File
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 <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 + 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 + AesType::AtExplosionSingle);
|
|
emit removeAiv(m_data.id);
|
|
}
|
|
|
|
QPolygonF ObjectExplosionSingle::generateForm()
|
|
{
|
|
const double cr = chargeRadius();
|
|
return Polygons::explosionSingle(m_data, cr);
|
|
}
|
|
|
|
} // Namespace AreaEffectSimulation
|