55// Created by Alsey Coleman Miller on 7/6/25.
66//
77
8+ #if canImport(Android)
9+ import Android
10+ import AndroidNDK
11+ #endif
12+
813/// A sensor event containing a measurement from a hardware sensor.
914public struct SensorEvent : Sendable {
1015
@@ -13,6 +18,23 @@ public struct SensorEvent: Sendable {
1318 internal init ( _ raw: ASensorEvent ) {
1419 self . raw = raw
1520 }
21+
22+ @inline ( __always)
23+ internal func withRawDataBytes< R> (
24+ _ body: ( UnsafeRawBufferPointer ) -> R
25+ ) -> R {
26+ withUnsafeBytes ( of: raw) { rawBytes in
27+ // ASensorEvent layout:
28+ // version(4) + sensor(4) + type(4) + reserved0(4) + timestamp(8) + data(64)
29+ let dataOffset = ( MemoryLayout < Int32 > . size * 4 ) + MemoryLayout< Int64> . size
30+ let dataStart = rawBytes. baseAddress!. advanced ( by: dataOffset)
31+ let dataBytes = UnsafeRawBufferPointer (
32+ start: dataStart,
33+ count: MemoryLayout < Float > . size * 16
34+ )
35+ return body ( dataBytes)
36+ }
37+ }
1638}
1739
1840// MARK: - Properties
@@ -33,7 +55,7 @@ public extension SensorEvent {
3355 /// The layout depends on `type`. For most sensors the relevant values
3456 /// are in the first 3 elements (x, y, z).
3557 var data : [ Float ] {
36- withUnsafeBytes ( of : raw . _data ) { bytes in
58+ withRawDataBytes { bytes in
3759 Array ( bytes. bindMemory ( to: Float . self) )
3860 }
3961 }
@@ -46,23 +68,23 @@ public extension SensorEvent {
4668 /// Acceleration vector in m/s² (x, y, z) — valid for `.accelerometer`,
4769 /// `.linearAcceleration`, and `.gravity` events.
4870 var acceleration : ( x: Float , y: Float , z: Float ) {
49- withUnsafeBytes ( of : raw . _data ) { bytes in
71+ withRawDataBytes { bytes in
5072 let f = bytes. bindMemory ( to: Float . self)
5173 return ( f [ 0 ] , f [ 1 ] , f [ 2 ] )
5274 }
5375 }
5476
5577 /// Rotation rate in rad/s (x, y, z) — valid for `.gyroscope` events.
5678 var angularVelocity : ( x: Float , y: Float , z: Float ) {
57- withUnsafeBytes ( of : raw . _data ) { bytes in
79+ withRawDataBytes { bytes in
5880 let f = bytes. bindMemory ( to: Float . self)
5981 return ( f [ 0 ] , f [ 1 ] , f [ 2 ] )
6082 }
6183 }
6284
6385 /// Magnetic field in μT (x, y, z) — valid for `.magneticField` events.
6486 var magneticField : ( x: Float , y: Float , z: Float ) {
65- withUnsafeBytes ( of : raw . _data ) { bytes in
87+ withRawDataBytes { bytes in
6688 let f = bytes. bindMemory ( to: Float . self)
6789 return ( f [ 0 ] , f [ 1 ] , f [ 2 ] )
6890 }
@@ -71,44 +93,44 @@ public extension SensorEvent {
7193 /// Rotation vector (x, y, z, w) — valid for `.rotationVector` and
7294 /// related events.
7395 var rotationVector : ( x: Float , y: Float , z: Float , w: Float ) {
74- withUnsafeBytes ( of : raw . _data ) { bytes in
96+ withRawDataBytes { bytes in
7597 let f = bytes. bindMemory ( to: Float . self)
7698 return ( f [ 0 ] , f [ 1 ] , f [ 2 ] , f [ 3 ] )
7799 }
78100 }
79101
80102 /// Illuminance in lx — valid for `.light` events.
81103 var light : Float {
82- withUnsafeBytes ( of : raw . _data ) { $0. bindMemory ( to: Float . self) [ 0 ] }
104+ withRawDataBytes { $0. bindMemory ( to: Float . self) [ 0 ] }
83105 }
84106
85107 /// Distance in cm — valid for `.proximity` events.
86108 var distance : Float {
87- withUnsafeBytes ( of : raw . _data ) { $0. bindMemory ( to: Float . self) [ 0 ] }
109+ withRawDataBytes { $0. bindMemory ( to: Float . self) [ 0 ] }
88110 }
89111
90112 /// Temperature in °C — valid for `.ambientTemperature` events.
91113 var temperature : Float {
92- withUnsafeBytes ( of : raw . _data ) { $0. bindMemory ( to: Float . self) [ 0 ] }
114+ withRawDataBytes { $0. bindMemory ( to: Float . self) [ 0 ] }
93115 }
94116
95117 /// Pressure in hPa — valid for `.pressure` events.
96118 var pressure : Float {
97- withUnsafeBytes ( of : raw . _data ) { $0. bindMemory ( to: Float . self) [ 0 ] }
119+ withRawDataBytes { $0. bindMemory ( to: Float . self) [ 0 ] }
98120 }
99121
100122 /// Relative humidity as a percentage — valid for `.relativeHumidity` events.
101123 var relativeHumidity : Float {
102- withUnsafeBytes ( of : raw . _data ) { $0. bindMemory ( to: Float . self) [ 0 ] }
124+ withRawDataBytes { $0. bindMemory ( to: Float . self) [ 0 ] }
103125 }
104126
105127 /// Cumulative step count since last reboot — valid for `.stepCounter` events.
106128 var stepCount : UInt64 {
107- withUnsafeBytes ( of : raw . _data ) { $0. bindMemory ( to: UInt64 . self) [ 0 ] }
129+ withRawDataBytes { $0. bindMemory ( to: UInt64 . self) [ 0 ] }
108130 }
109131
110132 /// Hinge angle in degrees — valid for `.hingeAngle` events.
111133 var hingeAngle : Float {
112- withUnsafeBytes ( of : raw . _data ) { $0. bindMemory ( to: Float . self) [ 0 ] }
134+ withRawDataBytes { $0. bindMemory ( to: Float . self) [ 0 ] }
113135 }
114136}
0 commit comments