import * as rpio from 'rpio' ; import * as _ from 'lodash' ; import { Button , Press } from './types' ; import { MovePacket , FirePacket , Packet , GameState , ButtonState , } from '../../common/types' ; function isButtonPressed ( button ) { return rpio . read ( button . pin ) === 0 ; } export class ButtonController { public readonly pollRateMsec : number = 15 ; public readonly buttons : Button [ ] ; public readonly sendPacket : ( packet : Packet ) => void ; private prevPresses : Press [ ] = [ ] ; constructor ( buttons , packetHandler , getGameState ) { this . sendPacket = packetHandler ; this . buttons = buttons ; this . setup ( ) ; this . prevPresses = this . getPresses ( ) ; setInterval ( this . poll . bind ( this ) , this . pollRateMsec ) ; } private setup ( ) { this . buttons . forEach ( ( { pin } ) => { rpio . open ( pin , rpio . INPUT , rpio . PULL_UP ) ; } ) ; } private poll ( ) { const presses = this . getPresses ( ) ; const newPresses = _ . differenceWith ( presses , this . prevPresses , _ . isEqual ) ; if ( _ . isEmpty ( newPresses ) ) { return ; } const packets = newPresses . map ( buttonPress => { if ( buttonPress . button . name === 'fire' ) { const packet = { kind : 'fire' , state : buttonPress . state , } ; return packet ; } else { const packet = { kind : 'move' , state : buttonPress . state , direction : buttonPress . button . name , } ; return packet ; } } ) ; packets . forEach ( packet => this . sendPacket ( packet ) ) ; this . prevPresses = presses ; } private getPresses ( ) { return this . buttons . map ( button => { const isPressed = isButtonPressed ( button ) ; return { button , state : ( isPressed ? 'pressed' : 'released' ) as ButtonState , } ; } ) ; } }