SignalBase: Add SignalGroup class and handling
authorSoeren Apel <soeren@apelpie.net>
Thu, 7 May 2020 20:26:14 +0000 (22:26 +0200)
committerSoeren Apel <soeren@apelpie.net>
Mon, 11 May 2020 19:24:22 +0000 (21:24 +0200)
pv/data/signalbase.cpp
pv/data/signalbase.hpp
pv/session.cpp
pv/session.hpp

index 2b38fe1ef1d3b7ec03af221453527d70cfd4f641..70580aef919e2aa6263233050216a7aa6ba98d49 100644 (file)
@@ -45,9 +45,55 @@ const int SignalBase::ColorBGAlpha = 8 * 256 / 100;
 const uint64_t SignalBase::ConversionBlockSize = 4096;
 const uint32_t SignalBase::ConversionDelay = 1000;  // 1 second
 
+
+SignalGroup::SignalGroup(const QString& name)
+{
+       name_ = name;
+}
+
+void SignalGroup::append_signal(shared_ptr<SignalBase> signal)
+{
+       if (!signal)
+               return;
+
+       signals_.push_back(signal);
+       signal->set_group(this);
+}
+
+void SignalGroup::remove_signal(shared_ptr<SignalBase> signal)
+{
+       if (!signal)
+               return;
+
+       signals_.erase(std::remove_if(signals_.begin(), signals_.end(),
+               [&](shared_ptr<SignalBase> s) { return s == signal; }),
+               signals_.end());
+}
+
+deque<shared_ptr<SignalBase>> SignalGroup::signals() const
+{
+       return signals_;
+}
+
+void SignalGroup::clear()
+{
+       for (shared_ptr<SignalBase> sb : signals_)
+               sb->set_group(nullptr);
+
+       signals_.clear();
+}
+
+const QString SignalGroup::name() const
+{
+       return name_;
+}
+
+
+
 SignalBase::SignalBase(shared_ptr<sigrok::Channel> channel, ChannelType channel_type) :
        channel_(channel),
        channel_type_(channel_type),
+       group_(nullptr),
        conversion_type_(NoConversion),
        min_value_(0),
        max_value_(0)
@@ -73,39 +119,6 @@ shared_ptr<sigrok::Channel> SignalBase::channel() const
        return channel_;
 }
 
-QString SignalBase::name() const
-{
-       return (channel_) ? QString::fromStdString(channel_->name()) : name_;
-}
-
-QString SignalBase::internal_name() const
-{
-       return internal_name_;
-}
-
-void SignalBase::set_internal_name(QString internal_name)
-{
-       internal_name_ = internal_name;
-}
-
-QString SignalBase::display_name() const
-{
-       if ((name() != internal_name_) && (!internal_name_.isEmpty()))
-               return name() + " (" + internal_name_ + ")";
-       else
-               return name();
-}
-
-void SignalBase::set_name(QString name)
-{
-       if (channel_)
-               channel_->set_name(name.toUtf8().constData());
-
-       name_ = name;
-
-       name_changed(name);
-}
-
 bool SignalBase::enabled() const
 {
        return (channel_) ? channel_->enabled() : true;
@@ -142,6 +155,49 @@ unsigned int SignalBase::logic_bit_index() const
                return 0;
 }
 
