Last active
January 18, 2021 04:40
-
-
Save AvneeshSarwate/d37420a08de65f53f4f9695bd2e110b2 to your computer and use it in GitHub Desktop.
JS closure livecoding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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