import * as React from "react" ; interface EmulatorInfoProps { toggleInfo : ( ) => void ; emulator : any ; } interface EmulatorInfoState { cpu : number ; disk : string ; lastCounter : number ; lastTick : number ; } export class EmulatorInfo extends React . Component < EmulatorInfoProps , EmulatorInfoState > { private cpuInterval = - 1 ; constructor ( props ) { super ( props ) ; this . cpuCount = this . cpuCount . bind ( this ) ; this . onIDEReadStart = this . onIDEReadStart . bind ( this ) ; this . onIDEReadWriteEnd = this . onIDEReadWriteEnd . bind ( this ) ; this . state = { cpu : 0 , disk : "Idle" , lastCounter : 0 , lastTick : 0 , } ; } public render ( ) { const { cpu , disk } = this . state ; return ( < div id = "status" > Disk : < span > { disk } < /span> | CPU Speed: <span>{cpu}</span > | { " " } < a href = "#" onClick = { this . props . toggleInfo } > Hide < /a> < /div>); } public componentWillUnmount ( ) { this . uninstallListeners ( ) ; } param newProps public componentDidUpdate ( prevProps ) { if ( prevProps . emulator !== this . props . emulator ) { if ( this . props . emulator ) { this . installListeners ( ) ; } else { this . uninstallListeners ( ) ; } } } /**
     * Let's start listening to what the emulator is up to.
     */ private installListeners ( ) { const { emulator } = this . props ; if ( ! emulator ) { console . log ( `Emulator info: Tried to install listeners, but emulator not defined yet.` ) ; return ; } if ( this . cpuInterval > - 1 ) { clearInterval ( this . cpuInterval ) ; } this . cpuInterval = ( setInterval ( this . cpuCount , 500 ) as unknown ) as number ; emulator . add_listener ( "ide-read-start" , this . onIDEReadStart ) ; emulator . add_listener ( "ide-read-end" , this . onIDEReadWriteEnd ) ; emulator . add_listener ( "ide-write-end" , this . onIDEReadWriteEnd ) ; emulator . add_listener ( "screen-set-size-graphical" , console . log ) ; } /**
     * Stop listening to the emulator.
     */ private uninstallListeners ( ) { const { emulator } = this . props ; if ( ! emulator ) { console . log ( `Emulator info: Tried to uninstall listeners, but emulator not defined yet.` ) ; return ; } if ( this . cpuInterval > - 1 ) { clearInterval ( this . cpuInterval ) ; } emulator . remove_listener ( "ide-read-start" , this . onIDEReadStart ) ; emulator . remove_listener ( "ide-read-end" , this . onIDEReadWriteEnd ) ; emulator . remove_listener ( "ide-write-end" , this . onIDEReadWriteEnd ) ; emulator . remove_listener ( "screen-set-size-graphical" , console . log ) ; } /**
     * The virtual IDE is handling read (start).
     */ private onIDEReadStart ( ) { this . requestIdle ( ( ) => this . setState ( { disk : "Read" } ) ) ; } /**
     * The virtual IDE is handling read/write (end).
     */ private onIDEReadWriteEnd ( ) { this . requestIdle ( ( ) => this . setState ( { disk : "Idle" } ) ) ; } param fn private requestIdle ( fn ) { ( window as any ) . requestIdleCallback ( fn , { timeout : 3000 } ) ; } /**
     * Calculates what's up with the virtual cpu.
     */ private cpuCount ( ) { const { lastCounter , lastTick } = this . state ; const now = Date . now ( ) ; const instructionCounter = this . props . emulator . get_instruction_counter ( ) ; const ips = instructionCounter - lastCounter ; const deltaTime = now - lastTick ; this . setState ( { lastTick : now , lastCounter : instructionCounter , cpu : Math . round ( ips / deltaTime ) , } ) ; } }