* @brief Main-thread 1 Hz poll: diffs the live data-table store against the last captured * state and enqueues changed registers for the table_snapshots table. */
| 790 | * state and enqueues changed registers for the table_snapshots table. |
| 791 | */ |
| 792 | void Sessions::Export::captureTableSnapshots() |
| 793 | { |
| 794 | if (!exportEnabled() || !isOpen() || SerialStudio::isAnyPlayerOpen()) { |
| 795 | m_lastTableSnapshot.clear(); |
| 796 | return; |
| 797 | } |
| 798 | |
| 799 | const auto& store = DataModel::FrameBuilder::instance().tableStore(); |
| 800 | if (!store.isInitialized()) |
| 801 | return; |
| 802 | |
| 803 | const auto changed = |
| 804 | [this](const QString& table, const QString& reg, const DataModel::RegisterValue& val) { |
| 805 | const auto t = m_lastTableSnapshot.constFind(table); |
| 806 | if (t == m_lastTableSnapshot.constEnd()) |
| 807 | return true; |
| 808 | |
| 809 | const auto r = t.value().constFind(reg); |
| 810 | if (r == t.value().constEnd()) |
| 811 | return true; |
| 812 | |
| 813 | return r.value().isNumeric != val.isNumeric || r.value().numericValue != val.numericValue |
| 814 | || r.value().stringValue != val.stringValue; |
| 815 | }; |
| 816 | |
| 817 | const auto now = DataModel::TimestampedFrame::SteadyClock::now(); |
| 818 | const auto snapshot = store.snapshot(); |
| 819 | for (auto t = snapshot.constBegin(); t != snapshot.constEnd(); ++t) { |
| 820 | if (t.key() == DataModel::systemDataTableName()) |
| 821 | continue; |
| 822 | |
| 823 | for (auto r = t.value().constBegin(); r != t.value().constEnd(); ++r) { |
| 824 | if (!changed(t.key(), r.key(), r.value())) |
| 825 | continue; |
| 826 | |
| 827 | TableSnapshotEntry entry; |
| 828 | entry.timestamp = now; |
| 829 | entry.tableName = t.key(); |
| 830 | entry.registerName = r.key(); |
| 831 | entry.value = r.value(); |
| 832 | m_tableSnapshotQueue.try_enqueue(std::move(entry)); |
| 833 | } |
| 834 | } |
| 835 | |
| 836 | m_lastTableSnapshot = snapshot; |
| 837 | } |
| 838 | |
| 839 | /** |
| 840 | * @brief Enqueues a timestamped frame for SQLite export. |
nothing calls this directly
no test coverage detected