+void SignalBase::set_group(SignalGroup* group)
+{
+       group_ = group;
+}
+
+SignalGroup* SignalBase::group() const
+{
+       return group_;
+}
+
+QString SignalBase::name() const
+{
+       return (channel_) ? QString::fromStdString(channel_->name()) : name_;
+}
+
+QString SignalBase::internal_name() const
+{
+       return internal_name_;
+}
+
+void SignalBase::set_internal_name(QString internal_name)
+{
+       internal_name_ = internal_name;
+}
+
+QString SignalBase::display_name() const
+{
+       if ((name() != internal_name_) && (!internal_name_.isEmpty()))
+               return name() + " (" + internal_name_ + ")";
+       else
+               return name();
+}
+
+void SignalBase::set_name(QString name)
+{
+       if (channel_)
+               channel_->set_name(name.toUtf8().constData());
+
+       name_ = name;
+
+       name_changed(name);
+}
+
 QColor SignalBase::color() const
 {
        return color_;
index 7e1196521d0d3ae303a8b6258e6f62dce71cb798..f646a40dcc24f7255822b6f4a9584a4f721c92b6 100644 (file)
@@ -22,6 +22,7 @@
 #define PULSEVIEW_PV_DATA_SIGNALBASE_HPP
 
 #include <atomic>
+#include <deque>
 #include <condition_variable>
 #include <thread>
 #include <vector>
@@ -39,6 +40,8 @@
 
 using std::atomic;
 using std::condition_variable;
+using std::deque;
+using std::enable_shared_from_this;
 using std::map;
 using std::mutex;
 using std::pair;
@@ -58,9 +61,30 @@ class DecoderStack;
 class Logic;
 class LogicSegment;
 class Segment;
+class SignalBase;
 class SignalData;
 
-class SignalBase : public QObject
+class SignalGroup : public QObject
+{
+       Q_OBJECT
+
+public:
+       SignalGroup(const QString& name);
+
+       void append_signal(shared_ptr<SignalBase> signal);
+       void remove_signal(shared_ptr<SignalBase> signal);
+       deque<shared_ptr<SignalBase>> signals() const;
+       void clear();
+
+       const QString name() const;
+
+private:
+       deque<shared_ptr<SignalBase>> signals_;
+       QString name_;
+};
+
+
+class SignalBase : public QObject, public enable_shared_from_this<SignalBase>
 {
        Q_OBJECT
 
@@ -141,6 +165,16 @@ public:
         */
        unsigned int logic_bit_index() const;
 
+       /**
+        * Sets the signal group this signal belongs to
+        */
+       void set_group(SignalGroup* group);
+
+       /**
+        * Returns the signal group this signal belongs to or nullptr if none
+        */
+       SignalGroup* group() const;
+
        /**
         * Gets the name of this signal.
         */
@@ -351,6 +385,7 @@ private Q_SLOTS:
 protected:
        shared_ptr<sigrok::Channel> channel_;
        ChannelType channel_type_;
+       SignalGroup* group_;
        shared_ptr<pv::data::SignalData> data_;
        shared_ptr<pv::data::SignalData> converted_data_;
        ConversionType conversion_type_;
index 85b6c0b4968795666cb422e2919afb892eb58fe8..9ec8bd07264036e85c052c05695749f4bccf797b 100644 (file)
@@ -105,6 +105,7 @@ using Gst::ElementFactory;
 using Gst::Pipeline;
 #endif
 
+using pv::data::SignalGroup;
 using pv::util::Timestamp;
 using pv::views::trace::Signal;
 using pv::views::trace::AnalogSignal;
@@ -131,6 +132,11 @@ Session::~Session()
 
        // Stop and join to the thread
        stop_capture();
+
+       for (SignalGroup* group : signal_groups_) {
+               group->clear();
+               delete group;
+       }
 }
 
 DeviceManager& Session::device_manager()
@@ -509,8 +515,16 @@ void Session::set_device(shared_ptr<devices::Device> device)
 #endif
                view->reset_view_state();
        }
+
+       for (SignalGroup* group : signal_groups_) {
+               group->clear();
+               delete group;
+       }
+       signal_groups_.clear();
+
        for (const shared_ptr<data::SignalData>& d : all_signal_data_)
                d->clear();
+
        all_signal_data_.clear();
        signalbases_.clear();
        cur_logic_segment_.reset();
@@ -885,17 +899,6 @@ void Session::remove_generated_signal(shared_ptr<data::SignalBase> signal)
        update_signals();
 }
 
-bool Session::all_segments_complete(uint32_t segment_id) const
-{
-       bool all_complete = true;
-
-       for (const shared_ptr<data::SignalBase>& base : signalbases_)
-               if (!base->segment_is_complete(segment_id))
-                       all_complete = false;
-
-       return all_complete;
-}
-
 #ifdef ENABLE_DECODE
 shared_ptr<data::DecodeSignal> Session::add_decode_signal()
 {
@@ -936,6 +939,17 @@ void Session::remove_decode_signal(shared_ptr<data::DecodeSignal> signal)
 }
 #endif
 
