- From: Rich Tibbett <rich.tibbett@gmail.com>
- Date: Tue, 14 Oct 2014 11:41:12 +0200
- To: Tim Volodine <timvolodine@google.com>
- Cc: Rick Waldron <waldron.rick@gmail.com>, Tobie Langel <tobie.langel@gmail.com>, Marcos Caceres <marcos@marcosc.com>, Jonas Sicking <jonas@sicking.cc>, "public-device-apis@w3.org" <public-device-apis@w3.org>, Anssi Kostiainen <anssi.kostiainen@intel.com>, public-script-coord <public-script-coord@w3.org>, Doug Turner <dougt@mozilla.com>, Domenic Denicola <domenic@domenicdenicola.com>, Anne van Kesteren <annevk@annevk.nl>
- Message-ID: <CALmeN0e2Di_1CGZFsQBAjHc7ONSC=KDQnvU8FnCbEK7q8N0DXg@mail.gmail.com>
On Fri, Sep 5, 2014 at 4:18 PM, Tim Volodine <timvolodine@google.com> wrote: > So how about something like this: > (taking Device Orientation API as example) > > enum SamplingFrequencyType { > "low", > "normal", > "high" > }; > > partial interface Navigator { > Promise<DeviceOrientationSensor> > getDeviceOrientationSensor(SamplingFrequencyType); > }; > > interface Sensor : EventTarget { > readonly attribute double samplingFrequency; > attribute EventHandler onchange; > }; > > interface DeviceOrientationSensor : Sensor { > readonly attribute OrientationData currentOrientation; > DOMMatrix getCurrentOrientationAsRotationMatrix(); // by means of example > }; > > > Example 1: > > function sensorSuccess(sensor) { > console.log(sensor.currentOrientation); > sensorManager.addEventListener(‘change’, function() { > console.log(this.currentOrientation); > }); > } > > function sensorFailed() { > console.log(“failed to obtain orientation sensor”); > } > > navigator.getDeviceOrientationSensor(“high”).then(sensorSuccess, > sensorFailed); > > > Example 2 (using requestAnimationFrame): > > var sensor = null; > function updateFrame() { > window.requestAnimationFrame(updateFrame); > if (sensor) > console.log(sensor.currentOrientation); > // do something else > } > > navigator.getDeviceOrientationSensor(“high”).then( > function(orientationSensor){ sensor = orientationSensor; }, > function() { console.log("error"); }); > > window.requestAnimationFrame(updateFrame); > > I've been experimenting with alternative APIs for Device Orientation and the API design has converged naturally on the pattern described above. This library is available at [1]. Having a Promise-based API means we can initialise and resolve a Promise object to a Device Orientation object only if/when the platform pipeline has been set up and has delivered its first device orientation sensor data. If any part of that pipeline set up fails then we have a way to reject the Promise object with timeout/not-implemented/permission-denied errors as appropriate. Having that mechanism to throw errors on set up allows web developers to take any necessary fallback action in their web apps such as to provide manual mouse/touch/keyboard controls instead of relying on unsupported Device Orientation events. Simultaneously, the 'DeviceOrientationSensor' interface above (called 'FULLTILT.DeviceOrientation' in [1]) is also exposed to web apps and is furnished with a constructor. Web developers can thus create new DeviceOrientationSensor objects (or AmbientLightSensor objects, etc) directly via that interface's constructor, bypassing the Promise-based mechanism for object invocation. Creating a new 'DeviceOrientationSensor' object via its interface's constructor does not automatically imply that the current browser will deliver deviceorientation events (see: 'window.DeviceOrientationEvent' being exposed on multiple platforms but those platforms not delivering device orientation events [2]). Using this approach does, however, allow you to use the API in the way Rick is proposing. In summary, using Promises to create new sensor objects provides a natural feature detection mechanism, allows the UA to set up the platform pipeline for delivering hardware sensor events asynchronously, allows the UA implement timeouts, error conditions on that pipeline set up and, reject Promises in case any error condition is met in that set up process. It avoids the 'warm up' phase of hardware sensor data delivery (where sensor data has not yet been received at the UA and is thus 'null' when sensor change events are fired prematurely toward web apps) though that can be overridden by invoking the object directly via its constructor. My Device Orientation library based on the pattern above is available at [1]. - Rich [1] https://github.com/richtr/Full-Tilt [2] https://github.com/w3c/deviceorientation/pull/12
Received on Tuesday, 14 October 2014 09:42:01 UTC