#include "Variable/VariableSynchronizer.h" #include "Variable/Variable.h" Q_LOGGING_CATEGORY(LOG_VariableSynchronizer, "VariableSynchronizer") namespace { using GroupId = VariableSynchronizer::GroupId; using Group = std::set >; } // namespace struct VariableSynchronizer::VariableSynchronizerPrivate { std::map m_Groups; std::map, Group *> m_GroupsIndex; }; VariableSynchronizer::VariableSynchronizer(QObject *parent) : QObject{parent}, impl{spimpl::make_unique_impl()} { } void VariableSynchronizer::addGroup(GroupId groupId) noexcept { if (impl->m_Groups.count(groupId) == 1) { qCWarning(LOG_VariableSynchronizer()) << tr("Can't create new synchronization group: a " "group already exists under the passed identifier"); return; } impl->m_Groups.insert(std::make_pair(groupId, Group{})); } void VariableSynchronizer::addVariable(std::shared_ptr variable, GroupId groupId) noexcept { if (impl->m_GroupsIndex.count(variable) == 1) { qCWarning(LOG_VariableSynchronizer()) << tr("Can't add variable to a new synchronization group: the variable is already in a " "synchronization group"); return; } auto groupIt = impl->m_Groups.find(groupId); if (groupIt == impl->m_Groups.end()) { qCWarning(LOG_VariableSynchronizer()) << tr("Can't add variable to the synchronization group: no group exists under the " "passed identifier"); return; } // Registers variable groupIt->second.insert(variable); // Creates index for variable impl->m_GroupsIndex.insert(std::make_pair(variable, &groupIt->second)); } void VariableSynchronizer::removeGroup(GroupId groupId) noexcept { auto groupIt = impl->m_Groups.find(groupId); if (groupIt == impl->m_Groups.end()) { qCWarning(LOG_VariableSynchronizer()) << tr( "Can't remove synchronization group: no group exists under the passed identifier"); return; } // Removes indexes for (const auto &variable : groupIt->second) { impl->m_GroupsIndex.erase(variable); } // Removes group impl->m_Groups.erase(groupIt); } void VariableSynchronizer::removeVariable(std::shared_ptr variable, GroupId groupId) noexcept { auto groupIt = impl->m_Groups.find(groupId); if (groupIt == impl->m_Groups.end()) { qCWarning(LOG_VariableSynchronizer()) << tr("Can't remove variable from synchronization group: no group exists under the " "passed identifier"); return; } // Removes variable index impl->m_GroupsIndex.erase(variable); // Removes variable from group groupIt->second.erase(variable); } std::set > VariableSynchronizer::synchronizedVariables(std::shared_ptr variable) const noexcept { auto groupIndexIt = impl->m_GroupsIndex.find(variable); return groupIndexIt != impl->m_GroupsIndex.end() ? *groupIndexIt->second : std::set >{}; }