import * as vscode from 'vscode' ; import { TreeNode } from "./tree/treeNode" ; import { TestCollection } from './tree/testCollection' ; import { TestAdapter } from 'vscode-test-adapter-api' ; import { TestSuiteNode } from './tree/testSuiteNode' ; export class TreeEventDebouncer { private timeout : NodeJS . Timer | undefined ; constructor ( private readonly collections , private readonly treeDataChanged ) { } sendNodeChangedEvents ( immediately ) { if ( immediately ) { if ( this . timeout ) { clearTimeout ( this . timeout ) ; this . timeout = undefined ; } this . sendNodeChangedEventsNow ( ) ; } else if ( ! this . timeout ) { this . timeout = setTimeout ( ( ) => { this . timeout = undefined ; this . sendNodeChangedEventsNow ( ) ; } , 200 ) ; } } sendTreeChangedEvent ( ) { if ( this . timeout ) { clearTimeout ( this . timeout ) ; this . timeout = undefined ; } this . treeDataChanged . fire ( undefined as any ) ; } private sendNodeChangedEventsNow ( ) { const changedNodes = [ ] ; for ( const collection of this . collections . values ( ) ) { if ( collection . suite ) { collection . recalcState ( ) ; changedNodes . push ( ... this . collectChangedNodes ( collection . suite ) ) ; } } for ( const node of changedNodes ) { if ( node . parent === undefined ) { this . treeDataChanged . fire ( undefined as any ) ; } else { this . treeDataChanged . fire ( node ) ; } } } private collectChangedNodes ( node ) { if ( node . sendStateNeeded ) { this . resetNeededUpdates ( node ) ; if ( ( node instanceof TestSuiteNode ) && node . isHidden ) { return [ node . parent ! ] ; } else { return [ node ] ; } } else { const nodesToSend = [ ] ; for ( const child of node . children ) { nodesToSend . push ( ... this . collectChangedNodes ( child ) ) ; } return nodesToSend ; } } private resetNeededUpdates ( node ) { node . sendStateNeeded = false ; for ( const child of node . children ) { this . resetNeededUpdates ( child ) ; } } }