UNPKG

1.98 kBJavaScriptView Raw
1// @flow
2
3import { NativeEventEmitter, Platform } from 'react-native';
4
5type Listener<E> = E => void;
6
7type Subscription = {
8 remove: () => void,
9};
10
11type NativeSensorModule = Object;
12
13/**
14 * A base class for subscribable sensors. The events emitted by this class are
15 * measurements specified by the parameter type `M`.
16 */
17export default class DeviceSensor<M> {
18 _nativeModule: NativeSensorModule;
19 _nativeEmitter: NativeEventEmitter;
20 _nativeEventName: string;
21
22 constructor(nativeSensorModule: NativeSensorModule, nativeEventName: string) {
23 this._nativeModule = nativeSensorModule;
24 this._nativeEmitter = new NativeEventEmitter(nativeSensorModule);
25 this._nativeEventName = nativeEventName;
26 }
27
28 hasListeners(): boolean {
29 return this.getListenerCount() > 0;
30 }
31
32 getListenerCount(): number {
33 return this._nativeEmitter.listeners(this._nativeEventName).length;
34 }
35
36 addListener(listener: Listener<M>): Subscription {
37 // RCTEventEmitter on iOS automatically calls startObserving and
38 // stopObserving as listeners are added and removed
39 if (Platform.OS === 'android') {
40 if (!this.hasListeners()) {
41 this._nativeModule.startObserving();
42 }
43 }
44
45 let subscription = this._nativeEmitter.addListener(
46 this._nativeEventName,
47 listener
48 );
49 subscription.remove = () => this.removeSubscription(subscription);
50 return subscription;
51 }
52
53 removeAllListeners(): void {
54 if (Platform.OS === 'android') {
55 this._nativeModule.stopObserving();
56 }
57
58 return this._nativeEmitter.removeAllListeners(this._nativeEventName);
59 }
60
61 removeSubscription(subscription: Subscription): void {
62 if (Platform.OS === 'android') {
63 if (this.getListenerCount() === 1) {
64 this._nativeModule.stopObserving();
65 }
66 }
67
68 return this._nativeEmitter.removeSubscription(subscription);
69 }
70
71 setUpdateInterval(intervalMs: number): void {
72 this._nativeModule.setUpdateInterval(intervalMs);
73 }
74}