Move delayed conversion starter to SignalBase
authorSoeren Apel <soeren@apelpie.net>
Wed, 2 Aug 2017 07:15:18 +0000 (09:15 +0200)
committerUwe Hermann <uwe@hermann-uwe.de>
Thu, 3 Aug 2017 11:16:21 +0000 (13:16 +0200)
This way, we can use the same mechanism for changing
min/max as well, preventing multiple successive starts
of the conversion algorithm.
Preventing this is necessary because it makes the UI
stop updating for a significant amount of time, which
we obviously don't want.

pv/data/signalbase.cpp
pv/data/signalbase.hpp
pv/views/trace/analogsignal.cpp
pv/views/trace/analogsignal.hpp

index fe7c584b62b4eab7c58e2383b77989f0bd0194da..da05f1079597bb2e708d587bb9f3789594baeb82 100644 (file)
@@ -40,6 +40,7 @@ namespace data {
 
 const int SignalBase::ColourBGAlpha = 8 * 256 / 100;
 const uint64_t SignalBase::ConversionBlockSize = 4096;
+const uint32_t SignalBase::ConversionDelay = 1000;  // 1 second
 
 SignalBase::SignalBase(shared_ptr<sigrok::Channel> channel, ChannelType channel_type) :
        channel_(channel),
@@ -50,6 +51,11 @@ SignalBase::SignalBase(shared_ptr<sigrok::Channel> channel, ChannelType channel_
 {
        if (channel_)
                internal_name_ = QString::fromStdString(channel_->name());
+
+       connect(&delayed_conversion_starter_, SIGNAL(timeout()),
+               this, SLOT(on_delayed_conversion_start()));
+       delayed_conversion_starter_.setSingleShot(true);
+       delayed_conversion_starter_.setInterval(ConversionDelay);
 }
 
 SignalBase::~SignalBase()
@@ -522,8 +528,13 @@ void SignalBase::conversion_thread_proc(QObject* segment)
        } while (!conversion_interrupt_);
 }
 
-void SignalBase::start_conversion()
+void SignalBase::start_conversion(bool delayed_start)
 {
+       if (delayed_start) {
+               delayed_conversion_starter_.start();
+               return;
+       }
+
        stop_conversion();
 
        if (converted_data_)
@@ -568,8 +579,9 @@ void SignalBase::on_samples_added(QObject* segment, uint64_t start_sample,
                        // Notify the conversion thread since it's running
                        conversion_input_cond_.notify_one();
                } else {
-                       // Start the conversion thread
-                       start_conversion();
+                       // Start the conversion thread unless the delay timer is running
+                       if (!delayed_conversion_starter_.isActive())
+                               start_conversion();
                }
        }
 
@@ -584,7 +596,7 @@ void SignalBase::on_min_max_changed(float min, float max)
        // Restart conversion if one is enabled and uses a calculated threshold
        if ((conversion_type_ != NoConversion) &&
                (get_current_conversion_preset() == DynamicPreset))
-               start_conversion();
+               start_conversion(true);
 }
 
 void SignalBase::on_capture_state_changed(int state)
@@ -596,5 +608,10 @@ void SignalBase::on_capture_state_changed(int state)
        }
 }
 
+void SignalBase::on_delayed_conversion_start()
+{
+       start_conversion();
+}
+
 } // namespace data
 } // namespace pv
index fd7c38f5ea627d768830170db4768d46ad81fd69..16a94bd43b816ce47ac6c7ca067b0611ea19bb93 100644 (file)
@@ -30,6 +30,7 @@
 #include <QObject>
 #include <QSettings>
 #include <QString>
+#include <QTimer>
 #include <QVariant>
 
 #include <libsigrokcxx/libsigrokcxx.hpp>
@@ -85,6 +86,7 @@ public:
 private:
        static const int ColourBGAlpha;
        static const uint64_t ConversionBlockSize;
+       static const uint32_t ConversionDelay;
 
 public:
        SignalBase(shared_ptr<sigrok::Channel> channel, ChannelType channel_type);
