src/core/Queue.js
/**
* A FIFO queue.
*
* Elements are added to the end of the queue and removed from the front.
*
* Based on:
* http://code.stephenmorley.org/javascript/queues/
*/
export class Queue {
/**
* Constructs a new queue.
*/
constructor() {
/**
* A list of elements.
*
* @type {Array}
*/
this.elements = [];
/**
* The head of the queue.
*
* @type {Number}
*/
this.head = 0;
}
/**
* The current size of the queue.
*
* @type {Number}
*/
get size() {
return (this.elements.length - this.head);
}
/**
* Returns true if the queue is empty, and false otherwise.
*
* @type {Boolean}
*/
get empty() {
return (this.elements.length === 0);
}
/**
* Copies the given queue.
*
* @param {Queue} queue - A queue.
* @return {Queue} This queue.
*/
copy(queue) {
this.elements = Array.from(queue.elements);
this.head = queue.head;
return this;
}
/**
* Clones this queue.
*
* @return {Queue} Th cloned queue.
*/
clone() {
return new this.constructor().copy(this);
}
/**
* Adds an element to the queue.
*
* @param {Object} element - An arbitrary object.
*/
add(element) {
this.elements.push(element);
}
/**
* Retrieves, but does not remove, the head of the queue.
*
* @return {Object} The head of the queue, or undefined if the queue is empty.
*/
peek() {
return (this.elements.length > 0) ? this.elements[this.head] : undefined;
}
/**
* Retrieves and removes the head of the queue.
*
* @return {Object} The head of the queue, or undefined if the queue is empty.
*/
poll() {
const elements = this.elements;
const length = elements.length;
let element;
if(length > 0) {
element = elements[this.head++];
// Remove free space if necessary.
if(this.head * 2 >= length) {
this.elements = elements.slice(this.head);
this.head = 0;
}
}
return element;
}
/**
* Resets this queue.
*/
clear() {
this.elements = [];
this.head = 0;
}
}