From 4d9edb754b3dff3331c8d8790a04548f0981f315 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 29 Jan 2013 15:01:40 +0100 Subject: Use real properties for QSensor::bufferSize & co The #ifdef Q_DOC hack is not really needed and was confusing. In addition, expose those properties to the QML API. As a result, the backends can now listen to the bufferSizeChanged() signal to update the buffering while the sensor is running. This has been implemented for the BlackBerry platform. Change-Id: I5239ba2a4b791cfc9f684b44ff2bc103a7b5b0da Reviewed-by: Lorn Potter --- src/imports/sensors/plugins.qmltypes | 15 +++++ src/imports/sensors/qmlsensor.cpp | 47 ++++++++++++++ src/imports/sensors/qmlsensor.h | 13 ++++ src/plugins/sensors/blackberry/bbsensorbackend.cpp | 66 +++++++++++++------- src/plugins/sensors/blackberry/bbsensorbackend.h | 2 + src/sensors/qsensor.cpp | 72 +++++++++++++++++++--- src/sensors/qsensor.h | 20 ++++-- src/sensors/qsensor_p.h | 7 +++ 8 files changed, 208 insertions(+), 34 deletions(-) diff --git a/src/imports/sensors/plugins.qmltypes b/src/imports/sensors/plugins.qmltypes index 974f714..2deff79 100644 --- a/src/imports/sensors/plugins.qmltypes +++ b/src/imports/sensors/plugins.qmltypes @@ -229,6 +229,9 @@ Module { Property { name: "axesOrientationMode"; revision: 1; type: "AxesOrientationMode" } Property { name: "currentOrientation"; revision: 1; type: "int"; isReadonly: true } Property { name: "userOrientation"; revision: 1; type: "int" } + Property { name: "maxBufferSize"; revision: 1; type: "int"; isReadonly: true } + Property { name: "efficientBufferSize"; revision: 1; type: "int"; isReadonly: true } + Property { name: "bufferSize"; revision: 1; type: "int" } Signal { name: "skipDuplicatesChanged" Parameter { name: "skipDuplicates"; type: "bool" } @@ -245,6 +248,18 @@ Module { name: "userOrientationChanged" Parameter { name: "userOrientation"; type: "int" } } + Signal { + name: "maxBufferSizeChanged" + Parameter { name: "maxBufferSize"; type: "int" } + } + Signal { + name: "efficientBufferSizeChanged" + Parameter { name: "efficientBufferSize"; type: "int" } + } + Signal { + name: "bufferSizeChanged" + Parameter { name: "bufferSize"; type: "int" } + } Method { name: "start"; type: "bool" } Method { name: "stop" } } diff --git a/src/imports/sensors/qmlsensor.cpp b/src/imports/sensors/qmlsensor.cpp index 727526a..3d59a72 100644 --- a/src/imports/sensors/qmlsensor.cpp +++ b/src/imports/sensors/qmlsensor.cpp @@ -355,6 +355,50 @@ void QmlSensor::setUserOrientation(int userOrientation) sensor()->setUserOrientation(userOrientation); } +/*! + \qmlproperty int Sensor::maxBufferSize + \since QtSensors 5.1 + This property holds the maximum buffer size. + + Please see QSensor::maxBufferSize for information about this property. +*/ + +int QmlSensor::maxBufferSize() const +{ + return sensor()->maxBufferSize(); +} + +/*! + \qmlproperty int Sensor::efficientBufferSize + \since QtSensors 5.1 + The property holds the most efficient buffer size. + + Please see QSensor::efficientBufferSize for information about this property. +*/ + +int QmlSensor::efficientBufferSize() const +{ + return sensor()->efficientBufferSize(); +} + +/*! + \qmlproperty int Sensor::bufferSize + \since QtSensors 5.1 + This property holds the size of the buffer. + + Please see QSensor::bufferSize for information about this property. +*/ + +int QmlSensor::bufferSize() const +{ + return sensor()->bufferSize(); +} + +void QmlSensor::setBufferSize(int bufferSize) +{ + sensor()->setBufferSize(bufferSize); +} + /*! \qmlmethod bool Sensor::start() Start retrieving values from the sensor. Returns true if the sensor was started, false otherwise. @@ -396,6 +440,9 @@ void QmlSensor::componentComplete() this, SIGNAL(axesOrientationModeChanged(AxesOrientationMode))); connect(sensor(), SIGNAL(userOrientationChanged(int)), this, SIGNAL(userOrientationChanged(int))); connect(sensor(), SIGNAL(currentOrientationChanged(int)), this, SIGNAL(currentOrientationChanged(int))); + connect(sensor(), SIGNAL(bufferSizeChanged(int)), this, SIGNAL(bufferSizeChanged(int))); + connect(sensor(), SIGNAL(maxBufferSizeChanged(int)), this, SIGNAL(maxBufferSizeChanged(int))); + connect(sensor(), SIGNAL(efficientBufferSizeChanged(int)), this, SIGNAL(efficientBufferSizeChanged(int))); // We need to set this on the sensor object now sensor()->setIdentifier(m_identifier.toLocal8Bit()); diff --git a/src/imports/sensors/qmlsensor.h b/src/imports/sensors/qmlsensor.h index b68a7b9..f72234a 100644 --- a/src/imports/sensors/qmlsensor.h +++ b/src/imports/sensors/qmlsensor.h @@ -75,6 +75,9 @@ class QmlSensor : public QObject, public QQmlParserStatus Q_PROPERTY(AxesOrientationMode axesOrientationMode READ axesOrientationMode WRITE setAxesOrientationMode NOTIFY axesOrientationModeChanged REVISION 1) Q_PROPERTY(int currentOrientation READ currentOrientation NOTIFY currentOrientationChanged REVISION 1) Q_PROPERTY(int userOrientation READ userOrientation WRITE setUserOrientation NOTIFY userOrientationChanged REVISION 1) + Q_PROPERTY(int maxBufferSize READ maxBufferSize NOTIFY maxBufferSizeChanged REVISION 1) + Q_PROPERTY(int efficientBufferSize READ efficientBufferSize NOTIFY efficientBufferSizeChanged REVISION 1) + Q_PROPERTY(int bufferSize READ bufferSize WRITE setBufferSize NOTIFY bufferSizeChanged REVISION 1) public: // Keep in sync with QSensor::AxesOrientationMode @@ -126,6 +129,13 @@ public: int userOrientation() const; void setUserOrientation(int userOrientation); + int maxBufferSize() const; + + int efficientBufferSize() const; + + int bufferSize() const; + void setBufferSize(int bufferSize); + public Q_SLOTS: bool start(); void stop(); @@ -147,6 +157,9 @@ Q_SIGNALS: void axesOrientationModeChanged(AxesOrientationMode axesOrientationMode); void currentOrientationChanged(int currentOrientation); void userOrientationChanged(int userOrientation); + void maxBufferSizeChanged(int maxBufferSize); + void efficientBufferSizeChanged(int efficientBufferSize); + void bufferSizeChanged(int bufferSize); protected: virtual QSensor *sensor() const = 0; diff --git a/src/plugins/sensors/blackberry/bbsensorbackend.cpp b/src/plugins/sensors/blackberry/bbsensorbackend.cpp index de6661e..fec40c5 100644 --- a/src/plugins/sensors/blackberry/bbsensorbackend.cpp +++ b/src/plugins/sensors/blackberry/bbsensorbackend.cpp @@ -81,16 +81,17 @@ static void remapMatrix(const float inputMatrix[3*3], BbSensorBackendBase::BbSensorBackendBase(const QString &devicePath, sensor_type_e sensorType, QSensor *sensor) : QSensorBackend(sensor), m_deviceFile(devicePath), m_sensorType(sensorType), m_guiHelper(0), - m_started(false) + m_started(false), m_applyingBufferSize(false) { m_mappingMatrix[0] = m_mappingMatrix[3] = 1; m_mappingMatrix[1] = m_mappingMatrix[2] = 0; connect(sensor, SIGNAL(alwaysOnChanged()), this, SLOT(applyAlwaysOnProperty())); + connect(sensor, SIGNAL(bufferSizeChanged(int)), this, SLOT(applyBuffering())); connect(sensor, SIGNAL(userOrientationChanged(int)), this, SLOT(updateOrientation())); // Set some sensible default values - sensor->setProperty("efficientBufferSize", defaultBufferSize); - sensor->setProperty("maxBufferSize", defaultBufferSize); + sensor->setEfficientBufferSize(defaultBufferSize); + sensor->setMaxBufferSize(defaultBufferSize); } BbGuiHelper *BbSensorBackendBase::guiHelper() const @@ -278,24 +279,7 @@ void BbSensorBackendBase::start() return; } - // Activate event queuing if needed - bool ok = false; - const int requestedBufferSize = sensor()->property("bufferSize").toInt(&ok); - if (ok && requestedBufferSize > 1) { - sensor_devctl_queue_u queueControl; - queueControl.tx.enable = 1; - const int result = devctl(m_deviceFile.handle(), DCMD_SENSOR_QUEUE, &queueControl, sizeof(queueControl), NULL); - if (result != EOK) { - perror(QString::fromLatin1("Enabling sensor queuing for %1 failed") - .arg(m_deviceFile.fileName()).toLocal8Bit()); - } - - const int actualBufferSize = queueControl.rx.size; - sensor()->setProperty("bufferSize", actualBufferSize); - sensor()->setProperty("efficientBufferSize", actualBufferSize); - sensor()->setProperty("maxBufferSize", actualBufferSize); - } - + applyBuffering(); applyAlwaysOnProperty(); } @@ -365,6 +349,46 @@ void BbSensorBackendBase::applyAlwaysOnProperty() updatePauseState(); } +void BbSensorBackendBase::applyBuffering() +{ + if (!m_deviceFile.isOpen() || !m_started || m_applyingBufferSize) + return; + + // Flag to prevent recursion. We call setBufferSize() below, and because of the changed signal, + // we might end up in this slot again. + // The call to setBufferSize() is needed since the requested buffer size is most likely different + // from the actual buffer size that will be used. + m_applyingBufferSize = true; + + const bool enableBuffering = sensor()->bufferSize() > 1; + sensor_devctl_queue_u queueControl; + queueControl.tx.enable = enableBuffering ? 1 : 0; + const int result = devctl(m_deviceFile.handle(), DCMD_SENSOR_QUEUE, &queueControl, sizeof(queueControl), NULL); + if (result != EOK) { + perror(QString::fromLatin1("Enabling sensor queuing for %1 failed") + .arg(m_deviceFile.fileName()).toLocal8Bit()); + } else { + if (enableBuffering) { + int actualBufferSize = queueControl.rx.size; + + // Some firmware versions don't report the buffer size correctly. Simply pretend the + // buffer size is the same as the requested buffer size, as setting the buffer size to + // 1 here would seem as if buffering were disabled. + if (actualBufferSize == 1) + actualBufferSize = sensor()->bufferSize(); + + sensor()->setBufferSize(actualBufferSize); + sensor()->setEfficientBufferSize(actualBufferSize); + sensor()->setMaxBufferSize(actualBufferSize); + } else { + sensor()->setBufferSize(1); + sensor()->setEfficientBufferSize(defaultBufferSize); + sensor()->setMaxBufferSize(defaultBufferSize); + } + } + m_applyingBufferSize = false; +} + bool BbSensorBackendBase::setPaused(bool paused) { if (!m_deviceFile.isOpen()) diff --git a/src/plugins/sensors/blackberry/bbsensorbackend.h b/src/plugins/sensors/blackberry/bbsensorbackend.h index 48a7216..4e7b810 100644 --- a/src/plugins/sensors/blackberry/bbsensorbackend.h +++ b/src/plugins/sensors/blackberry/bbsensorbackend.h @@ -107,6 +107,7 @@ protected: private slots: void dataAvailable(); void applyAlwaysOnProperty(); + void applyBuffering(); bool setPaused(bool paused); void updatePauseState(); void updateOrientation(); @@ -118,6 +119,7 @@ private: BbGuiHelper *m_guiHelper; float m_mappingMatrix[4]; bool m_started; + bool m_applyingBufferSize; }; template diff --git a/src/sensors/qsensor.cpp b/src/sensors/qsensor.cpp index 125d592..01a4f7b 100644 --- a/src/sensors/qsensor.cpp +++ b/src/sensors/qsensor.cpp @@ -1016,11 +1016,33 @@ void QSensor::setUserOrientation(int userOrientation) The property holds the maximum buffer size. - Note that this may be undefined, in which case the sensor does not support any form of buffering. + Note that this may be 1, in which case the sensor does not support any form of buffering. + In that case, isFeatureSupported(QSensor::Buffering) will also return false. \sa QSensor::bufferSize, QSensor::efficientBufferSize */ +int QSensor::maxBufferSize() const +{ + Q_D(const QSensor); + return d->maxBufferSize; +} + +/*! + \since 5.1 + Sets the maximum buffer size to \a maxBufferSize. This is to be called from the + backend. +*/ +void QSensor::setMaxBufferSize(int maxBufferSize) +{ + // ### Qt 6: Remove the entire maxBufferSize property, no backend really uses it + Q_D(QSensor); + if (d->maxBufferSize != maxBufferSize) { + d->maxBufferSize = maxBufferSize; + emit maxBufferSizeChanged(maxBufferSize); + } +} + /*! \property QSensor::efficientBufferSize @@ -1028,17 +1050,36 @@ void QSensor::setUserOrientation(int userOrientation) no particular size is most efficient). Some sensor drivers have a FIFO buffer which makes it more efficient to deliver the FIFO's size worth of readings at one time. - Note that this may be undefined, in which case the sensor does not support any form of buffering. - \sa QSensor::bufferSize, QSensor::maxBufferSize */ +int QSensor::efficientBufferSize() const +{ + Q_D(const QSensor); + return d->efficientBufferSize; +} + +/*! + \since 5.1 + Sets the efficient buffer size to \a efficientBufferSize. This is to be called from the + backend. +*/ +void QSensor::setEfficientBufferSize(int efficientBufferSize) +{ + // ### Qt 6: Remove the entire efficientBufferSize property, no backend really uses it + Q_D(QSensor); + if (d->efficientBufferSize != efficientBufferSize) { + d->efficientBufferSize = efficientBufferSize; + emit efficientBufferSizeChanged(efficientBufferSize); + } +} + /*! \property QSensor::bufferSize - This property holds the size of the buffer. By default (and if the property - is left undefined), the buffer size is 1, which means no buffering. - If the maximum buffer size is 1 (or undefined), then buffering is not supported + This property holds the size of the buffer. By default, the buffer size is 1, + which means no buffering. + If the maximum buffer size is 1, then buffering is not supported by the sensor. Setting bufferSize greater than maxBufferSize will cause maxBufferSize to be used. @@ -1065,11 +1106,26 @@ void QSensor::setUserOrientation(int userOrientation) in time, for example when the event loop is blocked for too long. Without a buffer, these readings would simply be dropped. - The buffer size can only be changed while the sensor is not active. - \sa QSensor::maxBufferSize, QSensor::efficientBufferSize */ +int QSensor::bufferSize() const +{ + Q_D(const QSensor); + return d->bufferSize; +} + +void QSensor::setBufferSize(int bufferSize) +{ + // ### Qt 6: Currently only the Blackberry backend supports this, but only as an on/off switch. + // We should consider changing this to a more appropriate API. + Q_D(QSensor); + if (d->bufferSize != bufferSize) { + d->bufferSize = bufferSize; + emit bufferSizeChanged(bufferSize); + } +} + // ===================================================================== /*! diff --git a/src/sensors/qsensor.h b/src/sensors/qsensor.h index 5c47df3..2314fb9 100644 --- a/src/sensors/qsensor.h +++ b/src/sensors/qsensor.h @@ -95,11 +95,9 @@ class Q_SENSORS_EXPORT QSensor : public QObject Q_PROPERTY(AxesOrientationMode axesOrientationMode READ axesOrientationMode WRITE setAxesOrientationMode NOTIFY axesOrientationModeChanged) Q_PROPERTY(int currentOrientation READ currentOrientation NOTIFY currentOrientationChanged) Q_PROPERTY(int userOrientation READ userOrientation WRITE setUserOrientation NOTIFY userOrientationChanged) -#ifdef Q_QDOC - Q_PROPERTY(int maxBufferSize) - Q_PROPERTY(int efficientBufferSize) - Q_PROPERTY(int bufferSize) -#endif + Q_PROPERTY(int maxBufferSize READ maxBufferSize NOTIFY maxBufferSizeChanged) + Q_PROPERTY(int efficientBufferSize READ efficientBufferSize NOTIFY efficientBufferSizeChanged) + Q_PROPERTY(int bufferSize READ bufferSize WRITE setBufferSize NOTIFY bufferSizeChanged) public: enum Feature { Buffering, @@ -177,6 +175,15 @@ public: int userOrientation() const; void setUserOrientation(int userOrientation); + int maxBufferSize() const; + void setMaxBufferSize(int maxBufferSize); + + int efficientBufferSize() const; + void setEfficientBufferSize(int efficientBufferSize); + + int bufferSize() const; + void setBufferSize(int bufferSize); + public Q_SLOTS: // Start receiving values from the sensor bool start(); @@ -196,6 +203,9 @@ Q_SIGNALS: void axesOrientationModeChanged(AxesOrientationMode axesOrientationMode); void currentOrientationChanged(int currentOrientation); void userOrientationChanged(int userOrientation); + void maxBufferSizeChanged(int maxBufferSize); + void efficientBufferSizeChanged(int efficientBufferSize); + void bufferSizeChanged(int bufferSize); protected: explicit QSensor(const QByteArray &type, QSensorPrivate &dd, QObject* parent = 0); diff --git a/src/sensors/qsensor_p.h b/src/sensors/qsensor_p.h index 9b6e7e5..71a5b6e 100644 --- a/src/sensors/qsensor_p.h +++ b/src/sensors/qsensor_p.h @@ -82,6 +82,9 @@ public: , axesOrientationMode(QSensor::FixedOrientation) , currentOrientation(0) , userOrientation(0) + , bufferSize(1) + , maxBufferSize(1) + , efficientBufferSize(1) { } @@ -116,6 +119,10 @@ public: QSensor::AxesOrientationMode axesOrientationMode; int currentOrientation; int userOrientation; + + int bufferSize; + int maxBufferSize; + int efficientBufferSize; }; class QSensorReadingPrivate -- cgit v1.2.1