import { IMatrixConsumer , IMatrixReader , IMatrixProducer } from "@tiny-calc/nano" ; import { DenseVector , RowMajorMatrix } from "@tiny-calc/micro" ; import { MatrixItem } from ".." ; /**
 * IMatrixConsumer implementation that applies change notifications to it's own
 * dense matrix.
 *
 * Comparing the state of the TestConsumer with the original IMatrixProducer is a
 * convenient way to vet that the producer is emitting the correct change notifications.
 */ export class TestConsumer < T = any > implements IMatrixConsumer < MatrixItem < T > > , IMatrixReader < MatrixItem < T > > { private readonly rows : DenseVector < void > = new DenseVector < void > ( ) ; private readonly cols : DenseVector < void > = new DenseVector < void > ( ) ; private readonly actual : RowMajorMatrix < MatrixItem < T > > = new RowMajorMatrix ( this . rows , this . cols ) ; private readonly expected : IMatrixReader < MatrixItem < T > > ; constructor ( producer ) { this . expected = producer . openMatrix ( this ) ; this . rows . splice ( 0 , 0 , this . expected . rowCount ) ; this . cols . splice ( 0 , 0 , this . expected . colCount ) ; this . updateCells ( ) ; } private forEachCell ( callback , rowStart = 0 , colStart = 0 , rowCount = this . rowCount , colCount = this . colCount ) { const rowEnd = rowStart + rowCount ; const colEnd = colStart + colCount ; for ( let row = rowStart ; row < rowEnd ; row ++ ) { for ( let col = colStart ; col < colEnd ; col ++ ) { callback ( row , col ) ; } } } private updateCells ( rowStart = 0 , colStart = 0 , rowCount = this . rowCount , colCount = this . colCount ) { this . forEachCell ( ( row , col ) => { this . actual . setCell ( row , col , this . expected . getCell ( row , col ) ) ; } , rowStart , colStart , rowCount , colCount ) ; } public get rowCount ( ) { return this . actual . rowCount ; } public get colCount ( ) { return this . actual . colCount ; } public get matrixProducer ( ) { return undefined as any ; } rowsChanged ( rowStart , removedCount , insertedCount ) { this . rows . splice ( rowStart , removedCount , insertedCount ) ; this . updateCells ( rowStart , 0 , insertedCount , this . actual . colCount ) ; } colsChanged ( colStart , removedCount , insertedCount ) { this . cols . splice ( colStart , removedCount , insertedCount ) ; this . updateCells ( 0 , colStart , this . actual . rowCount , insertedCount ) ; } cellsChanged ( rowStart , colStart , rowCount , colCount ) { this . updateCells ( rowStart , colStart , rowCount , colCount ) ; } getCell ( row , col ) { return this . expected . getCell ( row , col ) ; } }