Wrapped sr_dev_inst in a class: pv::DevInst
authorJoel Holdsworth <joel@airwebreathe.org.uk>
Sun, 9 Feb 2014 13:40:15 +0000 (13:40 +0000)
committerJoel Holdsworth <joel@airwebreathe.org.uk>
Sun, 9 Feb 2014 18:01:17 +0000 (18:01 +0000)
19 files changed:
CMakeLists.txt
pv/devicemanager.cpp
pv/devicemanager.h
pv/devinst.cpp [new file with mode: 0644]
pv/devinst.h [new file with mode: 0644]
pv/dialogs/connect.cpp
pv/dialogs/connect.h
pv/mainwindow.cpp
pv/mainwindow.h
pv/popups/deviceoptions.cpp
pv/popups/deviceoptions.h
pv/popups/probes.cpp
pv/prop/binding/deviceoptions.cpp
pv/prop/binding/deviceoptions.h
pv/sigsession.cpp
pv/sigsession.h
pv/toolbars/samplingbar.cpp
pv/toolbars/samplingbar.h
pv/view/logicsignal.cpp

index d98ff54c87023717e0ba5660b85b637070b8138a..695da5b4c831f0525d82b6c6d519d2dcbb33ef54 100644 (file)
@@ -111,6 +111,7 @@ configure_file (
 set(pulseview_SOURCES
        main.cpp
        pv/devicemanager.cpp
+       pv/devinst.cpp
        pv/mainwindow.cpp
        pv/sigsession.cpp
        pv/storesession.cpp
index 14ad16efcad67abb72f844cafd7c108f10c8d9bf..39c311c5a0e35726f4d38a1471af2d19bdaaf343 100644 (file)
  */
 
 #include "devicemanager.h"
+#include "devinst.h"
 #include "sigsession.h"
 
 #include <cassert>
-#include <sstream>
 #include <stdexcept>
 #include <string>
 
 #include <libsigrok/libsigrok.h>
 
+using boost::shared_ptr;
 using std::list;
 using std::map;
 using std::ostringstream;
@@ -48,44 +49,46 @@ DeviceManager::~DeviceManager()
        release_devices();
 }
 
-const std::list<sr_dev_inst*>& DeviceManager::devices() const
+const list< shared_ptr<pv::DevInst> >& DeviceManager::devices() const
 {
        return _devices;
 }
 
-void DeviceManager::use_device(sr_dev_inst *sdi, SigSession *owner)
+void DeviceManager::use_device(shared_ptr<DevInst> dev_inst, SigSession *owner)
 {
-       assert(sdi);
+       assert(dev_inst);
        assert(owner);
 
-       _used_devices[sdi] = owner;
+       _used_devices[dev_inst] = owner;
 
-       sr_dev_open(sdi);
+       sr_dev_open(dev_inst->dev_inst());
 }
 
-void DeviceManager::release_device(sr_dev_inst *sdi)
+void DeviceManager::release_device(shared_ptr<DevInst> dev_inst)
 {
-       assert(sdi);
+       assert(dev_inst);
 
-       // Notify the owner, and removed the device from the used device list
-       _used_devices[sdi]->release_device(sdi);
-       _used_devices.erase(sdi);
+       // Notify the owner, and remove the device from the used device list
+       map< shared_ptr<DevInst>, pv::SigSession*>::const_iterator iter =
+               _used_devices.find(dev_inst);
+       assert(iter != _used_devices.end());
 
-       sr_dev_close(sdi);
+       (*iter).second->release_device(dev_inst);
+       _used_devices.erase(dev_inst);
 }
 
-list<sr_dev_inst*> DeviceManager::driver_scan(
+list< shared_ptr<DevInst> > DeviceManager::driver_scan(
        struct sr_dev_driver *const driver, GSList *const drvopts)
 {
-       list<sr_dev_inst*> driver_devices;
+       list< shared_ptr<DevInst> > driver_devices;
 
        assert(driver);
 
        // Remove any device instances from this driver from the device
        // list. They will not be valid after the scan.
-       list<sr_dev_inst*>::iterator i = _devices.begin();
+       list< shared_ptr<DevInst> >::iterator i = _devices.begin();
        while (i != _devices.end()) {
-               if ((*i)->driver == driver)
+               if ((*i)->dev_inst()->driver == driver)
                        i = _devices.erase(i);
                else
                        i++;
@@ -97,7 +100,8 @@ list<sr_dev_inst*> DeviceManager::driver_scan(
        // Do the scan
        GSList *const devices = sr_driver_scan(driver, drvopts);
        for (GSList *l = devices; l; l = l->next)
-               driver_devices.push_back((sr_dev_inst*)l->data);
+               driver_devices.push_back(shared_ptr<DevInst>(
+                       new DevInst((sr_dev_inst*)l->data)));
        g_slist_free(devices);
        driver_devices.sort(compare_devices);
 
@@ -109,31 +113,6 @@ list<sr_dev_inst*> DeviceManager::driver_scan(
        return driver_devices;
 }
 
-string DeviceManager::format_device_title(const sr_dev_inst *const sdi)
-{
-       ostringstream s;
-
-       assert(sdi);
-
-       if (sdi->vendor && sdi->vendor[0]) {
-               s << sdi->vendor;
-               if ((sdi->model && sdi->model[0]) ||
-                       (sdi->version && sdi->version[0]))
-                       s << ' ';
-       }
-
-       if (sdi->model && sdi->model[0]) {
-               s << sdi->model;
-               if (sdi->version && sdi->version[0])
-                       s << ' ';
-       }
-
-       if (sdi->version && sdi->version[0])
-               s << sdi->version;
-
-       return s.str();
-}
-
 void DeviceManager::init_drivers()
 {
        // Initialise all libsigrok drivers
@@ -150,8 +129,8 @@ void DeviceManager::init_drivers()
 void DeviceManager::release_devices()
 {
        // Release all the used devices
-       for (map<sr_dev_inst*, SigSession*>::iterator i = _used_devices.begin();
-               i != _used_devices.end(); i++)
+       for (map<shared_ptr<DevInst>, SigSession*>::iterator i =
+               _used_devices.begin(); i != _used_devices.end(); i++)
                release_device((*i).first);
 
        _used_devices.clear();
@@ -173,9 +152,9 @@ void DeviceManager::scan_all_drivers()
 void DeviceManager::release_driver(struct sr_dev_driver *const driver)
 {
        assert(driver);
-       for (map<sr_dev_inst*, SigSession*>::iterator i = _used_devices.begin();
-               i != _used_devices.end(); i++)
-               if((*i).first->driver == driver)
+       for (map<shared_ptr<DevInst>, SigSession*>::iterator i =
+               _used_devices.begin(); i != _used_devices.end(); i++)
+               if((*i).first->dev_inst()->driver == driver)
                {
                        // Notify the current owner of the device
                        (*i).second->release_device((*i).first);
@@ -184,17 +163,19 @@ void DeviceManager::release_driver(struct sr_dev_driver *const driver)
                        _used_devices.erase(i);
 
                        // Close the device instance
-                       sr_dev_close((*i).first);
+                       sr_dev_close((*i).first->dev_inst());
                }
 
        // Clear all the old device instances from this driver
        sr_dev_clear(driver);
 }
 
-bool DeviceManager::compare_devices(const sr_dev_inst *const a,
-       const sr_dev_inst *const b)
+bool DeviceManager::compare_devices(shared_ptr<DevInst> a,
+       shared_ptr<DevInst> b)
 {
-       return format_device_title(a).compare(format_device_title(b)) < 0;
+       assert(a);
+       assert(b);
+       return a->format_device_title().compare(b->format_device_title()) < 0;
 }
 
 } // namespace pv
index b7f2d49a7e016ce49e6b66dc0124b17b1779dbb3..891ba3d2c1ac28a254917a7da49def32828779d2 100644 (file)
 #include <map>
 #include <string>
 
+#include <boost/shared_ptr.hpp>
+
 struct sr_context;
 struct sr_dev_driver;
-struct sr_dev_inst;
 
 namespace pv {
 
+class DevInst;
 class SigSession;
 
 class DeviceManager
@@ -42,18 +44,17 @@ public:
 
        ~DeviceManager();
 
-       const std::list<sr_dev_inst*>& devices() const;
+       const std::list< boost::shared_ptr<pv::DevInst> >& devices() const;
 
-       void use_device(sr_dev_inst *sdi, SigSession *owner);
+       void use_device(boost::shared_ptr<pv::DevInst> dev_inst,
+               SigSession *owner);
 
-       void release_device(sr_dev_inst *sdi);
+       void release_device(boost::shared_ptr<pv::DevInst> dev_inst);
 
-       std::list<sr_dev_inst*> driver_scan(
+       std::list< boost::shared_ptr<DevInst> > driver_scan(
                struct sr_dev_driver *const driver,
                GSList *const drvopts = NULL);
 
-       static std::string format_device_title(const sr_dev_inst *const sdi);
-
 private:
        void init_drivers();
 
@@ -63,13 +64,14 @@ private:
 
        void release_driver(struct sr_dev_driver *const driver);
 
-       static bool compare_devices(const sr_dev_inst *const a,
-               const sr_dev_inst *const b);
+       static bool compare_devices(boost::shared_ptr<DevInst> a,
+               boost::shared_ptr<DevInst> b);
 
 private:
        struct sr_context *const _sr_ctx;
-       std::list<sr_dev_inst*> _devices;
-       std::map<sr_dev_inst*, pv::SigSession*> _used_devices;
+       std::list< boost::shared_ptr<pv::DevInst> > _devices;
+       std::map< boost::shared_ptr<pv::DevInst>, pv::SigSession*>
+               _used_devices;
 };
 
 } // namespace pv
diff --git a/pv/devinst.cpp b/pv/devinst.cpp
new file mode 100644 (file)
index 0000000..4a152e0
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <cassert>
+#include <sstream>
+
+#include <libsigrok/libsigrok.h>
+
+#include "devinst.h"
+
+using std::ostringstream;
+using std::string;
+
+namespace pv {
+
+DevInst::DevInst(sr_dev_inst *sdi) :
+       _sdi(sdi)
+{
+       assert(_sdi);
+}
+
+sr_dev_inst* DevInst::dev_inst() const
+{
+       return _sdi;
+}
+
+string DevInst::format_device_title() const
+{
+       ostringstream s;
+
+       assert(_sdi);
+
+       if (_sdi->vendor && _sdi->vendor[0]) {
+               s << _sdi->vendor;
+               if ((_sdi->model && _sdi->model[0]) ||
+                       (_sdi->version && _sdi->version[0]))
+                       s << ' ';
+       }
+
+       if (_sdi->model && _sdi->model[0]) {
+               s << _sdi->model;
+               if (_sdi->version && _sdi->version[0])
+                       s << ' ';
+       }
+
+       if (_sdi->version && _sdi->version[0])
+               s << _sdi->version;
+
+       return s.str();
+}
+
+} // pv
diff --git a/pv/devinst.h b/pv/devinst.h
new file mode 100644 (file)
index 0000000..64d2758
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_DEVINST_H
+#define PULSEVIEW_PV_DEVINST_H
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+struct sr_dev_inst;
+
+namespace pv {
+
+class DevInst
+{
+public:
+       DevInst(sr_dev_inst *sdi);
+
+       sr_dev_inst* dev_inst() const;
+
+       std::string format_device_title() const;
+
+private:
+       sr_dev_inst *const _sdi;
+};
+
+} // pv
+
+#endif // PULSEVIEW_PV_DEVINST_H
index 9cd712508d463e0711ede42b79d399c219a1e956..11cf0e7b5de3e211643d62d6697ec9b6b80f1c10 100644 (file)
 
 #include <boost/foreach.hpp>
 
+#include <libsigrok/libsigrok.h>
+
 #include "connect.h"
 
 #include "pv/devicemanager.h"
+#include "pv/devinst.h"
 
 extern "C" {
 /* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */
@@ -31,6 +34,7 @@ extern "C" {
 #include <libsigrok/libsigrok.h>
 }
 
+using boost::shared_ptr;
 using std::list;
 using std::string;
 
@@ -78,13 +82,21 @@ Connect::Connect(QWidget *parent, pv::DeviceManager &device_manager) :
        _layout.addWidget(&_button_box);
 }
 
-struct sr_dev_inst* Connect::get_selected_device() const
+shared_ptr<DevInst> Connect::get_selected_device() const
 {
        const QListWidgetItem *const item = _device_list.currentItem();
        if (!item)
-               return NULL;
+               return shared_ptr<DevInst>();
+
+       const sr_dev_inst *const sdi = (sr_dev_inst*)item->data(
+               Qt::UserRole).value<void*>();
+       assert(sdi);
 
-       return (sr_dev_inst*)item->data(Qt::UserRole).value<void*>();
+       std::map<const sr_dev_inst*, boost::shared_ptr<pv::DevInst> >::
+               const_iterator iter = _device_map.find(sdi);
+       assert(iter != _device_map.end());
+
+       return (*iter).second;
 }
 
 void Connect::populate_drivers()
@@ -124,6 +136,7 @@ void Connect::populate_drivers()
 void Connect::unset_connection()
 {
        _device_list.clear();
+       _device_map.clear();
        _serial_device.hide();
        _form_layout.labelForField(&_serial_device)->hide();
        _button_box.button(QDialogButtonBox::Ok)->setDisabled(true);
@@ -138,6 +151,7 @@ void Connect::set_serial_connection()
 void Connect::scan_pressed()
 {
        _device_list.clear();
+       _device_map.clear();
 
        const int index = _drivers.currentIndex();
        if (index == -1)
@@ -156,15 +170,20 @@ void Connect::scan_pressed()
                drvopts = g_slist_append(drvopts, src);
        }
 
-       const list<sr_dev_inst*> devices = _device_manager.driver_scan(
+       const list< shared_ptr<DevInst> > devices = _device_manager.driver_scan(
                driver, drvopts);
 
        g_slist_free_full(drvopts, (GDestroyNotify)free_drvopts);
 
-       BOOST_FOREACH(sr_dev_inst *const sdi, devices)
+       BOOST_FOREACH(shared_ptr<DevInst> dev_inst, devices)
        {
-               const string title = DeviceManager::format_device_title(sdi);
+               assert(dev_inst);
+               const sr_dev_inst *const sdi = dev_inst->dev_inst();
+               assert(sdi);
+
+               const string title = dev_inst->format_device_title();
                QString text = QString::fromUtf8(title.c_str());
+
                if (sdi->probes) {
                        text += QString(" with %1 probes").arg(
                                g_slist_length(sdi->probes));
@@ -174,6 +193,7 @@ void Connect::scan_pressed()
                        &_device_list);
                item->setData(Qt::UserRole, qVariantFromValue((void*)sdi));
                _device_list.addItem(item);
+               _device_map[sdi] = dev_inst;
        }
 
        _device_list.setCurrentRow(0);
index 257efd359b860da1f721dc9a9c9aba0454d40750..0f272cae73a6eb8e0d94b5cf7fe3ee296896acee 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PULSEVIEW_PV_CONNECT_H
 #define PULSEVIEW_PV_CONNECT_H
 
+#include <boost/shared_ptr.hpp>
+
 #include <QComboBox>
 #include <QDialog>
 #include <QDialogButtonBox>
@@ -36,6 +38,7 @@ struct sr_dev_inst;
 namespace pv {
 
 class DeviceManager;
+class DevInst;
 
 namespace dialogs {
 
@@ -46,7 +49,7 @@ class Connect : public QDialog
 public:
        Connect(QWidget *parent, pv::DeviceManager &device_manager);
 
-       struct sr_dev_inst* get_selected_device() const;
+       boost::shared_ptr<DevInst> get_selected_device() const;
 
 private:
        void populate_drivers();
@@ -77,6 +80,8 @@ private:
 
        QPushButton _scan_button;
        QListWidget _device_list;
+       std::map<const sr_dev_inst*, boost::shared_ptr<pv::DevInst> >
+               _device_map;
 
        QDialogButtonBox _button_box;
 };
index e0ef3aa297e4f71e7f3678cc0bbd151ce27696ff..0b2805b18e44a1ee0908b2715476d62466faf58e 100644 (file)
@@ -39,6 +39,7 @@
 #include "mainwindow.h"
 
 #include "devicemanager.h"
+#include "devinst.h"
 #include "dialogs/about.h"
 #include "dialogs/connect.h"
 #include "dialogs/storeprogress.h"
@@ -57,6 +58,7 @@
 #include <glib.h>
 #include <libsigrok/libsigrok.h>
 
+using boost::shared_ptr;
 using std::list;
 
 namespace pv {
@@ -282,11 +284,11 @@ void MainWindow::session_error(
                Q_ARG(QString, info_text));
 }
 
-void MainWindow::update_device_list(struct sr_dev_inst *selected_device)
+void MainWindow::update_device_list(shared_ptr<pv::DevInst> selected_device)
 {
        assert(_sampling_bar);
 
-       const list<sr_dev_inst*> &devices = _device_manager.devices();
+       const list< shared_ptr<DevInst> > &devices = _device_manager.devices();
        _sampling_bar->set_device_list(devices);
 
        if (!selected_device && !devices.empty()) {
@@ -294,9 +296,10 @@ void MainWindow::update_device_list(struct sr_dev_inst *selected_device)
                selected_device = devices.front();
 
                // Try and find the demo device and select that by default
-               BOOST_FOREACH (struct sr_dev_inst *sdi, devices)
-                       if (strcmp(sdi->driver->name, "demo") == 0) {
-                               selected_device = sdi;
+               BOOST_FOREACH (shared_ptr<pv::DevInst> dev_inst, devices)
+                       if (strcmp(dev_inst->dev_inst()->driver->name,
+                               "demo") == 0) {
+                               selected_device = dev_inst;
                        }
        }
 
@@ -365,10 +368,10 @@ void MainWindow::on_actionConnect_triggered()
 
        // If the user selected a device, select it in the device list. Select the
        // current device otherwise.
-       struct sr_dev_inst *const sdi = dlg.exec() ?
+       shared_ptr<DevInst> dev_inst = dlg.exec() ?
                dlg.get_selected_device() : _session.get_device();
 
-       update_device_list(sdi);
+       update_device_list(dev_inst);
 }
 
 void MainWindow::on_actionQuit_triggered()
index 6f352f9f2cbcab545fd0980af1a215ddaad05f6a..6f3c8d56344d601d90628578ac1da419ac3f7e71 100644 (file)
@@ -36,6 +36,7 @@ class QVBoxLayout;
 namespace pv {
 
 class DeviceManager;
+class DevInst;
 
 namespace toolbars {
 class ContextBar;
@@ -71,7 +72,8 @@ private:
         * first device in the device list should be selected.
         */
        void update_device_list(
-               struct sr_dev_inst *selected_device = NULL);
+               boost::shared_ptr<pv::DevInst> selected_device =
+                       boost::shared_ptr<pv::DevInst>());
 
 private slots:
        void load_file(QString file_name);
index 6f9d7d9f558ebe3e56a2aec7c48db5c2016f1a7d..7e1be20d52d5ca4dd7b14835387f960590c75b82 100644 (file)
 
 #include <pv/prop/property.h>
 
+using boost::shared_ptr;
+
 namespace pv {
 namespace popups {
 
-DeviceOptions::DeviceOptions(sr_dev_inst *sdi, QWidget *parent) :
+DeviceOptions::DeviceOptions(shared_ptr<DevInst> dev_inst, QWidget *parent) :
        Popup(parent),
-       _sdi(sdi),
+       _dev_inst(dev_inst),
        _layout(this),
-       _binding(sdi)
+       _binding(dev_inst)
 {
        setLayout(&_layout);
 
index 788f9b5b85b407d18f1509f9b94862093f641dc8..745ed994e9ea7f449d0bdd8fdfe6b3b601ee9aeb 100644 (file)
@@ -35,12 +35,12 @@ class DeviceOptions : public pv::widgets::Popup
        Q_OBJECT
 
 public:
-       DeviceOptions(sr_dev_inst *sdi, QWidget *parent);
+       DeviceOptions(boost::shared_ptr<DevInst> dev_inst, QWidget *parent);
 
        pv::prop::binding::DeviceOptions& binding();
 
 private:
-       sr_dev_inst *const _sdi;
+       boost::shared_ptr<DevInst> _dev_inst;
 
        QVBoxLayout _layout;
 
index daad812b76ef48a27a4ab8ad6531088833d94579..b19f8967cbe15d9200bbd6c23dbcea9f2214a552 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "probes.h"
 
+#include <pv/devinst.h>
 #include <pv/prop/binding/deviceoptions.h>
 #include <pv/sigsession.h>
 #include <pv/view/signal.h>
@@ -56,7 +57,9 @@ Probes::Probes(SigSession &session, QWidget *parent) :
        // Create the layout
        setLayout(&_layout);
 
-       sr_dev_inst *const sdi = _session.get_device();
+       shared_ptr<DevInst> dev_inst = _session.get_device();
+       assert(dev_inst);
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
        assert(sdi);
 
        // Collect a set of signals
index d116521aa435524f5ac8871fb8b06a625e57905f..6da16652f2cc0dca814491b46c30e384fa29bc30 100644 (file)
 
 #include "deviceoptions.h"
 
+#include <pv/devinst.h>
 #include <pv/prop/bool.h>
 #include <pv/prop/double.h>
 #include <pv/prop/enum.h>
 #include <pv/prop/int.h>
 
+#include <libsigrok/libsigrok.h>
+
 using boost::bind;
 using boost::function;
 using boost::optional;
@@ -45,11 +48,13 @@ namespace pv {
 namespace prop {
 namespace binding {
 
-DeviceOptions::DeviceOptions(const sr_dev_inst *sdi,
+DeviceOptions::DeviceOptions(shared_ptr<pv::DevInst> dev_inst,
        const sr_probe_group *group) :
-       _sdi(sdi),
+       _dev_inst(dev_inst),
        _group(group)
 {
+       assert(dev_inst);
+       sr_dev_inst *const sdi = dev_inst->dev_inst();
        assert(sdi);
 
        GVariant *gvar_opts, *gvar_list;
@@ -71,7 +76,7 @@ DeviceOptions::DeviceOptions(const sr_dev_inst *sdi,
 
                const int key = info->key;
 
-               if (sr_config_list(_sdi->driver, _sdi, group,
+               if (sr_config_list(sdi->driver, sdi, group,
                        key, &gvar_list) != SR_OK)
                        gvar_list = NULL;
 
@@ -144,9 +149,12 @@ void DeviceOptions::config_setter(
 
 void DeviceOptions::bind_bool(const QString &name, int key)
 {
+       sr_dev_inst *const sdi = _dev_inst->dev_inst();
+       assert(sdi);
+
        _properties.push_back(shared_ptr<Property>(
-               new Bool(name, bind(config_getter, _sdi, _group, key),
-                       bind(config_setter, _sdi, _group, key, _1))));
+               new Bool(name, bind(config_getter, sdi, _group, key),
+                       bind(config_setter, sdi, _group, key, _1))));
 }
 
 void DeviceOptions::bind_enum(const QString &name, int key,
@@ -158,23 +166,29 @@ void DeviceOptions::bind_enum(const QString &name, int key,
 
        assert(gvar_list);
 
+       sr_dev_inst *const sdi = _dev_inst->dev_inst();
+       assert(sdi);
+
        g_variant_iter_init (&iter, gvar_list);
        while ((gvar = g_variant_iter_next_value (&iter)))
                values.push_back(make_pair(gvar, printer(gvar)));
 
        _properties.push_back(shared_ptr<Property>(
                new Enum(name, values,
-                       bind(config_getter, _sdi, _group, key),
-                       bind(config_setter, _sdi, _group, key, _1))));
+                       bind(config_getter, sdi, _group, key),
+                       bind(config_setter, sdi, _group, key, _1))));
 }
 
 void DeviceOptions::bind_int(const QString &name, int key, QString suffix,
        optional< std::pair<int64_t, int64_t> > range)
 {
+       sr_dev_inst *const sdi = _dev_inst->dev_inst();
+       assert(sdi);
+
        _properties.push_back(shared_ptr<Property>(
                new Int(name, suffix, range,
-                       bind(config_getter, _sdi, _group, key),
-                       bind(config_setter, _sdi, _group, key, _1))));
+                       bind(config_getter, sdi, _group, key),
+                       bind(config_setter, sdi, _group, key, _1))));
 }
 
 QString DeviceOptions::print_gvariant(GVariant *const gvar)
index ab0f01716f0377c563c5288a14050bed8ea7fae2..ca27a5b7fc69590654316bf08645eb4cf638d1e1 100644 (file)
 
 #include <QString>
 
-#include <libsigrok/libsigrok.h>
-
 #include "binding.h"
 
+#include <glib.h>
+
+struct sr_dev_inst;
+struct sr_probe_group;
+
 namespace pv {
+
+class DevInst;
+
 namespace prop {
 namespace binding {
 
 class DeviceOptions : public Binding
 {
 public:
-       DeviceOptions(const sr_dev_inst *sdi,
+       DeviceOptions(boost::shared_ptr<pv::DevInst> dev_inst,
                const sr_probe_group *group = NULL);
 
 private:
@@ -62,7 +68,7 @@ private:
        static QString print_voltage_threshold(GVariant *const gvar);
 
 protected:
-       const sr_dev_inst *const _sdi;
+       boost::shared_ptr<DevInst> _dev_inst;
        const sr_probe_group *const _group;
 };
 
index e507a09946801fa0c081d8ecfecb18ba6806c946..809509bb78768fc9a054b1a7db8d6b64c2d57f4d 100644 (file)
@@ -25,6 +25,7 @@
 #include "sigsession.h"
 
 #include "devicemanager.h"
+#include "devinst.h"
 
 #include "data/analog.h"
 #include "data/analogsnapshot.h"
@@ -64,7 +65,6 @@ SigSession* SigSession::_session = NULL;
 
 SigSession::SigSession(DeviceManager &device_manager) :
        _device_manager(device_manager),
-       _sdi(NULL),
        _capture_state(Stopped)
 {
        // TODO: This should not be necessary
@@ -77,39 +77,37 @@ SigSession::~SigSession()
 
        _sampling_thread.join();
 
-       if (_sdi)
-               _device_manager.release_device(_sdi);
-       _sdi = NULL;
+       if (_dev_inst)
+               _device_manager.release_device(_dev_inst);
 
        // TODO: This should not be necessary
        _session = NULL;
 }
 
-struct sr_dev_inst* SigSession::get_device() const
+shared_ptr<DevInst> SigSession::get_device() const
 {
-       return _sdi;
+       return _dev_inst;
 }
 
-void SigSession::set_device(struct sr_dev_inst *sdi)
+void SigSession::set_device(shared_ptr<DevInst> dev_inst)
 {
        // Ensure we are not capturing before setting the device
        stop_capture();
 
-       if (_sdi)
-               _device_manager.release_device(_sdi);
-       if (sdi)
-               _device_manager.use_device(sdi, this);
-       _sdi = sdi;
-       update_signals(sdi);
+       if (_dev_inst)
+               _device_manager.release_device(_dev_inst);
+       if (dev_inst)
+               _device_manager.use_device(dev_inst, this);
+       _dev_inst = dev_inst;
+       update_signals(dev_inst);
 }
 
-void SigSession::release_device(struct sr_dev_inst *sdi)
+void SigSession::release_device(shared_ptr<DevInst> dev_inst)
 {
-       (void)sdi;
+       (void)dev_inst;
 
        assert(_capture_state == Stopped);
-       _sdi = NULL;
-       update_signals(NULL);
+       _dev_inst = shared_ptr<DevInst>();
 }
 
 void SigSession::load_file(const string &name,
@@ -127,12 +125,13 @@ void SigSession::load_file(const string &name,
                        return;
                }
 
-               sr_dev_inst *const sdi = (sr_dev_inst*)devlist->data;
+               shared_ptr<DevInst> dev_inst(
+                       new DevInst((sr_dev_inst*)devlist->data));
                g_slist_free(devlist);
 
                _decode_traces.clear();
-               update_signals(sdi);
-               read_sample_rate(sdi);
+               update_signals(dev_inst);
+               read_sample_rate(dev_inst->dev_inst());
 
                _sampling_thread = boost::thread(
                        &SigSession::load_session_thread_proc, this,
@@ -146,7 +145,7 @@ void SigSession::load_file(const string &name,
                        return;
 
                _decode_traces.clear();
-               update_signals(in->sdi);
+               update_signals(shared_ptr<DevInst>(new DevInst(in->sdi)));
                read_sample_rate(in->sdi);
 
                _sampling_thread = boost::thread(
@@ -166,14 +165,16 @@ void SigSession::start_capture(function<void (const QString)> error_handler)
        stop_capture();
 
        // Check that a device instance has been selected.
-       if (!_sdi) {
+       if (!_dev_inst) {
                qDebug() << "No device selected";
                return;
        }
 
+       assert(_dev_inst->dev_inst());
+
        // Check that at least one probe is enabled
        const GSList *l;
-       for (l = _sdi->probes; l; l = l->next) {
+       for (l = _dev_inst->dev_inst()->probes; l; l = l->next) {
                sr_probe *const probe = (sr_probe*)l->data;
                assert(probe);
                if (probe->enabled)
@@ -187,7 +188,8 @@ void SigSession::start_capture(function<void (const QString)> error_handler)
 
        // Begin the session
        _sampling_thread = boost::thread(
-               &SigSession::sample_thread_proc, this, _sdi, error_handler);
+               &SigSession::sample_thread_proc, this, _dev_inst,
+                       error_handler);
 }
 
 void SigSession::stop_capture()
@@ -382,8 +384,9 @@ sr_input* SigSession::load_input_file_format(const string &filename,
        return in;
 }
 
-void SigSession::update_signals(const sr_dev_inst *const sdi)
+void SigSession::update_signals(shared_ptr<DevInst> dev_inst)
 {
+       assert(dev_inst);
        assert(_capture_state == Stopped);
 
        unsigned int logic_probe_count = 0;
@@ -392,8 +395,10 @@ void SigSession::update_signals(const sr_dev_inst *const sdi)
        _decode_traces.clear();
 
        // Detect what data types we will receive
-       if(sdi) {
-               for (const GSList *l = sdi->probes; l; l = l->next) {
+       if(dev_inst) {
+               assert(dev_inst->dev_inst());
+               for (const GSList *l = dev_inst->dev_inst()->probes;
+                       l; l = l->next) {
                        const sr_probe *const probe = (const sr_probe *)l->data;
                        if (!probe->enabled)
                                continue;
@@ -424,10 +429,12 @@ void SigSession::update_signals(const sr_dev_inst *const sdi)
 
                _signals.clear();
 
-               if(!sdi)
+               if(!dev_inst)
                        break;
 
-               for (const GSList *l = sdi->probes; l; l = l->next) {
+               assert(dev_inst->dev_inst());
+               for (const GSList *l = dev_inst->dev_inst()->probes;
+                       l; l = l->next) {
                        shared_ptr<view::Signal> signal;
                        sr_probe *const probe = (sr_probe *)l->data;
                        assert(probe);
@@ -465,8 +472,9 @@ void SigSession::update_signals(const sr_dev_inst *const sdi)
 
 bool SigSession::is_trigger_enabled() const
 {
-       assert(_sdi);
-       for (const GSList *l = _sdi->probes; l; l = l->next) {
+       assert(_dev_inst);
+       assert(_dev_inst->dev_inst());
+       for (const GSList *l = _dev_inst->dev_inst()->probes; l; l = l->next) {
                const sr_probe *const p = (const sr_probe *)l->data;
                assert(p);
                if (p->trigger && p->trigger[0] != '\0')
@@ -558,16 +566,17 @@ void SigSession::load_input_thread_proc(const string name,
        delete in;
 }
 
-void SigSession::sample_thread_proc(struct sr_dev_inst *sdi,
+void SigSession::sample_thread_proc(shared_ptr<DevInst> dev_inst,
        function<void (const QString)> error_handler)
 {
-       assert(sdi);
+       assert(dev_inst);
+       assert(dev_inst->dev_inst());
        assert(error_handler);
 
        sr_session_new();
        sr_session_datafeed_callback_add(data_feed_in_proc, NULL);
 
-       if (sr_session_dev_add(sdi) != SR_OK) {
+       if (sr_session_dev_add(dev_inst->dev_inst()) != SR_OK) {
                error_handler(tr("Failed to use device."));
                sr_session_destroy();
                return;
index 3848a3d4d6267a35093471cd7495a32c75595821..a9a7ce23dce93b5bbd70efdabc3c84a7bf1db4c3 100644 (file)
@@ -41,6 +41,7 @@ struct srd_probe;
 namespace pv {
 
 class DeviceManager;
+class DevInst;
 
 namespace data {
 class Analog;
@@ -72,14 +73,14 @@ public:
 
        ~SigSession();
 
-       struct sr_dev_inst* get_device() const;
+       boost::shared_ptr<DevInst> get_device() const;
 
        /**
         * Sets device instance that will be used in the next capture session.
         */
-       void set_device(struct sr_dev_inst *sdi);
+       void set_device(boost::shared_ptr<DevInst> dev_inst);
 
-       void release_device(struct sr_dev_inst *sdi);
+       void release_device(boost::shared_ptr<DevInst> dev_inst);
 
        void load_file(const std::string &name,
                boost::function<void (const QString)> error_handler);
@@ -107,7 +108,7 @@ public:
 private:
        void set_capture_state(capture_state state);
 
-       void update_signals(const sr_dev_inst *const sdi);
+       void update_signals(boost::shared_ptr<DevInst> dev_inst);
 
        bool is_trigger_enabled() const;
 
@@ -138,7 +139,7 @@ private:
        void load_input_thread_proc(const std::string name, sr_input *in,
                boost::function<void (const QString)> error_handler);
 
-       void sample_thread_proc(struct sr_dev_inst *sdi,
+       void sample_thread_proc(boost::shared_ptr<DevInst> dev_inst,
                boost::function<void (const QString)> error_handler);
 
        void feed_in_header(const sr_dev_inst *sdi);
@@ -162,7 +163,7 @@ private:
        /**
         * The device instance that will be used in the next capture session.
         */
-       struct sr_dev_inst *_sdi;
+       boost::shared_ptr<DevInst> _dev_inst;
 
        std::vector< boost::shared_ptr<view::DecodeTrace> > _decode_traces;
 
index 04aba21ab0f1ee7ab02f6468f9be9b504351043d..59d190d427792db64221feb338d166257dfbe2ec 100644 (file)
 #include "samplingbar.h"
 
 #include <pv/devicemanager.h>
+#include <pv/devinst.h>
 #include <pv/popups/deviceoptions.h>
 #include <pv/popups/probes.h>
 
+using boost::shared_ptr;
+using std::map;
 using std::max;
 using std::min;
 using std::string;
@@ -95,14 +98,20 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) :
 }
 
 void SamplingBar::set_device_list(
-       const std::list<struct sr_dev_inst*> &devices)
+       const std::list< shared_ptr<pv::DevInst> > &devices)
 {
        _updating_device_selector = true;
 
        _device_selector.clear();
+       _device_selector_map.clear();
 
-       BOOST_FOREACH (sr_dev_inst *sdi, devices) {
-               const string title = DeviceManager::format_device_title(sdi);
+       BOOST_FOREACH (shared_ptr<pv::DevInst> dev_inst, devices) {
+               assert(dev_inst);
+               const string title = dev_inst->format_device_title();
+               const sr_dev_inst *sdi = dev_inst->dev_inst();
+               assert(sdi);
+
+               _device_selector_map[sdi] = dev_inst;
                _device_selector.addItem(title.c_str(),
                        qVariantFromValue((void*)sdi));
        }
@@ -112,20 +121,32 @@ void SamplingBar::set_device_list(
        on_device_selected();
 }
 
-struct sr_dev_inst* SamplingBar::get_selected_device() const
+shared_ptr<pv::DevInst> SamplingBar::get_selected_device() const
 {
        const int index = _device_selector.currentIndex();
        if (index < 0)
-               return NULL;
+               return shared_ptr<pv::DevInst>();
+
+       const sr_dev_inst *const sdi =
+               (const sr_dev_inst*)_device_selector.itemData(
+                       index).value<void*>();
+       assert(sdi);
 
-       return (sr_dev_inst*)_device_selector.itemData(
-               index).value<void*>();
+       map<const sr_dev_inst*, boost::weak_ptr<DevInst> >::
+               const_iterator iter = _device_selector_map.find(sdi);
+       if (iter == _device_selector_map.end())
+               return shared_ptr<pv::DevInst>();
+
+       return shared_ptr<pv::DevInst>((*iter).second);
 }
 
-void SamplingBar::set_selected_device(struct sr_dev_inst *const sdi)
+void SamplingBar::set_selected_device(boost::shared_ptr<pv::DevInst> dev_inst)
 {
+       assert(dev_inst);
+
        for (int i = 0; i < _device_selector.count(); i++)
-               if (sdi == _device_selector.itemData(i).value<void*>()) {
+               if (dev_inst->dev_inst() ==
+                       _device_selector.itemData(i).value<void*>()) {
                        _device_selector.setCurrentIndex(i);
                        return;
                }
@@ -141,14 +162,17 @@ void SamplingBar::set_capture_state(pv::SigSession::capture_state state)
 
 void SamplingBar::update_sample_rate_selector()
 {
-       const sr_dev_inst *const sdi = get_selected_device();
        GVariant *gvar_dict, *gvar_list;
        const uint64_t *elements = NULL;
        gsize num_elements;
 
-       if (!sdi)
+       const shared_ptr<DevInst> dev_inst = get_selected_device();
+       if (!dev_inst)
                return;
 
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
+       assert(sdi);
+
        _updating_sample_rate = true;
 
        if (sr_config_list(sdi->driver, sdi, NULL,
@@ -203,10 +227,14 @@ void SamplingBar::update_sample_rate_selector()
 
 void SamplingBar::update_sample_rate_selector_value()
 {
-       sr_dev_inst *const sdi = get_selected_device();
        GVariant *gvar;
        uint64_t samplerate;
 
+       const shared_ptr<DevInst> dev_inst = get_selected_device();
+       if (!dev_inst)
+               return;
+
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
        assert(sdi);
 
        if (sr_config_get(sdi->driver, sdi, NULL,
@@ -225,9 +253,13 @@ void SamplingBar::update_sample_rate_selector_value()
 
 void SamplingBar::update_sample_count_selector()
 {
-       sr_dev_inst *const sdi = get_selected_device();
        GVariant *gvar;
 
+       const shared_ptr<DevInst> dev_inst = get_selected_device();
+       if (!dev_inst)
+               return;
+
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
        assert(sdi);
 
        _updating_sample_count = true;
@@ -275,7 +307,11 @@ void SamplingBar::commit_sample_count()
 {
        uint64_t sample_count = 0;
 
-       sr_dev_inst *const sdi = get_selected_device();
+       const shared_ptr<DevInst> dev_inst = get_selected_device();
+       if (!dev_inst)
+               return;
+
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
        assert(sdi);
 
        sample_count = _sample_count.value();
@@ -292,7 +328,11 @@ void SamplingBar::commit_sample_rate()
 {
        uint64_t sample_rate = 0;
 
-       sr_dev_inst *const sdi = get_selected_device();
+       const shared_ptr<DevInst> dev_inst = get_selected_device();
+       if (!dev_inst)
+               return;
+
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
        assert(sdi);
 
        sample_rate = _sample_rate.value();
@@ -316,11 +356,17 @@ void SamplingBar::on_device_selected()
        if (_updating_device_selector)
                return;
 
-       sr_dev_inst *const sdi = get_selected_device();
-       _session.set_device(sdi);
+       const shared_ptr<DevInst> dev_inst = get_selected_device();
+       if (!dev_inst)
+               return;
+
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
+       assert(sdi);
+
+       _session.set_device(dev_inst);
 
        // Update the configure popup
-       DeviceOptions *const opts = new DeviceOptions(sdi, this);
+       DeviceOptions *const opts = new DeviceOptions(dev_inst, this);
        _configure_button_action->setVisible(
                !opts->binding().properties().empty());
        _configure_button.set_popup(opts);
index 6fc8abd38e0fcdce4bcd6a45f2a4a36233f0b424..94d9344e1e07b4403d474e8b2748fc6c4149c478 100644 (file)
@@ -24,6 +24,9 @@
 #include <stdint.h>
 
 #include <list>
+#include <map>
+
+#include <boost/shared_ptr.hpp>
 
 #include <QComboBox>
 #include <QDoubleSpinBox>
 #include <pv/widgets/popuptoolbutton.h>
 #include <pv/widgets/sweeptimingwidget.h>
 
-struct st_dev_inst;
 class QAction;
 
 namespace pv {
 
+class DevInst;
 class SigSession;
 
 namespace toolbars {
@@ -55,10 +58,11 @@ private:
 public:
        SamplingBar(SigSession &session, QWidget *parent);
 
-       void set_device_list(const std::list<struct sr_dev_inst*> &devices);
+       void set_device_list(
+               const std::list< boost::shared_ptr<pv::DevInst> > &devices);
 
-       struct sr_dev_inst* get_selected_device() const;
-       void set_selected_device(struct sr_dev_inst *const sdi);
+       boost::shared_ptr<pv::DevInst> get_selected_device() const;
+       void set_selected_device(boost::shared_ptr<pv::DevInst> dev_inst);
 
        void set_capture_state(pv::SigSession::capture_state state);
 
@@ -82,6 +86,8 @@ private:
        SigSession &_session;
 
        QComboBox _device_selector;
+       std::map<const sr_dev_inst*, boost::weak_ptr<DevInst> >
+               _device_selector_map;
        bool _updating_device_selector;
 
        pv::widgets::PopupToolButton _configure_button;
index 65ecae53724be4394418472ac84dd9c0f7fe567f..bc6e09fa2aaf9e63adad840686ec7d3cdd634e98 100644 (file)
 #include "logicsignal.h"
 #include "view.h"
 
-#include "pv/sigsession.h"
-#include "pv/data/logic.h"
-#include "pv/data/logicsnapshot.h"
-#include "pv/view/view.h"
+#include <pv/sigsession.h>
+#include <pv/devinst.h>
+#include <pv/data/logic.h>
+#include <pv/data/logicsnapshot.h>
+#include <pv/view/view.h>
 
 using boost::shared_ptr;
 using std::deque;
@@ -246,7 +247,12 @@ void LogicSignal::populate_popup_form(QWidget *parent, QFormLayout *form)
        Signal::populate_popup_form(parent, form);
 
        // Add the trigger actions
-       const sr_dev_inst *const sdi = _session.get_device();
+       boost::shared_ptr<DevInst> dev_inst = _session.get_device();
+       assert(dev_inst);
+
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
+       assert(sdi);
+
        if (sr_config_list(sdi->driver, sdi, NULL, SR_CONF_TRIGGER_TYPE,
                &gvar) == SR_OK)
        {
@@ -302,7 +308,12 @@ void LogicSignal::set_trigger(char type)
        const char *const trigger_string =
                (type != 0) ? trigger_type_string : NULL;
 
-       const sr_dev_inst *const sdi = _session.get_device();
+       boost::shared_ptr<DevInst> dev_inst = _session.get_device();
+       assert(dev_inst);
+
+       const sr_dev_inst *const sdi = dev_inst->dev_inst();
+       assert(sdi);
+
        const int probe_count = g_slist_length(sdi->probes);
        assert(probe_count > 0);