Move binding logic into Variable

This commit is contained in:
Jordan Eldredge 2019-07-08 08:21:02 -07:00
parent de1b5350b0
commit 88b67e376a
5 changed files with 92 additions and 27 deletions

View file

@ -0,0 +1,44 @@
class Emitter {
constructor() {
this._hooks = {};
// TODO: Rename this property
this._globalHooks = [];
}
listen(eventName, cb) {
if (this._hooks[eventName] == null) {
this._hooks[eventName] = [];
}
this._hooks[eventName].push(cb);
return () => {
this._hooks[eventName] = this._hooks[eventName].filter(
hookCb => hookCb !== cb
);
};
}
trigger(eventName, ...args) {
this._globalHooks.forEach(cb => cb(eventName, args));
if (this._hooks[eventName] == null) {
return;
}
this._hooks[eventName].forEach(cb => {
cb(...args);
});
}
listenToAll(cb) {
this._globalHooks.push(cb);
return () => {
this._globalHooks = this._globalHooks.filter(hookCb => hookCb !== cb);
};
}
dispose() {
// Note: This will cause any future trigger or hook to cause a runtime error.
this._hooks = null;
this._globalHooks = null;
}
}
module.exports = Emitter;

View file

@ -29,20 +29,13 @@ function main({ runtime, data, system, log }) {
return interpret(binding.commandOffset, program, { log });
};
// For now we only know how to handle System handlers.
if (binding.variableOffset === 0) {
const obj = program.variables[binding.variableOffset].getValue();
const method = program.methods[binding.methodOffset];
obj[method.name](handler);
} else {
console.warn(
"Not Implemented: Not binding to non-system events",
binding
);
}
const variable = program.variables[binding.variableOffset];
const method = program.methods[binding.methodOffset];
variable.hook(method.name, handler);
});
system._start();
system.js_start();
}
module.exports = main;

View file

@ -1,4 +1,22 @@
const Emitter = require("../Emitter");
class MakiObject {
constructor() {
this._emitter = new Emitter();
}
js_trigger(eventName, ...args) {
this._emitter.trigger(eventName, args);
}
js_listenToAll(cb) {
return this._emitter.listenToAll(cb);
}
js_dispose() {
this._emitter.dispose();
}
/**
* getClassName()
*

View file

@ -12,23 +12,10 @@ class System extends MakiObject {
return "System";
}
constructor() {
super();
this._onScriptLoadedCallbacks = [];
this._onSetXuiParamCallbacks = [];
js_start() {
this.js_trigger("onScriptLoaded");
}
_start() {
this._onScriptLoadedCallbacks.forEach(cb => {
cb();
});
}
onScriptLoaded(cb) {
this._onScriptLoadedCallbacks.push(cb);
}
onSetXuiParam(cb) {
this._onSetXuiParamCallbacks.push(cb);
}
getScriptGroup() {
return new Group();
}

View file

@ -1,7 +1,11 @@
const Emitter = require("./Emitter");
class Variable {
constructor({ type, typeName }) {
this.type = type;
this.typeName = typeName;
this._emitter = new Emitter();
this._unsubscribeFromValue = null;
}
getValue() {
@ -9,8 +13,27 @@ class Variable {
}
setValue(value) {
if (this._unsubscribeFromValue != null) {
this._unsubscribeFromValue();
}
if (this.typeName === "OBJECT") {
this._unsubscribeFromValue = value.js_listenToAll((eventName, args) => {
this._emitter.trigger(eventName, args);
});
}
this._value = value;
}
hook(eventName, cb) {
this._emitter.listen(eventName, cb);
}
dispose() {
if (this._unsubscribeFromValue) {
this._unsubscribeFromValue();
}
this._emitter.dispose();
}
}
module.exports = Variable;