diff --git a/browser/devtools/shared/frame-script-utils.js b/browser/devtools/shared/frame-script-utils.js index aee6bd1ad801..51068b8ebfd6 100644 --- a/browser/devtools/shared/frame-script-utils.js +++ b/browser/devtools/shared/frame-script-utils.js @@ -4,8 +4,6 @@ "use strict"; -let { utils: Cu, interfaces: Ci } = Components; - addMessageListener("devtools:test:history", function ({ data }) { content.history[data.direction](); }); @@ -18,11 +16,3 @@ addMessageListener("devtools:test:reload", function ({ data }) { data = data || {}; content.location.reload(data.forceget); }); - -addMessageListener("devtools:test:forceCC", function () { - let DOMWindowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - DOMWindowUtils.cycleCollect(); - DOMWindowUtils.garbageCollect(); - DOMWindowUtils.garbageCollect(); -}); diff --git a/browser/devtools/webaudioeditor/test/browser.ini b/browser/devtools/webaudioeditor/test/browser.ini index 6766ea9c06d1..08a6b34e7f33 100644 --- a/browser/devtools/webaudioeditor/test/browser.ini +++ b/browser/devtools/webaudioeditor/test/browser.ini @@ -10,7 +10,6 @@ support-files = doc_connect-toggle.html doc_connect-param.html doc_connect-multi-param.html - doc_change-param.html 440hz_sine.ogg head.js @@ -20,10 +19,6 @@ support-files = [browser_audionode-actor-get-set-param.js] [browser_audionode-actor-get-type.js] [browser_audionode-actor-is-source.js] - -[browser_webaudio-actor-change-params-01.js] -[browser_webaudio-actor-change-params-02.js] -[browser_webaudio-actor-change-params-03.js] [browser_webaudio-actor-connect-param.js] [browser_webaudio-actor-destroy-node.js] [browser_webaudio-actor-simple.js] @@ -37,7 +32,6 @@ support-files = [browser_wa_graph-click.js] [browser_wa_graph-markers.js] -skip-if = (os == 'mac' && debug) # bug 1035820 [browser_wa_graph-render-01.js] [browser_wa_graph-render-02.js] [browser_wa_graph-render-03.js] @@ -49,7 +43,6 @@ skip-if = (os == 'mac' && debug) # bug 1035820 [browser_wa_inspector-toggle.js] [browser_wa_properties-view.js] -[browser_wa_properties-view-change-params.js] [browser_wa_properties-view-edit-01.js] skip-if = true # bug 1010423 [browser_wa_properties-view-edit-02.js] diff --git a/browser/devtools/webaudioeditor/test/browser_wa_properties-view-change-params.js b/browser/devtools/webaudioeditor/test/browser_wa_properties-view-change-params.js deleted file mode 100644 index 080f6a96da1c..000000000000 --- a/browser/devtools/webaudioeditor/test/browser_wa_properties-view-change-params.js +++ /dev/null @@ -1,46 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests that params view correctly updates changed parameters - * when source code updates them, as well as CHANGE_PARAM events. - */ - -function spawnTest() { - let [target, debuggee, panel] = yield initWebAudioEditor(CHANGE_PARAM_URL); - let { panelWin } = panel; - let { gFront, $, $$, EVENTS, WebAudioInspectorView } = panelWin; - let gVars = WebAudioInspectorView._propsView; - - // Set parameter polling to 20ms for tests - panelWin.PARAM_POLLING_FREQUENCY = 20; - - let started = once(gFront, "start-context"); - - reload(target); - - let [actors] = yield Promise.all([ - getN(gFront, "create-node", 3), - waitForGraphRendered(panelWin, 3, 0) - ]); - - let oscId = actors[1].actorID; - - click(panelWin, findGraphNode(panelWin, oscId)); - yield once(panelWin, EVENTS.UI_INSPECTOR_NODE_SET); - - // Yield twice so we get a diff - yield once(panelWin, EVENTS.CHANGE_PARAM); - let [[_, args]] = yield getSpread(panelWin, EVENTS.CHANGE_PARAM); - is(args.actorID, oscId, "EVENTS.CHANGE_PARAM has correct `actorID`"); - ok(args.oldValue < args.newValue, "EVENTS.CHANGE_PARAM has correct `newValue` and `oldValue`"); - is(args.param, "detune", "EVENTS.CHANGE_PARAM has correct `param`"); - - let [[_, args]] = yield getSpread(panelWin, EVENTS.CHANGE_PARAM); - checkVariableView(gVars, 0, { "detune": args.newValue }, "`detune` parameter updated."); - let [[_, args]] = yield getSpread(panelWin, EVENTS.CHANGE_PARAM); - checkVariableView(gVars, 0, { "detune": args.newValue }, "`detune` parameter updated."); - - yield teardown(panel); - finish(); -} diff --git a/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-01.js b/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-01.js deleted file mode 100644 index 072a17d6030b..000000000000 --- a/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-01.js +++ /dev/null @@ -1,46 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Test WebAudioActor `change-param` events and front.[en|dis]ableChangeParamEvents - */ - -function spawnTest () { - let [target, debuggee, front] = yield initBackend(CHANGE_PARAM_URL); - let [_, nodes] = yield Promise.all([ - front.setup({ reload: true }), - getN(front, "create-node", 3) - ]); - - let osc = nodes[1]; - let eventCount = 0; - - yield front.enableChangeParamEvents(osc, 20); - - front.on("change-param", onChangeParam); - - yield getN(front, "change-param", 3); - yield front.disableChangeParamEvents(); - - let currEventCount = eventCount; - - // Be flexible here incase we get an extra counter before the listener is turned off - ok(eventCount >= 3, "Calling `enableChangeParamEvents` should allow front to emit `change-param`."); - - yield wait(100); - - ok((eventCount - currEventCount) <= 2, "Calling `disableChangeParamEvents` should turn off the listener."); - - front.off("change-param", onChangeParam); - - yield removeTab(target.tab); - finish(); - - function onChangeParam ({ newValue, oldValue, param, actorID }) { - is(actorID, osc.actorID, "correct `actorID` in `change-param`."); - is(param, "detune", "correct `param` property in `change-param`."); - ok(newValue > oldValue, - "correct `newValue` (" + newValue + ") and `oldValue` (" + oldValue + ") in `change-param`"); - eventCount++; - } -} diff --git a/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-02.js b/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-02.js deleted file mode 100644 index b650e5e73b1e..000000000000 --- a/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-02.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Test that listening to param change polling does not break when the AudioNode is collected. - */ - -function spawnTest () { - let [target, debuggee, front] = yield initBackend(DESTROY_NODES_URL); - let waitUntilDestroyed = getN(front, "destroy-node", 10); - let [_, nodes] = yield Promise.all([ - front.setup({ reload: true }), - getN(front, "create-node", 13) - ]); - - let bufferNode = nodes[6]; - - yield front.enableChangeParamEvents(bufferNode, 20); - - front.on("change-param", onChangeParam); - - forceCC(); - - yield waitUntilDestroyed; - yield wait(50); - - front.off("change-param", onChangeParam); - - ok(true, "listening to `change-param` on a dead node doesn't throw."); - yield removeTab(target.tab); - finish(); - - function onChangeParam (args) { - ok(false, "`change-param` should not be emitted on a node that hasn't changed params or is dead."); - } -} diff --git a/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-03.js b/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-03.js deleted file mode 100644 index 43715cbd60eb..000000000000 --- a/browser/devtools/webaudioeditor/test/browser_webaudio-actor-change-params-03.js +++ /dev/null @@ -1,32 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Test WebAudioActor `change-param` events on special types. - */ - -function spawnTest () { - let [target, debuggee, front] = yield initBackend(CHANGE_PARAM_URL); - let [_, nodes] = yield Promise.all([ - front.setup({ reload: true }), - getN(front, "create-node", 3) - ]); - - let shaper = nodes[2]; - let eventCount = 0; - - yield front.enableChangeParamEvents(shaper, 20); - - let onChange = once(front, "change-param"); - - shaper.setParam("curve", null); - - let { newValue, oldValue } = yield onChange; - - is(oldValue.type, "object", "`oldValue` should be an object."); - is(oldValue.class, "Float32Array", "`oldValue` should be of class Float32Array."); - is(newValue.type, "null", "`newValue` should be null."); - - yield removeTab(target.tab); - finish(); -} diff --git a/browser/devtools/webaudioeditor/test/doc_change-param.html b/browser/devtools/webaudioeditor/test/doc_change-param.html deleted file mode 100644 index c8925d912fa9..000000000000 --- a/browser/devtools/webaudioeditor/test/doc_change-param.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - Web Audio Editor test page - - - - - - - - diff --git a/browser/devtools/webaudioeditor/test/head.js b/browser/devtools/webaudioeditor/test/head.js index 7a452d1bfbd4..2a69ae1697bb 100644 --- a/browser/devtools/webaudioeditor/test/head.js +++ b/browser/devtools/webaudioeditor/test/head.js @@ -19,9 +19,7 @@ let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.j let { WebAudioFront } = devtools.require("devtools/server/actors/webaudio"); let TargetFactory = devtools.TargetFactory; -let mm = null; -const FRAME_SCRIPT_UTILS_URL = "chrome://browser/content/devtools/frame-script-utils.js"; const EXAMPLE_URL = "http://example.com/browser/browser/devtools/webaudioeditor/test/"; const SIMPLE_CONTEXT_URL = EXAMPLE_URL + "doc_simple-context.html"; const COMPLEX_CONTEXT_URL = EXAMPLE_URL + "doc_complex-context.html"; @@ -32,7 +30,6 @@ const DESTROY_NODES_URL = EXAMPLE_URL + "doc_destroy-nodes.html"; const CONNECT_TOGGLE_URL = EXAMPLE_URL + "doc_connect-toggle.html"; const CONNECT_PARAM_URL = EXAMPLE_URL + "doc_connect-param.html"; const CONNECT_MULTI_PARAM_URL = EXAMPLE_URL + "doc_connect-multi-param.html"; -const CHANGE_PARAM_URL = EXAMPLE_URL + "doc_change-param.html"; // All tests are asynchronous. waitForExplicitFinish(); @@ -136,8 +133,6 @@ function initBackend(aUrl) { yield target.makeRemote(); let front = new WebAudioFront(target.client, target.form); - - loadFrameScripts(); return [target, debuggee, front]; }); } @@ -155,8 +150,6 @@ function initWebAudioEditor(aUrl) { Services.prefs.setBoolPref("devtools.webaudioeditor.enabled", true); let toolbox = yield gDevTools.showToolbox(target, "webaudioeditor"); let panel = toolbox.getCurrentPanel(); - - loadFrameScripts(); return [target, debuggee, panel]; }); } @@ -394,12 +387,9 @@ function countGraphObjects (win) { * Forces cycle collection and GC, used in AudioNode destruction tests. */ function forceCC () { - mm.sendAsyncMessage("devtools:test:forceCC"); -} - -function loadFrameScripts () { - mm = gBrowser.selectedBrowser.messageManager; - mm.loadFrameScript(FRAME_SCRIPT_UTILS_URL, false); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); } /** diff --git a/browser/devtools/webaudioeditor/webaudioeditor-controller.js b/browser/devtools/webaudioeditor/webaudioeditor-controller.js index 939d83773f54..7460e314c63b 100644 --- a/browser/devtools/webaudioeditor/webaudioeditor-controller.js +++ b/browser/devtools/webaudioeditor/webaudioeditor-controller.js @@ -20,9 +20,8 @@ const STRINGS_URI = "chrome://browser/locale/devtools/webaudioeditor.properties" const L10N = new ViewHelpers.L10N(STRINGS_URI); const Telemetry = require("devtools/shared/telemetry"); const telemetry = new Telemetry(); -let { console } = Cu.import("resource://gre/modules/devtools/Console.jsm", {}); -let PARAM_POLLING_FREQUENCY = 1000; +let { console } = Cu.import("resource://gre/modules/devtools/Console.jsm", {}); // The panel's window global is an EventEmitter firing the following events: const EVENTS = { @@ -174,8 +173,6 @@ let WebAudioEditorController = { telemetry.toolOpened("webaudioeditor"); this._onTabNavigated = this._onTabNavigated.bind(this); this._onThemeChange = this._onThemeChange.bind(this); - this._onSelectNode = this._onSelectNode.bind(this); - this._onChangeParam = this._onChangeParam.bind(this); gTarget.on("will-navigate", this._onTabNavigated); gTarget.on("navigate", this._onTabNavigated); gFront.on("start-context", this._onStartContext); @@ -197,15 +194,12 @@ let WebAudioEditorController = { window.on(EVENTS.DISCONNECT_NODE, this._onUpdatedContext); window.on(EVENTS.DESTROY_NODE, this._onUpdatedContext); window.on(EVENTS.CONNECT_PARAM, this._onUpdatedContext); - - // Set up a controller for managing parameter changes per audio node - window.on(EVENTS.UI_SELECT_NODE, this._onSelectNode); }, /** * Remove events emitted by the current tab target. */ - destroy: Task.async(function* () { + destroy: function() { telemetry.toolClosed("webaudioeditor"); gTarget.off("will-navigate", this._onTabNavigated); gTarget.off("navigate", this._onTabNavigated); @@ -221,11 +215,8 @@ let WebAudioEditorController = { window.off(EVENTS.DISCONNECT_NODE, this._onUpdatedContext); window.off(EVENTS.DESTROY_NODE, this._onUpdatedContext); window.off(EVENTS.CONNECT_PARAM, this._onUpdatedContext); - window.off(EVENTS.UI_SELECT_NODE, this._onSelectNode); gDevTools.off("pref-changed", this._onThemeChange); - - yield gFront.disableChangeParamEvents(); - }), + }, /** * Called when page is reloaded to show the reload notice and waiting @@ -354,21 +345,9 @@ let WebAudioEditorController = { /** * Called when a node param is changed. */ - _onChangeParam: function (args) { - window.emit(EVENTS.CHANGE_PARAM, args); - }, - - /** - * Called on UI_SELECT_NODE, used to manage - * `change-param` events on that node. - */ - _onSelectNode: function (_, id) { - let node = getViewNodeById(id); - - if (node && node.actor) { - gFront.enableChangeParamEvents(node.actor, PARAM_POLLING_FREQUENCY); - } - }, + _onChangeParam: function({ actor, param, value }) { + window.emit(EVENTS.CHANGE_PARAM, getViewNodeByActor(actor), param, value); + } }; /** diff --git a/browser/devtools/webaudioeditor/webaudioeditor-view.js b/browser/devtools/webaudioeditor/webaudioeditor-view.js index 283a5347666b..8bcf4b366eac 100644 --- a/browser/devtools/webaudioeditor/webaudioeditor-view.js +++ b/browser/devtools/webaudioeditor/webaudioeditor-view.js @@ -377,7 +377,6 @@ let WebAudioInspectorView = { this._onNodeSelect = this._onNodeSelect.bind(this); this._onTogglePaneClick = this._onTogglePaneClick.bind(this); this._onDestroyNode = this._onDestroyNode.bind(this); - this._onChangeParam = this._onChangeParam.bind(this); this._inspectorPaneToggleButton.addEventListener("mousedown", this._onTogglePaneClick, false); this._propsView = new VariablesView($("#properties-tabpanel-content"), GENERIC_VARIABLES_VIEW_SETTINGS); @@ -385,7 +384,6 @@ let WebAudioInspectorView = { window.on(EVENTS.UI_SELECT_NODE, this._onNodeSelect); window.on(EVENTS.DESTROY_NODE, this._onDestroyNode); - window.on(EVENTS.CHANGE_PARAM, this._onChangeParam); }, /** @@ -395,7 +393,6 @@ let WebAudioInspectorView = { this._inspectorPaneToggleButton.removeEventListener("mousedown", this._onTogglePaneClick); window.off(EVENTS.UI_SELECT_NODE, this._onNodeSelect); window.off(EVENTS.DESTROY_NODE, this._onDestroyNode); - window.off(EVENTS.CHANGE_PARAM, this._onChangeParam); this._inspectorPane = null; this._inspectorPaneToggleButton = null; @@ -615,22 +612,7 @@ let WebAudioInspectorView = { if (this._currentNode && this._currentNode.id === id) { this.setCurrentAudioNode(null); } - }, - - /** - * Called when `CHANGE_PARAM` is fired. We should ensure that this event is - * for the same node that is currently selected. We check the existence - * of each part of the scope to make sure that if this event was fired - * during a VariablesView rebuild, then we just ignore it. - */ - _onChangeParam: function (_, { param, newValue, oldValue, actorID }) { - if (!this._currentNode || this._currentNode.actor.actorID !== actorID) return; - let scope = this._getAudioPropertiesScope(); - if (!scope) return; - let property = scope.get(param); - if (!property) return; - property.setGrip(newValue); - }, + } }; /** diff --git a/toolkit/devtools/server/actors/webaudio.js b/toolkit/devtools/server/actors/webaudio.js index ef9b0fec6952..4cea0f9e925d 100644 --- a/toolkit/devtools/server/actors/webaudio.js +++ b/toolkit/devtools/server/actors/webaudio.js @@ -4,14 +4,16 @@ "use strict"; const {Cc, Ci, Cu, Cr} = require("chrome"); + const Services = require("Services"); + const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {}); const events = require("sdk/event/core"); const { on: systemOn, off: systemOff } = require("sdk/system/events"); -const { setTimeout, clearTimeout } = require("sdk/timers"); const protocol = require("devtools/server/protocol"); const { CallWatcherActor, CallWatcherFront } = require("devtools/server/actors/call-watcher"); const { ThreadActor } = require("devtools/server/actors/script"); + const { on, once, off, emit } = events; const { method, Arg, Option, RetVal } = protocol; @@ -25,10 +27,6 @@ exports.unregister = function(handle) { handle.removeGlobalActor(WebAudioActor); }; -// In milliseconds, how often should AudioNodes poll to see -// if an AudioParam's value has changed to emit to the client. -const PARAM_POLLING_FREQUENCY = 1000; - const AUDIO_GLOBALS = [ "AudioContext", "AudioNode" ]; @@ -148,10 +146,6 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({ } }, - destroy: function(conn) { - protocol.Actor.prototype.destroy.call(this, conn); - }, - /** * Returns the name of the audio type. * Examples: "OscillatorNode", "MediaElementAudioSourceNode" @@ -193,7 +187,6 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({ node[param].value = value; else node[param] = value; - return undefined; } catch (e) { return constructError(e); @@ -228,7 +221,14 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({ // AudioBuffer or Float32Array references and the like, // so this just formats the value to be displayed in the VariablesView, // without using real grips and managing via actor pools. - return createGrip(value); + let grip; + try { + grip = ThreadActor.prototype.createValueGrip(value); + } + catch (e) { + grip = createObjectGrip(value); + } + return grip; }, { request: { param: Arg(0, "string") @@ -252,27 +252,16 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({ }), /** - * Get an array of objects each containing a `param`, `value` and `flags` property, - * corresponding to a property name and current value of the audio node, and any - * associated flags as defined by NODE_PROPERTIES. + * Get an array of objects each containing a `param` and `value` property, + * corresponding to a property name and current value of the audio node. */ - getParams: method(function () { + getParams: method(function (param) { let props = Object.keys(NODE_PROPERTIES[this.type]); return props.map(prop => ({ param: prop, value: this.getParam(prop), flags: this.getParamFlags(prop) })); }, { response: { params: RetVal("json") } - }), - - /** - * Returns a boolean indicating whether or not - * the underlying AudioNode has been collected yet or not. - * - * @return Boolean - */ - isAlive: function () { - return !!this.node.get(); - } + }) }); /** @@ -418,7 +407,6 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ this.tabActor = null; this._initialized = false; off(this._callWatcher._contentObserver, "global-destroyed", this._onGlobalDestroyed); - this.disableChangeParamEvents(); this._nativeToActorID = null; this._callWatcher.eraseRecording(); this._callWatcher.finalize(); @@ -427,59 +415,6 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ oneway: true }), - /** - * Takes an AudioNodeActor and a duration specifying how often - * should the node's parameters be polled to detect changes. Emits - * `change-param` when a change is found. - * - * Currently, only one AudioNodeActor can be listened to at a time. - * - * `wait` is used in tests to specify the poll timer. - */ - enableChangeParamEvents: method(function (nodeActor, wait) { - // For now, only have one node being polled - this.disableChangeParamEvents(); - - // Ignore if node is dead - if (!nodeActor.isAlive()) { - return; - } - - let previous = mapAudioParams(nodeActor); - - // Store the ID of the node being polled - this._pollingID = nodeActor.actorID; - - this.poller = new Poller(() => { - // If node has been collected, disable param polling - if (!nodeActor.isAlive()) { - this.disableChangeParamEvents(); - return; - } - - let current = mapAudioParams(nodeActor); - diffAudioParams(previous, current).forEach(changed => { - this._onChangeParam(nodeActor, changed); - }); - previous = current; - }).on(wait || PARAM_POLLING_FREQUENCY); - }, { - request: { - node: Arg(0, "audionode"), - wait: Arg(1, "nullable:number"), - }, - oneway: true - }), - - disableChangeParamEvents: method(function () { - if (this.poller) { - this.poller.off(); - } - this._pollingID = null; - }, { - oneway: true - }), - /** * Events emitted by this actor. */ @@ -502,6 +437,12 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ dest: Option(0, "audionode"), param: Option(0, "string") }, + "change-param": { + type: "changeParam", + source: Option(0, "audionode"), + param: Option(0, "string"), + value: Option(0, "string") + }, "create-node": { type: "createNode", source: Arg(0, "audionode") @@ -509,13 +450,6 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ "destroy-node": { type: "destroyNode", source: Arg(0, "audionode") - }, - "change-param": { - type: "changeParam", - param: Option(0, "string"), - newValue: Option(0, "json"), - oldValue: Option(0, "json"), - actorID: Option(0, "string") } }, @@ -539,7 +473,7 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ /** * Takes an XrayWrapper node, and attaches the node's `nativeID` * to the AudioParams as `_parentID`, as well as the the type of param - * as a string on `_paramName`. Used to tag AudioParams for `connect-param` events. + * as a string on `_paramName`. */ _instrumentParams: function (node) { let type = getConstructorName(node); @@ -559,14 +493,6 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ * created), so make a new actor and store that. */ _getActorByNativeID: function (nativeID) { - // If the WebAudioActor has already been finalized, the `_nativeToActorID` - // map will already be destroyed -- the lingering destruction events - // seem to only occur in e10s, so add an extra check here to disregard - // these late events - if (!this._nativeToActorID) { - return null; - } - // Ensure we have a Number, rather than a string // return via notification. nativeID = ~~nativeID; @@ -618,12 +544,15 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ }, /** - * Called when an AudioParam that's being listened to changes. - * Takes an AudioNodeActor and an object with `newValue`, `oldValue`, and `param` name. + * Called when a parameter changes on an audio node */ - _onChangeParam: function (actor, changed) { - changed.actorID = actor.actorID; - emit(this, "change-param", changed); + _onParamChange: function (node, param, value) { + let actor = this._getActorByNativeID(node.id); + emit(this, "param-change", { + source: actor, + param: param, + value: value + }); }, /** @@ -634,8 +563,7 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ emit(this, "create-node", actor); }, - /** - * Called when `webaudio-node-demise` is triggered, + /** Called when `webaudio-node-demise` is triggered, * and emits the associated actor to the front if found. */ _onDestroyNode: function ({data}) { @@ -648,10 +576,6 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({ // notifications for a document that no longer exists, // the mapping should not be found, so we do not emit an event. if (actor) { - // Turn off polling for changes if on for this node - if (this._pollingID === actor.actorID) { - this.disableChangeParamEvents(); - } this._nativeToActorID.delete(nativeID); emit(this, "destroy-node", actor); } @@ -739,109 +663,17 @@ function getConstructorName (obj) { } /** - * Create a value grip for `value`, or fallback to a grip-like object - * for renderable information for the front-end for things like Float32Arrays, - * AudioBuffers, without tracking them in an actor pool. + * Create a grip-like object to pass in renderable information + * to the front-end for things like Float32Arrays, AudioBuffers, + * without tracking them in an actor pool. */ -function createGrip (value) { - try { - return ThreadActor.prototype.createValueGrip(value); - } - catch (e) { - return { - type: "object", - preview: { - kind: "ObjectWithText", - text: "" - }, - class: getConstructorName(value) - }; - } +function createObjectGrip (value) { + return { + type: "object", + preview: { + kind: "ObjectWithText", + text: "" + }, + class: getConstructorName(value) + }; } - -/** - * Takes an AudioNodeActor and maps its current parameter values - * to a hash, where the property is the AudioParam name, and value - * is the current value. - */ -function mapAudioParams (node) { - return node.getParams().reduce(function (obj, p) { - obj[p.param] = p.value; - return obj; - }, {}); -} - -/** - * Takes an object of previous and current values of audio parameters, - * and compares them. If they differ, emit a `change-param` event. - * - * @param Object prev - * Hash of previous set of AudioParam values. - * @param Object current - * Hash of current set of AudioParam values. - */ -function diffAudioParams (prev, current) { - return Object.keys(current).reduce((changed, param) => { - if (!equalGrips(current[param], prev[param])) { - changed.push({ - param: param, - oldValue: prev[param], - newValue: current[param] - }); - } - return changed; - }, []); -} - -/** - * Compares two grip objects to determine if they're equal or not. - * - * @param Any a - * @param Any a - * @return Boolean - */ -function equalGrips (a, b) { - let aType = typeof a; - let bType = typeof b; - if (aType !== bType) { - return false; - } else if (aType === "object") { - // In this case, we are comparing two objects, like an ArrayBuffer or Float32Array, - // or even just plain "null"s (which grip's will have `type` property "null", - // and we have no way of showing more information than its class, so assume - // these are equal since nothing can be updated with information of value. - if (a.type === b.type) { - return true; - } - // Otherwise return false -- this could be a case of a property going from `null` - // to having an ArrayBuffer or an object, in which case we should update it. - return false; - } else { - return a === b; - } -} - -/** - * Poller class -- takes a function, and call be turned on and off - * via methods to execute `fn` on the interval specified during `on`. - */ -function Poller (fn) { - this.fn = fn; -} - -Poller.prototype.on = function (wait) { - let poller = this; - poller.timer = setTimeout(poll, wait); - function poll () { - poller.fn(); - poller.timer = setTimeout(poll, wait); - } - return this; -}; - -Poller.prototype.off = function () { - if (this.timer) { - clearTimeout(this.timer); - } - return this; -};