Navigation Menu

Skip to content

Commit

Permalink
Adds support for value expressions in change specifications.
Browse files Browse the repository at this point in the history
  • Loading branch information
colinbdclark committed Feb 20, 2015
1 parent 4e94494 commit 5917c2a
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 44 deletions.
56 changes: 43 additions & 13 deletions dist/flocking-all.js
@@ -1,4 +1,4 @@
/*! Flocking 0.1.0 (February 16, 2015), Copyright 2015 Colin Clark | flockingjs.org */
/*! Flocking 0.1.0 (February 20, 2015), Copyright 2015 Colin Clark | flockingjs.org */

/*!
* jQuery JavaScript Library v2.1.1
Expand Down Expand Up @@ -20469,8 +20469,14 @@ var fluid = fluid || require("infusion"),

flock.interpolate.cubic = flock.interpolate.hermite;

flock.warn = function (msg) {
fluid.log(fluid.logLevel.WARN, msg);
flock.log = {
warn: function (msg) {
fluid.log(fluid.logLevel.WARN, msg);
},

debug: function (msg) {
fluid.log(fluid.logLevel.INFO, msg);
}
};

flock.fail = function (msg) {
Expand All @@ -20482,7 +20488,7 @@ var fluid = fluid || require("infusion"),
};

flock.pathParseError = function (root, path, token) {
var msg = "Error parsing path: " + path + ". Segment '" + token +
var msg = "Error parsing path '" + path + "'. Segment '" + token +
"' could not be resolved. Root object was: " + fluid.prettyPrintJSON(root);

flock.fail(msg);
Expand Down Expand Up @@ -20531,8 +20537,8 @@ var fluid = fluid || require("infusion"),
root = root[prop];
type = typeof root;
if (type !== "object") {
flock.fail("Error while setting a value at path + " + path +
". A non-container object was found at segment " + prop + ". Value: " + root);
flock.fail("Error while setting a value at path '" + path +
"'. A non-container object was found at segment '" + prop + "'. Value: " + root);

return;
}
Expand Down Expand Up @@ -20662,23 +20668,47 @@ var fluid = fluid || require("infusion"),
flock.input.getValuesForPathObject(root, path);
};

flock.input.resolveValue = function (root, path, val, target, inputName, previousInput, valueParser) {
// Check to see if the value is actually a "get expression"
// (i.e. an EL path wrapped in ${}) and resolve it if necessary.
if (typeof val === "string") {
var extracted = fluid.extractEL(val, flock.input.valueExpressionSpec);
if (extracted) {
var resolved = flock.input.getValueForPath(root, extracted);
if (resolved === undefined) {
flock.log.debug("The value expression '" + val + "' resolved to undefined. " +
"If this isn't expected, check to ensure that your path is valid.");
}

return resolved;
}
}

return flock.input.shouldExpand(inputName, target) && valueParser ?
valueParser(val, path, target, previousInput) : val;
};

flock.input.valueExpressionSpec = {
ELstyle: "${}"
};

flock.input.setValueForPath = function (root, path, val, baseTarget, valueParser) {
path = flock.input.expandPath(path);

var previousInput = flock.get(root, path),
lastDotIdx = path.lastIndexOf("."),
inputName = path.slice(lastDotIdx + 1),
target = lastDotIdx > -1 ? flock.get(root, path.slice(0, path.lastIndexOf(".inputs"))) : baseTarget,
newInput = flock.input.shouldExpand(inputName, target) && valueParser ?
valueParser(val, path, target, previousInput) : val;
target = lastDotIdx > -1 ? flock.get(root, path.slice(0, path.lastIndexOf(".inputs"))) :
baseTarget,
resolvedVal = flock.input.resolveValue(root, path, val, target, inputName, previousInput, valueParser);

flock.set(root, path, newInput);
flock.set(root, path, resolvedVal);

if (target && target.onInputChanged) {
target.onInputChanged(inputName);
}

return newInput;
return resolvedVal;
};

flock.input.setValuesForPaths = function (root, valueMap, baseTarget, valueParser) {
Expand Down Expand Up @@ -30082,11 +30112,11 @@ var fluid = fluid || require("infusion"),
// TODO: Remove this warning when Safari and Android
// fix their MediaElementAudioSourceNode implementations.
if (flock.platform.browser.safari) {
flock.warn("MediaElementSourceNode does not work on Safari. " +
flock.log.warn("MediaElementSourceNode does not work on Safari. " +
"For more information, see https://bugs.webkit.org/show_bug.cgi?id=84743 " +
"and https://bugs.webkit.org/show_bug.cgi?id=125031");
} else if (flock.platform.isAndroid) {
flock.warn("MediaElementSourceNode does not work on Android. " +
flock.log.warn("MediaElementSourceNode does not work on Android. " +
"For more information, see https://code.google.com/p/chromium/issues/detail?id=419446");
}
};
Expand Down
6 changes: 3 additions & 3 deletions dist/flocking-all.min.js

Large diffs are not rendered by default.

56 changes: 43 additions & 13 deletions dist/flocking-no-jquery.js
@@ -1,4 +1,4 @@
/*! Flocking 0.1.0 (February 16, 2015), Copyright 2015 Colin Clark | flockingjs.org */
/*! Flocking 0.1.0 (February 20, 2015), Copyright 2015 Colin Clark | flockingjs.org */

