Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// build.js (Windows + cross-platform replacement for build.sh)

const { execSync } = require("child_process");
const fs = require("fs");

console.log("Reading version.json...");

const versions = JSON.parse(fs.readFileSync("version.json", "utf8"))
.map((v) => v.version);

for (const version of versions) {
console.log(`\nBuilding for version: ${version}`);

try {
execSync(`npx vite build --config vite.config.${version}.ts`, {
stdio: "inherit",
});
} catch (err) {
console.error(`❌ Build failed for version: ${version}`);
process.exit(1);
}
}

console.log("\n✅ All builds completed successfully!");
33 changes: 19 additions & 14 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
#!/bin/bash
// build.js (Windows + cross-platform equivalent of build.sh)

const { execSync } = require("child_process");
const fs = require("fs");

versions=($(jq -r '.[].version' version.json))
console.log("Reading version.json...");

const versions = JSON.parse(fs.readFileSync("version.json", "utf8"))
.map((v) => v.version);
for version in "${versions[@]}"; do
echo "Building for version: $version"

npx vite build --config vite.config."$version".ts

#Build status
if [ $? -ne 0 ]; then
echo "Build failed for version: $version"
exit 1
fi
done
for (const version of versions) {
console.log(`\nBuilding for version: ${version}`);
echo "All builds completed successfully"
try {
execSync(`npx vite build --config vite.config.${version}.ts`, {
stdio: "inherit",
});
} catch (err) {
console.error(`❌ Build failed for version: ${version}`);
process.exit(1);
}
}
console.log("\n✅ All builds completed successfully!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

CRITICAL: File extension mismatch - JavaScript file named as shell script.

This file contains Node.js JavaScript code but is named build.sh. The .sh extension indicates a shell script, which will cause execution failures and confusion. The inline comment on Line 1 confirms this should be build.js, and the static analysis errors from shellcheck confirm it cannot parse this as shell script.

Please rename this file from build.sh to build.js to match its actual content and the build command referenced in package.json.

🧰 Tools
🪛 Shellcheck (0.11.0)

[error] 1-1: Was this intended as a comment? Use # in sh.

(SC1127)


[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)


[error] 1-1: '(' is invalid here. Did you forget to escape it?

(SC1036)


[error] 1-1: Parsing stopped here. Invalid use of parentheses?

(SC1088)

🤖 Prompt for AI Agents
In build.sh around lines 1 to 24, the file contains Node.js code but is named
with a .sh extension; rename the file to build.js and update any references
(package.json scripts, CI workflows, docs, or other tooling) that call build.sh
to point to build.js (and invoke it with node or via an npm script) so the
runtime matches the file contents and shellcheck/static analysis failures are
resolved.

Empty file added event-queue-cleanup.patch
Empty file.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"scripts": {
"serve": "vite preview",
"build": "bash build.sh",
"build": "node build.js",
"dev": "vite",
"tauri": "tauri",
"preview": "vite preview",
Expand Down
180 changes: 95 additions & 85 deletions src/simulator/src/eventQueue.ts
Original file line number Diff line number Diff line change
@@ -1,123 +1,133 @@
/**
* Event Queue is simply a priority Queue, basic implementation O(n^2).
* EventQueue implements a priority queue where events are ordered by time.
* Uses a binary min-heap for O(log n) insertion and removal.
* @category eventQueue
*/

interface QueueObject {
export interface QueueObject {
queueProperties: {
inQueue: boolean
time: number
index: number
}
propagationDelay: number
inQueue: boolean;
time: number;
index: number; // heap index
};
propagationDelay: number;
}

export class EventQueue {
size: number
queue: Array<QueueObject>
frontIndex: number
time: number
constructor(size: number) {
this.size = size
this.queue = new Array(size)
this.frontIndex = 0
this.time = 0
}
private heap: QueueObject[] = [];
time = 0;

constructor(private size: number) {}

/**
* Insert an object with delay. Maintains min-heap by event time.
*/
add(obj: QueueObject, delay: number) {
const eventTime = this.time + (delay ?? obj.propagationDelay);
obj.queueProperties.time = eventTime;

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
// Update time + reposition
this.heapifyUp(obj.queueProperties.index);
this.heapifyDown(obj.queueProperties.index);
return;
}

if (this.frontIndex == this.size) throw 'EventQueue size exceeded'
this.queue[this.frontIndex] = obj
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--
if (this.heap.length === this.size) {
throw new Error("EventQueue size exceeded");
}

obj.queueProperties.index = this.heap.length;
obj.queueProperties.inQueue = true;
this.heap.push(obj);
this.heapifyUp(obj.queueProperties.index);
}

/**
* To add without any delay.
* @param {CircuitElement} obj - the object to be added
* Insert object at current time.
*/
addImmediate(obj: QueueObject) {
this.queue[this.frontIndex] = obj
obj.queueProperties.time = this.time
obj.queueProperties.index = this.frontIndex
obj.queueProperties.inQueue = true
this.frontIndex++
this.add(obj, 0);
}

/**
* Function to swap two objects in queue.
* Pop next event (minimum event time)
*/
swap(v1: number, v2: number) {
const obj1 = this.queue[v1]
obj1.queueProperties.index = v2
pop() {
if (this.isEmpty()) throw new Error("Queue Empty");

const obj2 = this.queue[v2]
obj2.queueProperties.index = v1
const top = this.heap[0];
const last = this.heap.pop()!;

if (this.heap.length > 0) {
this.heap[0] = last;
last.queueProperties.index = 0;
this.heapifyDown(0);
}

this.queue[v1] = obj2
this.queue[v2] = obj1
top.queueProperties.inQueue = false;
this.time = top.queueProperties.time;
return top;
}

/**
* function to pop element from queue.
* Whether queue contains zero events.
*/
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
isEmpty() {
return this.heap.length === 0;
}

/**
* function to reset queue.
* Reset entire queue.
*/
reset() {
for (let i = 0; i < this.frontIndex; i++)
this.queue[i].queueProperties.inQueue = false
this.time = 0
this.frontIndex = 0
for (const obj of this.heap) obj.queueProperties.inQueue = false;
this.heap = [];
this.time = 0;
}

/**
* function to check if empty queue.
*/
isEmpty() {
return this.frontIndex == 0
// -------------------------------
// Heap Utility Functions
// -------------------------------

private swap(i: number, j: number) {
const a = this.heap[i];
const b = this.heap[j];
this.heap[i] = b;
this.heap[j] = a;
a.queueProperties.index = j;
b.queueProperties.index = i;
}

private heapifyUp(i: number) {
while (i > 0) {
const parent = Math.floor((i - 1) / 2);
if (this.heap[i].queueProperties.time >= this.heap[parent].queueProperties.time) break;
this.swap(i, parent);
i = parent;
}
}

private heapifyDown(i: number) {
const n = this.heap.length;

while (true) {
let smallest = i;
const left = 2 * i + 1;
const right = 2 * i + 2;

if (left < n && this.heap[left].queueProperties.time < this.heap[smallest].queueProperties.time) {
smallest = left;
}

if (right < n && this.heap[right].queueProperties.time < this.heap[smallest].queueProperties.time) {
smallest = right;
}

if (smallest === i) break;

this.swap(i, smallest);
i = smallest;
}
}
}