/** * Handler for all exercise objects * $Id$ * $HeadURL$ * $Author$ * Created by Malte Diers, SLSE, 2017-04-05 */ #include "handler_technical_area.h" #include namespace AreaEffectSimulation { HandlerTechnicalArea::HandlerTechnicalArea(MainHandler *mainHandler) : HandlerBaseTmpl(mainHandler, QStringLiteral("TechnicalArea"), s_areaCount[AesType::AtTechnicalArea], s_areaCountCentral[AesType::AtTechnicalArea]) , Interface::Fts::TechnicalAreaModifyRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::TechnicalAreaRemoveRequestHandler(mainHandler->dds()->fts()) { } bool HandlerTechnicalArea::init() { QVector dataVec; // read all TechnicalAreas from database if (!m_mainHandler->db()->select(dataVec)) { ERROR_LOG(m_logger) << "Error reading data from database!"; return false; } // create Technical area objects for (const Database::AesTechnicalArea &dbData : qAsConst(dataVec)) { ObjectTechnicalArea *ifs(new ObjectTechnicalArea(m_mainHandler, this)); connect(ifs, &ObjectTechnicalArea::effectStateChanged, this, &HandlerTechnicalArea::onEffectStateChanged); Core::FunctionReplyObject ret = ifs->createObject(dbData); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); return false; } if (totalAreas() >= s_maxActiveAreas[AesType::AtTechnicalArea]) { ERROR_LOG(m_logger) << "More active technical areas in database than allowed - ignoring the rest!"; delete ifs; continue; } if (ifs->isObjectInTrainingArea()) ++m_areaCount; m_objectMap.insert(ifs->id(), ifs); connect(ifs, &ObjectTechnicalArea::newAiv, this, &HandlerTechnicalArea::newAiv); connect(ifs, &ObjectTechnicalArea::removeAiv, this, &HandlerTechnicalArea::removeAiv); } DEBUG_LOG(m_logger) << "m_exeObjMap.size() = " << m_objectMap.size(); return true; } int HandlerTechnicalArea::totalAreas() const { return s_areaCount[AesType::AtTechnicalArea]; } int HandlerTechnicalArea::totalAreasCentral() const { return s_areaCountCentral[AesType::AtTechnicalArea]; } static void fillData(const TechnicalAreaModifyRequest &src, Database::AesTechnicalArea &dst) { dst.name = QString::fromStdString(src.name()); dst.chargeTypeId = 421; // dummy dst.effectDuration = 0; // forever active dst.typeId = src.type().underlying(); dst.position.rx() = src.area().cornerBottomLeft().lon(); dst.position.ry() = src.area().cornerBottomLeft().lat(); dst.length = src.area().height(); dst.width = src.area().width(); } void HandlerTechnicalArea::onTechnicalAreaModifyRequest(const rti::core::SampleIdentity &cookie, const TechnicalAreaModifyRequest &request) { DEBUG_LOG(m_logger) << "onTechnicalAreaModifyRequest: " << request; Core::FunctionReplyObject ret = request.id() > 0 ? technicalAreaModifyRequest(request) : technicalAreaCreateRequest(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->technicalAreaModifyReply(cookie, ret); } Core::FunctionReplyObject HandlerTechnicalArea::technicalAreaCreateRequest(const TechnicalAreaModifyRequest &request) { if (totalAreas() >= s_maxActiveAreas[AesType::AtTechnicalArea]) return Core::FunctionReplyObject(tr_lts("dds", "Too many active technical areas.")); Database::AesTechnicalArea newData; fillData(request, newData); // set time contrain outside of fillData newData.effectStart = QDateTime::fromMSecsSinceEpoch(m_mainHandler->dds()->currentPartitionTimeMSec() + 100); // now active ObjectTechnicalArea *ifs(new ObjectTechnicalArea(m_mainHandler, this)); connect(ifs, &ObjectTechnicalArea::effectStateChanged, this, &HandlerTechnicalArea::onEffectStateChanged); const Core::FunctionReplyObject ret = ifs->createObject(newData); if (ret.error()) { delete ifs; ifs = nullptr; return ret; } m_objectMap.insert(ifs->id(), ifs); if (ifs->isObjectInTrainingArea()) { ++m_areaCount; DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtTechnicalArea] = " << m_areaCount; } connect(ifs, &ObjectTechnicalArea::newAiv, this, &HandlerTechnicalArea::newAiv); connect(ifs, &ObjectTechnicalArea::removeAiv, this, &HandlerTechnicalArea::removeAiv); return ret; } Core::FunctionReplyObject HandlerTechnicalArea::technicalAreaModifyRequest(const TechnicalAreaModifyRequest &request) { Core::FunctionReplyObject ret; ObjectTechnicalArea *ifs = getObjectFromMap(m_objectMap, request.id(), ret); if (!ifs) return ret; // Anzahl aktiver Areas ist erreicht, der Wirkbeginn ist (soll) gesetzt sein, aber die Area war // vorher noch ohne Wirkbeginn if (totalAreas() >= s_maxActiveAreas[AesType::AtTechnicalArea] && !ifs->isObjectModifiable()) return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Too many active technical areas.")); // Todo: IsObjectModifiable() ?!? AreaEffectSimulation::Database::AesTechnicalArea aea(ifs->data()); fillData(request, aea); if (request.id() < 0 && checkStateForSfm(ifs)) { DEBUG_LOG(m_logger) << "Overwrite technical area Effect State for OC"; aea.effectStateId = AesEffectState::EsPrepared; } return ifs->updateObject(aea); } void HandlerTechnicalArea::onTechnicalAreaRemoveRequest(const rti::core::SampleIdentity &cookie, const Core::RemoveElementRequest &request) { m_mainHandler->dds()->fts()->technicalAreaRemoveReply(cookie, removeReply(&DatabaseInterface::removeAesTechnicalArea, request)); } } // Namespace AreaEffectSimulation