diff options
author | Richard Moe Gustavsen <richard.gustavsen@digia.com> | 2013-06-10 13:17:53 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-06-12 11:14:48 +0200 |
commit | be1d61cbbec9d02d95cc8ee5d0bc655b81d6a07d (patch) | |
tree | 1d14af616412918fde292a123f1ba1e8629a8202 /src/plugins | |
parent | b01f928735a768fe676df60523be1fd718d45593 (diff) | |
download | qtsensors-be1d61cbbec9d02d95cc8ee5d0bc655b81d6a07d.tar.gz |
iOS: change magnetometer implementation to use Timer base polling
Ref change: 102bdf3
We need to change the implementation to use polling rather
than callback to achieve full performance together with
fine-grained QTimers.
Change-Id: Ic3bf978633c56175eeca90cad8ed764a0b1c9b0c
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/sensors/ios/iosmagnetometer.h | 8 | ||||
-rw-r--r-- | src/plugins/sensors/ios/iosmagnetometer.mm | 129 |
2 files changed, 54 insertions, 83 deletions
diff --git a/src/plugins/sensors/ios/iosmagnetometer.h b/src/plugins/sensors/ios/iosmagnetometer.h index 72ceab6..b0dc848 100644 --- a/src/plugins/sensors/ios/iosmagnetometer.h +++ b/src/plugins/sensors/ios/iosmagnetometer.h @@ -42,7 +42,7 @@ #ifndef IOSMAGNETOMETER_H #define IOSMAGNETOMETER_H -#include <Foundation/Foundation.h> +#include <CoreMotion/CMMotionManager.h> #include <qsensorbackend.h> #include <qmagnetometer.h> @@ -55,7 +55,7 @@ public: static char const * const id; explicit IOSMagnetometer(QSensor *sensor); - ~IOSMagnetometer(); + void timerEvent(QTimerEvent *); void start(); void stop(); @@ -64,8 +64,10 @@ public: void startDeviceMotion(); private: - NSOperationQueue *m_updateQueue; + CMMotionManager *m_motionManager; QMagnetometerReading m_reading; + int m_timer; + bool m_returnGeoValues; }; QT_END_NAMESPACE diff --git a/src/plugins/sensors/ios/iosmagnetometer.mm b/src/plugins/sensors/ios/iosmagnetometer.mm index f46d7d5..95f85ae 100644 --- a/src/plugins/sensors/ios/iosmagnetometer.mm +++ b/src/plugins/sensors/ios/iosmagnetometer.mm @@ -39,9 +39,6 @@ ** ****************************************************************************/ -#include <CoreMotion/CMMotionManager.h> -#include <QPointer> - #include "iosmotionmanager.h" #include "iosmagnetometer.h" @@ -51,7 +48,9 @@ char const * const IOSMagnetometer::id("ios.magnetometer"); IOSMagnetometer::IOSMagnetometer(QSensor *sensor) : QSensorBackend(sensor) - , m_updateQueue([[NSOperationQueue alloc] init]) + , m_motionManager([QIOSMotionManager sharedManager]) + , m_timer(0) + , m_returnGeoValues(false) { setReading<QMagnetometerReading>(&m_reading); // Technical information about data rate is not found, but @@ -62,94 +61,64 @@ IOSMagnetometer::IOSMagnetometer(QSensor *sensor) addOutputRange(-0.0002, 0.0002, 1e-08); } -IOSMagnetometer::~IOSMagnetometer() -{ - [m_updateQueue release]; -} - void IOSMagnetometer::start() { - if (static_cast<QMagnetometer *>(sensor())->returnGeoValues()) - startDeviceMotion(); + int hz = sensor()->dataRate(); + m_timer = startTimer(1000 / (hz == 0 ? 60 : hz)); + m_returnGeoValues = static_cast<QMagnetometer *>(sensor())->returnGeoValues(); + + if (m_returnGeoValues) + [m_motionManager startDeviceMotionUpdates]; else - startMagnetometer(); + [m_motionManager startMagnetometerUpdates]; } -void IOSMagnetometer::startMagnetometer() +void IOSMagnetometer::stop() { - CMMotionManager *motionManager = [QIOSMotionManager sharedManager]; - // Convert Hz to NSTimeInterval: - int hz = sensor()->dataRate(); - motionManager.magnetometerUpdateInterval = (hz == 0) ? 0 : 1. / hz; - - QPointer<QObject> self = this; - [motionManager startMagnetometerUpdatesToQueue:m_updateQueue withHandler:^(CMMagnetometerData *data, NSError *error) { - // NSOperationQueue is multi-threaded, so we process the data by queuing a callback to - // the main application queue. By the time the callback executes, IOSMagnetometer might - // have been deleted, so we need an extra QPointer check for that: - dispatch_async(dispatch_get_main_queue(), ^{ - if (self) { - Q_UNUSED(error); - CMMagneticField field = data.magneticField; - // Convert NSTimeInterval to microseconds and microtesla to tesla: - m_reading.setTimestamp(quint64(data.timestamp * 1e6)); - m_reading.setX(qreal(field.x) / 1e6); - m_reading.setY(qreal(field.y) / 1e6); - m_reading.setZ(qreal(field.z) / 1e6); - m_reading.setCalibrationLevel(1.0); - newReadingAvailable(); - } - }); - }]; + if (m_returnGeoValues) + [m_motionManager stopDeviceMotionUpdates]; + else + [m_motionManager stopMagnetometerUpdates]; + killTimer(m_timer); + m_timer = 0; } -void IOSMagnetometer::startDeviceMotion() +void IOSMagnetometer::timerEvent(QTimerEvent *) { - CMMotionManager *motionManager = [QIOSMotionManager sharedManager]; - // Convert Hz to NSTimeInterval: - int hz = sensor()->dataRate(); - motionManager.deviceMotionUpdateInterval = (hz == 0) ? 0 : 1. / hz; - QPointer<QObject> self = this; + CMMagneticField field; - [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryCorrectedZVertical - toQueue:m_updateQueue withHandler:^(CMDeviceMotion *data, NSError *error) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (self) { - Q_UNUSED(error); - CMCalibratedMagneticField calibratedField = data.magneticField; - CMMagneticField field = calibratedField.field; - field = motionManager.deviceMotion.magneticField.field; - // Convert NSTimeInterval to microseconds and microtesla to tesla: - m_reading.setTimestamp(quint64(data.timestamp * 1e6)); - m_reading.setX(qreal(field.x) / 1e6); - m_reading.setY(qreal(field.y) / 1e6); - m_reading.setZ(qreal(field.z) / 1e6); + if (m_returnGeoValues) { + CMDeviceMotion *deviceMotion = m_motionManager.deviceMotion; + CMCalibratedMagneticField calibratedField = deviceMotion.magneticField; + field = calibratedField.field; + m_reading.setTimestamp(quint64(deviceMotion.timestamp * 1e6)); - switch (calibratedField.accuracy) { - case CMMagneticFieldCalibrationAccuracyUncalibrated: - m_reading.setCalibrationLevel(0.0); - break; - case CMMagneticFieldCalibrationAccuracyLow: - m_reading.setCalibrationLevel(0.3); - break; - case CMMagneticFieldCalibrationAccuracyMedium: - m_reading.setCalibrationLevel(0.6); - break; - case CMMagneticFieldCalibrationAccuracyHigh: - m_reading.setCalibrationLevel(1.0); - break; - } + switch (calibratedField.accuracy) { + case CMMagneticFieldCalibrationAccuracyUncalibrated: + m_reading.setCalibrationLevel(0.0); + break; + case CMMagneticFieldCalibrationAccuracyLow: + m_reading.setCalibrationLevel(0.3); + break; + case CMMagneticFieldCalibrationAccuracyMedium: + m_reading.setCalibrationLevel(0.6); + break; + case CMMagneticFieldCalibrationAccuracyHigh: + m_reading.setCalibrationLevel(1.0); + break; + } + } else { + CMMagnetometerData *data = m_motionManager.magnetometerData; + field = data.magneticField; + m_reading.setTimestamp(quint64(data.timestamp * 1e6)); + m_reading.setCalibrationLevel(1.0); + } - newReadingAvailable(); - } - }); - }]; -} - -void IOSMagnetometer::stop() -{ - [[QIOSMotionManager sharedManager] stopMagnetometerUpdates]; - [[QIOSMotionManager sharedManager] stopDeviceMotionUpdates]; + // Convert NSTimeInterval to microseconds and microtesla to tesla: + m_reading.setX(qreal(field.x) / 1e6); + m_reading.setY(qreal(field.y) / 1e6); + m_reading.setZ(qreal(field.z) / 1e6); + newReadingAvailable(); } QT_END_NAMESPACE |