From: Soeren Apel Date: Mon, 13 Feb 2017 22:26:31 +0000 (+0100) Subject: Provide notifiers for when signal data changes X-Git-Tag: pulseview-0.4.0~191 X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=7db61e770abd2d1c7eb326a09e35cd4266664c1d Provide notifiers for when signal data changes --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d35376b..3ae7e7d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/pv/data/analog.cpp b/pv/data/analog.cpp index 217cdfd7..1a244989 100644 --- a/pv/data/analog.cpp +++ b/pv/data/analog.cpp @@ -54,6 +54,8 @@ vector< shared_ptr > 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 diff --git a/pv/data/analog.hpp b/pv/data/analog.hpp index 6634728a..6fd01e03 100644 --- a/pv/data/analog.hpp +++ b/pv/data/analog.hpp @@ -25,13 +25,17 @@ #include #include +#include + 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 > segments_; }; diff --git a/pv/data/analogsegment.cpp b/pv/data/analogsegment.cpp index 886bd4f5..cfc0f2bb 100644 --- a/pv/data/analogsegment.cpp +++ b/pv/data/analogsegment.cpp @@ -26,6 +26,7 @@ #include +#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 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( diff --git a/pv/data/analogsegment.hpp b/pv/data/analogsegment.hpp index 09ae2c02..e6c312ad 100644 --- a/pv/data/analogsegment.hpp +++ b/pv/data/analogsegment.hpp @@ -25,6 +25,8 @@ #include #include +#include + 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_; diff --git a/pv/data/logic.cpp b/pv/data/logic.cpp index 9ba8f2c3..cd80ac99 100644 --- a/pv/data/logic.cpp +++ b/pv/data/logic.cpp @@ -62,6 +62,8 @@ vector< shared_ptr > 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 diff --git a/pv/data/logic.hpp b/pv/data/logic.hpp index 6e5749a3..e7f7a055 100644 --- a/pv/data/logic.hpp +++ b/pv/data/logic.hpp @@ -24,13 +24,17 @@ #include +#include + 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 > segments_; diff --git a/pv/data/logicsegment.cpp b/pv/data/logicsegment.cpp index a62d9e2f..ddcf308d 100644 --- a/pv/data/logicsegment.cpp +++ b/pv/data/logicsegment.cpp @@ -24,6 +24,7 @@ #include #include +#include "logic.hpp" #include "logicsegment.hpp" #include @@ -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, uint64_t samplerate) : - Segment(samplerate, logic->unit_size()), +LogicSegment::LogicSegment(pv::data::Logic& owner, shared_ptr data, + uint64_t samplerate) : + Segment(samplerate, data->unit_size()), + owner_(owner), last_append_sample_(0) { lock_guard 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) +void LogicSegment::append_payload(shared_ptr logic) { assert(unit_size_ == logic->unit_size()); assert((logic->data_length() % unit_size_) == 0); lock_guard 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, diff --git a/pv/data/logicsegment.hpp b/pv/data/logicsegment.hpp index 43fd4112..a7a38ebe 100644 --- a/pv/data/logicsegment.hpp +++ b/pv/data/logicsegment.hpp @@ -25,6 +25,8 @@ #include #include +#include + 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 EdgePair; public: - LogicSegment(std::shared_ptr logic, uint64_t samplerate); + LogicSegment(pv::data::Logic& owner, std::shared_ptr 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_; diff --git a/pv/session.cpp b/pv/session.cpp index df09ff3b..c4649428 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -954,7 +954,7 @@ void Session::feed_in_logic(shared_ptr logic) // Create a new data segment cur_logic_segment_ = shared_ptr( - 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) // in the sweep containing this segment. sweep_beginning = true; - // Create a segment, keep it in the maps of channels - segment = shared_ptr( - new data::AnalogSegment(cur_samplerate_)); - cur_analog_segments_[channel] = segment; - // Find the analog data associated with the channel shared_ptr base = signalbase_from_channel(channel); assert(base); @@ -1009,6 +1004,11 @@ void Session::feed_in_analog(shared_ptr analog) shared_ptr data(base->analog_data()); assert(data); + // Create a segment, keep it in the maps of channels + segment = shared_ptr( + new data::AnalogSegment(*data, cur_samplerate_)); + cur_analog_segments_[channel] = segment; + // Push the segment into the analog data. data->push_segment(segment); }