* @brief Builds the per-source column lists and installs the FrameBuilder replay map * (uid -> payload cell index); runs for any source count. Single-source payloads * travel through processPayload, which routes to source 0, so the map is rekeyed. */
| 811 | * travel through processPayload, which routes to source 0, so the map is rekeyed. |
| 812 | */ |
| 813 | void Sessions::Player::buildMultiSourceMapping() |
| 814 | { |
| 815 | m_columnToSource.clear(); |
| 816 | m_sourceColumns.clear(); |
| 817 | |
| 818 | QMap<int, int> uidToSource; |
| 819 | const auto& groups = DataModel::ProjectModel::instance().groups(); |
| 820 | for (const auto& g : groups) |
| 821 | for (const auto& d : g.datasets) |
| 822 | uidToSource.insert(d.uniqueId, g.sourceId); |
| 823 | |
| 824 | std::unordered_map<int, std::unordered_map<int, int>> replay; |
| 825 | for (int col = 0; col < static_cast<int>(m_columnUniqueIds.size()); ++col) { |
| 826 | const int uid = m_columnUniqueIds[static_cast<size_t>(col)]; |
| 827 | const auto srcIt = uidToSource.constFind(uid); |
| 828 | if (srcIt == uidToSource.constEnd()) |
| 829 | continue; |
| 830 | |
| 831 | const int srcId = srcIt.value(); |
| 832 | auto& columns = m_sourceColumns[srcId]; |
| 833 | replay[srcId][uid] = static_cast<int>(columns.size()); |
| 834 | columns.push_back(uid); |
| 835 | |
| 836 | m_columnToSource[col] = srcId; |
| 837 | } |
| 838 | |
| 839 | m_multiSource = m_sourceColumns.size() > 1; |
| 840 | |
| 841 | if (!m_multiSource && !replay.empty() && replay.begin()->first != 0) { |
| 842 | auto columns = std::move(replay.begin()->second); |
| 843 | replay.clear(); |
| 844 | replay[0] = std::move(columns); |
| 845 | } |
| 846 | |
| 847 | DataModel::FrameBuilder::instance().setReplayColumnMap(std::move(replay)); |
| 848 | } |
| 849 | |
| 850 | //-------------------------------------------------------------------------------------------------- |
| 851 | // Frame synthesis |