Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+339
@@ -0,0 +1,339 @@
|
||||
/**
|
||||
* Object for the null mine area (where the unassigned DUS mines belong to)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "object_mine_area_null.h"
|
||||
#include "special_area_provider.h"
|
||||
|
||||
#include <QPolygonF>
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
#include <ngldb/dbtransaction.h>
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
ObjectMineAreaNull::ObjectMineAreaNull(MainHandler *mainHandler,
|
||||
QObject *parent)
|
||||
: ObjectBaseTmpl(mainHandler, QStringLiteral("MineAreaNull"), parent)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_setId(0)
|
||||
{
|
||||
// read all Triggered Mines from database
|
||||
// Store all those of this mine area in m_triggeredMines
|
||||
auto cb = [this] (const Database::AesMineAreaTriggeredMines &mine)
|
||||
{
|
||||
m_triggeredMines.insert(mine.mineId, mine);
|
||||
};
|
||||
if (!m_mainHandler->db()->selectByMineAreaId(cb, 0)) // mineArea 0
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error reading data from database!";
|
||||
}
|
||||
|
||||
// Set TriggeredExplosions Base Data
|
||||
m_tis.id(AesType::AtMineAreaSingleMines);
|
||||
m_tis.aesItemId(0);
|
||||
m_tis.aesTypeId(AesType::AtMineAreaSingleMines);
|
||||
|
||||
// Set DUS-Mine status Base Data
|
||||
m_dms.mines().resize(m_triggeredMines.size());
|
||||
|
||||
onPublishData();
|
||||
}
|
||||
|
||||
ObjectMineAreaNull::~ObjectMineAreaNull()
|
||||
{
|
||||
removeTopics();
|
||||
}
|
||||
bool ObjectMineAreaNull::isDusMineArea() const
|
||||
{
|
||||
return static_cast<MineClass::type>(m_mainHandler->dds()->pdmDtc()->mineClass(m_data.chargeTypeId, m_data.igniterTypeId, m_data.igniterFunctionId))
|
||||
== MineClass::DUS;
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::isConcreteMine() const
|
||||
{
|
||||
return static_cast<MineClass::type>(m_mainHandler->dds()->pdmDtc()->mineClass(m_data.chargeTypeId, m_data.igniterTypeId, m_data.igniterFunctionId))
|
||||
== MineClass::Concrete;
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::isVirtualSingleMine() const
|
||||
{
|
||||
return static_cast<MineClass::type>(m_mainHandler->dds()->pdmDtc()->mineClass(m_data.chargeTypeId, m_data.igniterTypeId, m_data.igniterFunctionId))
|
||||
== MineClass::VirtualSingle;
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::isVirtualMine() const
|
||||
{
|
||||
return static_cast<MineClass::type>(m_mainHandler->dds()->pdmDtc()->mineClass(m_data.chargeTypeId, m_data.igniterTypeId, m_data.igniterFunctionId))
|
||||
== MineClass::Virtual;
|
||||
}
|
||||
int ObjectMineAreaNull::lastConcreteMineNo()
|
||||
{
|
||||
int lastMineNo = 0;
|
||||
for (const Database::AesMineAreaTriggeredMines &mine : qAsConst(m_triggeredMines))
|
||||
{
|
||||
// NOTE: igniterType/IgniterFunciton = 0 as long as AesMineAreaTriggeredMines does not contain values
|
||||
DEBUG_LOG(m_logger) << "mine: chargeTypeId " << mine.chargeTypeId << ", mineId: " << mine.mineId;
|
||||
if (isConcreteMine() ||
|
||||
isDusMineArea())
|
||||
{
|
||||
if (mine.mineId > lastMineNo)
|
||||
lastMineNo = mine.mineId;
|
||||
}
|
||||
}
|
||||
return lastMineNo;
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::triggerMine(int mineId, bool trigger, int chargeTypeId, const QPointF &position, bool publish)
|
||||
{
|
||||
Database::AesMineAreaTriggeredMines &tm = m_triggeredMines[mineId];
|
||||
tm.mineAreaId = 0;
|
||||
tm.mineId = mineId;
|
||||
tm.isTriggered = trigger;
|
||||
if (chargeTypeId > 0)
|
||||
tm.chargeTypeId = chargeTypeId;
|
||||
if (trigger)
|
||||
tm.triggerTime = QDateTime::fromMSecsSinceEpoch(partitionTimeMSec());
|
||||
if (!position.isNull())
|
||||
tm.position = position;
|
||||
|
||||
bool bOk = true;
|
||||
|
||||
DEBUG_LOG(m_logger) << "tm.id: " << tm.id << ", mineId: " << tm.mineId << ", mineAreaId: " << tm.mineAreaId;
|
||||
|
||||
if (tm.chargeTypeId == 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Not possible to trigger mine with invalid chargeTypeId 0";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tm.id)
|
||||
{
|
||||
bOk &= m_mainHandler->db()->insert(tm);
|
||||
m_setId++;
|
||||
}
|
||||
else
|
||||
bOk &= m_mainHandler->db()->update(tm);
|
||||
|
||||
if (!bOk)
|
||||
return false;
|
||||
|
||||
if (publish)
|
||||
onPublishData();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::triggerMine(Database::AesMineAreaTriggeredMines &mine)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Triggering mine " << mine.mineId << " with dbId " << mine.id;
|
||||
mine.mineAreaId = m_data.id;
|
||||
mine.isTriggered = true;
|
||||
mine.triggerTime = QDateTime::fromMSecsSinceEpoch(partitionTimeMSec());
|
||||
|
||||
m_triggeredMines[mine.mineId] = mine;
|
||||
|
||||
if (!m_mainHandler->db()->update(mine))
|
||||
ERROR_LOG (m_logger) << "Error updating mine " << mine.mineId << " in db!";
|
||||
|
||||
onPublishData();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjectMineAreaNull::triggerMines(const QList<Database::AesMineAreaTriggeredMines> &mines)
|
||||
{
|
||||
DBTransaction trans(m_mainHandler->db()->database());
|
||||
bool bOk = true;
|
||||
for (const auto &mine : mines)
|
||||
{
|
||||
m_triggeredMines[mine.mineId] = mine;
|
||||
m_triggeredMines[mine.mineId].mineAreaId = 0;
|
||||
|
||||
if (!m_mainHandler->db()->update(m_triggeredMines[mine.mineId]))
|
||||
{
|
||||
bOk = false;
|
||||
ERROR_LOG (m_logger) << "Error updating mine " << mine.mineId << " in db!";
|
||||
}
|
||||
}
|
||||
if (bOk)
|
||||
trans.commit();
|
||||
|
||||
m_setId++;
|
||||
onPublishData();
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::resetMine(int mineId)
|
||||
{
|
||||
return triggerMine(mineId, false);
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::resetMines()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Resetting unassociated DUS mines, count: " << m_triggeredMines.size();
|
||||
|
||||
bool bOk = true;
|
||||
auto it = m_triggeredMines.begin();
|
||||
while (it != m_triggeredMines.end())
|
||||
{
|
||||
Database::AesMineAreaTriggeredMines &tm = (*it);
|
||||
if (tm.isTriggered)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Reset mine with id " << tm.mineId;
|
||||
tm.isTriggered = false;
|
||||
bOk &= m_mainHandler->db()->update(tm);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
if (!bOk)
|
||||
return false;
|
||||
|
||||
// This pauses the TAB reaction on mine reset changes...
|
||||
const TrainingAreaBase::SendResetAllDusMinesRequest req;
|
||||
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_mainHandler->dds()->tabFtc()->sendResetAllDusMinesRequest(req,this);
|
||||
});
|
||||
|
||||
// We're publishing data anyhow. So do the other DUS mine areas.
|
||||
onPublishData();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Database::AesMineAreaTriggeredMines ObjectMineAreaNull::takeMine(int mineId)
|
||||
{
|
||||
if (!m_triggeredMines.contains(mineId))
|
||||
return Database::AesMineAreaTriggeredMines();
|
||||
|
||||
Database::AesMineAreaTriggeredMines ret = m_triggeredMines.value(mineId);
|
||||
m_triggeredMines.remove(mineId);
|
||||
|
||||
m_setId++;
|
||||
onPublishData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObjectMineAreaNull::onPublishData()
|
||||
{
|
||||
DDSConnector::CoherentSet cs (m_mainHandler->dds()->ddsConnector());
|
||||
ObjectBaseTmpl::onPublishData();
|
||||
|
||||
publishTriggeredImpacts();
|
||||
publishDusMineStatus();
|
||||
publishAiv();
|
||||
}
|
||||
|
||||
void ObjectMineAreaNull::removeTopics()
|
||||
{
|
||||
auto dts = m_mainHandler->dds()->dts();
|
||||
dts->removeMineAreaByKey(m_data.id);
|
||||
dts->removeAesItemViewByKey(1000 * m_data.id + AesType::AtMineAreaSingleMines);
|
||||
dts->removeTriggeredImpactsByKey(1000 * m_data.id + AesType::AtMineAreaSingleMines);
|
||||
emit removeAiv(m_data.id);
|
||||
}
|
||||
|
||||
void ObjectMineAreaNull::publishAiv()
|
||||
{
|
||||
// Todo: calculate unique id.
|
||||
// Better than aiv.id(1000 * aesItemId + AesType::AtMineArea);
|
||||
std::vector<Core::GeoPosition> vec;
|
||||
vec.reserve(m_triggeredMines.size());
|
||||
QPolygonF tmp;
|
||||
tmp.reserve(m_triggeredMines.size());
|
||||
for (const auto &mine : qAsConst(m_triggeredMines))
|
||||
{
|
||||
vec.emplace_back(Core::GeoPosition(mine.position.x(), mine.position.y(), 0));
|
||||
tmp.push_back(mine.position);
|
||||
}
|
||||
|
||||
AesItemView aiv2(m_aiv2);
|
||||
aiv2.aesItemId(0);
|
||||
aiv2.chargeStruct().chargeTypeId(m_data.chargeTypeId); // Shall be invalid. EffectSimulation has been conducted before, so not necessary for service sCES
|
||||
aiv2.effectStart(0);
|
||||
aiv2.form(vec);
|
||||
aiv2.boundingBoxBottomLeft() = Core::GeoPosition2D(tmp.boundingRect().bottomLeft().x(), tmp.boundingRect().bottomLeft().y());
|
||||
aiv2.boundingBoxTopRight() = Core::GeoPosition2D(tmp.boundingRect().topRight().x(), tmp.boundingRect().topRight().y());
|
||||
aiv2.aesTypeId(AesType::inner_enum::AtMineAreaSingleMines);
|
||||
aiv2.id(AesType::inner_enum::AtMineAreaSingleMines);
|
||||
aiv2.effectStateId(AesEffectState::inner_enum::EsActivated);
|
||||
aiv2.setId(dds::core::optional<rti::core::int64>(m_setId));
|
||||
if (m_data.partyId != 0)
|
||||
aiv2.partyId(m_data.partyId);
|
||||
|
||||
checkIsCentralAndPublish(aiv2.form(), m_aiv2.form(), m_data.isCentral);
|
||||
|
||||
if (aiv2 != m_aiv2)
|
||||
{
|
||||
aiv2.sampleTime(partitionTimeMSec());
|
||||
m_aiv2 = aiv2;
|
||||
m_mainHandler->dds()->dts()->publish(aiv2);
|
||||
emit newAiv(aiv2);
|
||||
}
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::publishTriggeredImpacts()
|
||||
{
|
||||
// Build an own tes-bitfield and compare, only store and publish if changed.
|
||||
TriggeredImpacts tis(m_tis);
|
||||
tis.impactCount(m_triggeredMines.size());
|
||||
tis.bitfield().resize((m_triggeredMines.size() + 7) / 8);
|
||||
tis.setId(dds::core::optional<rti::core::int64>(m_setId));
|
||||
|
||||
int i = 0;
|
||||
for (const auto &mine : qAsConst(m_triggeredMines))
|
||||
{
|
||||
// Triggered Impact == 0, if mine is disarmed/exploded
|
||||
LtsUtils::BitArray::setBit(tis.bitfield(), i++, !mine.isTriggered);
|
||||
}
|
||||
if (m_tis != tis)
|
||||
{
|
||||
m_tis = tis;
|
||||
m_tis.sampleTime(partitionTimeMSec());
|
||||
return m_mainHandler->dds()->dts()->publish(m_tis);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectMineAreaNull::publishDusMineStatus()
|
||||
{
|
||||
// DusMineStatus mines vector is coherent to triggered impacts bitfield
|
||||
DusMineState dms(m_dms);
|
||||
|
||||
dms.mines().resize(m_triggeredMines.size());
|
||||
dms.setId(dds::core::optional<rti::core::int64>(m_setId));
|
||||
int i = 0;
|
||||
for (const auto &mine : qAsConst(m_triggeredMines))
|
||||
{
|
||||
const DusMine entry(mine.mineId, mine.isTriggered, mine.chargeTypeId, {mine.position.x(), mine.position.y()});
|
||||
dms.mines()[i++] = entry;
|
||||
}
|
||||
|
||||
if (m_dms != dms)
|
||||
{
|
||||
m_dms = dms;
|
||||
m_dms.sampleTime(partitionTimeMSec());
|
||||
return m_mainHandler->dds()->dts()->publish(m_dms);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QPolygonF ObjectMineAreaNull::generateForm()
|
||||
{
|
||||
std::vector<Core::GeoPosition> vec;
|
||||
vec.reserve(m_triggeredMines.size());
|
||||
QPolygonF tmp;
|
||||
tmp.reserve(m_triggeredMines.size());
|
||||
for (const auto &mine : qAsConst(m_triggeredMines))
|
||||
{
|
||||
vec.emplace_back(Core::GeoPosition(mine.position.x(), mine.position.y(), 0));
|
||||
tmp.push_back(mine.position);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in new issue
Block a user