Reimplement mempool animation smoothing within viz component
This commit is contained in:
		
							parent
							
								
									a8868b5f0f
								
							
						
					
					
						commit
						44116424b0
					
				@ -81,6 +81,20 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
				
			|||||||
  tooltipPosition: Position;
 | 
					  tooltipPosition: Position;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  readyNextFrame = false;
 | 
					  readyNextFrame = false;
 | 
				
			||||||
 | 
					  lastUpdate: number = 0;
 | 
				
			||||||
 | 
					  pendingUpdate: {
 | 
				
			||||||
 | 
					    count: number,
 | 
				
			||||||
 | 
					    add: { [txid: string]: TransactionStripped },
 | 
				
			||||||
 | 
					    remove: { [txid: string]: string },
 | 
				
			||||||
 | 
					    change: { [txid: string]: { txid: string, rate: number | undefined, acc: boolean | undefined } },
 | 
				
			||||||
 | 
					    direction?: string,
 | 
				
			||||||
 | 
					  } = {
 | 
				
			||||||
 | 
					    count: 0,
 | 
				
			||||||
 | 
					    add: {},
 | 
				
			||||||
 | 
					    remove: {},
 | 
				
			||||||
 | 
					    change: {},
 | 
				
			||||||
 | 
					    direction: 'left',
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  searchText: string;
 | 
					  searchText: string;
 | 
				
			||||||
  searchSubscription: Subscription;
 | 
					  searchSubscription: Subscription;
 | 
				
			||||||
@ -176,6 +190,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
				
			|||||||
  destroy(): void {
 | 
					  destroy(): void {
 | 
				
			||||||
    if (this.scene) {
 | 
					    if (this.scene) {
 | 
				
			||||||
      this.scene.destroy();
 | 
					      this.scene.destroy();
 | 
				
			||||||
 | 
					      this.clearUpdateQueue();
 | 
				
			||||||
      this.start();
 | 
					      this.start();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -188,6 +203,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    this.filtersAvailable = filtersAvailable;
 | 
					    this.filtersAvailable = filtersAvailable;
 | 
				
			||||||
    if (this.scene) {
 | 
					    if (this.scene) {
 | 
				
			||||||
 | 
					      this.clearUpdateQueue();
 | 
				
			||||||
      this.scene.setup(transactions);
 | 
					      this.scene.setup(transactions);
 | 
				
			||||||
      this.readyNextFrame = true;
 | 
					      this.readyNextFrame = true;
 | 
				
			||||||
      this.start();
 | 
					      this.start();
 | 
				
			||||||
@ -197,6 +213,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  enter(transactions: TransactionStripped[], direction: string): void {
 | 
					  enter(transactions: TransactionStripped[], direction: string): void {
 | 
				
			||||||
    if (this.scene) {
 | 
					    if (this.scene) {
 | 
				
			||||||
 | 
					      this.clearUpdateQueue();
 | 
				
			||||||
      this.scene.enter(transactions, direction);
 | 
					      this.scene.enter(transactions, direction);
 | 
				
			||||||
      this.start();
 | 
					      this.start();
 | 
				
			||||||
      this.updateSearchHighlight();
 | 
					      this.updateSearchHighlight();
 | 
				
			||||||
@ -205,6 +222,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  exit(direction: string): void {
 | 
					  exit(direction: string): void {
 | 
				
			||||||
    if (this.scene) {
 | 
					    if (this.scene) {
 | 
				
			||||||
 | 
					      this.clearUpdateQueue();
 | 
				
			||||||
      this.scene.exit(direction);
 | 
					      this.scene.exit(direction);
 | 
				
			||||||
      this.start();
 | 
					      this.start();
 | 
				
			||||||
      this.updateSearchHighlight();
 | 
					      this.updateSearchHighlight();
 | 
				
			||||||
@ -213,13 +231,61 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  replace(transactions: TransactionStripped[], direction: string, sort: boolean = true, startTime?: number): void {
 | 
					  replace(transactions: TransactionStripped[], direction: string, sort: boolean = true, startTime?: number): void {
 | 
				
			||||||
    if (this.scene) {
 | 
					    if (this.scene) {
 | 
				
			||||||
 | 
					      this.clearUpdateQueue();
 | 
				
			||||||
      this.scene.replace(transactions || [], direction, sort, startTime);
 | 
					      this.scene.replace(transactions || [], direction, sort, startTime);
 | 
				
			||||||
      this.start();
 | 
					      this.start();
 | 
				
			||||||
      this.updateSearchHighlight();
 | 
					      this.updateSearchHighlight();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // collates non-urgent updates into a set of consistent pending changes
 | 
				
			||||||
 | 
					  queueUpdate(add: TransactionStripped[], remove: string[], change: { txid: string, rate: number | undefined, acc: boolean | undefined }[], direction: string = 'left'): void {
 | 
				
			||||||
 | 
					    for (const tx of add) {
 | 
				
			||||||
 | 
					      this.pendingUpdate.add[tx.txid] = tx;
 | 
				
			||||||
 | 
					      delete this.pendingUpdate.remove[tx.txid];
 | 
				
			||||||
 | 
					      delete this.pendingUpdate.change[tx.txid];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (const txid of remove) {
 | 
				
			||||||
 | 
					      delete this.pendingUpdate.add[txid];
 | 
				
			||||||
 | 
					      this.pendingUpdate.remove[txid] = txid;
 | 
				
			||||||
 | 
					      delete this.pendingUpdate.change[txid];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (const tx of change) {
 | 
				
			||||||
 | 
					      if (this.pendingUpdate.add[tx.txid]) {
 | 
				
			||||||
 | 
					        this.pendingUpdate.add[tx.txid].rate = tx.rate;
 | 
				
			||||||
 | 
					        this.pendingUpdate.add[tx.txid].acc = tx.acc;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.pendingUpdate.change[tx.txid] = tx;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.pendingUpdate.direction = direction;
 | 
				
			||||||
 | 
					    this.pendingUpdate.count++;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  applyQueuedUpdates(): void {
 | 
				
			||||||
 | 
					    if (this.pendingUpdate.count && performance.now() > (this.lastUpdate + this.animationDuration)) {
 | 
				
			||||||
 | 
					      this.update([], [], [], this.pendingUpdate?.direction);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  clearUpdateQueue(): void {
 | 
				
			||||||
 | 
					    this.pendingUpdate = {
 | 
				
			||||||
 | 
					      count: 0,
 | 
				
			||||||
 | 
					      add: {},
 | 
				
			||||||
 | 
					      remove: {},
 | 
				
			||||||
 | 
					      change: {},
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    this.lastUpdate = performance.now();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  update(add: TransactionStripped[], remove: string[], change: { txid: string, rate: number | undefined, acc: boolean | undefined }[], direction: string = 'left', resetLayout: boolean = false): void {
 | 
					  update(add: TransactionStripped[], remove: string[], change: { txid: string, rate: number | undefined, acc: boolean | undefined }[], direction: string = 'left', resetLayout: boolean = false): void {
 | 
				
			||||||
 | 
					    // merge any pending changes into this update
 | 
				
			||||||
 | 
					    this.queueUpdate(add, remove, change);
 | 
				
			||||||
 | 
					    this.applyUpdate(Object.values(this.pendingUpdate.add), Object.values(this.pendingUpdate.remove), Object.values(this.pendingUpdate.change), direction, resetLayout);
 | 
				
			||||||
 | 
					    this.clearUpdateQueue();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  applyUpdate(add: TransactionStripped[], remove: string[], change: { txid: string, rate: number | undefined, acc: boolean | undefined }[], direction: string = 'left', resetLayout: boolean = false): void {
 | 
				
			||||||
    if (this.scene) {
 | 
					    if (this.scene) {
 | 
				
			||||||
      add = add.filter(tx => !this.scene.txs[tx.txid]);
 | 
					      add = add.filter(tx => !this.scene.txs[tx.txid]);
 | 
				
			||||||
      remove = remove.filter(txid => this.scene.txs[txid]);
 | 
					      remove = remove.filter(txid => this.scene.txs[txid]);
 | 
				
			||||||
@ -230,6 +296,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      this.scene.update(add, remove, change, direction, resetLayout);
 | 
					      this.scene.update(add, remove, change, direction, resetLayout);
 | 
				
			||||||
      this.start();
 | 
					      this.start();
 | 
				
			||||||
 | 
					      this.lastUpdate = performance.now();
 | 
				
			||||||
      this.updateSearchHighlight();
 | 
					      this.updateSearchHighlight();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -370,6 +437,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
				
			|||||||
    if (!now) {
 | 
					    if (!now) {
 | 
				
			||||||
      now = performance.now();
 | 
					      now = performance.now();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    this.applyQueuedUpdates();
 | 
				
			||||||
    // skip re-render if there's no change to the scene
 | 
					    // skip re-render if there's no change to the scene
 | 
				
			||||||
    if (this.scene && this.gl) {
 | 
					    if (this.scene && this.gl) {
 | 
				
			||||||
      /* SET UP SHADER UNIFORMS */
 | 
					      /* SET UP SHADER UNIFORMS */
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,7 @@ export default class BlockScene {
 | 
				
			|||||||
  theme: ThemeService;
 | 
					  theme: ThemeService;
 | 
				
			||||||
  orientation: string;
 | 
					  orientation: string;
 | 
				
			||||||
  flip: boolean;
 | 
					  flip: boolean;
 | 
				
			||||||
  animationDuration: number = 900;
 | 
					  animationDuration: number = 1000;
 | 
				
			||||||
  configAnimationOffset: number | null;
 | 
					  configAnimationOffset: number | null;
 | 
				
			||||||
  animationOffset: number;
 | 
					  animationOffset: number;
 | 
				
			||||||
  highlightingEnabled: boolean;
 | 
					  highlightingEnabled: boolean;
 | 
				
			||||||
@ -179,7 +179,7 @@ export default class BlockScene {
 | 
				
			|||||||
      removed.forEach(tx => {
 | 
					      removed.forEach(tx => {
 | 
				
			||||||
        tx.destroy();
 | 
					        tx.destroy();
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }, 1000);
 | 
					    }, (startTime - performance.now()) + this.animationDuration + 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (resetLayout) {
 | 
					    if (resetLayout) {
 | 
				
			||||||
      add.forEach(tx => {
 | 
					      add.forEach(tx => {
 | 
				
			||||||
@ -239,7 +239,7 @@ export default class BlockScene {
 | 
				
			|||||||
      { width: number, height: number, resolution: number, blockLimit: number, animationDuration: number, animationOffset: number,
 | 
					      { width: number, height: number, resolution: number, blockLimit: number, animationDuration: number, animationOffset: number,
 | 
				
			||||||
        orientation: string, flip: boolean, vertexArray: FastVertexArray, theme: ThemeService, highlighting: boolean, colorFunction: ((tx: TxView) => Color) | null }
 | 
					        orientation: string, flip: boolean, vertexArray: FastVertexArray, theme: ThemeService, highlighting: boolean, colorFunction: ((tx: TxView) => Color) | null }
 | 
				
			||||||
  ): void {
 | 
					  ): void {
 | 
				
			||||||
    this.animationDuration = animationDuration || 1000;
 | 
					    this.animationDuration = animationDuration || this.animationDuration || 1000;
 | 
				
			||||||
    this.configAnimationOffset = animationOffset;
 | 
					    this.configAnimationOffset = animationOffset;
 | 
				
			||||||
    this.animationOffset = this.configAnimationOffset == null ? (this.width * 1.4) : this.configAnimationOffset;
 | 
					    this.animationOffset = this.configAnimationOffset == null ? (this.width * 1.4) : this.configAnimationOffset;
 | 
				
			||||||
    this.orientation = orientation;
 | 
					    this.orientation = orientation;
 | 
				
			||||||
 | 
				
			|||||||
@ -141,7 +141,11 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
 | 
				
			|||||||
      const direction = (this.blockIndex == null || this.index < this.blockIndex) ? this.poolDirection : this.chainDirection;
 | 
					      const direction = (this.blockIndex == null || this.index < this.blockIndex) ? this.poolDirection : this.chainDirection;
 | 
				
			||||||
      this.blockGraph.replace(delta.added, direction);
 | 
					      this.blockGraph.replace(delta.added, direction);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this.blockGraph.update(delta.added, delta.removed, delta.changed || [], blockMined ? this.chainDirection : this.poolDirection, blockMined);
 | 
					      if (blockMined) {
 | 
				
			||||||
 | 
					        this.blockGraph.update(delta.added, delta.removed, delta.changed || [], blockMined ? this.chainDirection : this.poolDirection, blockMined);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.blockGraph.queueUpdate(delta.added, delta.removed, delta.changed || [], this.poolDirection);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.lastBlockHeight = this.stateService.latestBlockHeight;
 | 
					    this.lastBlockHeight = this.stateService.latestBlockHeight;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user