Rework new segment notification mechanism
authorSoeren Apel <soeren@apelpie.net>
Sun, 29 Oct 2017 22:38:06 +0000 (23:38 +0100)
committerSoeren Apel <soeren@apelpie.net>
Sun, 29 Oct 2017 22:38:06 +0000 (23:38 +0100)
pv/session.cpp
pv/session.hpp
pv/views/trace/standardbar.cpp
pv/views/trace/standardbar.hpp
pv/views/trace/view.cpp
pv/views/trace/view.hpp
pv/views/viewbase.cpp
pv/views/viewbase.hpp

index 07ee594d7c1ca0390e5af1cef6ca6d24c2f4b22e..dd06cfed360a2bd6a45e65577d2441e30404639e 100644 (file)
@@ -681,11 +681,12 @@ int Session::get_segment_count() const
 {
        int min_val = INT_MAX;
 
+       // Find the lowest common number of segments
        for (shared_ptr<data::SignalData> data : all_signal_data_)
                if (data->get_segment_count() < min_val)
                        min_val = data->get_segment_count();
 
-       return min_val;
+       return (min_val != INT_MAX) ? min_val : 0;
 }
 
 const unordered_set< shared_ptr<data::SignalBase> > Session::signalbases() const
@@ -899,6 +900,13 @@ void Session::sample_thread_proc(function<void (const QString)> error_handler)
 
        out_of_memory_ = false;
 
+       {
+               lock_guard<recursive_mutex> lock(data_mutex_);
+               cur_logic_segment_.reset();
+               cur_analog_segments_.clear();
+       }
+       highest_segment_id_ = -1;
+
        try {
                device_->start();
        } catch (Error e) {
@@ -950,6 +958,36 @@ void Session::free_unused_memory()
        }
 }
 
+void Session::signal_new_segment()
+{
+       int new_segment_id = 1;
+
+       if ((cur_logic_segment_ != nullptr) || !cur_analog_segments_.empty()) {
+
+               // Determine new frame/segment number, assuming that all
+               // signals have the same number of frames/segments
+               if (cur_logic_segment_) {
+                       new_segment_id = logic_data_->get_segment_count();
+               } else {
+                       shared_ptr<sigrok::Channel> any_channel =
+                               (*cur_analog_segments_.begin()).first;
+
+                       shared_ptr<data::SignalBase> base = signalbase_from_channel(any_channel);
+                       assert(base);
+
+                       shared_ptr<data::Analog> data(base->analog_data());
+                       assert(data);
+
+                       new_segment_id = data->get_segment_count();
+               }
+       }
+
+       if (new_segment_id > highest_segment_id_) {
+               highest_segment_id_ = new_segment_id;
+               new_segment(highest_segment_id_);
+       }
+}
+
 void Session::feed_in_header()
 {
        // Nothing to do here for now
@@ -1002,9 +1040,6 @@ void Session::feed_in_trigger()
 void Session::feed_in_frame_begin()
 {
        frame_began_ = true;
-
-       if (cur_logic_segment_ || !cur_analog_segments_.empty())
-               frame_began();
 }
 
 void Session::feed_in_frame_end()
@@ -1015,10 +1050,8 @@ void Session::feed_in_frame_end()
                cur_analog_segments_.clear();
        }
 
-       if (frame_began_) {
+       if (frame_began_)
                frame_began_ = false;
-               frame_ended();
-       }
 }
 
 void Session::feed_in_logic(shared_ptr<Logic> logic)
@@ -1044,11 +1077,7 @@ void Session::feed_in_logic(shared_ptr<Logic> logic)
                        *logic_data_, logic->unit_size(), cur_samplerate_);
                logic_data_->push_segment(cur_logic_segment_);
 
-               // @todo Putting this here means that only listeners querying
-               // for logic will be notified. Currently the only user of
-               // frame_began is DecoderStack, but in future we need to signal
-               // this after both analog and logic sweeps have begun.
-               frame_began();
+               signal_new_segment();
        }
 
        cur_logic_segment_->append_payload(logic);
@@ -1103,6 +1132,8 @@ void Session::feed_in_analog(shared_ptr<Analog> analog)
 
                        // Push the segment into the analog data.
                        data->push_segment(segment);
+
+                       signal_new_segment();
                }
 
                assert(segment);
index dcb4ad1db96cd55cc06f133838acf1ea42c187b3..1cb370a9eff216b2b4a541428e6d1c9b86bfc027 100644 (file)
@@ -196,6 +196,8 @@ private:
 
        void free_unused_memory();
 
+       void signal_new_segment();
+
        void feed_in_header();
 
        void feed_in_meta(shared_ptr<sigrok::Meta> meta);