(function (root, factory) {
if (typeof exports === "object") {
Expand Down Expand Up @@ -11298,8 +11298,14 @@ var fluid = fluid || require("infusion"),

flock.interpolate.cubic = flock.interpolate.hermite;

flock.warn = function (msg) {
fluid.log(fluid.logLevel.WARN, msg);
flock.log = {
warn: function (msg) {
fluid.log(fluid.logLevel.WARN, msg);
},

debug: function (msg) {
fluid.log(fluid.logLevel.INFO, msg);
}
};

flock.fail = function (msg) {
Expand All @@ -11311,7 +11317,7 @@ var fluid = fluid || require("infusion"),
};

flock.pathParseError = function (root, path, token) {
var msg = "Error parsing path: " + path + ". Segment '" + token +
var msg = "Error parsing path '" + path + "'. Segment '" + token +
"' could not be resolved. Root object was: " + fluid.prettyPrintJSON(root);

flock.fail(msg);
Expand Down Expand Up @@ -11360,8 +11366,8 @@ var fluid = fluid || require("infusion"),
root = root[prop];
type = typeof root;
if (type !== "object") {
flock.fail("Error while setting a value at path + " + path +
". A non-container object was found at segment " + prop + ". Value: " + root);
flock.fail("Error while setting a value at path '" + path +
"'. A non-container object was found at segment '" + prop + "'. Value: " + root);

return;
}
Expand Down Expand Up @@ -11491,23 +11497,47 @@ var fluid = fluid || require("infusion"),
flock.input.getValuesForPathObject(root, path);
};

flock.input.resolveValue = function (root, path, val, target, inputName, previousInput, valueParser) {
// Check to see if the value is actually a "get expression"
// (i.e. an EL path wrapped in ${}) and resolve it if necessary.
if (typeof val === "string") {
var extracted = fluid.extractEL(val, flock.input.valueExpressionSpec);
if (extracted) {
var resolved = flock.input.getValueForPath(root, extracted);
if (resolved === undefined) {
flock.log.debug("The value expression '" + val + "' resolved to undefined. " +
"If this isn't expected, check to ensure that your path is valid.");
}

return resolved;
}
}

return flock.input.shouldExpand(inputName, target) && valueParser ?
valueParser(val, path, target, previousInput) : val;
};

flock.input.valueExpressionSpec = {
ELstyle: "${}"
};

flock.input.setValueForPath = function (root, path, val, baseTarget, valueParser) {
path = flock.input.expandPath(path);

var previousInput = flock.get(root, path),
lastDotIdx = path.lastIndexOf("."),
inputName = path.slice(lastDotIdx + 1),
target = lastDotIdx > -1 ? flock.get(root, path.slice(0, path.lastIndexOf(".inputs"))) : baseTarget,
newInput = flock.input.shouldExpand(inputName, target) && valueParser ?
valueParser(val, path, target, previousInput) : val;
target = lastDotIdx > -1 ? flock.get(root, path.slice(0, path.lastIndexOf(".inputs"))) :
baseTarget,
resolvedVal = flock.input.resolveValue(root, path, val, target, inputName, previousInput, valueParser);

flock.set(root, path, newInput);
flock.set(root, path, resolvedVal);

if (target && target.onInputChanged) {
target.onInputChanged(inputName);
}

return newInput;
return resolvedVal;
};

flock.input.setValuesForPaths = function (root, valueMap, baseTarget, valueParser) {
Expand Down Expand Up @@ -20911,11 +20941,11 @@ var fluid = fluid || require("infusion"),
// TODO: Remove this warning when Safari and Android
// fix their MediaElementAudioSourceNode implementations.
if (flock.platform.browser.safari) {
flock.warn("MediaElementSourceNode does not work on Safari. " +
flock.log.warn("MediaElementSourceNode does not work on Safari. " +
"For more information, see https://bugs.webkit.org/show_bug.cgi?id=84743 " +
"and https://bugs.webkit.org/show_bug.cgi?id=125031");
} else if (flock.platform.isAndroid) {
flock.warn("MediaElementSourceNode does not work on Android. " +
flock.log.warn("MediaElementSourceNode does not work on Android. " +
"For more information, see https://code.google.com/p/chromium/issues/detail?id=419446");
}
};
Expand Down
6 changes: 3 additions & 3 deletions dist/flocking-no-jquery.min.js

Large diffs are not rendered by default.

50 changes: 40 additions & 10 deletions flocking/flocking-core.js
Expand Up @@ -507,8 +507,14 @@ var fluid = fluid || require("infusion"),

flock.interpolate.cubic = flock.interpolate.hermite;

flock.warn = function (msg) {
fluid.log(fluid.logLevel.WARN, msg);
flock.log = {
warn: function (msg) {
fluid.log(fluid.logLevel.WARN, msg);
},

debug: function (msg) {
fluid.log(fluid.logLevel.INFO, msg);
}
};

flock.fail = function (msg) {
Expand All @@ -520,7 +526,7 @@ var fluid = fluid || require("infusion"),
};

flock.pathParseError = function (root, path, token) {
var msg = "Error parsing path: " + path + ". Segment '" + token +
var msg = "Error parsing path '" + path + "'. Segment '" + token +
"' could not be resolved. Root object was: " + fluid.prettyPrintJSON(root);

flock.fail(msg);
Expand Down Expand Up @@ -569,8 +575,8 @@ var fluid = fluid || require("infusion"),
root = root[prop];
type = typeof root;
if (type !== "object") {
flock.fail("Error while setting a value at path + " + path +
". A non-container object was found at segment " + prop + ". Value: " + root);
flock.fail("Error while setting a value at path '" + path +
"'. A non-container object was found at segment '" + prop + "'. Value: " + root);

return;
}
Expand Down Expand Up @@ -700,23 +706,47 @@ var fluid = fluid || require("infusion"),
flock.input.getValuesForPathObject(root, path);
};

flock.input.resolveValue = function (root, path, val, target, inputName, previousInput, valueParser) {
// Check to see if the value is actually a "get expression"
// (i.e. an EL path wrapped in ${}) and resolve it if necessary.
if (typeof val === "string") {
var extracted = fluid.extractEL(val, flock.input.valueExpressionSpec);
if (extracted) {
var resolved = flock.input.getValueForPath(root, extracted);
if (resolved === undefined) {
flock.log.debug("The value expression '" + val + "' resolved to undefined. " +
"If this isn't expected, check to ensure that your path is valid.");
}

return resolved;
}
}

return flock.input.shouldExpand(inputName, target) && valueParser ?
valueParser(val, path, target, previousInput) : val;
};

flock.input.valueExpressionSpec = {
ELstyle: "${}"
};

flock.input.setValueForPath = function (root, path, val, baseTarget, valueParser) {
path = flock.input.expandPath(path);

var previousInput = flock.get(root, path),
lastDotIdx = path.lastIndexOf("."),
inputName = path.slice(lastDotIdx + 1),
target = lastDotIdx > -1 ? flock.get(root, path.slice(0, path.lastIndexOf(".inputs"))) : baseTarget,
newInput = flock.input.shouldExpand(inputName, target) && valueParser ?
valueParser(val, path, target, previousInput) : val;
target = lastDotIdx > -1 ? flock.get(root, path.slice(0, path.lastIndexOf(".inputs"))) :
baseTarget,
resolvedVal = flock.input.resolveValue(root, path, val, target, inputName, previousInput, valueParser);

flock.set(root, path, newInput);
flock.set(root, path, resolvedVal);

if (target && target.onInputChanged) {
target.onInputChanged(inputName);
}

return newInput;
return resolvedVal;
};

flock.input.setValuesForPaths = function (root, valueMap, baseTarget, valueParser) {
Expand Down
4 changes: 2 additions & 2 deletions flocking/flocking-ugens-browser.js
Expand Up @@ -366,11 +366,11 @@ var fluid = fluid || require("infusion"),
// TODO: Remove this warning when Safari and Android
// fix their MediaElementAudioSourceNode implementations.
if (flock.platform.browser.safari) {
flock.warn("MediaElementSourceNode does not work on Safari. " +
flock.log.warn("MediaElementSourceNode does not work on Safari. " +
"For more information, see https://bugs.webkit.org/show_bug.cgi?id=84743 " +
"and https://bugs.webkit.org/show_bug.cgi?id=125031");
} else if (flock.platform.isAndroid) {
flock.warn("MediaElementSourceNode does not work on Android. " +
flock.log.warn("MediaElementSourceNode does not work on Android. " +
"For more information, see https://code.google.com/p/chromium/issues/detail?id=419446");
}
};
Expand Down
39 changes: 39 additions & 0 deletions tests/flocking/js/core-tests.js
Expand Up @@ -879,6 +879,45 @@ var fluid = fluid || require("infusion"),
testSetMultiple("input");
});

var valueExpressionTestSpecs = [
{
name: "Value expression resolving into the model",
change: {
"sine.freq": "${mod.freq.model.value}"
},
targetUGenName: "mod",
expectedPath: "inputs.freq.model.value"
},
{
name: "Value expression resolving to a unit generator instance",
change: {
"sine.freq": "${mod}"
},
targetUGenName: "mod"
}
];

var testValueExpressions = function (testSpecs) {
fluid.each(testSpecs, function (testSpec) {
test(testSpec.name, function () {
var synth = createSynth(simpleSynthDef);
synth.set(testSpec.change);

var actual = synth.get(Object.keys(testSpec.change)[0]),
expected = synth.get(testSpec.targetUGenName);

if (testSpec.expectedPath) {
expected = fluid.get(expected, testSpec.expectedPath);
}

equal(actual, expected,
"The value expression should have been resolved and set at the specified path.");
});
});
};

testValueExpressions(valueExpressionTestSpecs);

test("Synth.set(): correct node evaluation order", function () {
var synth = flock.synth({
synthDef: {
Expand Down

0 comments on commit 5917c2a

Please sign in to comment.