diff options
Diffstat (limited to 'src/plugins/sensors/ios/iosaccelerometer.mm')
-rw-r--r-- | src/plugins/sensors/ios/iosaccelerometer.mm | 105 |
1 files changed, 31 insertions, 74 deletions
diff --git a/src/plugins/sensors/ios/iosaccelerometer.mm b/src/plugins/sensors/ios/iosaccelerometer.mm index ef7d2a6d..b657b507 100644 --- a/src/plugins/sensors/ios/iosaccelerometer.mm +++ b/src/plugins/sensors/ios/iosaccelerometer.mm @@ -39,76 +39,20 @@ ** ****************************************************************************/ -#include "iosaccelerometer.h" -#include "iosmotionmanager.h" - #include <UIKit/UIAccelerometer.h> #include <CoreMotion/CMMotionManager.h> +#include <QPointer> -char const * const IOSAccelerometer::id("ios.accelerometer"); - -@interface QtIoAccelListener : NSObject -{ - IOSAccelerometer *m_qiosAccelerometer; - NSOperationQueue *m_updateQueue; -} -@end - -@implementation QtIoAccelListener - --(id)initWithQIOSAccelerometer:(IOSAccelerometer *) qiosAccelerometer -{ - self = [super init]; - if (self) { - m_qiosAccelerometer = qiosAccelerometer; - m_updateQueue = [[NSOperationQueue alloc] init]; - } - return self; -} - --(void)dealloc -{ - [m_updateQueue release]; - [super dealloc]; -} - --(void)startAccelerometer -{ - CMMotionManager *motionManager = [QIOSMotionManager sharedManager]; - - if (motionManager.deviceMotionAvailable) { - [motionManager startAccelerometerUpdatesToQueue:m_updateQueue withHandler:^(CMAccelerometerData *data, NSError *error) { - dispatch_async(dispatch_get_main_queue(), ^{ - Q_UNUSED(error); - CMAcceleration acc = data.acceleration; - // Convert from G to m/s2, and flip axes: - const qreal G = 9.8066; - qreal x = qreal(acc.x) * G * -1; - qreal y = qreal(acc.y) * G * -1; - qreal z = qreal(acc.z) * G * -1; - m_qiosAccelerometer->readingsChanged(quint64(data.timestamp), x, y, z); - }); - }]; - } -} - --(void)stopAccelerometer -{ - [[QIOSMotionManager sharedManager] stopAccelerometerUpdates]; -} - --(void)setInterval:(NSTimeInterval) interval -{ - [QIOSMotionManager sharedManager].accelerometerUpdateInterval = interval; -} +#include "iosaccelerometer.h" +#include "iosmotionmanager.h" -@end +char const * const IOSAccelerometer::id("ios.accelerometer"); QT_BEGIN_NAMESPACE IOSAccelerometer::IOSAccelerometer(QSensor *sensor) : QSensorBackend(sensor) - , m_listener([[QtIoAccelListener alloc] initWithQIOSAccelerometer:this]) + , m_updateQueue([[NSOperationQueue alloc] init]) { setReading<QAccelerometerReading>(&m_reading); addDataRate(1, 100); // 100Hz @@ -117,27 +61,40 @@ IOSAccelerometer::IOSAccelerometer(QSensor *sensor) IOSAccelerometer::~IOSAccelerometer() { - [m_listener dealloc]; + [m_updateQueue release]; } void IOSAccelerometer::start() { - [m_listener startAccelerometer]; + CMMotionManager *motionManager = [QIOSMotionManager sharedManager]; + // Convert from Hz to NSTimeInterval: + int hz = sensor()->dataRate(); + motionManager.accelerometerUpdateInterval = (hz == 0) ? 0 : 1. / hz; + + QPointer<QObject> self = this; + [motionManager startAccelerometerUpdatesToQueue:m_updateQueue withHandler:^(CMAccelerometerData *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, IOSAccelerometer might + // have been deleted, so we need an extra QPointer check for that: + dispatch_async(dispatch_get_main_queue(), ^{ + if (self) { + Q_UNUSED(error); + // Convert from NSTimeInterval to microseconds and G to m/s2, and flip axes: + CMAcceleration acc = data.acceleration; + const qreal G = 9.8066; + m_reading.setTimestamp(quint64(data.timestamp * 1000000)); + m_reading.setX(qreal(acc.x) * G * -1); + m_reading.setY(qreal(acc.y) * G * -1); + m_reading.setZ(qreal(acc.z) * G * -1); + newReadingAvailable(); + } + }); + }]; } void IOSAccelerometer::stop() { - [m_listener stopAccelerometer]; -} - -void IOSAccelerometer::readingsChanged(quint64 ts, qreal x, qreal y, qreal z) -{ - m_reading.setTimestamp(ts); - m_reading.setX(x); - m_reading.setY(y); - m_reading.setZ(z); - - newReadingAvailable(); + [[QIOSMotionManager sharedManager] stopAccelerometerUpdates]; } QT_END_NAMESPACE |