1// Copyright 2022 The Pigweed Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may not 4// use this file except in compliance with the License. You may obtain a copy of 5// the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12// License for the specific language governing permissions and limitations under 13// the License. 14 15/** 16 * Provides a simple array-based queue that will block caller on await 17 * queue.shift() if the queue is empty, until a new item is pushed to the 18 * queue. */ 19 20export default class Queue<T> { 21 queue = Array<T>(); 22 elementListeners = Array<() => void>(); 23 24 get length(): number { 25 return this.queue.length; 26 } 27 28 push(...items: T[]): number { 29 this.queue.push(...items); 30 this._checkListeners(); 31 return this.length; 32 } 33 34 shift(): Promise<T> { 35 return new Promise(resolve => { 36 if (this.length > 0) { 37 return resolve(this.queue.shift()!); 38 } else { 39 this.elementListeners.push(() => { 40 return resolve(this.queue.shift()!); 41 }); 42 } 43 }); 44 } 45 46 _checkListeners() { 47 if (this.length > 0 && this.elementListeners.length > 0) { 48 const listener = this.elementListeners.shift()!; 49 listener.call(this); 50 this._checkListeners(); 51 } 52 } 53 54 unshift(...items: T[]): number { 55 this.queue.unshift(...items); 56 this._checkListeners(); 57 return this.length; 58 } 59} 60