import { closest } from '@/helpers/closest' ; import { ConfigDto } from '@/models/Config' ; import { StateDto } from '@/models/State' ; import { Value } from '@/models/Value' ; import { StateProcessor } from '@/StateProcessor' ; interface Ctor { config : ConfigDto ; getState : ( ) => StateDto ; onChange : ( index : number , value : Value ) => void ; } /**
 * InputHandler is class responsible for manipulating values.
 * Any values, that are modified in the system, should be modified
 * through the InputHandler.
 */ export class InputHandler { private config : ConfigDto ; private onChange : ( index : number , value : Value ) => void ; private getState : ( ) => StateDto ; private constructor ( ctor ) { this . config = ctor . config ; this . onChange = ctor . onChange ; this . getState = ctor . getState ; } /**
     * Set real value of value at given index.
     */ public setRealValue ( index , value ) { this . onChange ( index , Value . fromReal ( { max : this . config . max , min : this . config . min , real : value , } ) ) ; } /**
     * Set ratio value of value at given index.
     */ public setRatioValue ( index , value ) { this . onChange ( index , Value . fromRatio ( { max : this . config . max , min : this . config . min , ratio : value , } ) ) ; } example public setClosestRatioValue ( valueToSet ) { const values = this . getState ( ) . values ; let closestIndex = closest ( valueToSet , values . map ( v => v . asRatio ( ) ) ) ; if ( values [ closestIndex ] . asReal ( ) === values [ closestIndex - 1 ] ?. asReal ( ) && valueToSet < values [ closestIndex - 1 ] ?. asRatio ( ) ) { closestIndex -= 1 ; } this . onChange ( closestIndex , Value . fromRatio ( { max : this . config . max , min : this . config . min , ratio : valueToSet , } ) ) ; } example public changeRatioBy ( index , value ) { const currentValue = this . getState ( ) . values [ index ] ; this . onChange ( index , Value . fromRatio ( { max : this . config . max , min : this . config . min , ratio : currentValue . asRatio ( ) + value , } ) ) ; } example public changeRealBy ( index , value ) { const currentValue = this . getState ( ) . values [ index ] ; this . onChange ( index , Value . fromReal ( { max : this . config . max , min : this . config . min , real : currentValue . asReal ( ) + value , } ) ) ; } example public makeValueRatioOffsetModifier ( index ) { const currentValue = this . getState ( ) . values [ index ] . asRatio ( ) ; return ( offset ) => { this . onChange ( index , Value . fromRatio ( { max : this . config . max , min : this . config . min , ratio : currentValue + offset , } ) ) ; } ; } public static init ( ctor ) { return new InputHandler ( ctor ) ; } }