From: Joel Holdsworth Date: Sun, 9 Feb 2014 13:40:15 +0000 (+0000) Subject: Wrapped sr_dev_inst in a class: pv::DevInst X-Git-Tag: pulseview-0.2.0~82 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=19adbc2c342b190161ec1223377a3619974b91f7;p=pulseview.git Wrapped sr_dev_inst in a class: pv::DevInst --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d98ff54c..695da5b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/pv/devicemanager.cpp b/pv/devicemanager.cpp index 14ad16ef..39c311c5 100644 --- a/pv/devicemanager.cpp +++ b/pv/devicemanager.cpp @@ -19,15 +19,16 @@ */ #include "devicemanager.h" +#include "devinst.h" #include "sigsession.h" #include -#include #include #include #include +using boost::shared_ptr; using std::list; using std::map; using std::ostringstream; @@ -48,44 +49,46 @@ DeviceManager::~DeviceManager() release_devices(); } -const std::list& DeviceManager::devices() const +const list< shared_ptr >& DeviceManager::devices() const { return _devices; } -void DeviceManager::use_device(sr_dev_inst *sdi, SigSession *owner) +void DeviceManager::use_device(shared_ptr 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 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, 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 DeviceManager::driver_scan( +list< shared_ptr > DeviceManager::driver_scan( struct sr_dev_driver *const driver, GSList *const drvopts) { - list driver_devices; + list< shared_ptr > driver_devices; assert(driver); // Remove any device instances from this driver from the device // list. They will not be valid after the scan. - list::iterator i = _devices.begin(); + list< shared_ptr >::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 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( + new DevInst((sr_dev_inst*)l->data))); g_slist_free(devices); driver_devices.sort(compare_devices); @@ -109,31 +113,6 @@ list 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::iterator i = _used_devices.begin(); - i != _used_devices.end(); i++) + for (map, 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::iterator i = _used_devices.begin(); - i != _used_devices.end(); i++) - if((*i).first->driver == driver) + for (map, 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 a, + shared_ptr 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 diff --git a/pv/devicemanager.h b/pv/devicemanager.h index b7f2d49a..891ba3d2 100644 --- a/pv/devicemanager.h +++ b/pv/devicemanager.h @@ -27,12 +27,14 @@ #include #include +#include + 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& devices() const; + const std::list< boost::shared_ptr >& devices() const; - void use_device(sr_dev_inst *sdi, SigSession *owner); + void use_device(boost::shared_ptr dev_inst, + SigSession *owner); - void release_device(sr_dev_inst *sdi); + void release_device(boost::shared_ptr dev_inst); - std::list driver_scan( + std::list< boost::shared_ptr > 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 a, + boost::shared_ptr b); private: struct sr_context *const _sr_ctx; - std::list _devices; - std::map _used_devices; + std::list< boost::shared_ptr > _devices; + std::map< boost::shared_ptr, pv::SigSession*> + _used_devices; }; } // namespace pv diff --git a/pv/devinst.cpp b/pv/devinst.cpp new file mode 100644 index 00000000..4a152e0c --- /dev/null +++ b/pv/devinst.cpp @@ -0,0 +1,69 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2014 Joel Holdsworth + * + * 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 +#include + +#include + +#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 index 00000000..64d27583 --- /dev/null +++ b/pv/devinst.h @@ -0,0 +1,47 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2014 Joel Holdsworth + * + * 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 + +#include + +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 diff --git a/pv/dialogs/connect.cpp b/pv/dialogs/connect.cpp index 9cd71250..11cf0e7b 100644 --- a/pv/dialogs/connect.cpp +++ b/pv/dialogs/connect.cpp @@ -20,9 +20,12 @@ #include +#include + #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 } +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 Connect::get_selected_device() const { const QListWidgetItem *const item = _device_list.currentItem(); if (!item) - return NULL; + return shared_ptr(); + + const sr_dev_inst *const sdi = (sr_dev_inst*)item->data( + Qt::UserRole).value(); + assert(sdi); - return (sr_dev_inst*)item->data(Qt::UserRole).value(); + std::map >:: + 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 devices = _device_manager.driver_scan( + const list< shared_ptr > 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 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); diff --git a/pv/dialogs/connect.h b/pv/dialogs/connect.h index 257efd35..0f272cae 100644 --- a/pv/dialogs/connect.h +++ b/pv/dialogs/connect.h @@ -21,6 +21,8 @@ #ifndef PULSEVIEW_PV_CONNECT_H #define PULSEVIEW_PV_CONNECT_H +#include + #include #include #include @@ -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 get_selected_device() const; private: void populate_drivers(); @@ -77,6 +80,8 @@ private: QPushButton _scan_button; QListWidget _device_list; + std::map > + _device_map; QDialogButtonBox _button_box; }; diff --git a/pv/mainwindow.cpp b/pv/mainwindow.cpp index e0ef3aa2..0b2805b1 100644 --- a/pv/mainwindow.cpp +++ b/pv/mainwindow.cpp @@ -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 #include +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 selected_device) { assert(_sampling_bar); - const list &devices = _device_manager.devices(); + const list< shared_ptr > &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 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 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() diff --git a/pv/mainwindow.h b/pv/mainwindow.h index 6f352f9f..6f3c8d56 100644 --- a/pv/mainwindow.h +++ b/pv/mainwindow.h @@ -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 selected_device = + boost::shared_ptr()); private slots: void load_file(QString file_name); diff --git a/pv/popups/deviceoptions.cpp b/pv/popups/deviceoptions.cpp index 6f9d7d9f..7e1be20d 100644 --- a/pv/popups/deviceoptions.cpp +++ b/pv/popups/deviceoptions.cpp @@ -27,14 +27,16 @@ #include +using boost::shared_ptr; + namespace pv { namespace popups { -DeviceOptions::DeviceOptions(sr_dev_inst *sdi, QWidget *parent) : +DeviceOptions::DeviceOptions(shared_ptr dev_inst, QWidget *parent) : Popup(parent), - _sdi(sdi), + _dev_inst(dev_inst), _layout(this), - _binding(sdi) + _binding(dev_inst) { setLayout(&_layout); diff --git a/pv/popups/deviceoptions.h b/pv/popups/deviceoptions.h index 788f9b5b..745ed994 100644 --- a/pv/popups/deviceoptions.h +++ b/pv/popups/deviceoptions.h @@ -35,12 +35,12 @@ class DeviceOptions : public pv::widgets::Popup Q_OBJECT public: - DeviceOptions(sr_dev_inst *sdi, QWidget *parent); + DeviceOptions(boost::shared_ptr dev_inst, QWidget *parent); pv::prop::binding::DeviceOptions& binding(); private: - sr_dev_inst *const _sdi; + boost::shared_ptr _dev_inst; QVBoxLayout _layout; diff --git a/pv/popups/probes.cpp b/pv/popups/probes.cpp index daad812b..b19f8967 100644 --- a/pv/popups/probes.cpp +++ b/pv/popups/probes.cpp @@ -29,6 +29,7 @@ #include "probes.h" +#include #include #include #include @@ -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 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 diff --git a/pv/prop/binding/deviceoptions.cpp b/pv/prop/binding/deviceoptions.cpp index d116521a..6da16652 100644 --- a/pv/prop/binding/deviceoptions.cpp +++ b/pv/prop/binding/deviceoptions.cpp @@ -27,11 +27,14 @@ #include "deviceoptions.h" +#include #include #include #include #include +#include + 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 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( - 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( 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 > range) { + sr_dev_inst *const sdi = _dev_inst->dev_inst(); + assert(sdi); + _properties.push_back(shared_ptr( 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) diff --git a/pv/prop/binding/deviceoptions.h b/pv/prop/binding/deviceoptions.h index ab0f0171..ca27a5b7 100644 --- a/pv/prop/binding/deviceoptions.h +++ b/pv/prop/binding/deviceoptions.h @@ -26,18 +26,24 @@ #include -#include - #include "binding.h" +#include + +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 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 _dev_inst; const sr_probe_group *const _group; }; diff --git a/pv/sigsession.cpp b/pv/sigsession.cpp index e507a099..809509bb 100644 --- a/pv/sigsession.cpp +++ b/pv/sigsession.cpp @@ -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 SigSession::get_device() const { - return _sdi; + return _dev_inst; } -void SigSession::set_device(struct sr_dev_inst *sdi) +void SigSession::set_device(shared_ptr 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 dev_inst) { - (void)sdi; + (void)dev_inst; assert(_capture_state == Stopped); - _sdi = NULL; - update_signals(NULL); + _dev_inst = shared_ptr(); } 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 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(new DevInst(in->sdi))); read_sample_rate(in->sdi); _sampling_thread = boost::thread( @@ -166,14 +165,16 @@ void SigSession::start_capture(function 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 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 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 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 dev_inst, function 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; diff --git a/pv/sigsession.h b/pv/sigsession.h index 3848a3d4..a9a7ce23 100644 --- a/pv/sigsession.h +++ b/pv/sigsession.h @@ -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 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 dev_inst); - void release_device(struct sr_dev_inst *sdi); + void release_device(boost::shared_ptr dev_inst); void load_file(const std::string &name, boost::function 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 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 error_handler); - void sample_thread_proc(struct sr_dev_inst *sdi, + void sample_thread_proc(boost::shared_ptr dev_inst, boost::function 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 _dev_inst; std::vector< boost::shared_ptr > _decode_traces; diff --git a/pv/toolbars/samplingbar.cpp b/pv/toolbars/samplingbar.cpp index 04aba21a..59d190d4 100644 --- a/pv/toolbars/samplingbar.cpp +++ b/pv/toolbars/samplingbar.cpp @@ -32,9 +32,12 @@ #include "samplingbar.h" #include +#include #include #include +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 &devices) + const std::list< shared_ptr > &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 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 SamplingBar::get_selected_device() const { const int index = _device_selector.currentIndex(); if (index < 0) - return NULL; + return shared_ptr(); + + const sr_dev_inst *const sdi = + (const sr_dev_inst*)_device_selector.itemData( + index).value(); + assert(sdi); - return (sr_dev_inst*)_device_selector.itemData( - index).value(); + map >:: + const_iterator iter = _device_selector_map.find(sdi); + if (iter == _device_selector_map.end()) + return shared_ptr(); + + return shared_ptr((*iter).second); } -void SamplingBar::set_selected_device(struct sr_dev_inst *const sdi) +void SamplingBar::set_selected_device(boost::shared_ptr dev_inst) { + assert(dev_inst); + for (int i = 0; i < _device_selector.count(); i++) - if (sdi == _device_selector.itemData(i).value()) { + if (dev_inst->dev_inst() == + _device_selector.itemData(i).value()) { _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 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 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 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 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 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 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); diff --git a/pv/toolbars/samplingbar.h b/pv/toolbars/samplingbar.h index 6fc8abd3..94d9344e 100644 --- a/pv/toolbars/samplingbar.h +++ b/pv/toolbars/samplingbar.h @@ -24,6 +24,9 @@ #include #include +#include + +#include #include #include @@ -34,11 +37,11 @@ #include #include -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 &devices); + void set_device_list( + const std::list< boost::shared_ptr > &devices); - struct sr_dev_inst* get_selected_device() const; - void set_selected_device(struct sr_dev_inst *const sdi); + boost::shared_ptr get_selected_device() const; + void set_selected_device(boost::shared_ptr dev_inst); void set_capture_state(pv::SigSession::capture_state state); @@ -82,6 +86,8 @@ private: SigSession &_session; QComboBox _device_selector; + std::map > + _device_selector_map; bool _updating_device_selector; pv::widgets::PopupToolButton _configure_button; diff --git a/pv/view/logicsignal.cpp b/pv/view/logicsignal.cpp index 65ecae53..bc6e09fa 100644 --- a/pv/view/logicsignal.cpp +++ b/pv/view/logicsignal.cpp @@ -28,10 +28,11 @@ #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 +#include +#include +#include +#include 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 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 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);