Skip to content

Instantly share code, notes, and snippets.

@AvneeshSarwate
Last active January 18, 2021 04:40
Show Gist options
  • Save AvneeshSarwate/d37420a08de65f53f4f9695bd2e110b2 to your computer and use it in GitHub Desktop.
Save AvneeshSarwate/d37420a08de65f53f4f9695bd2e110b2 to your computer and use it in GitHub Desktop.
JS closure livecoding
//how to install/import an editor with native es6 modules without having
//to deal with JS builds
// npm install ace-builds
/*
import * as acemodule from './node_modules/ace-builds/src-noconflict/ace.js';
let editor = ace.edit('container-div');
*/
// https://stackoverflow.com/a/49245333
// https://github.com/AvneeshSarwate/graphicsLivecoding/blob/master/editorSetup.js
/*
central mechanism for implementing a live-coding version of dat.gui:
add a function (marked with a key) anywhere in your code and be able
to live code it. Each keyed function gets a collapsible pane that
includes a code editor and a "replace" button. functions used should
have no arguments, grabbing all necessary data from closures at their
point of definition.
*/
class funcInject {
constructor() {
this.funcInfo = {};
//create the container element
}
/**
*
* @param {string} funcKey - the name of this func in the UI
* @param {function} evalFunc - the function 'c => eval(c)'
* - must be defined to be able to live-code the function
* - and keep the same closure/variable bindings
* @param {*} func - the initial function to use
*/
bind(funcKey, evalFunc, func) {
if(!this.funcInfo[funcKey]) {
this.funcInfo[funcKey] = {
func,
stack: [func],
evalFunc,
debugOnError: false
}
//create UI pane for this function automatically
}
try {
this.funcInfo[funcKey].func();
} catch {
//signal error to UI
if(this.funcInfo[funcKey].debugOnError){
debugger;
}
let funcSlot = this.funcInfo[funcKey];
funcSlot.func = funcSlot.stack.pop();
funcSlot.func();
}
}
//this is run when the "save" button is hit in a pane
replace(funcKey, funcString) {
let funcSlot = this.funcInfo[funcKey];
let newFunc;
try {
newFunc = funcSlot.evalFunc(funcString);
} catch {
//print stack trace on parse error
//annotate ace editor with parse issues
return;
}
funcSlot.func = newFunc
}
}
let injector = new funcInject();
window.injector = injector;
window.testFunc = function() {
let grabVar = 5;
injector.bind('testKey', c => eval(c), () => {
grabVar++;
console.log(grabVar);
});
}
// injector.replace('testKey', '() => {grabVar++; console.log(grabVar*2)}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment