Backed out changeset e7215fed014f (bug 1025864) for frequent OSX debug crashes.
This commit is contained in:
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Web Audio Editor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="text/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
let ctx = new AudioContext();
|
||||
let osc = ctx.createOscillator();
|
||||
let shaperNode = ctx.createWaveShaper();
|
||||
let detuneVal = 0;
|
||||
shaperNode.curve = new Float32Array(65536);
|
||||
setInterval(() => osc.detune.value = ++detuneVal, 10);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,15 +663,11 @@ 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) {
|
||||
function createObjectGrip (value) {
|
||||
return {
|
||||
type: "object",
|
||||
preview: {
|
||||
@@ -756,92 +676,4 @@ function createGrip (value) {
|
||||
},
|
||||
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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user