@@ -234,6 +236,7 @@ private:
        shared_ptr<data::LogicSegment> cur_logic_segment_;
        map< shared_ptr<sigrok::Channel>, shared_ptr<data::AnalogSegment> >
                cur_analog_segments_;
+       int32_t highest_segment_id_;
 
        std::thread sampling_thread_;
 
@@ -251,12 +254,10 @@ Q_SIGNALS:
 
        void trigger_event(util::Timestamp location);
 
-       void frame_began();
+       void new_segment(int new_frame_id);
 
        void data_received();
 
-       void frame_ended();
-
        void add_view(const QString &title, views::ViewType type,
                Session *session);
 
index e2d6f3e2b540c7d201208329f6a3958b6ec7b29d..d773a5c1367df44113d9392ef8e44a2e4a53a38a 100644 (file)
@@ -87,8 +87,8 @@ StandardBar::StandardBar(Session &session, QWidget *parent,
 
        segment_selector_->setMinimum(1);
        segment_selector_->hide();
-       connect(&session_, SIGNAL(frame_ended()),
-               this, SLOT(on_segment_added()));
+       connect(&session_, SIGNAL(new_segment(int)),
+               this, SLOT(on_new_segment(int)));
        connect(segment_selector_, SIGNAL(valueChanged(int)),
                view_, SLOT(on_segment_changed(int)));
 
@@ -186,13 +186,11 @@ void StandardBar::on_always_zoom_to_fit_changed(bool state)
        action_view_zoom_fit_->setChecked(state);
 }
 
-void StandardBar::on_segment_added()
+void StandardBar::on_new_segment(int new_segment_id)
 {
-       const int segment_count = session_.get_segment_count();
-
-       if (segment_count > 1) {
+       if (new_segment_id > 1) {
                show_multi_segment_ui(true);
-               segment_selector_->setMaximum(segment_count);
+               segment_selector_->setMaximum(new_segment_id);
        } else
                show_multi_segment_ui(false);
 }
index 94a6d81b3e3f9f0ac47c219bd9efea0cbd82d580..8640b4c9520ae01b0f41a2721a8cd4da8261a13a 100644 (file)
@@ -88,7 +88,7 @@ protected Q_SLOTS:
 
        void on_always_zoom_to_fit_changed(bool state);
 
-       void on_segment_added();
+       void on_new_segment(int new_segment_id);
 
 private:
        vector<QAction*> multi_segment_actions_;
index 29c6fef4ee4f1ec3bb24742e46865ef8806eca1c..07919c28ac937d13b4767f5ccea297e2df5543df 100644 (file)
@@ -1383,6 +1383,11 @@ void View::capture_state_updated(int state)
        }
 }
 
+void View::on_new_segment(int new_segment_id)
+{
+       on_segment_changed(new_segment_id);
+}
+
 void View::on_segment_changed(int segment)
 {
        current_segment_ = segment - 1;
index b6759a4ffbc64ac911ebfc75fe0812a422c73e8f..8fd7e968552f6af0528e3697e16f8eca2a5fb11e 100644 (file)
@@ -366,6 +366,7 @@ private Q_SLOTS:
        void signals_changed();
        void capture_state_updated(int state);
 
+       void on_new_segment(int new_segment_id);
        void on_segment_changed(int segment);
 
        virtual void perform_delayed_view_update();
index 4031211fcbec6e1641a76bd40312fd98dd340a3d..30fd7cec7a59fddcf80ae729614cbe4f67161a9d 100644 (file)
@@ -44,6 +44,8 @@ ViewBase::ViewBase(Session &session, bool is_main_view, QWidget *parent) :
                this, SLOT(signals_changed()));
        connect(&session_, SIGNAL(capture_state_changed(int)),
                this, SLOT(capture_state_updated(int)));
+       connect(&session_, SIGNAL(new_segment(int)),
+               this, SLOT(on_new_segment(int)));
 
        connect(&delayed_view_updater_, SIGNAL(timeout()),
                this, SLOT(perform_delayed_view_update()));
@@ -127,6 +129,11 @@ void ViewBase::signals_changed()
 {
 }
 
+void ViewBase::on_new_segment(int new_segment_id)
+{
+       (void)new_segment_id;
+}
+
 void ViewBase::capture_state_updated(int state)
 {
        (void)state;
index e6a003a596c7ddda4b03226af3b759f21e4aa75f..fdf12a8693d20505d417346b74587dc6d2e43995 100644 (file)
@@ -95,6 +95,7 @@ public Q_SLOTS:
        virtual void trigger_event(util::Timestamp location);
        virtual void signals_changed();
        virtual void capture_state_updated(int state);
+       virtual void on_new_segment(int new_segment_id);
        virtual void perform_delayed_view_update();
 
 private Q_SLOTS: