]> sigrok.org Git - pulseview.git/commitdiff
Rework the callback mechanism for the global settings
authorSoeren Apel <redacted>
Sun, 21 Jan 2018 13:28:27 +0000 (14:28 +0100)
committerSoeren Apel <redacted>
Wed, 7 Feb 2018 18:41:56 +0000 (19:41 +0100)
Up to now, registered callbacks could not be unregistered
because std::function does not permit comparing for equality.

Using an interface class removes the need for std::function,
making the mechanism a little less elegant but at least fully
functional.

pv/globalsettings.cpp
pv/globalsettings.hpp
pv/mainwindow.cpp
pv/mainwindow.hpp
pv/views/trace/analogsignal.cpp
pv/views/trace/analogsignal.hpp
pv/views/trace/view.cpp
pv/views/trace/view.hpp

index c9a757c9ebb238b3b8a7d1ff4cc4d6487fb56fa6..1a589fe9cf0459b986d88f2b5dfaa3398a1ba710 100644 (file)
 #include "globalsettings.hpp"
 
 #include <QApplication>
-#include <QByteArray>
 #include <QFontMetrics>
 #include <QString>
 
-using std::function;
 using std::map;
-using std::multimap;
+using std::vector;
 
 namespace pv {
 
@@ -42,7 +40,7 @@ const QString GlobalSettings::Key_View_DefaultDivHeight = "View_DefaultDivHeight
 const QString GlobalSettings::Key_View_DefaultLogicHeight = "View_DefaultLogicHeight";
 const QString GlobalSettings::Key_Dec_InitialStateConfigurable = "Dec_InitialStateConfigurable";
 
-multimap< QString, function<void(QVariant)> > GlobalSettings::callbacks_;
+vector<GlobalSettingsInterface*> GlobalSettings::callbacks_;
 bool GlobalSettings::tracking_ = false;
 map<QString, QVariant> GlobalSettings::tracked_changes_;
 
@@ -75,10 +73,18 @@ void GlobalSettings::set_defaults_where_needed()
                2 * QFontMetrics(QApplication::font()).height());
 }
 
-void GlobalSettings::register_change_handler(const QString key,
-       function<void(QVariant)> cb)
+void GlobalSettings::add_change_handler(GlobalSettingsInterface *cb)
 {
-       callbacks_.emplace(key, cb);
+       callbacks_.push_back(cb);
+}
+
+void GlobalSettings::remove_change_handler(GlobalSettingsInterface *cb)
+{
+       for (auto cb_it = callbacks_.begin(); cb_it != callbacks_.end(); cb_it++)
+               if (*cb_it == cb) {
+                       callbacks_.erase(cb_it);
+                       break;
+               }
 }
 
 void GlobalSettings::setValue(const QString &key, const QVariant &value)
@@ -90,11 +96,9 @@ void GlobalSettings::setValue(const QString &key, const QVariant &value)
 
        QSettings::setValue(key, value);
 
-       // Call all registered callbacks for this key
-       auto range = callbacks_.equal_range(key);
-
-       for (auto it = range.first; it != range.second; it++)
-               it->second(value);
+       // Call all registered callbacks
+       for (GlobalSettingsInterface *cb : callbacks_)
+               cb->on_setting_changed(key, value);
 }
 
 void GlobalSettings::start_tracking()
index c6b4cfc5891e617a4d44985f240268bf2a2fa1a0..ea43491c35b1a2b63d3656cbf375a8940113df5b 100644 (file)
@@ -20,7 +20,6 @@
 #ifndef PULSEVIEW_GLOBALSETTINGS_HPP
 #define PULSEVIEW_GLOBALSETTINGS_HPP
 
-#include <functional>
 #include <map>
 
 #include <glib.h>
 
 using std::function;
 using std::map;
