Files
qt5-legatus-legacy/Lts/Services/AreaEffectSimulation/handler_base.h
T
2026-08-13 18:33:10 +02:00

271 lines
8.1 KiB
C++
Executable File

/**
* Base class for all aes handlers
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "main_handler.h"
#include "logger.h"
#include <QObject>
namespace AreaEffectSimulation
{
class HandlerBase : public QObject
{
Q_OBJECT
public:
explicit HandlerBase(MainHandler *mainHandler, const QString &typeName);
protected:
virtual int totalAreas() const = 0; // Total Current areas
virtual void recountActiveAreas() = 0;
virtual int totalAreasCentral() const = 0; // Total Current areas
public Q_SLOTS:
void onEffectStateChanged()
{
recountActiveAreas();
}
protected:
template <typename T, typename S>
T *getObjectFromMap(const QMap<int, T*> &objMap, const S &requestId, Core::FunctionReplyObject &ret)
{
T *ifs = objMap.value(requestId);
if (!ifs)
ret = Core::FunctionReplyObject(requestId, tr_lts("dds", "Effect simulation with id %1 not found.")).arg(requestId);
return ifs;
}
template <typename T, typename S>
T *getObjectFromMapByExternalId(const QMap<int, T*> &objMap, const S &requestId, Core::FunctionReplyObject &ret)
{
for (const T* obj : objMap)
{
if (obj->externalId() == requestId)
return objMap.value(obj->id());
}
ret = Core::FunctionReplyObject(requestId, tr_lts("dds", "Effect simulation with id %1 not found.")).arg(requestId);
return nullptr;
}
bool isLockedTopic(int id)
{
AreaEffectSimulation::AesItem data;
data.id(id);
int exId = m_mainHandler->dds()->ddsConnector()->getPartitionId();
return m_mainHandler->dds()->topicLockMaster()->isLocked<AreaEffectSimulation::AesItem>(data, exId);
}
Q_SIGNALS:
void newAiv(const AreaEffectSimulation::AesItemView &item);
void removeAiv(int32_t aesItemId);
protected:
MainHandler *m_mainHandler;
QString m_typeName;
LOGGER_T m_logger;
static int s_areaCount[31];
static int s_maxActiveAreas[31];
static int s_areaCountCentral[31];
static int s_maxActiveAreasCentral[31];
static int s_maxSingleMinesCount;
static int s_maxCentralSingleMinesCount;
static int s_safePzAbwWMiCount;
static int s_maxAirSupportCount;
static int s_currentAirSupportCount;
static int s_startPzAbwWMiCCount;
static int s_mineAreaCreationInterval;
};
template<typename Obj>
class HandlerBaseTmpl : public HandlerBase
{
protected:
HandlerBaseTmpl(MainHandler *mainHandler, const QString &typeName, int &areaCount, int &areaCountCentral)
: HandlerBase(mainHandler, typeName)
, m_areaCount(areaCount)
, m_areaCountCentral(areaCountCentral)
{}
public:
~HandlerBaseTmpl() = default;
Obj *getItem(int id)
{
return m_objectMap.value(id);
}
bool checkStateForSfm(Obj *ifs)
{
if (ifs->effectState() == AesEffectState::EsRemoved)
return true;
return false;
}
bool contains(int id)
{
return m_objectMap.contains(id);
}
QHash<int, std::vector<Core::GeoPosition> > forms() const
{
QHash<int, std::vector<Core::GeoPosition> > forms;
for (const auto &object : m_objectMap)
forms[object->id()] = object->form();
return forms;
}
std::vector<Core::GeoPosition> form(qint32 aesItemId) const
{
return m_objectMap.value(aesItemId)->form();
}
void recountActiveAreas() override
{
m_areaCount = 0;
m_areaCountCentral = 0;
for (const Obj *area : qAsConst(m_objectMap))
{
if (area->isObjectInTrainingArea()) // meanwhile an ugly name, means EsPrepared, EsActivated, EsPaused
{
if (area->isCentral())
++m_areaCountCentral;
else
++m_areaCount;
}
}
DEBUG_LOG(m_logger) << "m_areaCount after Recount = " << m_areaCount;
DEBUG_LOG(m_logger) << "m_areaCountCentral after Recount = " << m_areaCountCentral;
}
Core::FunctionReplyObject removeObject(Obj *ifs)
{
Core::FunctionReplyObject ret;
// bool wasInArea = ifs->isObjectInTrainingArea();
ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
// else
// {
// if (wasInArea)
// --m_areaCount;
// DEBUG_LOG(m_logger) << "[Remove] m_areaCount = " << m_areaCount;
// }
return ret;
}
Core::FunctionReplyObject removeObject(int id)
{
Obj *ifs = m_objectMap.value(id);
if (ifs == nullptr)
return Core::FunctionReplyObject(id, tr_lts("dds", "Effect simulation with id %1 not found.")).arg(id);
return removeObject(ifs);
}
Core::FunctionReplyObject activateObjectOffset(int id, qint64 msecs)
{
Obj *ifs = m_objectMap.value(id);
if (ifs == nullptr)
return Core::FunctionReplyObject(id, tr_lts("dds", "Effect simulation with id %1 not found.")).arg(id);
return ifs->setActivationOffset(msecs);
}
Core::FunctionReplyObject switchTo(int id, AesEffectState effectState)
{
Obj *ifs = m_objectMap.value(id);
if (ifs == nullptr)
return Core::FunctionReplyObject(id, tr_lts("dds", "Effect simulation with id %1 not found.")).arg(id);
bool succ = false;
switch (effectState.underlying())
{
case AesEffectState_def::EsReceived:
succ = ifs->trySwitchToReceived();
break;
case AesEffectState_def::EsCreated:
succ = ifs->trySwitchToCreated();
break;
case AesEffectState_def::EsPrepared:
succ = ifs->trySwitchToPrepared();
break;
case AesEffectState_def::EsFired:
succ = ifs->trySwitchToFired();
break;
case AesEffectState_def::EsActivated:
succ = !ifs->activateObjectNow().error();
break;
case AesEffectState_def::EsPaused:
succ = ifs->trySwitchToPaused();
break;
case AesEffectState_def::EsExpired:
succ = ifs->trySwitchToExpired();
break;
case AesEffectState_def::EsRemoved:
succ = ifs->trySwitchToRemoved();
break;
default:
break;
}
if (succ)
return Core::FunctionReplyObject();
return Core::FunctionReplyObject(id, tr_lts("dds", "Could not switch effect simulation with id %1 to state with id %2.")).arg(id).arg(effectState.underlying());
}
Core::FunctionReplyObject aesItemRemove(const Core::RemoveElementRequest &request)
{
DEBUG_LOG(m_logger) << "on" << m_typeName << "RemoveRequest: " << request;
int id = request.id();
Core::FunctionReplyObject ret;
Obj *ifs = getObjectFromMap(m_objectMap, id, ret);
// Todo: IsObjectModifiable()?
if (ifs)
{
if (isLockedTopic(id))
return Core::FunctionReplyObject(id, tr_lts("dds", "Effect simulation '%1' is used by another user")).arg(ifs->objectName());
ret = removeObject(ifs);
}
return ret;
}
Core::FunctionReplyObject removeReply(bool (AreaEffectSimulation::DatabaseInterface::*dbRemoveMethod)(qint32), const Core::RemoveElementRequest &request)
{
if (request.id() >= 0)
return aesItemRemove(request);
// else force = negative id
qint32 id = request.id() * -1;
Obj *ifs = m_objectMap.value(id);
if (ifs == nullptr)
return Core::FunctionReplyObject(id, tr_lts("dds", "Effect simulation with id %1 not found.")).arg(id);
ifs->removeTopics();
m_objectMap.remove(id);
if (!((*m_mainHandler->db().get().*dbRemoveMethod)(id)))
return Core::FunctionReplyObject(id, tr_lts("dds", "Could not remove effect simulation with id %1 from database")).arg(id);
return Core::FunctionReplyObject(id);
}
protected:
QMap<int, Obj*> m_objectMap;
int &m_areaCount;
int &m_areaCountCentral;
};
} // namespace AreaEffectSimulation