exp/sensor: remove the manager type
The manager type is not required, because the APIs don't allow
more than one event sources as they used to. In this CL, I am
flattening out the underlying implementations by removing the
manager type.
Change-Id: I3b606ac160b9cecd85cb657e3df1d7d789604764
Reviewed-on: https://go-review.googlesource.com/14293
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/exp/sensor/android.c b/exp/sensor/android.c
index 258b10b..dfe4bbf 100644
--- a/exp/sensor/android.c
+++ b/exp/sensor/android.c
@@ -9,39 +9,38 @@
#include <android/sensor.h>
-#include "android.h"
+#define GO_ANDROID_SENSOR_LOOPER_ID 100
-void GoAndroid_createManager(int looperId, GoAndroid_SensorManager* dst) {
+ASensorEventQueue* queue = NULL;
+ALooper* looper = NULL;
+
+void GoAndroid_createManager() {
ASensorManager* manager = ASensorManager_getInstance();
-
- ALooper* looper = ALooper_forThread();
+ looper = ALooper_forThread();
if (looper == NULL) {
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
}
- ASensorEventQueue* queue = ASensorManager_createEventQueue(manager, looper, looperId, NULL, NULL);
- dst->looper = looper;
- dst->queue = queue;
- dst->looperId = looperId;
+ queue = ASensorManager_createEventQueue(manager, looper, GO_ANDROID_SENSOR_LOOPER_ID, NULL, NULL);
}
-int GoAndroid_enableSensor(ASensorEventQueue* q, int s, int32_t usec) {
+int GoAndroid_enableSensor(int s, int32_t usec) {
ASensorManager* manager = ASensorManager_getInstance();
const ASensor* sensor = ASensorManager_getDefaultSensor(manager, s);
if (sensor == NULL) {
return 1;
}
- ASensorEventQueue_enableSensor(q, sensor);
- ASensorEventQueue_setEventRate(q, sensor, usec);
+ ASensorEventQueue_enableSensor(queue, sensor);
+ ASensorEventQueue_setEventRate(queue, sensor, usec);
return 0;
}
-void GoAndroid_disableSensor(ASensorEventQueue* q, int s) {
+void GoAndroid_disableSensor(int s) {
ASensorManager* manager = ASensorManager_getInstance();
const ASensor* sensor = ASensorManager_getDefaultSensor(manager, s);
- ASensorEventQueue_disableSensor(q, sensor);
+ ASensorEventQueue_disableSensor(queue, sensor);
}
-int GoAndroid_readQueue(int looperId, ASensorEventQueue* q, int n, int32_t* types, int64_t* timestamps, float* vectors) {
+int GoAndroid_readQueue(int n, int32_t* types, int64_t* timestamps, float* vectors) {
int id;
int events;
ASensorEvent event;
@@ -50,10 +49,10 @@
// If anytime timeout occurs, don't retry to read and immediately return.
// Consume the event queue entirely between polls.
while (i < n && (id = ALooper_pollAll(-1, NULL, &events, NULL)) >= 0) {
- if (id != looperId) {
+ if (id != GO_ANDROID_SENSOR_LOOPER_ID) {
continue;
}
- while (i < n && ASensorEventQueue_getEvents(q, &event, 1)) {
+ while (i < n && ASensorEventQueue_getEvents(queue, &event, 1)) {
types[i] = event.type;
timestamps[i] = event.timestamp;
vectors[i*3] = event.vector.x;
@@ -65,8 +64,8 @@
return i;
}
-void GoAndroid_destroyManager(GoAndroid_SensorManager* m) {
+void GoAndroid_destroyManager() {
ASensorManager* manager = ASensorManager_getInstance();
- ASensorManager_destroyEventQueue(manager, m->queue);
- ALooper_release(m->looper);
+ ASensorManager_destroyEventQueue(manager, queue);
+ ALooper_release(looper);
}
diff --git a/exp/sensor/android.go b/exp/sensor/android.go
index d110cbf..bfb257a 100644
--- a/exp/sensor/android.go
+++ b/exp/sensor/android.go
@@ -12,14 +12,17 @@
#include <stdlib.h>
#include <android/sensor.h>
-#include "android.h"
+void GoAndroid_createManager();
+void GoAndroid_destroyManager();
+int GoAndroid_enableSensor(int, int32_t);
+void GoAndroid_disableSensor(int);
+int GoAndroid_readQueue(int n, int32_t* types, int64_t* timestamps, float* vectors);
*/
import "C"
import (
"fmt"
"runtime"
"sync"
- "sync/atomic"
"time"
"unsafe"
)
@@ -32,8 +35,6 @@
collecting bool
)
-var nextLooperID int64 // each underlying ALooper should have a unique ID.
-
// initSignal initializes an underlying looper and event queue.
type initSignal struct{}
@@ -69,43 +70,34 @@
out chan struct{}
}
-// manager is the Android-specific implementation of Manager.
-type manager struct {
- m *C.GoAndroid_SensorManager
- inout chan inOut
-}
+var inout = make(chan inOut)
-// initialize inits the manager and creates a goroutine to proxy the CGO calls.
+// init inits the manager and creates a goroutine to proxy the CGO calls.
// All actions related to an ALooper needs to be performed from the same
// OS thread. The goroutine proxy locks itself to an OS thread and handles the
// CGO traffic on the same thread.
-func (m *manager) initialize() {
- m.inout = make(chan inOut)
-
+func init() {
go func() {
runtime.LockOSThread()
for {
- v := <-m.inout
+ v := <-inout
switch s := v.in.(type) {
case initSignal:
- id := atomic.AddInt64(&nextLooperID, 1)
- var mgr C.GoAndroid_SensorManager
- C.GoAndroid_createManager(C.int(id), &mgr)
- m.m = &mgr
+ C.GoAndroid_createManager()
case enableSignal:
usecsDelay := s.delay.Nanoseconds() / 1000
- code := int(C.GoAndroid_enableSensor(m.m.queue, typeToInt(s.t), C.int32_t(usecsDelay)))
+ code := int(C.GoAndroid_enableSensor(typeToInt(s.t), C.int32_t(usecsDelay)))
if code != 0 {
*s.err = fmt.Errorf("sensor: no default %v sensor on the device", s.t)
}
case disableSignal:
- C.GoAndroid_disableSensor(m.m.queue, typeToInt(s.t))
+ C.GoAndroid_disableSensor(typeToInt(s.t))
case readSignal:
- n, err := readEvents(m, s.dst)
+ n, err := readEvents(s.dst)
*s.n = n
*s.err = err
case closeSignal:
- C.GoAndroid_destroyManager(m.m)
+ C.GoAndroid_destroyManager()
close(v.out)
return // we don't need this goroutine anymore
}
@@ -113,22 +105,20 @@
}
}()
- if m.m == nil {
- done := make(chan struct{})
- m.inout <- inOut{
- in: initSignal{},
- out: done,
- }
- <-done
+ done := make(chan struct{})
+ inout <- inOut{
+ in: initSignal{},
+ out: done,
}
+ <-done
}
-func (m *manager) enable(s Sender, t Type, delay time.Duration) error {
- m.startCollecting(s)
+func enable(s Sender, t Type, delay time.Duration) error {
+ startCollecting(s)
var err error
done := make(chan struct{})
- m.inout <- inOut{
+ inout <- inOut{
in: enableSignal{t: t, delay: delay, err: &err},
out: done,
}
@@ -136,7 +126,7 @@
return err
}
-func (m *manager) startCollecting(s Sender) {
+func startCollecting(s Sender) {
collectingMu.Lock()
defer collectingMu.Unlock()
@@ -159,7 +149,7 @@
// TODO(jbd): readSignal is not required anymore. Use the proxying
// goroutine to continously poll the queue and send the events to s.
done := make(chan struct{})
- m.inout <- inOut{
+ inout <- inOut{
in: readSignal{dst: ev, n: &n, err: &err},
out: done,
}
@@ -171,9 +161,9 @@
}()
}
-func (m *manager) disable(t Type) error {
+func disable(t Type) error {
done := make(chan struct{})
- m.inout <- inOut{
+ inout <- inOut{
in: disableSignal{t: t},
out: done,
}
@@ -181,14 +171,13 @@
return nil
}
-func readEvents(m *manager, e []Event) (n int, err error) {
+func readEvents(e []Event) (n int, err error) {
num := len(e)
types := make([]C.int32_t, num)
timestamps := make([]C.int64_t, num)
vectors := make([]C.float, 3*num)
n = int(C.GoAndroid_readQueue(
- m.m.looperId, m.m.queue,
C.int(num),
(*C.int32_t)(unsafe.Pointer(&types[0])),
(*C.int64_t)(unsafe.Pointer(×tamps[0])),
@@ -208,10 +197,10 @@
return
}
-// TODO(jbd): Remove close?
-func (m *manager) close() error {
+// TODO(jbd): Remove destroy?
+func destroy() error {
done := make(chan struct{})
- m.inout <- inOut{
+ inout <- inOut{
in: closeSignal{},
out: done,
}
diff --git a/exp/sensor/android.h b/exp/sensor/android.h
deleted file mode 100644
index c7a452f..0000000
--- a/exp/sensor/android.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build android
-
-#ifndef GO_SENSORS_ANDROID_H
-#define GO_SENSORS_ANDROID_H
-
-typedef struct GoAndroid_SensorManager {
- ASensorEventQueue* queue;
- ALooper* looper;
- int looperId;
-} GoAndroid_SensorManager;
-
-void GoAndroid_createManager(int looperId, GoAndroid_SensorManager* dst);
-void GoAndroid_destroyManager(GoAndroid_SensorManager* m);
-int GoAndroid_enableSensor(ASensorEventQueue*, int, int32_t);
-void GoAndroid_disableSensor(ASensorEventQueue*, int);
-int GoAndroid_readQueue(int looperId, ASensorEventQueue* q, int n, int32_t* types, int64_t* timestamps, float* vectors);
-
-#endif
diff --git a/exp/sensor/darwin_armx.go b/exp/sensor/darwin_armx.go
index 94c3f89..c6a54b2 100644
--- a/exp/sensor/darwin_armx.go
+++ b/exp/sensor/darwin_armx.go
@@ -42,10 +42,7 @@
done [nTypes]chan struct{}
}
-type manager struct {
-}
-
-func (m *manager) initialize() {
+func init() {
C.GoIOS_createManager()
}
@@ -63,7 +60,7 @@
const minDelay = 10 * time.Millisecond
-func (m *manager) enable(s Sender, t Type, delay time.Duration) error {
+func enable(s Sender, t Type, delay time.Duration) error {
channels.Lock()
defer channels.Unlock()
@@ -85,11 +82,11 @@
case Magnetometer:
C.GoIOS_startMagneto(interval)
}
- go m.pollSensor(s, t, delay, channels.done[t])
+ go pollSensor(s, t, delay, channels.done[t])
return nil
}
-func (m *manager) disable(t Type) error {
+func disable(t Type) error {
channels.Lock()
defer channels.Unlock()
@@ -110,7 +107,7 @@
return nil
}
-func (m *manager) pollSensor(s Sender, t Type, d time.Duration, done chan struct{}) {
+func pollSensor(s Sender, t Type, d time.Duration, done chan struct{}) {
var lastTimestamp int64
var timestamp C.int64_t
@@ -148,8 +145,8 @@
}
}
-// TODO(jbd): Remove close?
-func (m *manager) close() error {
+// TODO(jbd): Remove destroy?
+func destroy() error {
C.GoIOS_destroyManager()
return nil
}
diff --git a/exp/sensor/notmobile.go b/exp/sensor/notmobile.go
index dabc3d2..ee1636a 100644
--- a/exp/sensor/notmobile.go
+++ b/exp/sensor/notmobile.go
@@ -11,18 +11,14 @@
"time"
)
-type manager struct{}
-
-func (m *manager) initialize() {}
-
-func (m *manager) enable(s Sender, t Type, delay time.Duration) error {
+func enable(s Sender, t Type, delay time.Duration) error {
return errors.New("sensor: no sensors available")
}
-func (m *manager) disable(t Type) error {
+func disable(t Type) error {
return errors.New("sensor: no sensors available")
}
-func (m *manager) close() error {
+func destroy() error {
return nil
}
diff --git a/exp/sensor/sensor.go b/exp/sensor/sensor.go
index eea4e83..74d1ae1 100644
--- a/exp/sensor/sensor.go
+++ b/exp/sensor/sensor.go
@@ -15,7 +15,7 @@
var sensorNames = map[Type]string{
Accelerometer: "Accelerometer",
- Gyroscope: "Gyrsocope",
+ Gyroscope: "Gyroscope",
Magnetometer: "Magnetometer",
}
@@ -71,9 +71,6 @@
Send(event interface{})
}
-// m is the underlying platform-specific sensor manager.
-var m = newManager()
-
// Enable enables the specified sensor type with the given delay rate.
// Sensor events will be sent to s, a typical example of Sender
// implementations is app.App.
@@ -82,7 +79,7 @@
if t < 0 || int(t) >= len(sensorNames) {
return errors.New("sensor: unknown sensor type")
}
- return m.enable(s, t, delay)
+ return enable(s, t, delay)
}
// Disable disables to feed the manager with the specified sensor.
@@ -91,13 +88,5 @@
if t < 0 || int(t) >= len(sensorNames) {
return errors.New("sensor: unknown sensor type")
}
- return m.disable(t)
-}
-
-func newManager() *manager {
- // TODO(jbd): manager type is unnecessary, flatten out the
- // platform specific implementation.
- mgr := new(manager)
- mgr.initialize()
- return mgr
+ return disable(t)
}