mirror of
https://github.com/go-i2p/gomobile-java.git
synced 2025-07-13 06:07:45 -04:00
exp/sensor: don't enable a sensor on a sender
The underlying implementation was not enabling the sensors on a particular sender even though the Enable signature accepts different instances of Sender to enable. Consider the following program: type A struct{} func (a A) Send(ev interface{}) {} type B struct{} func (b B) Send(ev interface{}) {} sensor.Enable(A{}, sensor.Gyroscope, time.Millisecond) sensor.Enable(B{}, sensor.Accelerometer, time.Millisecond) is going to compile but only A will be notified when there are new gyroscope and accelerometer events. In order to improve the misleading APIs, this CL introduces a Notify function that users can register a Sender implementation to listen the changes. If set nil, the sensor package will keep reading the events but will won't notify. sensor.Notify(A{}) sensor.Enable(sensor.Gyroscope, time.Millisecond) sensor.Enable(sensor.Accelerometer, time.Millisecond) Change-Id: I25e43349e4ae682930baa2d32430f46f24b588b7 Reviewed-on: https://go-review.googlesource.com/15650 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
@ -101,8 +101,10 @@ func init() {
|
||||
}()
|
||||
}
|
||||
|
||||
func enable(s Sender, t Type, delay time.Duration) error {
|
||||
startCollecting(s)
|
||||
// enable enables the sensor t on sender. A non-nil sender is
|
||||
// required before calling enable.
|
||||
func enable(t Type, delay time.Duration) error {
|
||||
startCollecting()
|
||||
|
||||
var err error
|
||||
done := make(chan struct{})
|
||||
@ -114,7 +116,7 @@ func enable(s Sender, t Type, delay time.Duration) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func startCollecting(s Sender) {
|
||||
func startCollecting() {
|
||||
collectingMu.Lock()
|
||||
defer collectingMu.Unlock()
|
||||
|
||||
@ -135,7 +137,7 @@ func startCollecting(s Sender) {
|
||||
}
|
||||
<-done
|
||||
for i := 0; i < n; i++ {
|
||||
s.Send(ev[i])
|
||||
sender.Send(ev[i])
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
@ -60,7 +60,9 @@ func init() {
|
||||
|
||||
const minDelay = 10 * time.Millisecond
|
||||
|
||||
func enable(s Sender, t Type, delay time.Duration) error {
|
||||
// enable enables the sensor t on sender. A non-nil sender is
|
||||
// required before calling enable.
|
||||
func enable(t Type, delay time.Duration) error {
|
||||
channels.Lock()
|
||||
defer channels.Unlock()
|
||||
|
||||
@ -82,7 +84,7 @@ func enable(s Sender, t Type, delay time.Duration) error {
|
||||
case Magnetometer:
|
||||
C.GoIOS_startMagneto(interval)
|
||||
}
|
||||
go pollSensor(s, t, delay, channels.done[t])
|
||||
go pollSensor(t, delay, channels.done[t])
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -107,7 +109,7 @@ func disable(t Type) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func pollSensor(s Sender, t Type, d time.Duration, done chan struct{}) {
|
||||
func pollSensor(t Type, d time.Duration, done chan struct{}) {
|
||||
var lastTimestamp int64
|
||||
|
||||
var timestamp C.int64_t
|
||||
@ -133,7 +135,7 @@ func pollSensor(s Sender, t Type, d time.Duration, done chan struct{}) {
|
||||
if ts > lastTimestamp {
|
||||
// TODO(jbd): Do we need to convert the values to another unit?
|
||||
// How does iOS units compare to the Android units.
|
||||
s.Send(Event{
|
||||
sender.Send(Event{
|
||||
Sensor: t,
|
||||
Timestamp: ts,
|
||||
Data: []float64{float64(ev[0]), float64(ev[1]), float64(ev[2])},
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func enable(s Sender, t Type, delay time.Duration) error {
|
||||
func enable(t Type, delay time.Duration) error {
|
||||
return errors.New("sensor: no sensors available")
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ package sensor // import "golang.org/x/mobile/exp/sensor"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -66,20 +67,47 @@ type Event struct {
|
||||
|
||||
// TODO(jbd): Move Sender interface definition to a top-level package.
|
||||
|
||||
var (
|
||||
// senderMu protects sender.
|
||||
senderMu sync.Mutex
|
||||
|
||||
// sender is notified with the sensor data each time a new event is available.
|
||||
sender Sender
|
||||
)
|
||||
|
||||
// Sender sends an event.
|
||||
type Sender interface {
|
||||
Send(event interface{})
|
||||
}
|
||||
|
||||
// Notify registers a Sender and sensor events will be sent to s.
|
||||
// A typical example of Sender implementations is app.App.
|
||||
// Once you call Notify, you are not allowed to call it again.
|
||||
// You cannot call Notify with a nil Sender.
|
||||
func Notify(s Sender) {
|
||||
senderMu.Lock()
|
||||
defer senderMu.Unlock()
|
||||
|
||||
if s == nil {
|
||||
panic("sensor: cannot set a nil sender")
|
||||
}
|
||||
if sender != nil {
|
||||
panic("sensor: another sender is being notified, cannot set s as the sender")
|
||||
}
|
||||
sender = s
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Enable is not safe for concurrent use.
|
||||
func Enable(s Sender, t Type, delay time.Duration) error {
|
||||
// Users must set a non-nil Sender via Notify before enabling a sensor,
|
||||
// otherwise an error will be returned.
|
||||
func Enable(t Type, delay time.Duration) error {
|
||||
if t < 0 || int(t) >= len(sensorNames) {
|
||||
return errors.New("sensor: unknown sensor type")
|
||||
}
|
||||
return enable(s, t, delay)
|
||||
if err := validSender(); err != nil {
|
||||
return err
|
||||
}
|
||||
return enable(t, delay)
|
||||
}
|
||||
|
||||
// Disable disables to feed the manager with the specified sensor.
|
||||
@ -90,3 +118,13 @@ func Disable(t Type) error {
|
||||
}
|
||||
return disable(t)
|
||||
}
|
||||
|
||||
func validSender() error {
|
||||
senderMu.Lock()
|
||||
defer senderMu.Unlock()
|
||||
|
||||
if sender == nil {
|
||||
return errors.New("sensor: no senders to be notified; cannot enable the sensor")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user