Published
Edited
Dec 13, 2021
Insert cell
Insert cell
Insert cell
{
const log = [];

const sigList = [];
const signals = {};

function initSignal(code, sigFun) {
const s = {outputKey: code};
sigFun.apply(s);
log.push("Init "+code+" fun:" + sigFun.evaluateSignal);
sigList.push(s);
signals[code] = s;
}
//=======================================
// Start of wrapper for signalA

initSignal("A", function() {
// Start of signalA evalscript
const twoVal = 2;
function evaluateSignal(signalResults, samples) {
return twoVal * samples * samples;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
this.eval = evaluateSignal;
});

//=======================================
// Start of wrapper for signalB
initSignal("B", function() {
// Start of signalB evalscript
function evaluateSignal(signalResults, samples) {
return 2 * signalResults.A / 32; // <-- Use the result of signalA
}
// End of signalB evalscript
this.eval = evaluateSignal;
});

//==================================================
// Aggregation code - glue together all the wrappers
function evaluate(param) {
const ret = {};
sigList.forEach(s => {
log.push("Calling " + s.outputKey +" with " + param + ", " +JSON.stringify(ret));
ret[s.outputKey] = s.eval(ret, param);
log.push("Signal " + s.outputKey +" computed " + ret[s.outputKey]);
});
ret.log = log;
return ret;
}

return evaluate(4);
}
Insert cell
Insert cell
Insert cell
{
const log = [];

function evaluate(param) {
//=======================================
// Start of wrapper for signalA
const signals = {};
{
//-------------------------------------
// Start of signalA evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
function evaluate(param) {
log.push("Eval A called");
const ret = 2 * doStuff(param);
log.push("Computed A");
return ret;
}
function doStuff(param) {
return param*param;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalA evalscript
//-------------------------------------
signals.signalA = evaluate(param);
};
//=======================================
// Start of wrapper for signalB
{
//-------------------------------------
// Start of signalB evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
function evaluate(param) {
log.push("Eval B called");
const ret = doStuff(signals.signalA);
log.push("Computed B");
return ret;
}
function doStuff(param) {
return 2 * param/32;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalB evalscript
//--------------------------------------
signals.signalB = evaluate(param);
}
//==================================================
// Aggregation code - glue together all the wrappers

return ({
signalB: signals.signalB,
signalA: signals.signalA,
log: log
})
}
return evaluate(4);
}
Insert cell
Insert cell
{
const log = [];

//=======================================
// Start of wrapper for signalA

const signalA = {
outputKey : "A",
init : function() {
//-------------------------------------
// Start of signalA evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
this.evaluate = function(param) {
log.push("Eval A called");
const ret = signalB.twoVal * param * param; // <-- Use a constant or utility function from another signal
log.push("Computed A");
return ret;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalA evalscript
//-------------------------------------
if (this.evaluate === undefined) { this.evaluate = evaluate; }
}
};

//=======================================
// Start of wrapper for signalB
const signalB = {
outputKey : "B",
init : function() {
//-------------------------------------
// Start of signalB evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
this.twoVal = 2;
function evaluate(param) {
log.push("Eval B called");
const ret = this.twoVal * signalA.result / 32; // <-- Use the result of signalA
log.push("Computed B");
return ret;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalB evalscript
//-------------------------------------
if (!this.evaluate) { this.evaluate = evaluate } // capture 'evaluate' function so we can reference it
}
};

//==================================================
// Aggregation code - glue together all the wrappers
function evaluate(param) {
const ret = {};

const signals = [signalA, signalB]; //list signals in correct order here

signals.forEach(s => s.init());
signals.forEach(s => {
s.result = s.evaluate(param)
ret[s.outputKey] = s.result;
});
ret.log = log;
return ret;
}

return evaluate(4);
}
Insert cell
Insert cell
{
const log = [];
const sigList = [];
const signals = {};

function initSignal(code, sigFun) {
const s = {outputKey: code};
sigFun.apply(s);
sigList.push(s);
signals[code] = s;
}
//=======================================
// Start of wrapper for signalA

initSignal("A", function() {
//-------------------------------------
// Start of signalA evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV

this.twoVal = 2;
function evaluate(signalResults, samples/*, ...*/) {
log.push("Eval A called");
const ret = this.twoVal * samples * samples; // <-- Use a constant or utility function from another signal
log.push("Computed A");
return ret;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalA evalscript
//-------------------------------------
this.evaluate = evaluate; // capture 'evaluate' function so we can reference it
});

//=======================================
// Start of wrapper for signalB
initSignal("B", function() {
//-------------------------------------
// Start of signalB evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
this.evaluate = function(param, results) {
log.push("Eval B called signalA.twoVal:"+signals.A.twoVal+ " results.A:"+results.A);
const ret = signals.A.twoVal * results.A / 32; // <-- Use the result of signalA
log.push("Computed B");
return ret;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalB evalscript
//-------------------------------------
});

//==================================================
// Aggregation code - glue together all the wrappers
function evaluate(param) {
const ret = {};
sigList.forEach(s => {
ret[s.outputKey] = s.evaluate(param, ret);
});
ret.log = log;
return ret;
}

return evaluate(4);
}
Insert cell
Insert cell
{
const log = [];
const signalsList = [];
const signals = {};

function initSignal(code, sigFun) {
const s = {outputKey: code};
try {
sigFun.apply(s);
} catch (err) {
log.push("ERR @ "+code+":"+err);
}
// handle the version of script with just `return`
if (s.evaluate === undefined) {
s.evaluate = sigFun;
}
signalsList.push(s);
signals[code] = s;
}
//=======================================
// Start of wrapper for signalA

initSignal("A", function(param, results) {
//vvvvvv user script start
this.twoVal = 2;
return this.twoVal * param.B01 * param.B01; // <-- Use a constant or utility function from another signal
//^^^^^^ user script end
});

//=======================================
// Start of wrapper for signalB
initSignal("B", function(param, results) {
//vvvvvv user script start
this.evaluate = function(param, results) {
return signals.A.twoVal * results.A / 32; // <-- Use the result of signalA
}
//^^^^^^ user script end
});

//==================================================
// Aggregation code - glue together all the wrappers
function evaluateAll(param) {
const ret = {};
signalsList.forEach(s => {
ret[s.outputKey] = s.evaluate(param, ret);
});
ret.log = log;
return ret;
}
//try {
return evaluateAll({B01: 4});
//} catch (err) {
//return {log, err};
//}
}
Insert cell
Insert cell
{
const log = [];

//=======================================
// Start of wrapper for signalA

const signalA = {
outputKey : "A",
evaluate : function(param) {
//-------------------------------------
// Start of signalA evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
this.twoVal = 2;

log.push("Eval A called");
const ret = this.twoVal * param * param;
log.push("Computed A");
return ret;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalA evalscript
//-------------------------------------
}
};

//=======================================
// Start of wrapper for signalB
const signalB = {
outputKey : "B",
evaluate: function(param) {
//-------------------------------------
// Start of signalB evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
log.push("Eval B called");
const ret = signalA.twoVal * signalA.result / 32; // <-- Use the result of signalA
// <-- Use a constant or utility function from another signal
log.push("Computed B");
return ret;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalB evalscript
//-------------------------------------
}
};

//==================================================
// Aggregation code - glue together all the wrappers
function evaluate(param) {
const ret = {};

const signals = [signalA, signalB]; //list signals in correct order here

signals.forEach(s => {
s.result = s.evaluate(param)
ret[s.outputKey] = s.result;
});
ret.log = log;
return ret;
}

return evaluate(4);
}
Insert cell
Insert cell
{
const log = [];

const getResultForSignal = function(signalObject, param) {
// lazy compute and cache result, to avoid having to call signals in order
if (signalObject.result === undefined) {
signalObject.result = signalObject.evaluate(param);
signalObject.resultParam = param;
}
if (signalObject.resultParam === param) {
return signalObject.result;
}
log.push("Eval called with different params");
return signalObject.evaluate(param);
};

//=======================================
// Start of wrapper for signalB
const signalB = (param) => getResultForSignal(signalB, param);
signalB.init = function() {
//-------------------------------------
// Start of signalB evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV

this.twoVal = 2;
function evaluate(param) {
log.push("Eval B called");
const ret = this.twoVal * signalA(param) / 32; // <-- Use the result of signalA
log.push("Computed B");
return ret;
};

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalB evalscript
//-------------------------------------
if (!this.evaluate) {
this.evaluate = evaluate;
}
};
signalB.init();
//=======================================
// Start of wrapper for signalA

const signalA = (param) => getResultForSignal(signalA, param);
signalA.init = function() {
//-------------------------------------
// Start of signalA evalscript
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV

this.evaluate = function(param) {
log.push("Eval A called");
const ret = signalB.twoVal * param * param; // <-- Use a constant or utility function from another signal
log.push("Computed A");
return ret;
};

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End of signalA evalscript
//-------------------------------------
if (this.evaluate === undefined) {
this.evaluate = evaluate;
}
};
signalA.init();




//==================================================
// Aggregation code - glue together all the wrappers
function evaluate(param) {
//cleanup results
signalA.result = undefined;
signalB.result = undefined;
return ({
signalB: signalB(param),
signalA: signalA(param),
log: log
})
}
return evaluate(4);
}
Insert cell
testExtractParams = {
const eob_params = ({a: 13});

const evalscript = `//VERSION=3
const eob_params = (${JSON.stringify(eob_params)});
// ...the script: setup, evaluatePixel and other functions
`;

const extracted_params = eval('(() => {'+evalscript +' return eob_params;})()');
return extracted_params;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more