/** * Handler for gasPipe objects * $Id$ * $HeadURL$ * $Author$ * Created by hjl, SLSE, 2017-06-14 */ #include "handler_gas_pipe.h" #include "object_gas_pipe.h" #include #include "Utils/polygons.h" #include namespace AreaEffectSimulation { HandlerGasPipe::HandlerGasPipe(MainHandler *mainHandler) : HandlerBaseTmpl(mainHandler, QStringLiteral("ExplosionArea"), s_areaCount[AesType::AtGasPipe], s_areaCountCentral[AesType::AtGasPipe]) , Interface::Fts::GasPipeModifyRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::GasPipeRemoveRequestHandler(mainHandler->dds()->fts()) { } // end of ctor() //----------------------------------------------------------------------------- HandlerGasPipe::~HandlerGasPipe() { } // end of dtor() //----------------------------------------------------------------------------- bool HandlerGasPipe::init() { DEBUG_LOG(m_logger) << "--- Start AreaEffectSimulation HandlerGasPipe."; QVector gasPipeVec; QVector segmentVec; // get all data for gasPipes from database if (!m_mainHandler->db()->select(gasPipeVec) || !m_mainHandler->db()->select(segmentVec)) { ERROR_LOG(m_logger) << LOGFUNCTION << " Error reading data from database!"; return false; } DEBUG_LOG(m_logger) << "read all data for gasPipes from database" << " aes_GasPipe.size(): " << gasPipeVec.size() << " aes_GasPipe_segment.size(): " << segmentVec.size(); // contains all segments of an gasPipe in ascending order QVector dbGasPipeSegments; for (const Database::AesGasPipe &dbGasPipe : qAsConst(gasPipeVec)) { if (dbGasPipe.effectStateId == AesEffectState_def::EsRemoved) continue; dbGasPipeSegments.clear(); for (const Database::AesGasPipeSegment &segment : qAsConst(segmentVec)) { if (segment.gasPipeId == dbGasPipe.privGasPipeId) dbGasPipeSegments.insert(segment.positionIndex, segment); } // create and publish a new object ObjectGasPipe *ifs(new ObjectGasPipe(m_mainHandler, this)); Core::FunctionReplyObject ret = ifs->createObject(dbGasPipe, {}, dbGasPipeSegments); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); return false; } m_objectMap.insert(ifs->id(), ifs); } DEBUG_LOG(m_logger) << " m_gasPipeObjMap.size() = " << m_objectMap.size(); return true; } // end of init() //----------------------------------------------------------------------------- void HandlerGasPipe::onGasPipeModifyRequest(const rti::core::SampleIdentity &cookie, const GasPipeModifyRequest &request) { DEBUG_LOG(m_logger) << "onGasPipeModifyRequest: " << request; Core::FunctionReplyObject ret = request.id() > 0 ? gasPipeModifyRequest(request) : gasPipeCreateRequest(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->gasPipeModifyReply(cookie, ret); } //----------------------------------------------------------------------------- Core::FunctionReplyObject HandlerGasPipe::gasPipeCreateRequest(const GasPipeModifyRequest &request) { Database::AesGasPipe newData; newData.name = QString::fromStdString(request.name()); newData.effectStart = request.effectStart().is_set() && request.effectStart().get() > 0 ? QDateTime::fromMSecsSinceEpoch(request.effectStart().get()) : QDateTime(); newData.partyId = request.partyId().is_set() ? request.partyId().get() : 0; newData.width = request.width(); newData.effectDuration = request.effectDuration(); ObjectGasPipe *ifs(new ObjectGasPipe(m_mainHandler, this)); Core::FunctionReplyObject ret = ifs->createObject(newData, request.segments(), QVector()); if (ret.error()) { delete ifs; return ret; } if (ifs->data().isCentral) { if (totalAreasCentral() >= s_maxActiveAreasCentral[AesType::AtGasPipe] && request.effectStart().is_set()) { ifs->removeObject(); delete ifs; return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active central gas pipes.")); } } else { if (totalAreas() >= s_maxActiveAreas[AesType::AtGasPipe] && request.effectStart().is_set()) { ifs->removeObject(); delete ifs; return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active gas pipes.")); } } if (ifs->data().isCentral) { ++m_areaCountCentral; DEBUG_LOG(m_logger) << "s_areaCountCentral[AesType::AtFunctionalArea] = " << m_areaCountCentral; } else if (ifs->isObjectInTrainingArea()) { ++m_areaCount; DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtFunctionalArea] = " << m_areaCount; } m_objectMap.insert(ifs->id(), ifs); return ret; } // end of onGasPipeCreateRequest() //----------------------------------------------------------------------------- Core::FunctionReplyObject HandlerGasPipe::gasPipeModifyRequest(const GasPipeModifyRequest &request) { Core::FunctionReplyObject ret; ObjectGasPipe *ifs = getObjectFromMap(m_objectMap, request.id(), ret); if (!ifs) return ret; Database::AesGasPipe newData; newData.name = QString::fromStdString(request.name()); newData.effectStart = request.effectStart().is_set() && request.effectStart().get() > 0 ? QDateTime::fromMSecsSinceEpoch(request.effectStart().get()) : QDateTime(); newData.partyId = request.partyId().is_set() ? request.partyId().get() : 0; newData.width = request.width(); newData.effectDuration = request.effectDuration(); if (request.id() < 0 && checkStateForSfm(ifs)) { DEBUG_LOG(m_logger) << "Overwrite gas pipe Effect State for OC"; newData.effectStateId = AesEffectState::EsPrepared; } /*! * If the effect start added after creation, the max amount need to be checked !*/ if(!ifs->isActivationTimeSet() && request.effectStart().is_set()) { if (ifs->data().isCentral) { if (totalAreasCentral() >= s_maxActiveAreasCentral[AesType::AtGasPipe]) { return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active central functional areas.")); } } else { if (totalAreas() >= s_maxActiveAreas[AesType::AtGasPipe]) { return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active functional areas areas.")); } } } //TODO: Implement switch from decentral to central in gasp pipes // // For counting, only Elements being at least prepared are important: // if (request.effectStart().is_set() && ifs->isObjectModifiable()) // { // // Calculate new polygon here. Not nice, though // auto poly = Polygons::gasPipe(newData); // std::vector _form; // ObjectBase::ddsVecFromPoly(poly, _form); // bool isCentral = ifs->checkIsCentral(_form); // bool wasCentral = ifs->data().isCentral; // // Supply-Truck always isCentral // // if ( request.supplyMode() == AesOperatingMode_def::OmWaitingTime) // // { // // isCentral = true; // // wasCentral = true; // // } // DEBUG_LOG(m_logger) << "isCentral: " << isCentral; // DEBUG_LOG(m_logger) << "wasCentral: " << wasCentral; // // only change if element changed from central to training area or vice versa // if (isCentral != wasCentral) // { // // Change from central to training area // if (wasCentral) // { // if (totalAreas() >= s_maxActiveAreas[AesType::AtFunctionalArea]) // return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Too many active B/C contamination areas.")); // m_areaCount++; // m_areaCountCentral--; // DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtFunctionalArea] = " << m_areaCount; // DEBUG_LOG(m_logger) << "s_areaCountCentral[AesType::AtFunctionalArea] = " << m_areaCountCentral; // } // else // Change from training area to central // { // if (totalAreasCentral() >= s_maxActiveAreasCentral[AesType::AtFunctionalArea]) // return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Too many active central B/C contamination areas.")); // m_areaCount--; // m_areaCountCentral++; // DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtFunctionalArea] = " << m_areaCount; // DEBUG_LOG(m_logger) << "s_areaCountCentral[AesType::AtFunctionalArea] = " << m_areaCountCentral; // } // } // } return ifs->updateObject(newData, request.segments()); } // end of onGasPipeModifyRequest() //----------------------------------------------------------------------------- void HandlerGasPipe::onGasPipeRemoveRequest(const rti::core::SampleIdentity &cookie, const Core::RemoveElementRequest &request) { m_mainHandler->dds()->fts()->gasPipeRemoveReply(cookie, removeReply(&DatabaseInterface::removeAesGasPipe, request)); } // end of onGasPipeRemoveRequest() //----------------------------------------------------------------------------- } // Namespace AreaEffectSimulation