• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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