/** * Base class for all aes handlers * $Id$ * $HeadURL$ * $Author$ */ #pragma once #include "main_handler.h" #include "logger.h" #include 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 T *getObjectFromMap(const QMap &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 T *getObjectFromMapByExternalId(const QMap &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(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 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 > forms() const { QHash > forms; for (const auto &object : m_objectMap) forms[object->id()] = object->form(); return forms; } std::vector 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 m_objectMap; int &m_areaCount; int &m_areaCountCentral; }; } // namespace AreaEffectSimulation