]> sigrok.org Git - pulseview.git/commitdiff
Provide notifiers for when signal data changes
authorSoeren Apel <redacted>
Mon, 13 Feb 2017 22:26:31 +0000 (23:26 +0100)
committerUwe Hermann <redacted>
Wed, 15 Feb 2017 11:12:51 +0000 (12:12 +0100)
CMakeLists.txt
pv/data/analog.cpp
pv/data/analog.hpp
pv/data/analogsegment.cpp
pv/data/analogsegment.hpp
pv/data/logic.cpp
pv/data/logic.hpp
pv/data/logicsegment.cpp
pv/data/logicsegment.hpp
pv/session.cpp

index 9d35376bbfcd2d9dff1773e306d51bfd0d105ce1..3ae7e7d27711410d9f727661f10689f51def53f7 100644 (file)
@@ -287,6 +287,10 @@ set(pulseview_HEADERS
        pv/session.hpp
        pv/storesession.hpp
        pv/binding/device.hpp
+       pv/data/analog.hpp
+       pv/data/analogsegment.hpp
+       pv/data/logic.hpp
+       pv/data/logicsegment.hpp
        pv/data/signalbase.hpp
        pv/dialogs/about.hpp
        pv/dialogs/connect.hpp
index 217cdfd742b3e4c84557f87178aee195ba82d5f4..1a2449891d9d8b86922c6b6efb6350d8b14db70d 100644 (file)
@@ -54,6 +54,8 @@ vector< shared_ptr<Segment> > Analog::segments() const
 void Analog::clear()
 {
        segments_.clear();
+
+       samples_cleared();
 }
 
 uint64_t Analog::max_sample_count() const
@@ -66,5 +68,11 @@ uint64_t Analog::max_sample_count() const
        return l;
 }
 
+void Analog::notify_samples_added(QObject* segment, uint64_t start_sample,
+       uint64_t end_sample)
+{
+       samples_added(segment, start_sample, end_sample);
+}
+
 } // namespace data
 } // namespace pv
index 6634728a78e45e6c7ab73fe3661ccf1a80e65f71..6fd01e035208b0374bf44dfe59e7e1fc57646619 100644 (file)
 #include <deque>
 #include <memory>
 