-using std::multimap;
+using std::vector;
 
 namespace pv {
 
+class GlobalSettingsInterface
+{
+public:
+       virtual void on_setting_changed(const QString &key, const QVariant &value) = 0;
+};
+
+
 class GlobalSettings : public QSettings
 {
        Q_OBJECT
@@ -63,8 +69,8 @@ public:
 
        void set_defaults_where_needed();
 
-       static void register_change_handler(const QString key,
-               function<void(QVariant)> cb);
+       static void add_change_handler(GlobalSettingsInterface *cb);
+       static void remove_change_handler(GlobalSettingsInterface *cb);
 
        void setValue(const QString& key, const QVariant& value);
 
@@ -91,7 +97,7 @@ public:
        static GVariant* restore_gvariant(QSettings &settings);
 
 private:
-       static multimap< QString, function<void(QVariant)> > callbacks_;
+       static vector<GlobalSettingsInterface*> callbacks_;
 
        static bool tracking_;
        static map<QString, QVariant> tracked_changes_;
index 91e38729167d98135b8d9755ecdc315042820217..6eabdb6737e0a5b3a8e6641392480c8ea271bff4 100644 (file)
@@ -79,14 +79,7 @@ MainWindow::MainWindow(DeviceManager &device_manager, QWidget *parent) :
        qRegisterMetaType<util::Timestamp>("util::Timestamp");
        qRegisterMetaType<uint64_t>("uint64_t");
 
-       GlobalSettings::register_change_handler(GlobalSettings::Key_View_ColouredBG,
-               bind(&MainWindow::on_settingViewColouredBg_changed, this, _1));
-
-       GlobalSettings::register_change_handler(GlobalSettings::Key_View_ShowSamplingPoints,
-               bind(&MainWindow::on_settingViewShowSamplingPoints_changed, this, _1));
-
-       GlobalSettings::register_change_handler(GlobalSettings::Key_View_ShowAnalogMinorGrid,
-               bind(&MainWindow::on_settingViewShowAnalogMinorGrid_changed, this, _1));
+       GlobalSettings::add_change_handler(this);
 
        GlobalSettings settings;
        settings.set_defaults_where_needed();
@@ -97,6 +90,8 @@ MainWindow::MainWindow(DeviceManager &device_manager, QWidget *parent) :
 
 MainWindow::~MainWindow()
 {
+       GlobalSettings::remove_change_handler(this);
+
        while (!sessions_.empty())
                remove_session(sessions_.front());
 }
@@ -400,6 +395,18 @@ void MainWindow::restore_sessions()
        }
 }
 
+void MainWindow::on_setting_changed(const QString &key, const QVariant &value)
+{
+       if (key == GlobalSettings::Key_View_ColouredBG)
+               on_settingViewColouredBg_changed(value);
+
+       if (key == GlobalSettings::Key_View_ShowSamplingPoints)
+               on_settingViewShowSamplingPoints_changed(value);
+
+       if (key == GlobalSettings::Key_View_ShowAnalogMinorGrid)
+               on_settingViewShowAnalogMinorGrid_changed(value);
+}
+
 void MainWindow::setup_ui()
 {
        setObjectName(QString::fromUtf8("MainWindow"));
index 71cad57817a0554ad832b8710e0dc39dbe8fcc91..3cffb54b47ce85f36a49d5a2c85216714751d0ea 100644 (file)
@@ -30,6 +30,7 @@
 #include <QTabWidget>
 #include <QToolButton>
 
+#include "globalsettings.hpp"
 #include "session.hpp"
 #include "views/viewbase.hpp"
 
@@ -61,7 +62,7 @@ class DecoderMenu;
 #endif
 }
 