@@ -255,7 +257,7 @@ public:
 
        virtual void restore_settings(QSettings &settings);
 
-       void start_conversion();
+       void start_conversion(bool delayed_start=false);
 
 private:
        bool conversion_is_a2l() const;
@@ -292,6 +294,8 @@ private Q_SLOTS:
 
        void on_capture_state_changed(int state);
 
+       void on_delayed_conversion_start();
+
 protected:
        shared_ptr<sigrok::Channel> channel_;
        ChannelType channel_type_;
@@ -306,6 +310,7 @@ protected:
        atomic<bool> conversion_interrupt_;
        mutex conversion_input_mutex_;
        condition_variable conversion_input_cond_;
+       QTimer delayed_conversion_starter_;
 
        QString internal_name_, name_;
        QColor colour_, bgcolour_;
index 2ea5ffc55f92dbcdcc56dbe75271b903fe9a5f66..81dd551b91d33b3913ccb53cb7c81b9e2ba12d56 100644 (file)
@@ -108,11 +108,6 @@ AnalogSignal::AnalogSignal(
        connect(analog_data, SIGNAL(samples_added(QObject*, uint64_t, uint64_t)),
                this, SLOT(on_samples_added()));
 
-       connect(&delayed_conversion_starter_, SIGNAL(timeout()),
-               this, SLOT(on_delayed_conversion_starter()));
-       delayed_conversion_starter_.setSingleShot(true);
-       delayed_conversion_starter_.setInterval(1000);  // 1s timeout
-
        GlobalSettings gs;
        div_height_ = gs.value(GlobalSettings::Key_View_DefaultDivHeight).toInt();
 
@@ -1017,9 +1012,11 @@ void AnalogSignal::on_conv_threshold_changed(int index)
                // For now, we simply assume that the unit is volt without modifiers
                const double thr = tokens.at(1).toDouble();
 
-               // Only restart the conversion if the threshold was updated
+               // Only restart the conversion if the threshold was updated.
+               // We're starting a delayed conversion because the user may still be
+               // typing and the UI would lag if we kept on restarting it immediately
                if (base_->set_conversion_option("threshold_value", thr))
-                       delayed_conversion_starter_.start();
+                       base_->start_conversion(true);
        }
 
        if (conv_type == SignalBase::A2LConversionBySchmittTrigger && use_custom_thr) {
@@ -1043,17 +1040,20 @@ void AnalogSignal::on_conv_threshold_changed(int index)
                const double low_thr = tokens.at(1).toDouble();
                const double high_thr = tokens.at(3).toDouble();
 
-               // Only restart the conversion if one of the options was updated
+               // Only restart the conversion if one of the options was updated.
+               // We're starting a delayed conversion because the user may still be
+               // typing and the UI would lag if we kept on restarting it immediately
                bool o1 = base_->set_conversion_option("threshold_value_low", low_thr);
                bool o2 = base_->set_conversion_option("threshold_value_high", high_thr);
                if (o1 || o2)
-                       delayed_conversion_starter_.start();
+                       base_->start_conversion(true);  // Start delayed conversion
        }
 
        base_->set_conversion_preset((SignalBase::ConversionPreset)index);
 
-       // Immediately start the conversion if we're not asking for a delayed reaction
-       if (!delayed_conversion_starter_.isActive())
+       // Immediately start the conversion if we're not using custom values
+       // (i.e. we're using one of the presets)
+       if (!use_custom_thr)
                base_->start_conversion();
 }
 
index 3b352f932e7a0c0808d18ff7f4cb48bf30d98f17..24d4a21cacb6dae92aba8a37d85fb39f028ce86f 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <QComboBox>
 #include <QSpinBox>
-#include <QTimer>
 
 using std::pair;
 using std::shared_ptr;
@@ -178,8 +177,6 @@ private:
                *display_type_cb_;
        QSpinBox *pvdiv_sb_, *nvdiv_sb_, *div_height_sb_;
 
-       QTimer delayed_conversion_starter_;
-
        float scale_;
        int scale_index_;
        int scale_index_drag_offset_;