Merge branch 'plugin-manager' into master

This commit is contained in:
Alexei Stukov 2018-01-16 07:04:51 +02:00 committed by GitHub
commit 4d44ba673b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 121 additions and 27774 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,37 +9,124 @@
*/ */
const { Module } = require('./modulebase'); const { Module } = require('./modulebase');
const { BDIpc } = require('./bdipc');
const { Utils, FileUtils } = require('./utils');
const fs = window.require('fs');
const path = window.require('path');
class Plugin {
constructor(args) {
}
start() {
if (this.onStart) return this.onStart();
return true; //Assume plugin started since it doesn't have onStart
}
stop() {
if (this.onStop) return this.onStop();
return true; //Assume plugin stopped since it doesn't have onStop
}
}
class PluginManager extends Module { class PluginManager extends Module {
setInitialState() { setInitialState() {
window.pm = this;
this.setState({ this.setState({
plugins: [] plugins: []
}); });
tests();
} }
get plugins() { get plugins() {
return this.state.plugins; return this.state.plugins;
} }
loadPlugin(plugin) { async pluginsPath() {
const { plugins } = this; //TODO Get this from config module
plugins.push(plugin); const config = await BDIpc.send('getConfig');
this.setState({ return config.paths.find(path => 'plugins' in path).plugins;
plugins
});
} }
getPluginByName(name) { async loadPlugin(pluginPath) {
return this.plugins.find(plugin => plugin.name === name); const { plugins } = this.state;
try {
const pluginsPath = await this.pluginsPath();
pluginPath = path.join(pluginsPath, pluginPath);
const loaded = plugins.find(plugin => plugin.pluginPath === pluginPath);
if (loaded) {
throw { 'message': 'Attempted to load an already loaded plugin' };
}
const readConfig = await this.readConfig(pluginPath);
const mainPath = path.join(pluginPath, readConfig.main);
const plugin = window.require(mainPath)(Plugin, {}, {});
const instance = new plugin();
plugins.push(Object.assign({
pluginPath,
instance
}, readConfig));
this.setState(plugins);
//TODO Read plugin user config and call onStart if enabled
return instance;
} catch (err) {
throw err;
}
} }
getPluginById(id) { async reloadPlugin(pluginPath) {
return this.plugins.find(plugin => plugin.id === id); //TODO Cleanup loaded plugin
return await this.loadPlugin(pluginPath);
}
getPluginByName(name) { return this.plugins.find(plugin => plugin.name === name); }
getPluginById(id) { return this.plugins.find(plugin => plugin.id === id); }
stopPlugin(name) {
const plugin = this.getPluginByName(name);
if (plugin && plugin.instance) return plugin.instance.stop();
return true; //Return true anyways since plugin doesn't exist
}
startPlugin(name) {
const plugin = this.getPluginByName(name);
if (plugin && plugin.instance) return plugin.instance.start();
return true; //Return true anyways since plugin doesn't exist
}
async readConfig(path) {
path = `${path}/config.json`;
return FileUtils.readJsonFromFile(path);
} }
} }
const _instance = new PluginManager(); const _instance = new PluginManager();
async function tests() {
const pluginName = 'Example';
try {
//Load test plugin
const plugin = await _instance.loadPlugin(pluginName);
//Attempt to load the same plugin again
const plugin2 = await _instance.loadPlugin(pluginName);
} catch (err) {
console.log(`Failed to load plugin! ${err.message}`);
}
}
module.exports = { PluginManager: _instance } module.exports = { PluginManager: _instance }

View File

@ -0,0 +1,6 @@
{
"name": "Example Plugin",
"authors": [ "Jiiks" ],
"version": 1.0,
"main": "index.js"
}

View File

@ -0,0 +1,18 @@
module.exports = (Plugin, Api, Vendor) => {
const { $, moment } = Vendor;
const { Events } = Api;
const test = 'Testing';
return class extends Plugin {
test() {
return test;
}
onStart() {
console.log('On Start!');
}
}
}