]> sigrok.org Git - pulseview.git/commitdiff
pv::DeviceManager now manages opening/closing devices
authorJoel Holdsworth <redacted>
Wed, 1 May 2013 21:12:26 +0000 (22:12 +0100)
committerBert Vermeulen <redacted>
Wed, 1 May 2013 21:47:21 +0000 (23:47 +0200)
It also notifies pv::SigSession objects when their devices are
going to be cleared.

pv/devicemanager.cpp
pv/devicemanager.h
pv/mainwindow.cpp
pv/sigsession.cpp
pv/sigsession.h

index 5a72b31b78563c73e3053e107d14b112c9e040b0..0765cac645c87315c43ca64ab39e16ac319a6cf4 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "devicemanager.h"
+#include "sigsession.h"
 
 #include <cassert>
 #include <sstream>
@@ -48,6 +49,27 @@ const std::list<sr_dev_inst*>& DeviceManager::devices() const
        return _devices;
 }
 
+void DeviceManager::use_device(sr_dev_inst *sdi, SigSession *owner)
+{
+       assert(sdi);
+       assert(owner);
+
+       _used_devices[sdi] = owner;
+
+       sr_dev_open(sdi);
+}
+
+void DeviceManager::release_device(sr_dev_inst *sdi)
+{
+       assert(sdi);
+
+       // Notify the owner, and removed the device from the used device list
+       _used_devices[sdi]->release_device(sdi);
+       _used_devices.erase(sdi);
+
+       sr_dev_close(sdi);
+}
+
 list<sr_dev_inst*> DeviceManager::driver_scan(
        struct sr_dev_driver *const driver, GSList *const drvopts)
 {
@@ -65,8 +87,8 @@ list<sr_dev_inst*> DeviceManager::driver_scan(
                        i++;
        }
 
-       // Clear all the old device instances from this driver
-       sr_dev_clear(driver);
+       // Release this driver and all it's attached devices
+       release_driver(driver);
 
        // Do the scan
        GSList *const devices = sr_driver_scan(driver, drvopts);
@@ -123,6 +145,14 @@ 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++)
+               release_device((*i).first);
+
+       _used_devices.clear();
+
+       // Clear all the drivers
        sr_dev_driver **const drivers = sr_driver_list();
        for (sr_dev_driver **driver = drivers; *driver; driver++)
                sr_dev_clear(*driver);
@@ -136,6 +166,27 @@ void DeviceManager::scan_all_drivers()
                driver_scan(*driver);
 }
 
+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)
+               {
+                       // Notify the current owner of the device
+                       (*i).second->release_device((*i).first);
+
+                       // Remove it from the used device list
+                       _used_devices.erase(i);
+
+                       // Close the device instance
+                       sr_dev_close((*i).first);
+               }
+
+       // 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)
 {
index f4be73b9274565e93832becba4e01985a54dece0..b7f2d49a7e016ce49e6b66dc0124b17b1779dbb3 100644 (file)
@@ -24,6 +24,7 @@
 #include <glib.h>
 
 #include <list>
+#include <map>
 #include <string>
 
 struct sr_context;
@@ -32,6 +33,8 @@ struct sr_dev_inst;
 
 namespace pv {
 
+class SigSession;
+
 class DeviceManager
 {
 public:
@@ -41,6 +44,10 @@ public:
 
        const std::list<sr_dev_inst*>& devices() const;
 
+       void use_device(sr_dev_inst *sdi, SigSession *owner);
+
+       void release_device(sr_dev_inst *sdi);
+
        std::list<sr_dev_inst*> driver_scan(
                struct sr_dev_driver *const driver,
                GSList *const drvopts = NULL);
@@ -50,16 +57,19 @@ public:
 private:
        void init_drivers();
 
-       static void release_devices();
+       void release_devices();
 
        void scan_all_drivers();
 
+       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);
 
 private:
        struct sr_context *const _sr_ctx;
        std::list<sr_dev_inst*> _devices;
+       std::map<sr_dev_inst*, pv::SigSession*> _used_devices;
 };
 
 } // namespace pv
index ca514bf97a703eba3e7a8bc56dbebd23467c439a..dcbaf1812ab268765e626d69f5c280042c6ff65e 100644 (file)
@@ -60,7 +60,8 @@ MainWindow::MainWindow(DeviceManager &device_manager,
        const char *open_file_name,
        QWidget *parent) :
        QMainWindow(parent),
-       _device_manager(device_manager)
+       _device_manager(device_manager),
+       _session(device_manager)
 {
        setup_ui();
        if (open_file_name) {
@@ -278,10 +279,12 @@ void MainWindow::on_actionOpen_triggered()
 void MainWindow::on_actionConnect_triggered()
 {
        dialogs::Connect dlg(this, _device_manager);
-       if (!dlg.exec())
-               return;
 
-       struct sr_dev_inst *const sdi = dlg.get_selected_device();
+       // 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() ?
+               dlg.get_selected_device() : _session.get_device();
+
        update_device_list(sdi);
 }
 
index 4fe51dd57131682ae11c31f45eb85f6aee4de461..5ab30ab1299e2e7bb81475053049eb46f189c3e1 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "sigsession.h"
 
+#include "devicemanager.h"
 #include "data/analog.h"
 #include "data/analogsnapshot.h"
 #include "data/logic.h"
@@ -39,7 +40,8 @@ namespace pv {
 // TODO: This should not be necessary
 SigSession* SigSession::_session = NULL;
 
-SigSession::SigSession() :
+SigSession::SigSession(DeviceManager &device_manager) :
+       _device_manager(device_manager),
        _sdi(NULL),
        _capture_state(Stopped)
 {
@@ -59,15 +61,28 @@ SigSession::~SigSession()
        _session = NULL;
 }
 
+struct sr_dev_inst* SigSession::get_device() const
+{
+       return _sdi;
+}
+
 void SigSession::set_device(struct sr_dev_inst *sdi)
 {
        if (_sdi)
-               sr_dev_close(_sdi);
+               _device_manager.release_device(_sdi);
        if (sdi)
-               sr_dev_open(sdi);
+               _device_manager.use_device(sdi, this);
        _sdi = sdi;
 }
 
+void SigSession::release_device(struct sr_dev_inst *sdi)
+{
+       (void)sdi;
+
+       assert(_capture_state == Stopped);
+       _sdi = NULL;
+}
+
 void SigSession::load_file(const string &name,
        function<void (const QString)> error_handler)
 {
index 1978293481423b0dbae4645c6f57d38e98ceb2e1..ae33c3a8a508713acde59c650cfadaeb256e634e 100644 (file)
@@ -36,6 +36,8 @@
 
 namespace pv {
 
+class DeviceManager;
+
 namespace data {
 class Analog;
 class AnalogSnapshot;
@@ -58,15 +60,19 @@ public:
        };
 
 public:
-       SigSession();
+       SigSession(DeviceManager &device_manager);
 
        ~SigSession();
 
+       struct sr_dev_inst* get_device() const;
+
        /**
         * Sets device instance that will be used in the next capture session.
         */
        void set_device(struct sr_dev_inst *sdi);
 
+       void release_device(struct sr_dev_inst *sdi);
+
        void load_file(const std::string &name,
                boost::function<void (const QString)> error_handler);
 
@@ -109,6 +115,7 @@ private:
                const struct sr_datafeed_packet *packet, void *cb_data);
 
 private:
+       DeviceManager &_device_manager;
 
        /**
         * The device instance that will be used in the next capture session.