- From: Lachlan Hunt <lachlan.hunt@lachy.id.au>
- Date: Wed, 16 Mar 2011 17:58:02 +0100
On 2011-03-15 16:24, Rich Tibbett wrote: > We want to replace the success callback with a 'connect' event and the > error callback with an 'error' event. We would also like to introduce > a 'disconnect' event as mentioned in point 3) above. > > The IDL is as follows: > > [NoInterfaceObject] > interface Device { > const unsigned short WAITING = 0; > const unsigned short CONNECTED = 1; > const unsigned short DISCONNECTED = 2; > const unsigned short ERROR = 3; > readonly attribute unsigned short readyState; > > // event handler attributes > attribute Function onconnect; > attribute Function ondisconnect; > attribute Function onerror; > > readonly attribute any data; > > void disconnect(); > } > > // Specific Device Classes with independent constructors > > [Constructor(in DOMString options)] > interface UserMedia : Device {} For me, this event model approach seems more natural and fits with pre-existing design patterns used for other APIs, better than the callback approach does. But even so, I thought I'd do a side by side comparison of the code to accomplish a simple tasks. In both cases, this variable is declared: var v = document.querySelector("video"); --- /* Callback model: */ var s; // For keeping a reference to the stream available for later use. navigator.getUserMedia("audio,video", success, error); function success(stream) { s = stream; // Store it for later use v.src = s; s.onplay = play; // Assume these functions are defined somewhere s.onpause = pause; s.onended = ended; } function error(e) { // Permission denied... } --- /* Event model: */ var m = new UserMedia("audio,video"); m.onconnect = function(evt) { v.src = this.data; this.onplay = play; // Assume these functions are defined somewhere this.onpause = pause; this.onended = ended; } m.onerror = function(evt) { // Permission denied } --- Based on this simple comparison, it's clear that the neither model requires significantly more verbose code than the other model, no there doesn't seem to be any real disadvantage from an authoring perspective. The event model has the advantage of being able to scale up to handle more events in the future, such as handling disconnections or the user switching cameras or microphones. (e.g. The user want switches from their computer's built in microphone to a USB headset.) For the callback model to handle that, it would require adding more callback functions. One problem with both models is that they don't easily distinguish between different input devices, which is a problem because both the proposed Device interface and the Stream/GeneratedStream interfaces can potentially represent multiple Devices/Streams (this is the case when "audio,video" is passed as the type). This creates a problem when a user, for example, unplugs or revokes permission for one of the devices or streams but not the other, triggering either an error or disconnect event, it's not clear how the script can identify which specific device was disconnected. Both interfaces also use a single readyState variable to represent the state of potentially multiple devices/streams, which seems problematic for the same reason. Finally, the object passed to the error callback/event currently only has a PERMISSION_DENIED error code. It might be worth investigating the need for other codes like PERMISSION_REVOKED, DEVICE_REMOVED, etc. as well, to handle the case where permission was granted, but then the user later changed their mind or unplugged the device. (It's possible that the proposed ondisconnect event in the event model could be handled as an error event with an appropriate code, though I'm not sure if that's better or worse than separate event.) -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
Received on Wednesday, 16 March 2011 09:58:02 UTC