- From: Ehsan Akhgari <ehsan.akhgari@gmail.com>
- Date: Tue, 14 May 2013 15:27:39 -0400
- To: Srikumar Karaikudi Subramanian <srikumarks@gmail.com>
- Cc: "Robert O'Callahan" <robert@ocallahan.org>, Chris Rogers <crogers@google.com>, "public-audio@w3.org" <public-audio@w3.org>
- Message-ID: <CANTur_7L8jj9zNafO967L=pkP3OZzzfLQHb+Mwo0m1DBsqbRDA@mail.gmail.com>
On Tue, May 14, 2013 at 1:57 AM, Srikumar Karaikudi Subramanian < srikumarks@gmail.com> wrote: > > On 14 May, 2013, at 9:07 AM, "Robert O'Callahan" <robert@ocallahan.org> > wrote: > > On Tue, May 14, 2013 at 2:58 PM, Srikumar Karaikudi Subramanian < > srikumarks@gmail.com> wrote: > >> shaper.curve = new Float32Array(100); >>>> for (var i = 0; i < 100; ++i) { >>>> // oops, at this point the array has been internally copied, >>>> // and while the code below doesn't throw an exception, >>>> // it effectively sets the curve property to an all-0 array, >>>> // which is not what the author has intended. >>>> shaper.curve[i] = whatever; >>>> } >>>> >>> >> This code will bomb anyway if the array is neutered after setting the >> curve (the length of a >> neutered array is 0). >> > > That's a good thing. Code that fails obviously and synchronously is better > than code that silently fails to work, from the point of view of an author > trying to find bugs. > > > Agreed in general. What I was trying to point out was that if a dev would > expect this code to modify the curve used by the shaper, neutering the > array won't serve that purpose either. > The goal here is to _not_ allow modifying the array under WaveShaperNode's nose. > The bigger inconvenience of neutering, as I've said before, is that a dev > cannot now use the same shape curve array with two wave shaper nodes. If > the system is to somehow sneak in behind the neutered array and get the > contents, then there really needs to be a whole section in the spec on how > objects are to respond to array properties when neutered arrays are passed > 'cos it is all non-obvious. As a dev, I worry more about the following not > working - > > var curve = new Float32Array(N); > // ... fill up curve with data... > shaper1.curve = shaper2.curve = curve; > If we make the getter return a new JS object pointing to an array with a copy of the data passed to the setter, then this code will work fine. > >> Furthermore, what would be >> the point of having a getter for the shaper.curve property if all it will >> provide is a neutered array? >> RoC's suggestion of a setCurve() without a getter is in this case a much >> cleaner solution. >> > > We could arrange for the getter of 'curve' to return a new non-neutered > array, with the old contents, if the original array has been neutered. > > > Possible solution, but this makes a copy anyway and raises further > questions. > Sure, but there's no way to fix this situation by avoiding to copy in all cases. It's better to copy in the non-common case. > If the first code is expected to work, when should the shaper node check > that the contents of this new array has changed and update itself? > There's not a good answer for that, except that, it shouldn't have to. :-) > >> In general, please consider whether any "setBlah" qualifies as a full >> property before >> also including a getter for it. In this case, what we (devs) really need >> is a write-only property >> to avoid all this potential confusion. A setCurve() will offer a clear >> point where any consistency >> checks on the array can be expected to be performed. >> > > Sounds good to me :-). Maybe we could add setCurve(), deprecate the > attribute, make setting the attribute neuter the array, and make getting > the attribute return a new array with the latest curve data. > > > This is close to best, but since compatibility is of interest here, the > deprecated attribute shouldn't be spec'd to neuter because it'll break code > that shares an array between shaper nodes. setCurve() should then be spec'd > such that modifying the array after setCurve() is called should not affect > the shaper node. > I don't think that's a good argument. I think spec'ing neutering on set and copying on get is the best we can do compatibility wise. I don't expect that to break a lot of existing content, and we should not be interested in the theoretical breakages. > This situation is analogous to WebGL where a texture is created from an > array of pixels. The pixel data is copied and the array with the pixel data > is free to be modified with no expectation of immediately affecting the > texture. The advantage of an internal copy is that the copy can use a more > efficient representation if it so desires - for example, by supersampling > the array using polynomial interpolation, for higher quality if that cost > cannot be paid in the inner processing loop. > > To sum up the points on this - > a) there is loss of functionality in neutering array attributes after > they're set, > b) what a node should do with neutered array data is non-obvious and needs > separate specification if neutered arrays behave differently from > zero-length arrays, > c) there are potential efficiency advantages to a node keeping internal > copies, and > d) internal copies are more friendly to implementations that might sandbox > the audio code in a separate process (like Chrome does with WebGL). > > On a wider note, the only case I can find for neutering is for Blob > objects after close() is called on them ( > http://dev.w3.org/2006/webapi/FileAPI/). That makes sense and I wouldn't > expect to use a Blob after close()ing it. Any other cases that might serve > as guides for when to neuter and when not to? > Note that I'm not suggesting neutering as a good way to design the API, I'm suggesting that as the best compromise to fix the API that is already broken, because overhauling the API without changing WebKit/Blink is not practical. -- Ehsan <http://ehsanakhgari.org/>
Received on Tuesday, 14 May 2013 19:28:51 UTC