+bool Session::all_segments_complete(uint32_t segment_id) const
+{
+       bool all_complete = true;
+
+       for (const shared_ptr<data::SignalBase>& base : signalbases_)
+               if (!base->segment_is_complete(segment_id))
+                       all_complete = false;
+
+       return all_complete;
+}
+
 MetadataObjManager* Session::metadata_obj_manager()
 {
        return &metadata_obj_manager_;
@@ -1028,7 +1042,7 @@ void Session::update_signals()
                                signalbase->set_data(logic_data_);
 
                                connect(this, SIGNAL(capture_state_changed(int)),
-                                               signalbase.get(), SLOT(on_capture_state_changed(int)));
+                                       signalbase.get(), SLOT(on_capture_state_changed(int)));
                                break;
 
                        case SR_CHANNEL_ANALOG:
@@ -1040,12 +1054,34 @@ void Session::update_signals()
                                signalbase->set_data(data);
 
                                connect(this, SIGNAL(capture_state_changed(int)),
-                                               signalbase.get(), SLOT(on_capture_state_changed(int)));
+                                       signalbase.get(), SLOT(on_capture_state_changed(int)));
                                break;
                        }
                }
        }
 
+       // Create and assign default signal groups if needed
+       if (signal_groups_.empty()) {
+               for (auto& entry : sr_dev->channel_groups()) {
+                       const shared_ptr<sigrok::ChannelGroup>& group = entry.second;
+
+                       if (group->channels().size() <= 1)
+                               continue;
+
+                       SignalGroup* sg = new SignalGroup(QString::fromStdString(entry.first));
+                       for (const shared_ptr<sigrok::Channel>& channel : group->channels()) {
+                               for (shared_ptr<data::SignalBase> s : signalbases_) {
+                                       if (s->channel() == channel) {
+                                               sg->append_signal(s);
+                                               break;
+                                       }
+                               }
+                       }
+                       signal_groups_.emplace_back(sg);
+               }
+       }
+
+       // Update all views
        for (shared_ptr<views::ViewBase>& viewbase : views_) {
                vector< shared_ptr<SignalBase> > view_signalbases =
                                viewbase->signalbases();
index 77a20e3cfa106031e8f4d6f8f42d3c515a19606f..cfc69d4aa94e4fbdda0fb4d8806058a0ecaa491c 100644 (file)
@@ -25,6 +25,7 @@
 #include <condition_variable>
 #endif
 
+#include <deque>
 #include <functional>
 #include <map>
 #include <memory>
@@ -48,6 +49,7 @@
 #include "util.hpp"
 #include "views/viewbase.hpp"
 
+using std::deque;
 using std::function;
 using std::map;
 using std::mutex;
@@ -93,6 +95,7 @@ class Logic;
 class LogicSegment;
 class SignalBase;
 class SignalData;
+class SignalGroup;
 }
 
 namespace devices {
@@ -192,14 +195,14 @@ public:
        void add_generated_signal(shared_ptr<data::SignalBase> signal);
        void remove_generated_signal(shared_ptr<data::SignalBase> signal);
 
-       bool all_segments_complete(uint32_t segment_id) const;
-
 #ifdef ENABLE_DECODE
        shared_ptr<data::DecodeSignal> add_decode_signal();
 
        void remove_decode_signal(shared_ptr<data::DecodeSignal> signal);
 #endif
 
+       bool all_segments_complete(uint32_t segment_id) const;
+
        MetadataObjManager* metadata_obj_manager();
 
 private:
@@ -279,6 +282,7 @@ private:
 
        vector< shared_ptr<data::SignalBase> > signalbases_;
        unordered_set< shared_ptr<data::SignalData> > all_signal_data_;
+       deque<data::SignalGroup*> signal_groups_;
 
        /// trigger_list_ contains pairs of <segment_id, timestamp> values
        vector< std::pair<uint32_t, util::Timestamp> > trigger_list_;