From dbfbe50df671ebded3cf08b1794d8dd35ec51690 Mon Sep 17 00:00:00 2001 From: Rainer Clasen Date: Fri, 22 Jul 2011 00:15:24 +0200 Subject: [PATCH] split Device class to allow keeping download state right now there's just one object for each Device type througout the whole app. This forbids keeping actual state in the Device object during download/cleanup. This patch puts the list of supported Devices into a seperate class. Actual Device objects are now created dynamically. This is necessary for the upcoming Download changes. --- src/Device.cpp | 28 ++++++++++++++++++---------- src/Device.h | 35 ++++++++++++++++++++++++++++------- src/DownloadRideDialog.cpp | 21 ++++++++++++--------- src/MacroDevice.cpp | 14 ++++++++++---- src/MacroDevice.h | 14 +++++++++++--- src/PowerTapDevice.cpp | 12 +++++++++--- src/PowerTapDevice.h | 13 ++++++++++--- src/SrmDevice.cpp | 16 +++++++++------- src/SrmDevice.h | 25 +++++++++++++++++++++---- 9 files changed, 128 insertions(+), 50 deletions(-) diff --git a/src/Device.cpp b/src/Device.cpp index 9dba014f2..f60880000 100644 --- a/src/Device.cpp +++ b/src/Device.cpp @@ -18,7 +18,9 @@ #include "Device.h" -typedef QMap DevicesMap; +#define tr(s) QObject::tr(s) + +typedef QMap DevicesMap; static DevicesMap *devicesPtr; @@ -26,28 +28,34 @@ inline DevicesMap & devices() { if (devicesPtr == NULL) - devicesPtr = new QMap; + devicesPtr = new QMap; return *devicesPtr; } +Device::~Device() +{ + if( dev->isOpen() ) + dev->close(); +} + QList -Device::deviceTypes() +Devices::typeNames() { return devices().keys(); } -Device & -Device::device(const QString &deviceType) +DevicesPtr +Devices::getType(const QString &deviceTypeName ) { - assert(devices().contains(deviceType)); - return *devices().value(deviceType); + assert(devices().contains(deviceTypeName)); + return devices().value(deviceTypeName); } bool -Device::addDevice(const QString &deviceType, Device *device) +Devices::addType(const QString &deviceTypeName, DevicesPtr p ) { - assert(!devices().contains(deviceType)); - devices().insert(deviceType, device); + assert(!devices().contains(deviceTypeName)); + devices().insert(deviceTypeName, p); return true; } diff --git a/src/Device.h b/src/Device.h index 798f83c8b..8b51594e7 100644 --- a/src/Device.h +++ b/src/Device.h @@ -23,22 +23,43 @@ #include "CommPort.h" #include +struct Device; +typedef boost::shared_ptr DevicePtr; + struct Device { - virtual ~Device() {} + Device( CommPortPtr dev ) : dev( dev ) {}; + virtual ~Device(); typedef boost::function StatusCallback; - virtual QString downloadInstructions() const = 0; - virtual bool download(CommPortPtr dev, const QDir &tmpdir, + virtual bool download( const QDir &tmpdir, QString &tmpname, QString &filename, StatusCallback statusCallback, QString &err) = 0; - virtual void cleanup(CommPortPtr dev) { (void) dev; } - static QList deviceTypes(); - static Device &device(const QString &deviceType); - static bool addDevice(const QString &deviceType, Device *device); + virtual void cleanup() { (void) dev; }; + +protected: + CommPortPtr dev; + }; +struct Devices; +typedef boost::shared_ptr DevicesPtr; + +struct Devices +{ + virtual DevicePtr newDevice( CommPortPtr ) = 0; + + virtual bool canCleanup() { return false; }; + virtual QString downloadInstructions() { return ""; }; + + + static QList typeNames(); + static DevicesPtr getType(const QString &deviceTypeName ); + static bool addType(const QString &deviceTypeName, DevicesPtr p ); +}; + + #endif // _GC_Device_h diff --git a/src/DownloadRideDialog.cpp b/src/DownloadRideDialog.cpp index b0dee63a3..943c83fd9 100644 --- a/src/DownloadRideDialog.cpp +++ b/src/DownloadRideDialog.cpp @@ -42,7 +42,7 @@ DownloadRideDialog::DownloadRideDialog(MainWindow *mainWindow, label->setIndent(10); deviceCombo = new QComboBox(this); - QList deviceTypes = Device::deviceTypes(); + QList deviceTypes = Devices::typeNames(); assert(deviceTypes.size() > 0); BOOST_FOREACH(QString device, deviceTypes) { deviceCombo->addItem(device); @@ -87,8 +87,8 @@ DownloadRideDialog::setReadyInstruct() eraseRideButton->setEnabled(false); } else { - Device &device = Device::device(deviceCombo->currentText()); - QString inst = device.downloadInstructions(); + DevicesPtr devtype = Devices::getType(deviceCombo->currentText()); + QString inst = devtype->downloadInstructions(); if (inst.size() == 0) label->setText("Click Download to begin downloading."); else @@ -152,9 +152,11 @@ DownloadRideDialog::downloadClicked() assert(dev); QString err; QString tmpname, filename; - Device &device = Device::device(deviceCombo->currentText()); - if (!device.download( - dev, home, tmpname, filename, + DevicesPtr devtype = Devices::getType(deviceCombo->currentText()); + DevicePtr device = devtype->newDevice( dev ); + + if (!device->download( + home, tmpname, filename, boost::bind(&DownloadRideDialog::statusCallback, this, _1), err)) { if (cancelled) { @@ -212,7 +214,7 @@ DownloadRideDialog::downloadClicked() QMessageBox::information(this, tr("Success"), tr("Download complete.")); mainWindow->addRide(filename); - device.cleanup(dev); + device->cleanup(); downloadInProgress = false; accept(); @@ -233,8 +235,9 @@ DownloadRideDialog::eraseClicked() } } assert(dev); - Device &device = Device::device(deviceCombo->currentText()); - device.cleanup(dev); + DevicesPtr devtype = Devices::getType(deviceCombo->currentText()); + DevicePtr device = devtype->newDevice( dev ); + device->cleanup(); downloadInProgress = false; accept(); } diff --git a/src/MacroDevice.cpp b/src/MacroDevice.cpp index 5c553cf00..8a2f7880d 100644 --- a/src/MacroDevice.cpp +++ b/src/MacroDevice.cpp @@ -41,15 +41,21 @@ #define LAST_PAGE 0xFA0A // LastPage number static bool macroRegistered = - Device::addDevice("O-Synce Macro PC-Link", new MacroDevice()); + Devices::addType("O-Synce Macro PC-Link", DevicesPtr(new MacroDevices()) ); QString -MacroDevice::downloadInstructions() const +MacroDevices::downloadInstructions() const { return ("Make sure the Macro unit is turned\n" "on and that its display says, \"PC Link\""); } +DevicePtr +MacroDevices::newDevice( CommPortPtr dev ) +{ + return DevicePtr( new MacroDevice( dev )); +} + static QString cEscape(char *buf, int len) { @@ -85,7 +91,7 @@ hexHex2Int(char c, char c2) } bool -MacroDevice::download(CommPortPtr dev, const QDir &tmpdir, +MacroDevice::download( const QDir &tmpdir, QString &tmpname, QString &filename, StatusCallback statusCallback, QString &err) { @@ -239,7 +245,7 @@ MacroDevice::download(CommPortPtr dev, const QDir &tmpdir, } void -MacroDevice::cleanup(CommPortPtr dev){ +MacroDevice::cleanup(){ if (MACRO_DEBUG) printf("Erase all records on computer\n"); QString err; diff --git a/src/MacroDevice.h b/src/MacroDevice.h index 50edbc384..2a6476cee 100644 --- a/src/MacroDevice.h +++ b/src/MacroDevice.h @@ -6,15 +6,23 @@ class DeviceFileInfo; +struct MacroDevices : public Devices +{ + virtual DevicePtr newDevice( CommPortPtr dev ); + virtual QString downloadInstructions() const; + virtual bool canCleanup( void ) {return true; }; +}; + struct MacroDevice : public Device { - virtual QString downloadInstructions() const; + MacroDevice( CommPortPtr dev ) : + Device( dev ) {}; - virtual bool download(CommPortPtr dev, const QDir &tmpdir, + virtual bool download( const QDir &tmpdir, QString &tmpname, QString &filename, StatusCallback statusCallback, QString &err); - virtual void cleanup(CommPortPtr dev); + virtual void cleanup(); }; class MacroPacket diff --git a/src/PowerTapDevice.cpp b/src/PowerTapDevice.cpp index 71f897be7..098fa59ed 100644 --- a/src/PowerTapDevice.cpp +++ b/src/PowerTapDevice.cpp @@ -23,10 +23,16 @@ #define PT_DEBUG false static bool powerTapRegistered = - Device::addDevice("PowerTap", new PowerTapDevice()); + Devices::addType("PowerTap", DevicesPtr(new PowerTapDevices()) ); + +DevicePtr +PowerTapDevices::newDevice( CommPortPtr dev ) +{ + return DevicePtr( new PowerTapDevice( dev )); +} QString -PowerTapDevice::downloadInstructions() const +PowerTapDevices::downloadInstructions() const { return ("Make sure the PowerTap unit is turned\n" "on and that its display says, \"Host\""); @@ -114,7 +120,7 @@ readUntilNewline(CommPortPtr dev, char *buf, int len, QString &err) } bool -PowerTapDevice::download(CommPortPtr dev, const QDir &tmpdir, +PowerTapDevice::download( const QDir &tmpdir, QString &tmpname, QString &filename, StatusCallback statusCallback, QString &err) { diff --git a/src/PowerTapDevice.h b/src/PowerTapDevice.h index 0ffdded5d..3a3025d59 100644 --- a/src/PowerTapDevice.h +++ b/src/PowerTapDevice.h @@ -20,13 +20,20 @@ #define _GC_PowerTapDevice_h 1 #include "GoldenCheetah.h" -#include "CommPort.h" #include "Device.h" +struct PowerTapDevices : public Devices +{ + virtual DevicePtr newDevice( CommPortPtr dev ); + virtual QString downloadInstructions() const; +}; + struct PowerTapDevice : public Device { - virtual QString downloadInstructions() const; - virtual bool download(CommPortPtr dev, const QDir &tmpdir, + PowerTapDevice( CommPortPtr dev ) : + Device( dev ) {}; + + virtual bool download( const QDir &tmpdir, QString &tmpname, QString &filename, StatusCallback statusCallback, QString &err); }; diff --git a/src/SrmDevice.cpp b/src/SrmDevice.cpp index 0ca1fd60e..c2e6a6962 100644 --- a/src/SrmDevice.cpp +++ b/src/SrmDevice.cpp @@ -27,15 +27,17 @@ #define tr(s) QObject::tr(s) -static bool srm5Registered = Device::addDevice("SRM PCV", new SrmDevice( 5 )); -static bool srm7Registered = Device::addDevice("SRM PCVI/7", new SrmDevice( 7 )); +static bool srm5Registered = + Devices::addType("SRM PCV", DevicesPtr(new SrmDevices( 5 )) ); +static bool srm7Registered = + Devices::addType("SRM PCVI/7", DevicesPtr(new SrmDevices( 7 ))); static Device::StatusCallback cb; -QString -SrmDevice::downloadInstructions() const +DevicePtr +SrmDevices::newDevice( CommPortPtr dev ) { - return ""; // no particular instructions for SRM + return DevicePtr( new SrmDevice( dev, protoVersion)); } static void progress( size_t total, size_t done, void *user_data ) @@ -64,7 +66,7 @@ get_tmpname(const QDir &tmpdir, QString &tmpname, QString &err) } bool -SrmDevice::download(CommPortPtr dev, const QDir &tmpdir, +SrmDevice::download( const QDir &tmpdir, QString &tmpname, QString &filename, StatusCallback statusCallback, QString &err) { @@ -188,7 +190,7 @@ fail: } void -SrmDevice::cleanup(CommPortPtr dev) +SrmDevice::cleanup() { QString err; srmio_io_t io( NULL ); diff --git a/src/SrmDevice.h b/src/SrmDevice.h index dcfc8e722..33b91e402 100644 --- a/src/SrmDevice.h +++ b/src/SrmDevice.h @@ -20,16 +20,33 @@ #define _GC_SrmDevice_h 1 #include "GoldenCheetah.h" -#include "CommPort.h" #include "Device.h" +struct SrmDevices : public Devices +{ + SrmDevices( int protoVersion ) : protoVersion( protoVersion ) {} + + virtual DevicePtr newDevice( CommPortPtr dev ); + virtual bool canCleanup( void ) {return true; }; + +private: + int protoVersion; +}; + struct SrmDevice : public Device { - virtual QString downloadInstructions() const; - virtual bool download(CommPortPtr dev, const QDir &tmpdir, + SrmDevice( CommPortPtr dev, int protoVersion ) : + Device( dev ), + protoVersion( protoVersion ) {}; + + virtual bool download( const QDir &tmpdir, QString &tmpname, QString &filename, StatusCallback statusCallback, QString &err); - virtual void cleanup(CommPortPtr dev); + + virtual void cleanup(); + +private: + int protoVersion; }; #endif // _GC_SrmDevice_h