/** * TODO here: * Create try catch in start and stop: modules are not being unloaded/reloaded if there is exception in stop * Improve fields, solve redundancy, on "on" and "after" * Maybe use the XPrefix to create an endpoint named events or fetch a channel * channel should work for emit aswell * * Separate vars in several contexts * * For the endpoint when bundle is stopped we could * * */ var log = require('hlogger').createLogger('bundle-context'); /** * Check method in bundleActivator if not check as bundleMethod */ function solveMethod(instance,name) { if(instance.bundleActivator != undefined && instance.bundleActivator[name]!= undefined ) { return (context) => {instance.bundleActivator[name](context)}; } var subName = "bundle" + name[0].toUpperCase() + name.slice(1); if(instance[subName] != undefined ) { return (context) => {instance[subName](context)}; } return null; } // Maybe create channel code here and completelly remove on here // // This will contain the listeners for Activator class BundleContext /*extends XEventEmitter*/ { constructor(conf) { /*super();*/ var info = {}; ({id:info.id, name:info.name, manager:info.manager, instance:info.instance, modulePath:info.modulePath, pkgInfo:info.pkgInfo} = conf); //info = fromFields(["id","name","manager","instance","modulePath","pkgInfo"],conf); info.state = 0; info.loadDate = new Date(); this.info = info; this._bundleContext = { intervals:[], timeouts:[], instanceStart: null, instanceStop: null }; var dummyFunc = () => {}; this._bundleContext.instanceStart = solveMethod(this.instance,"start") || dummyFunc; this._bundleContext.instanceStop = solveMethod(this.instance,"stop") || dummyFunc; // New contextual events } get events() { if(this._events == undefined) { this._events = this.manager.eventual.createContext(); } return this._events; } get id() { return this.info.id; } get modulePath() { return this.info.modulePath; } get name() { return this.info.name; } get instance() { return this.info.instance; } get manager() { return this.info.manager; } get version() { return this.info.version; } start() { if(this.info.state == 1) { log.warn("Instance is turned on trying to turn off first"); this.stop(); } //process.nextTick(() => { try { this._bundleContext.instanceStart(this); } catch(e) { log.error("Bundle start error: " + this.name + "\n",e); } //this.manager.events.toggleOn(this.name,this.instance); this.info.state = 1; this.info.startDate = new Date(); //}); } stop() { if(this.info.state == 0) return; //this.toggleOff("start"); this.emit("stop"); try { this._bundleContext.instanceStop(this); } catch( e) { log.error("Bundle stop error: " + this.name + "\n",e); } this.clearIntervals(); this.clearTimeouts(); this.events.destroy(); //this.manager.events.removeListener(this); this.info.state = 0; } /* Event wrappers */ /*removeListener(ename) { this.manager.events.removeListener(this,ename); }*/ emit(name,...args) { return this.events.broadcast( this.name + ":" +name,...args); } state(name,...args) { this.events.state( this.name + ":"+ name,...args); return this; } /*emit(ename,...args) { return this.manager.events.emit(this.name+":"+ename,...args); }*/ /*toggleOn(ename,arg) { this.manager.events.toggleOn(this.name+":"+ename,arg); } toggleOff(ename) { this.manager.events.toggleOff(this.name+":"+ename); }*/ channel(name) { return this.events.channel(name); } on(name,cb) { // Only create events if does not exists, maybe with a getter this.events.on(name,cb); return this; } /*on(...args) { var cb = args.pop(); var evtName = args.join(":"); this.manager.events.on(this,evtName ,cb); return this; }*/ after(name,cb) { // Priorities this.events.on(name,cb,1000); return this; } // Channel prefix(name) { return this.manager.events.prefix(this,name); } // Wrappers /** * @param {array} args * @param {function} callback */ with(args,callback) { return this.manager.with(args,callback); } /** * @param {string} match * @param {variable} ...args */ call(name,...args) { return this.manager.call(name,args); } /* get(name) { var ctx = this.manager.get(name); if(ctx == null || ctx.info.state != 1) { // Early bail return null; } return ctx.instance; }*/ // Auto clear helpers // setInterval(cb,n) { var ret = setInterval(cb,n); this._bundleContext.intervals.push(ret); return ret; } clearIntervals() { this._bundleContext.intervals.forEach((v) => { clearInterval(v); }); } setTimeout(cb,n) { var ret = setTimeout(cb,n); this._bundleContext.timeouts.push(ret); return ret; } clearTimeouts() { this._bundleContext.timeouts.forEach((v) => { clearTimeout(v); }); } } module.exports = BundleContext;