271 lines
8.1 KiB
C++
Executable File
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
|