-class MainWindow : public QMainWindow
+class MainWindow : public QMainWindow, public GlobalSettingsInterface
 {
        Q_OBJECT
 
@@ -92,6 +93,8 @@ public:
        void save_sessions();
        void restore_sessions();
 
+       void on_setting_changed(const QString &key, const QVariant &value);
+
 private:
        void setup_ui();
 
index e6bd875600130141e5789f9f9b7626aec3c0b75c..bbc23fb70074bace6adc25e304d70d50583de3dd 100644 (file)
@@ -118,8 +118,7 @@ AnalogSignal::AnalogSignal(
        connect(analog_data, SIGNAL(min_max_changed(float, float)),
                this, SLOT(on_min_max_changed(float, float)));
 
-       GlobalSettings::register_change_handler(GlobalSettings::Key_View_ConversionThresholdDispMode,
-               bind(&AnalogSignal::on_settingViewConversionThresholdDispMode_changed, this, _1));
+       GlobalSettings::add_change_handler(this);
 
        GlobalSettings gs;
        conversion_threshold_disp_mode_ =
@@ -131,6 +130,11 @@ AnalogSignal::AnalogSignal(
        update_scale();
 }
 
+AnalogSignal::~AnalogSignal()
+{
+       GlobalSettings::remove_change_handler(this);
+}
+
 shared_ptr<pv::data::SignalData> AnalogSignal::data() const
 {
        return base_->analog_data();
@@ -206,6 +210,12 @@ void AnalogSignal::scale_handle_drag_release()
        update_scale();
 }
 
+void AnalogSignal::on_setting_changed(const QString &key, const QVariant &value)
+{
+       if (key == GlobalSettings::Key_View_ConversionThresholdDispMode)
+               on_settingViewConversionThresholdDispMode_changed(value);
+}
+
 void AnalogSignal::paint_back(QPainter &p, ViewItemPaintParams &pp)
 {
        if (!base_->enabled())
index a66fb9e2fcefca99164644ac7ceb7dae75c209a4..97d5160bd08b42591191211121f6d16fc874669a 100644 (file)
 #ifndef PULSEVIEW_PV_VIEWS_TRACEVIEW_ANALOGSIGNAL_HPP
 #define PULSEVIEW_PV_VIEWS_TRACEVIEW_ANALOGSIGNAL_HPP
 
-#include "signal.hpp"
-
 #include <memory>
 
 #include <QComboBox>
 #include <QSpinBox>
 
+#include <pv/globalsettings.hpp>
+#include <pv/views/trace/signal.hpp>
+
 using std::pair;
 using std::shared_ptr;
 
@@ -41,7 +42,7 @@ class SignalBase;
 namespace views {
 namespace trace {
 
-class AnalogSignal : public Signal
+class AnalogSignal : public Signal, public GlobalSettingsInterface
 {
        Q_OBJECT
 
@@ -74,7 +75,7 @@ private:
 public:
        AnalogSignal(pv::Session &session, shared_ptr<data::SignalBase> base);
 
-       virtual ~AnalogSignal() = default;
+       ~AnalogSignal();
 
        shared_ptr<pv::data::SignalData> data() const;
 
@@ -104,6 +105,8 @@ public:
         */
        void scale_handle_drag_release();
 
+       void on_setting_changed(const QString &key, const QVariant &value);
+
        /**
         * Paints the background layer of the signal with a QPainter
         * @param p the QPainter to paint into.
index 35b6807dfc75c11ba825831c1552ee17fe490f5a..6a9c01af731180378de18a45c9c3e2affe34286d 100644 (file)
@@ -199,8 +199,7 @@ View::View(Session &session, bool is_main_view, QWidget *parent) :
        GlobalSettings settings;
        coloured_bg_ = settings.value(GlobalSettings::Key_View_ColouredBG).toBool();
 
-       GlobalSettings::register_change_handler(GlobalSettings::Key_View_TriggerIsZeroTime,
-               bind(&View::on_settingViewTriggerIsZeroTime_changed, this, _1));
+       GlobalSettings::add_change_handler(this);
 
        connect(scrollarea_->horizontalScrollBar(), SIGNAL(valueChanged(int)),
                this, SLOT(h_scroll_value_changed(int)));
@@ -239,6 +238,11 @@ View::View(Session &session, bool is_main_view, QWidget *parent) :
        set_segment_display_mode(segment_display_mode_);
 }
 
+View::~View()
+{
+       GlobalSettings::remove_change_handler(this);
+}
+
 Session& View::session()
 {
        return session_;
@@ -861,6 +865,12 @@ void View::restack_all_trace_tree_items()
                i->animate_to_layout_v_offset();
 }
 
+void View::on_setting_changed(const QString &key, const QVariant &value)
+{
+       if (key == GlobalSettings::Key_View_TriggerIsZeroTime)
+               on_settingViewTriggerIsZeroTime_changed(value);
+}
+
 void View::trigger_event(int segment_id, util::Timestamp location)
 {
        // TODO This doesn't work if we're showing multiple segments at once
index 9529e7a3fee25a3c057a76c5c1c76a5ebc0c4d08..a351fd9306332f0169e917c16c6bbf2246a07368 100644 (file)
@@ -31,8 +31,9 @@
 #include <QSizeF>
 #include <QSplitter>
 
-#include <pv/data/signaldata.hpp>
+#include <pv/globalsettings.hpp>
 #include <pv/util.hpp>
+#include <pv/data/signaldata.hpp>
 #include <pv/views/viewbase.hpp>
 
 #include "cursorpair.hpp"
@@ -81,7 +82,7 @@ public:
        bool viewportEvent(QEvent *event);
 };
 
-class View : public ViewBase, public TraceTreeItemOwner
+class View : public ViewBase, public TraceTreeItemOwner, public GlobalSettingsInterface
 {
        Q_OBJECT
 
@@ -102,6 +103,8 @@ private:
 public:
        explicit View(Session &session, bool is_main_view=false, QWidget *parent = nullptr);
 
+       ~View();
+
        Session& session();
        const Session& session() const;
 
@@ -298,6 +301,8 @@ public:
 
        void restack_all_trace_tree_items();
 
+       void on_setting_changed(const QString &key, const QVariant &value);
+
 Q_SIGNALS:
        void hover_point_changed(const QPoint &hp);