import Interrupt from './interrupt' import Base from '@uci/base' import logger from '@uci-utils/logger' let log = {} // will more easily create a group of sbc pin interrupts class Interrupts extends Base { constructor(pins, opts = {}) { super(opts) this.id = this.id || 'interrupts' this.pins = pins.map(pin => Number(pin)) // make sure actual numbers are passed this._interrupts = new Map() this.resetCmd = opts.resetCmd || 'interrupt.reset' log = logger({ name: 'interrupts', id: this.id, package:'@uci/interrupt', file:'src/interrupts.js'}) this.amendConsumerCommands({reset:makefunc.bind(this,'reset')}) this.amendSocketCommands({ reset:makefunc.bind(this,'reset'), status:makefunc.bind(this,'status'), fire:makefunc.bind(this,'fire'), intervalReset:makefunc.bind(this,'intervalReset') }) let pinopts = {} this.pins.forEach(pin => { // remove per pin opts and store pinopts[pin] = Object.assign({}, opts[pin]) delete opts[pin] pinopts[pin].multiple=true // each pin will only extend a simple emitter, uci-base }) this.pins.forEach(pin => { pinopts[pin] = Object.assign({}, opts, pinopts[pin]) pinopts[pin].id = pinopts[pin].id || this.id + ':' + pin log.debug({ opts: pinopts[pin], method:'constructor', line:25, msg:`pin options for pin ${pin}`}) this._interrupts.set(pin, new Interrupt(pin, pinopts[pin])) // bubble up events from single interrupts const EVENTS=['log','interrupt','reset', 'ready'] // that should emit up from pin base EVENTS.forEach(event => { this.interrupt(pin).on(event, obj => { if (event==='ready') this.emit('ready:'+pin,obj) else { if (Object.prototype.toString.call(obj) !== '[object Object]') { // is plain object let data=obj obj = {} obj.data = data } obj.pin = pin obj.id = pinopts[pin].id this.emit(event,obj) // will emit a pin specific event } }) }) }) // end pins construct this.on('interrupt', async ev=>{ await this.push(ev) // push interrupt to any connected consumers }) } // end constructor interrupt(pin) { if (isNaN(pin)) return null return this._interrupts.get(Number(pin)) } // pin type here same as when instantiated above. async init() { await super.init() return Promise.all( Array.from(this._interrupts).map(inter => { return inter[1].init() }) ) } registerHook(func) { // same hook for each pin this._interrupts.forEach(inter => { inter.registerHook(func) }) } } // end Class export default Interrupts // combines indiviudal pin function calls into single call and combines returns async function makefunc(fn, packet={}) { if (!packet.pin || packet.pin==='all') { let rpacket = {pins:[]} for (let inter of this._interrupts.entries()) { let ipacket = Object.assign({},packet) delete(ipacket.cmd);delete(ipacket._header) let res = await inter[1][fn](ipacket) res.pin = inter[0] rpacket.pins.push(res) } return rpacket } let pin = isNaN(Number(packet)) ? packet.pin : packet if (this._interrupts.has(Number(pin))) return await this.interrupt(packet.pin)[fn](packet) }