+#include <QObject>
+
 namespace pv {
 namespace data {
 
 class AnalogSegment;
 
-class Analog : public SignalData
+class Analog : public QObject, public SignalData
 {
+       Q_OBJECT
+
 public:
        Analog();
 
@@ -47,6 +51,15 @@ public:
 
        uint64_t max_sample_count() const;
 
+       void notify_samples_added(QObject* segment, uint64_t start_sample,
+               uint64_t end_sample);
+
+Q_SIGNALS:
+       void samples_cleared();
+
+       void samples_added(QObject* segment, uint64_t start_sample,
+               uint64_t end_sample);
+
 private:
        std::deque< std::shared_ptr<AnalogSegment> > segments_;
 };
index 886bd4f58f9a531d5aff113e692352fa7460f742..cfc0f2bb60a9498d9561f10c27b5e22ae84ee896 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <algorithm>
 
+#include "analog.hpp"
 #include "analogsegment.hpp"
 
 using std::lock_guard;
@@ -44,8 +45,9 @@ const float AnalogSegment::LogEnvelopeScaleFactor =
        logf(EnvelopeScaleFactor);
 const uint64_t AnalogSegment::EnvelopeDataUnit = 64*1024;      // bytes
 
-AnalogSegment::AnalogSegment(uint64_t samplerate) :
+AnalogSegment::AnalogSegment(Analog& owner, uint64_t samplerate) :
        Segment(samplerate, sizeof(float)),
+       owner_(owner),
        min_value_(0),
        max_value_(0)
 {
@@ -67,6 +69,8 @@ void AnalogSegment::append_interleaved_samples(const float *data,
 
        lock_guard<recursive_mutex> lock(mutex_);
 
+       uint64_t prev_sample_count = sample_count_;
+
        for (uint32_t i=0; i < sample_count; i++) {
                append_single_sample((void*)data);
                data += stride;
@@ -74,6 +78,13 @@ void AnalogSegment::append_interleaved_samples(const float *data,
 
        // Generate the first mip-map from the data
        append_payload_to_envelope_levels();
+
+       if (sample_count > 1)
+               owner_.notify_samples_added(this, prev_sample_count + 1,
+                       prev_sample_count + 1 + sample_count);
+       else
+               owner_.notify_samples_added(this, prev_sample_count + 1,
+                       prev_sample_count + 1);
 }
 
 const float* AnalogSegment::get_samples(
index 09ae2c0203dfa65d4c36c8a791754e9379e7804b..e6c312ade78d3b7157b43cc2f9584ba283381edb 100644 (file)
@@ -25,6 +25,8 @@
 #include <utility>
 #include <vector>
 
+#include <QObject>
+
 namespace AnalogSegmentTest {
 struct Basic;
 }
@@ -32,14 +34,18 @@ struct Basic;
 namespace pv {
 namespace data {
 
+class Analog;
+
 typedef struct {
        uint64_t sample_index, chunk_num, chunk_offs;
        uint8_t* chunk;
        float* value;
 } SegmentAnalogDataIterator;
 
-class AnalogSegment : public Segment
+class AnalogSegment : public QObject, public Segment
 {
+       Q_OBJECT
+
 public:
        struct EnvelopeSample
        {
@@ -71,7 +77,7 @@ private:
        static const uint64_t EnvelopeDataUnit;
 
 public:
-       AnalogSegment(uint64_t samplerate);
+       AnalogSegment(Analog& owner, uint64_t samplerate);
 
        virtual ~AnalogSegment();
 
@@ -96,6 +102,8 @@ private:
        void append_payload_to_envelope_levels();
 
 private:
+       Analog& owner_;
+
        struct Envelope envelope_levels_[ScaleStepCount];
 
        float min_value_, max_value_;
index 9ba8f2c3d6e1a70ed761f88ea57d27dfff9d38a8..cd80ac99de13ca54384e9a7013239d68076f7823 100644 (file)
@@ -62,6 +62,8 @@ vector< shared_ptr<Segment> > Logic::segments() const
 void Logic::clear()
 {
        segments_.clear();
+
+       samples_cleared();
 }
 
 uint64_t Logic::max_sample_count() const
@@ -74,5 +76,11 @@ uint64_t Logic::max_sample_count() const
        return l;
 }
 
+void Logic::notify_samples_added(QObject* segment, uint64_t start_sample,
+       uint64_t end_sample)
+{
+       samples_added(segment, start_sample, end_sample);
+}
+
 } // namespace data
 } // namespace pv
index 6e5749a31ee86daac20bf38f2b963a66ed69ebb3..e7f7a055da3db150f12f8365edf16af3b7aec59c 100644 (file)
 
 #include <deque>
 
+#include <QObject>
+
 namespace pv {
 namespace data {
 
 class LogicSegment;
 
-class Logic : public SignalData
+class Logic : public QObject, public SignalData
 {
+       Q_OBJECT
+
 public:
        Logic(unsigned int num_channels);
 
@@ -48,6 +52,15 @@ public:
 
        uint64_t max_sample_count() const;
 
+       void notify_samples_added(QObject* segment, uint64_t start_sample,
+               uint64_t end_sample);
+
+Q_SIGNALS:
+       void samples_cleared();
+
+       void samples_added(QObject* segment, uint64_t start_sample,
+               uint64_t end_sample);
+
 private:
        const unsigned int num_channels_;
        std::deque< std::shared_ptr<LogicSegment> > segments_;
index a62d9e2f4dae7bca74e79d5f6ca04a3a6a7f87b0..ddcf308d141be35b5f4e65db3dfe84aa4800f972 100644 (file)
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <cmath>
 
+#include "logic.hpp"
 #include "logicsegment.hpp"
 
 #include <libsigrokcxx/libsigrokcxx.hpp>
@@ -45,13 +46,15 @@ const int LogicSegment::MipMapScaleFactor = 1 << MipMapScalePower;
 const float LogicSegment::LogMipMapScaleFactor = logf(MipMapScaleFactor);
 const uint64_t LogicSegment::MipMapDataUnit = 64*1024; // bytes
 
-LogicSegment::LogicSegment(shared_ptr<Logic> logic, uint64_t samplerate) :
-       Segment(samplerate, logic->unit_size()),
+LogicSegment::LogicSegment(pv::data::Logic& owner, shared_ptr<sigrok::Logic> data,
+       uint64_t samplerate) :
+       Segment(samplerate, data->unit_size()),
+       owner_(owner),
        last_append_sample_(0)
 {
        lock_guard<recursive_mutex> lock(mutex_);
        memset(mip_map_, 0, sizeof(mip_map_));
-       append_payload(logic);
+       append_payload(data);
 }
 
 LogicSegment::~LogicSegment()
@@ -135,18 +138,27 @@ void LogicSegment::pack_sample(uint8_t *ptr, uint64_t value)
 #endif
 }
 
-void LogicSegment::append_payload(shared_ptr<Logic> logic)
+void LogicSegment::append_payload(shared_ptr<sigrok::Logic> logic)
 {
        assert(unit_size_ == logic->unit_size());
        assert((logic->data_length() % unit_size_) == 0);
 
        lock_guard<recursive_mutex> lock(mutex_);
 
-       append_samples(logic->data_pointer(),
-               logic->data_length() / unit_size_);
+       uint64_t prev_sample_count = sample_count_;
+       uint64_t sample_count = logic->data_length() / unit_size_;
+
+       append_samples(logic->data_pointer(), sample_count);
 
        // Generate the first mip-map from the data
        append_payload_to_mipmap();
+
+       if (sample_count > 1)
+               owner_.notify_samples_added(this, prev_sample_count + 1,
+                       prev_sample_count + 1 + sample_count);
+       else
+               owner_.notify_samples_added(this, prev_sample_count + 1,
+                       prev_sample_count + 1);
 }
 
 const uint8_t* LogicSegment::get_samples(int64_t start_sample,
index 43fd41126617bd0b9d76dbc0f8bbf7875c5569bd..a7a38ebefa7761a7929073272d5e7dcabf1b0361 100644 (file)
@@ -25,6 +25,8 @@
 #include <utility>
 #include <vector>
 
+#include <QObject>
+
 namespace sigrok {
        class Logic;
 }
@@ -40,14 +42,18 @@ struct LongPulses;
 namespace pv {
 namespace data {
 
+class Logic;
+
 typedef struct {
        uint64_t sample_index, chunk_num, chunk_offs;
        uint8_t* chunk;
        uint8_t* value;
 } SegmentLogicDataIterator;
 
-class LogicSegment : public Segment
+class LogicSegment : public QObject, public Segment
 {
+       Q_OBJECT
+
 private:
        struct MipMapLevel
        {
@@ -67,7 +73,7 @@ public:
        typedef std::pair<int64_t, bool> EdgePair;
 
 public:
-       LogicSegment(std::shared_ptr<sigrok::Logic> logic, uint64_t samplerate);
+       LogicSegment(pv::data::Logic& owner, std::shared_ptr<sigrok::Logic> data, uint64_t samplerate);
 
        virtual ~LogicSegment();
 
@@ -110,6 +116,8 @@ private:
        static uint64_t pow2_ceil(uint64_t x, unsigned int power);
 
 private:
+       Logic& owner_;
+
        struct MipMapLevel mip_map_[ScaleStepCount];
        uint64_t last_append_sample_;
 
index df09ff3b2ebc0b924a9158158de9a2362ab385db..c464942893c271a16c637a4df1c5aac982d9cd9c 100644 (file)
@@ -954,7 +954,7 @@ void Session::feed_in_logic(shared_ptr<Logic> logic)
 
                // Create a new data segment
                cur_logic_segment_ = shared_ptr<data::LogicSegment>(
-                       new data::LogicSegment(logic, cur_samplerate_));
+                       new data::LogicSegment(*logic_data_, logic, cur_samplerate_));
                logic_data_->push_segment(cur_logic_segment_);
 
                // @todo Putting this here means that only listeners querying
@@ -997,11 +997,6 @@ void Session::feed_in_analog(shared_ptr<Analog> analog)
                        // in the sweep containing this segment.
                        sweep_beginning = true;
 
-                       // Create a segment, keep it in the maps of channels
-                       segment = shared_ptr<data::AnalogSegment>(
-                               new data::AnalogSegment(cur_samplerate_));
-                       cur_analog_segments_[channel] = segment;
-
                        // Find the analog data associated with the channel
                        shared_ptr<data::SignalBase> base = signalbase_from_channel(channel);
                        assert(base);
@@ -1009,6 +1004,11 @@ void Session::feed_in_analog(shared_ptr<Analog> analog)
                        shared_ptr<data::Analog> data(base->analog_data());
                        assert(data);
 
+                       // Create a segment, keep it in the maps of channels
+                       segment = shared_ptr<data::AnalogSegment>(
+                               new data::AnalogSegment(*data, cur_samplerate_));
+                       cur_analog_segments_[channel] = segment;
+
                        // Push the segment into the analog data.
                        data->push_segment(segment);
                }