]> sigrok.org Git - pulseview.git/commitdiff
Implement decode pausing/resuming
authorSoeren Apel <redacted>
Wed, 22 Aug 2018 07:33:48 +0000 (09:33 +0200)
committerSoeren Apel <redacted>
Wed, 22 Aug 2018 19:28:10 +0000 (21:28 +0200)
icons/media-playback-pause.png [new file with mode: 0644]
icons/media-playback-start.png [new file with mode: 0644]
pv/data/decodesignal.cpp
pv/data/decodesignal.hpp
pv/views/trace/decodetrace.cpp
pv/views/trace/decodetrace.hpp

diff --git a/icons/media-playback-pause.png b/icons/media-playback-pause.png
new file mode 100644 (file)
index 0000000..ee40fc2
Binary files /dev/null and b/icons/media-playback-pause.png differ
diff --git a/icons/media-playback-start.png b/icons/media-playback-start.png
new file mode 100644 (file)
index 0000000..10102d8
Binary files /dev/null and b/icons/media-playback-start.png differ
index 05dc3428ab5ce8e9f2bcb964175b55fceb3557d2..4705b104542cef6c9875d8fa7e1922b6b6cae0c8 100644 (file)
@@ -151,6 +151,9 @@ void DecodeSignal::reset_decode(bool shutting_down)
                logic_mux_thread_.join();
        }
 
+       decode_pause_mutex_.unlock();
+       decode_paused_ = false;
+
        class_rows_.clear();
        current_segment_id_ = 0;
        segments_.clear();
@@ -258,6 +261,25 @@ void DecodeSignal::begin_decode()
        decode_thread_ = std::thread(&DecodeSignal::decode_proc, this);
 }
 
+void DecodeSignal::pause_decode()
+{
+       decode_paused_ = true;
+}
+
+void DecodeSignal::resume_decode()
+{
+       // Manual unlocking is done before notifying, to avoid waking up the
+       // waiting thread only to block again (see notify_one for details)
+       decode_pause_mutex_.unlock();
+       decode_pause_cond_.notify_one();
+       decode_paused_ = false;
+}
+
+bool DecodeSignal::is_paused() const
+{
+       return decode_paused_;
+}
+
 QString DecodeSignal::error_message() const
 {
        lock_guard<mutex> lock(output_mutex_);
@@ -981,6 +1003,11 @@ void DecodeSignal::decode_data(
                // Notify the frontend that we processed some data and
                // possibly have new annotations as well
                new_annotations();
+
+               if (decode_paused_) {
+                       unique_lock<mutex> pause_wait_lock(decode_pause_mutex_);
+                       decode_pause_cond_.wait(pause_wait_lock);
+               }
        }
 }
 
index f00a9f1cabaefc35de74ea66ede5544f15d99a56..ba9c9b5e4ecaa8021b712446e487ede10a54eb6b 100644 (file)
@@ -101,6 +101,9 @@ public:
 
        void reset_decode(bool shutting_down = false);
        void begin_decode();
+       void pause_decode();
+       void resume_decode();
+       bool is_paused() const;
        QString error_message() const;
 
        const vector<data::DecodeChannel> get_channels() const;
@@ -215,12 +218,15 @@ private:
        vector<DecodeSegment> segments_;
        uint32_t current_segment_id_;
 
-       mutable mutex input_mutex_, output_mutex_, logic_mux_mutex_;
-       mutable condition_variable decode_input_cond_, logic_mux_cond_;
+       mutable mutex input_mutex_, output_mutex_, decode_pause_mutex_, logic_mux_mutex_;
+       mutable condition_variable decode_input_cond_, decode_pause_cond_,
+               logic_mux_cond_;
 
        std::thread decode_thread_, logic_mux_thread_;
        atomic<bool> decode_interrupt_, logic_mux_interrupt_;
 
+       bool decode_paused_;
+
        QString error_message_;
 };
 
index 651b8c3d77b27f7797d66285896ab56da69f9959..574e9d1ae96b8891689c402548182cceae2b869d 100644 (file)
@@ -341,15 +341,33 @@ QMenu* DecodeTrace::create_view_context_menu(QWidget *parent, QPoint &click_pos)
 
        QMenu *const menu = new QMenu(parent);
 
+       if (decode_signal_->is_paused()) {
+               QAction *const resume =
+                       new QAction(tr("Resume decoding"), this);
+               resume->setIcon(QIcon::fromTheme("media-playback-start",
+                       QIcon(":/icons/media-playback-start.png")));
+               connect(resume, SIGNAL(triggered()), this, SLOT(on_pause_decode()));
+               menu->addAction(resume);
+       } else {
+               QAction *const pause =
+                       new QAction(tr("Pause decoding"), this);
+               pause->setIcon(QIcon::fromTheme("media-playback-pause",
+                       QIcon(":/icons/media-playback-pause.png")));
+               connect(pause, SIGNAL(triggered()), this, SLOT(on_pause_decode()));
+               menu->addAction(pause);
+       }
+
+       menu->addSeparator();
+
        QAction *const export_all_rows =
-                       new QAction(tr("Export all annotations"), this);
+               new QAction(tr("Export all annotations"), this);
        export_all_rows->setIcon(QIcon::fromTheme("document-save-as",
                QIcon(":/icons/document-save-as.png")));
        connect(export_all_rows, SIGNAL(triggered()), this, SLOT(on_export_all_rows()));
        menu->addAction(export_all_rows);
 
        QAction *const export_row =
-                       new QAction(tr("Export all annotations for this row"), this);
+               new QAction(tr("Export all annotations for this row"), this);
        export_row->setIcon(QIcon::fromTheme("document-save-as",
                QIcon(":/icons/document-save-as.png")));
        connect(export_row, SIGNAL(triggered()), this, SLOT(on_export_row()));
@@ -1037,6 +1055,14 @@ void DecodeTrace::on_decode_finished()
                owner_->row_item_appearance_changed(false, true);
 }
 
+void DecodeTrace::on_pause_decode()
+{
+       if (decode_signal_->is_paused())
+               decode_signal_->resume_decode();
+       else
+               decode_signal_->pause_decode();
+}
+
 void DecodeTrace::delete_pressed()
 {
        on_delete();
index 9372f7af138f9e37b82a4f4b9880fda4063ff339..57e462203f1fc60ca9a8c01da58414185021e466 100644 (file)
@@ -187,6 +187,7 @@ private Q_SLOTS:
        void on_delayed_trace_update();
        void on_decode_reset();
        void on_decode_finished();
+       void on_pause_decode();
 
        void on_delete();