From d0c0573b3ee694827a747727f862c5f91736ca05 Mon Sep 17 00:00:00 2001 From: Soeren Apel Date: Sun, 21 Jan 2018 14:28:27 +0100 Subject: [PATCH] Rework the callback mechanism for the global settings 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 | 28 ++++++++++++++++------------ pv/globalsettings.hpp | 16 +++++++++++----- pv/mainwindow.cpp | 23 +++++++++++++++-------- pv/mainwindow.hpp | 5 ++++- pv/views/trace/analogsignal.cpp | 14 ++++++++++++-- pv/views/trace/analogsignal.hpp | 11 +++++++---- pv/views/trace/view.cpp | 14 ++++++++++++-- pv/views/trace/view.hpp | 9 +++++++-- 8 files changed, 84 insertions(+), 36 deletions(-) diff --git a/pv/globalsettings.cpp b/pv/globalsettings.cpp index c9a757c9..1a589fe9 100644 --- a/pv/globalsettings.cpp +++ b/pv/globalsettings.cpp @@ -20,13 +20,11 @@ #include "globalsettings.hpp" #include -#include #include #include -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 > GlobalSettings::callbacks_; +vector GlobalSettings::callbacks_; bool GlobalSettings::tracking_ = false; map 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 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() diff --git a/pv/globalsettings.hpp b/pv/globalsettings.hpp index c6b4cfc5..ea43491c 100644 --- a/pv/globalsettings.hpp +++ b/pv/globalsettings.hpp @@ -20,7 +20,6 @@ #ifndef PULSEVIEW_GLOBALSETTINGS_HPP #define PULSEVIEW_GLOBALSETTINGS_HPP -#include #include #include @@ -31,10 +30,17 @@ 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 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 > callbacks_; + static vector callbacks_; static bool tracking_; static map tracked_changes_; diff --git a/pv/mainwindow.cpp b/pv/mainwindow.cpp index 91e38729..6eabdb67 100644 --- a/pv/mainwindow.cpp +++ b/pv/mainwindow.cpp @@ -79,14 +79,7 @@ MainWindow::MainWindow(DeviceManager &device_manager, QWidget *parent) : qRegisterMetaType("util::Timestamp"); qRegisterMetaType("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")); diff --git a/pv/mainwindow.hpp b/pv/mainwindow.hpp index 71cad578..3cffb54b 100644 --- a/pv/mainwindow.hpp +++ b/pv/mainwindow.hpp @@ -30,6 +30,7 @@ #include #include +#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(); diff --git a/pv/views/trace/analogsignal.cpp b/pv/views/trace/analogsignal.cpp index e6bd8756..bbc23fb7 100644 --- a/pv/views/trace/analogsignal.cpp +++ b/pv/views/trace/analogsignal.cpp @@ -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 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()) diff --git a/pv/views/trace/analogsignal.hpp b/pv/views/trace/analogsignal.hpp index a66fb9e2..97d5160b 100644 --- a/pv/views/trace/analogsignal.hpp +++ b/pv/views/trace/analogsignal.hpp @@ -20,13 +20,14 @@ #ifndef PULSEVIEW_PV_VIEWS_TRACEVIEW_ANALOGSIGNAL_HPP #define PULSEVIEW_PV_VIEWS_TRACEVIEW_ANALOGSIGNAL_HPP -#include "signal.hpp" - #include #include #include +#include +#include + 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 base); - virtual ~AnalogSignal() = default; + ~AnalogSignal(); shared_ptr 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. diff --git a/pv/views/trace/view.cpp b/pv/views/trace/view.cpp index 35b6807d..6a9c01af 100644 --- a/pv/views/trace/view.cpp +++ b/pv/views/trace/view.cpp @@ -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 diff --git a/pv/views/trace/view.hpp b/pv/views/trace/view.hpp index 9529e7a3..a351fd93 100644 --- a/pv/views/trace/view.hpp +++ b/pv/views/trace/view.hpp @@ -31,8 +31,9 @@ #include #include -#include +#include #include +#include #include #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); -- 2.30.2