]> sigrok.org Git - pulseview.git/blame - pv/data/decode/rowdata.cpp
Introduce DecodeSignal::annotation_visibility_changed and use it
[pulseview.git] / pv / data / decode / rowdata.cpp
CommitLineData
f9101a91
JH
1/*
2 * This file is part of the PulseView project.
3 *
4 * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
efdec55a 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
f9101a91
JH
18 */
19
d67b0972
SA
20#include <cassert>
21
6a26fc44
SA
22#include <pv/data/decode/decoder.hpp>
23#include <pv/data/decode/row.hpp>
24#include <pv/data/decode/rowdata.hpp>
f9101a91
JH
25
26using std::vector;
27
28namespace pv {
29namespace data {
30namespace decode {
31
6a26fc44 32RowData::RowData(Row* row) :
5a9146ac
SA
33 row_(row),
34 prev_ann_start_sample_(0)
6a26fc44
SA
35{
36 assert(row);
37}
38
1dcd9b18
SA
39const Row* RowData::row() const
40{
41 return row_;
42}
43
f9101a91
JH
44uint64_t RowData::get_max_sample() const
45{
8dbbc7f0 46 if (annotations_.empty())
f9101a91 47 return 0;
8dbbc7f0 48 return annotations_.back().end_sample();
f9101a91
JH
49}
50
f994f496
SA
51uint64_t RowData::get_annotation_count() const
52{
53 return annotations_.size();
54}
55
f9101a91 56void RowData::get_annotation_subset(
462941e2 57 deque<const pv::data::decode::Annotation*> &dest,
f9101a91
JH
58 uint64_t start_sample, uint64_t end_sample) const
59{
6a26fc44
SA
60 // Determine whether we must apply per-class filtering or not
61 bool all_ann_classes_enabled = true;
62 bool all_ann_classes_disabled = true;
63
64 uint32_t max_ann_class_id = 0;
65 for (AnnotationClass* c : row_->ann_classes()) {
02078aa1 66 if (!c->visible())
6a26fc44
SA
67 all_ann_classes_enabled = false;
68 else
69 all_ann_classes_disabled = false;
70 if (c->id > max_ann_class_id)
71 max_ann_class_id = c->id;
72 }
73
74 if (all_ann_classes_enabled) {
75 // No filtering, send everyting out as-is
76 for (const auto& annotation : annotations_)
77 if ((annotation.end_sample() > start_sample) &&
78 (annotation.start_sample() <= end_sample))
5a9146ac 79 dest.push_back(&annotation);
6a26fc44
SA
80 } else {
81 if (!all_ann_classes_disabled) {
82 // Filter out invisible annotation classes
83 vector<size_t> class_visible;
84 class_visible.resize(max_ann_class_id + 1, 0);
85 for (AnnotationClass* c : row_->ann_classes())
02078aa1 86 if (c->visible())
6a26fc44
SA
87 class_visible[c->id] = 1;
88
89 for (const auto& annotation : annotations_)
462941e2 90 if ((class_visible[annotation.ann_class_id()]) &&
81dc0221
SA
91 (annotation.end_sample() > start_sample) &&
92 (annotation.start_sample() <= end_sample))
5a9146ac 93 dest.push_back(&annotation);
6a26fc44
SA
94 }
95 }
f9101a91
JH
96}
97
88a25978
SA
98const deque<Annotation>& RowData::annotations() const
99{
100 return annotations_;
101}
102
f54e68b0 103const Annotation* RowData::emplace_annotation(srd_proto_data *pdata)
f9101a91 104{
1dcd9b18
SA
105 const srd_proto_data_annotation *const pda = (const srd_proto_data_annotation*)pdata->data;
106
107 Annotation::Class ann_class_id = (Annotation::Class)(pda->ann_class);
108
88a25978
SA
109 // Look up the longest annotation text to see if we have it in storage.
110 // This implies that if the longest text is the same, the shorter texts
111 // are expected to be the same, too. PDs that violate this assumption
112 // should be considered broken.
1dcd9b18
SA
113 const char* const* ann_texts = (char**)pda->ann_text;
114 const QString ann0 = QString::fromUtf8(ann_texts[0]);
115 vector<QString>* storage_entry = &(ann_texts_[ann0]);
116
117 if (storage_entry->empty()) {
118 while (*ann_texts) {
119 storage_entry->emplace_back(QString::fromUtf8(*ann_texts));
120 ann_texts++;
121 }
122 storage_entry->shrink_to_fit();
123 }
124
125
f54e68b0
SA
126 const Annotation* result = nullptr;
127
5a9146ac
SA
128 // We insert the annotation in a way so that the annotation list
129 // is sorted by start sample. Otherwise, we'd have to sort when
130 // painting, which is expensive
131
132 if (pdata->start_sample < prev_ann_start_sample_) {
133 // Find location to insert the annotation at
134
135 auto it = annotations_.end();
136 do {
137 it--;
138 } while ((it->start_sample() > pdata->start_sample) && (it != annotations_.begin()));
139
140 // Allow inserting at the front
141 if (it != annotations_.begin())
142 it++;
143
1dcd9b18
SA
144 it = annotations_.emplace(it, pdata->start_sample, pdata->end_sample,
145 storage_entry, ann_class_id, this);
f54e68b0 146 result = &(*it);
5a9146ac 147 } else {
1dcd9b18
SA
148 annotations_.emplace_back(pdata->start_sample, pdata->end_sample,
149 storage_entry, ann_class_id, this);
f54e68b0 150 result = &(annotations_.back());
5a9146ac
SA
151 prev_ann_start_sample_ = pdata->start_sample;
152 }
f54e68b0
SA
153
154 return result;
f9101a91
JH
155}
156
870ea3db
UH
157} // namespace decode
158} // namespace data
159} // namespace pv