/** * Exercises Handler - checks the avilable exercises and creates subhandlers fort each of them * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2016-04-14 */ #include "exercise_participant_handler.h" #include "exercises_handler.h" #include "dds_handler_exercise.h" using namespace WarehouseManagement; ExerciseParticipantHandler::ExerciseParticipantHandler(const dds::domain::DomainParticipant &domainParticipant, int exerciseId, ExercisesHandler *exercisesHandler) : m_exerciseId(exerciseId) , m_ddsHandlerExercise(new DdsHandlerExercise(domainParticipant, exerciseId)) , m_exercisesHandler(exercisesHandler) , m_logger(getLogger(QLatin1String("ExerciseParticipantHandler.") + QString::number(exerciseId))) {} ExerciseParticipantHandler::~ExerciseParticipantHandler() { m_ddsHandlerExercise.reset(); } bool ExerciseParticipantHandler::init() { if (!m_ddsHandlerExercise->init()) return false; auto cbParty = [this](const ParticipantManagement::Party &party) { onPartyChanged(party, DataModification::eAdded); }; m_ddsHandlerExercise->ppmDtc()->partys(cbParty); auto cpParticipant = [this](const ParticipantManagement::Participant &participant) { onParticipantChanged(participant, DataModification::eAdded); }; m_ddsHandlerExercise->ppmDtc()->participants(cpParticipant); connect(m_ddsHandlerExercise->ppmDtc().get(), &ParticipantManagement::Interface::Dtc::participantChanged, this, &ExerciseParticipantHandler::onParticipantChanged); connect(m_ddsHandlerExercise->ppmDtc().get(), &ParticipantManagement::Interface::Dtc::partyChanged, this, &ExerciseParticipantHandler::onPartyChanged); return true; } ParticipantManagement::Party ExerciseParticipantHandler::getParty(int partyId) const { return m_partyMap.value(partyId); } QString ExerciseParticipantHandler::getHierarchyFromParticipant(int participantId, const QMap &allParticipants) const { return allParticipants.isEmpty() ? m_ddsHandlerExercise->ppmDtc()->hierarchyFromParticipant(participantId) : m_ddsHandlerExercise->ppmDtc()->hierarchyFromParticipant(participantId, allParticipants); } ParticipantManagement::Participant ExerciseParticipantHandler::getParticipant(int participantId) const { return m_ddsHandlerExercise->ppmDtc()->participant(participantId); } QMap ExerciseParticipantHandler::getParticipants() const { return m_ddsHandlerExercise->ppmDtc()->participants(); } void ExerciseParticipantHandler::registerParticipant(qint32 participantId, ParticipantManagement::ParticipantAssignState assignState, const dds::core::optional &equipNo, const dds::core::optional &identification, const dds::core::optional &info) { ParticipantManagement::RegisterParticipantRequest req; req.assignState(assignState); if (equipNo.is_set()) req.equipmentNumber(equipNo.get()); if (identification.is_set()) req.identification(identification.get().toStdString()); if (info.is_set()) req.info(info.get().toStdString()); if (!equipNo.is_set() || !info.is_set() || !identification.is_set()) { const auto participant = m_ddsHandlerExercise->ppmDtc()->participant(participantId); if (!equipNo.is_set() && participant.equipmentNumber().is_set()) req.equipmentNumber(participant.equipmentNumber().get()); if (!info.is_set()) req.info(participant.info()); if (!identification.is_set()) req.identification(participant.identification()); } req.participantId(participantId); INFO_LOG(m_logger) << "IN ::registerParticipant, ParticipantId: " << participantId << ", equipNo: " << equipNo << ", assignState: " << assignState; m_ddsHandlerExercise->ppmFtc()->registerParticipantRequest(req, this); } void ExerciseParticipantHandler::onRegisterParticipantReply(const ParticipantManagement::RegisterReply &reply) { INFO_LOG(m_logger) << "RegisterReply id " << reply.id() << " - registerReturnValue: " << reply.registerReturnValue() << " for exercise " << reply.exerciseId(); // TODO: better idea please :) Core::FunctionReplyObject fro; fro.setStr(reply.errorString().c_str()); for (const auto &arg : reply.errorParams()) fro = fro.arg(arg); // send data via signal emit registrationReturnValue(reply.exerciseId(), reply.id(), reply.registerReturnValue()); if (fro.error()) ERROR_LOG(m_logger) << "Error: " << fro(); } void ExerciseParticipantHandler::participantAdded(const ParticipantManagement::Participant &participant) { // check if participant has equipment number if (!participant.equipmentNumber().is_set() || participant.equipmentNumber().get() == 0) { // no -> all ok INFO_LOG(m_logger) << "New participant but no equipment number - ignoring"; return; } addParticipant(participant.id(), participant.equipmentNumber().get()); } void ExerciseParticipantHandler::participantModified(const ParticipantManagement::Participant &participant) { // what can happen: // - 1: participant is not in our map // - 1.1: participant has no equipment number -> ignore // - 1.2: participant has equipment number -> add participant to our map // - 2_ participant is in our map -> participant had an equipment number // - 2.1: participant has same equipment number -> ignore // - 2.2: participant has no longer an equipment number -> remove participant from our map // - 2.3: participant has other equipment number -> modify participant for new equipment number const auto itEquipNumber = m_participantId2EquipmentNumber.constFind(participant.id()); if (itEquipNumber == m_participantId2EquipmentNumber.constEnd()) { // 1: participant is not in our map // no entry for this participant in our map ... if (!participant.equipmentNumber().is_set() || participant.equipmentNumber() == 0) { // 1.1: participant has no equipment number -> ignore return; } // 1.2: participant has equipment number -> add participant to our map addParticipant(participant.id(), participant.equipmentNumber().get()); return; } // 2: participant is in our map -> participant had an equipment number if (itEquipNumber.value() == participant.equipmentNumber()) { // 2.1: participant has same equipment number -> ignore return; } if (participant.equipmentNumber().is_set()) { INFO_LOG(m_logger) << "Participant with id " << participant.id() << " changed its equipment number from " << itEquipNumber.value() << " to " << participant.equipmentNumber().get(); } if (participant.equipmentNumber() == 0) { // 2.2: participant has no longer an equipment number -> remove participant from our map removeParticipant(participant.id(), participant.equipmentNumber().get()); return; } // 2.3: participant has other equipment number -> modify participant for new equipment number removeParticipant(itEquipNumber.key(), itEquipNumber.value()); if (participant.equipmentNumber().is_set()) addParticipant(participant.id(), participant.equipmentNumber().get()); } void ExerciseParticipantHandler::participantRemoved(const ParticipantManagement::Participant &participant) { // check if participant is in our map const auto itEquipNumber = m_participantId2EquipmentNumber.find(participant.id()); if (itEquipNumber == m_participantId2EquipmentNumber.end()) { // no -> all ok INFO_LOG(m_logger) << "Participant was removed but has no equipment number - ignoring"; return; } removeParticipant(itEquipNumber.key(), itEquipNumber.value()); } void ExerciseParticipantHandler::emitChangedForInferiors(const ParticipantManagement::Participant &participant) { for (const int inferior : participant.inferiorIds()) { const auto inf = m_ddsHandlerExercise->ppmDtc()->participant(inferior); if (inf.id() != 0) emit participantChanged(inf, DataModification::eModified, m_exerciseId); emitChangedForInferiors(inf); } } void ExerciseParticipantHandler::addParticipant(int participantId, int equipmentNumber) { m_participantId2EquipmentNumber.insert(participantId, equipmentNumber); ParticipantInfoStruct pis; pis.equipmentNumber = equipmentNumber; pis.participantId = participantId; pis.exerciseId = m_ddsHandlerExercise->getExerciseId(); m_exercisesHandler->addParticipant(pis); } void ExerciseParticipantHandler::removeParticipant(int participantId, int equipmentNumber) { m_participantId2EquipmentNumber.remove(participantId); ParticipantInfoStruct pis; pis.equipmentNumber = equipmentNumber; pis.participantId = participantId; pis.exerciseId = m_ddsHandlerExercise->getExerciseId(); m_exercisesHandler->removeParticipant(pis); } void ExerciseParticipantHandler::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType) { switch (modType) { case DataModification::eAdded: participantAdded(data); break; case DataModification::eModified: participantModified(data); break; case DataModification::eRemoved: participantRemoved(data); break; } emit participantChanged(data, modType, m_exerciseId); emitChangedForInferiors(data); } void ExerciseParticipantHandler::onPartyChanged(const ParticipantManagement::Party &data, DataModification modType) { switch (modType) { case DataModification::eAdded: case DataModification::eModified: m_partyMap[data.id()] = data; break; case DataModification::eRemoved: m_partyMap.remove(data.id()); break; } }