/**
* Event Queue is simply a priority Queue, basic implementation O(n^2).
* @category eventQueue
*/
export default class EventQueue {
constructor(size) {
this.size = size;
this.queue = new Array(size);
this.frontIndex = 0;
this.time = 0;
}
/**
* @param {CircuitElement} obj - the elemnt to be added
* @param {number} delay - the delay in adding an object to queue
*/
add(obj, delay) {
if (obj.queueProperties.inQueue) {
obj.queueProperties.time = this.time + (delay || obj.propagationDelay);
let i = obj.queueProperties.index;
while (i > 0 && obj.queueProperties.time > this.queue[i - 1].queueProperties.time) {
this.swap(i, i - 1);
i--;
}
i = obj.queueProperties.index;
while (i < this.frontIndex - 1 && obj.queueProperties.time < this.queue[i + 1].queueProperties.time) {
this.swap(i, i + 1);
i++;
}
return;
}
if (this.frontIndex == this.size) throw 'EventQueue size exceeded';
this.queue[this.frontIndex] = obj;
// obj.queueProperties.time=obj.propagationDelay;
obj.queueProperties.time = this.time + (delay || obj.propagationDelay);
obj.queueProperties.index = this.frontIndex;
this.frontIndex++;
obj.queueProperties.inQueue = true;
let i = obj.queueProperties.index;
while (i > 0 && obj.queueProperties.time > this.queue[i - 1].queueProperties.time) {
this.swap(i, i - 1);
i--;
}
}
/**
* To add without any delay.
* @param {CircuitElement} obj - the object to be added
*/
addImmediate(obj) {
this.queue[this.frontIndex] = obj;
obj.queueProperties.time = this.time;
obj.queueProperties.index = this.frontIndex;
obj.queueProperties.inQueue = true;
this.frontIndex++;
}
/**
* Function to swap two objects in queue.
* @param {number} v1
* @param {number} v2
*/
swap(v1, v2) {
const obj1 = this.queue[v1];
obj1.queueProperties.index = v2;
const obj2 = this.queue[v2];
obj2.queueProperties.index = v1;
this.queue[v1] = obj2;
this.queue[v2] = obj1;
}
/**
* function to pop element from queue.
*/
pop() {
if (this.isEmpty()) throw 'Queue Empty';
this.frontIndex--;
const obj = this.queue[this.frontIndex];
this.time = obj.queueProperties.time;
obj.queueProperties.inQueue = false;
return obj;
}
/**
* function to reset queue.
*/
reset() {
for (let i = 0; i < this.frontIndex; i++) this.queue[i].queueProperties.inQueue = false;
this.time = 0;
this.frontIndex = 0;
}
/**
* function to check if empty queue.
*/
isEmpty() {
return this.frontIndex == 0;
}
}
Source