wasmboy
Version:
Gameboy / Gameboy Color Emulator written for Web Assembly using AssemblyScript. Shell/Debugger in Preact
77 lines (64 loc) • 2.27 kB
JavaScript
// API For adding plugins for WasmBoy
// Should follow the Rollup Plugin API
// https://rollupjs.org/guide/en#plugins
// Plugins have the following supported hooks
// And properties
const WASMBOY_PLUGIN = {
name: 'wasmboy-plugin REQUIRED',
graphics: rgbaArray => {}, // Returns undefined. Edit object in place
audio: (audioContext, headAudioNode, channelId) => {}, // Return AudioNode, which will be connected to the destination node eventually.
saveState: saveStateObject => {}, // Returns undefined. Edit object in place.
canvas: (canvasElement, canvasContext, canvasImageData) => {}, // Returns undefined. Edit object in place.
breakpoint: () => {},
ready: () => {},
play: () => {},
pause: () => {},
loadedAndStarted: () => {}
};
class WasmBoyPluginsService {
constructor() {
this.plugins = {};
this.pluginIdCounter = 0;
}
addPlugin(pluginObject) {
// Verify the plugin
if (!pluginObject && typeof pluginObject !== 'object') {
throw new Error('Invalid Plugin Object');
}
if (!pluginObject.name) {
throw new Error('Added plugin must have a "name" property');
}
// Add the plugin to our plugin container
const id = this.pluginIdCounter;
this.plugins[this.pluginIdCounter] = pluginObject;
this.pluginIdCounter++;
// Return a function to remove the plugin
return () => {
this.removePlugin(id);
};
}
removePlugin(id) {
delete this.plugins[id];
}
runHook(hookConfig) {
if (!WASMBOY_PLUGIN[hookConfig.key] || typeof WASMBOY_PLUGIN[hookConfig.key] !== 'function') {
throw new Error('No such hook as ' + hookConfig.key);
}
Object.keys(this.plugins).forEach(pluginKey => {
const plugin = this.plugins[pluginKey];
if (plugin[hookConfig.key]) {
let hookResponse = undefined;
try {
hookResponse = plugin[hookConfig.key].apply(null, hookConfig.params);
} catch (e) {
console.error(`There was an error running the '${hookConfig.key}' hook, on the ${plugin.name} plugin.`);
console.error(e);
}
if (hookConfig.callback) {
hookConfig.callback(hookResponse);
}
}
});
}
}
export const WasmBoyPlugins = new WasmBoyPluginsService();