Skip to content

Commit 6b44fa6

Browse files
authored
feat: improve pause and speed handling across simulation (#174)
Fixes #125 This PR makes pause and speed handling consistent across the simulation. - It makes programs stop when simulation is paused - It makes speed and pauses affect packet processing in routers It also refactors the `SpeedMultiplier` to present the current speed multiplier as 0 when the simulation is paused and removes the `Packet.isSimulationPaused` field.
1 parent b161b7d commit 6b44fa6

File tree

9 files changed

+55
-46
lines changed

9 files changed

+55
-46
lines changed

src/context.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class GlobalContext {
2121
private viewport: Viewport = null;
2222
private datagraph: DataGraph;
2323
private viewgraph: ViewGraph;
24-
private speedMultiplier: SpeedMultiplier;
24+
private speedMultiplier = new SpeedMultiplier(1);
2525
private saveIntervalId: NodeJS.Timeout | null = null;
2626
private ipGenerator: IpAddressGenerator;
2727
private macGenerator: MacAddressGenerator;
@@ -58,17 +58,16 @@ export class GlobalContext {
5858
}
5959

6060
private setSpeedMultiplier(speedMultiplier: SpeedMultiplier) {
61-
if (speedMultiplier && speedMultiplier.value > 0) {
62-
this.changeSpeedMultiplier(speedMultiplier.value);
63-
// Update the wheel display after setting the speed
64-
const speedWheel = document.getElementById(
65-
"speed-wheel",
66-
) as HTMLInputElement;
67-
const valueDisplay = document.querySelector(".value-display");
68-
if (speedWheel && valueDisplay) {
69-
speedWheel.value = speedMultiplier.value.toString();
70-
valueDisplay.textContent = `${speedMultiplier.value}x`;
71-
}
61+
this.speedMultiplier = speedMultiplier;
62+
// TODO: make this change go through SpeedControlHandler
63+
// Update the wheel display after setting the speed
64+
const speedWheel = document.getElementById(
65+
"speed-wheel",
66+
) as HTMLInputElement;
67+
const valueDisplay = document.querySelector(".value-display");
68+
if (speedWheel && valueDisplay) {
69+
speedWheel.value = speedMultiplier.value.toString();
70+
valueDisplay.textContent = `${speedMultiplier.value}x`;
7271
}
7372
}
7473

@@ -97,7 +96,7 @@ export class GlobalContext {
9796
}
9897

9998
getCurrentSpeed() {
100-
return this.speedMultiplier;
99+
return this.speedMultiplier.value;
101100
}
102101

103102
getDataGraph() {
@@ -109,11 +108,17 @@ export class GlobalContext {
109108
this.setNetwork(this.datagraph, layer);
110109
}
111110

111+
pause() {
112+
this.speedMultiplier.pause();
113+
}
114+
115+
unpause() {
116+
this.speedMultiplier.unpause();
117+
}
118+
112119
changeSpeedMultiplier(speedMultiplier: number) {
113-
if (this.viewgraph) {
114-
this.speedMultiplier = new SpeedMultiplier(speedMultiplier);
115-
saveToLocalStorage(this);
116-
}
120+
this.speedMultiplier.setSpeed(speedMultiplier);
121+
saveToLocalStorage(this);
117122
}
118123

119124
private setupAutoSave() {

src/handlers/pauseHandler.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import PlaySvg from "../assets/play-icon.svg";
22
import PauseSvg from "../assets/pause-icon.svg";
3-
import { Packet } from "../types/packet";
3+
import { GlobalContext } from "../context";
44

55
export class PauseHandler {
6+
private ctx: GlobalContext;
67
private pauseButton: HTMLButtonElement | null;
78
private pauseIcon: HTMLImageElement;
89
private isPaused: boolean;
910

10-
constructor() {
11+
constructor(ctx: GlobalContext) {
12+
this.ctx = ctx;
1113
this.pauseButton = document.getElementById(
1214
"pause-button",
1315
) as HTMLButtonElement;
@@ -57,9 +59,9 @@ export class PauseHandler {
5759

5860
// Handle animation pause/unpause
5961
if (this.isPaused) {
60-
Packet.pauseAnimation();
62+
this.ctx.pause();
6163
} else {
62-
Packet.unpauseAnimation();
64+
this.ctx.unpause();
6365
}
6466
}
6567
}

src/handlers/speedControlHandler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { GlobalContext } from "../context";
22

33
export class SpeedControlHandler {
4-
private ctx: GlobalContext; // Adjust the type based on GlobalContext
4+
private ctx: GlobalContext;
55
private speedWheel: HTMLInputElement | null;
66
private valueDisplay: HTMLElement | null;
77

@@ -13,7 +13,7 @@ export class SpeedControlHandler {
1313
this.valueDisplay = document.querySelector(".value-display");
1414

1515
if (this.speedWheel && this.valueDisplay) {
16-
this.updateSpeedWheel(this.ctx.getCurrentSpeed().value);
16+
this.updateSpeedWheel(this.ctx.getCurrentSpeed());
1717
this.speedWheel.addEventListener("input", (event) =>
1818
this.handleSpeedChange(event),
1919
);

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ async function loadAssets(otherPromises: Promise<void>[]) {
7373
new LayerHandler(ctx, leftBar);
7474
new ResponsiveHandler(app, viewport);
7575
new UndoRedoHandler(ctx);
76-
new PauseHandler();
76+
new PauseHandler(ctx);
7777
new SpeedControlHandler(ctx);
7878

7979
const configModal = new ConfigModal(ctx);

src/types/devices/router.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ export class Router extends NetworkDevice {
7777
}
7878

7979
processPacket(ticker: Ticker) {
80-
const datagram = this.getPacketsToProcess(ticker.deltaMS);
80+
const elapsedTime = ticker.deltaMS * this.viewgraph.getSpeed();
81+
const datagram = this.getPacketsToProcess(elapsedTime);
8182
if (!datagram) {
8283
return;
8384
}
Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
export class SpeedMultiplier {
22
private _value: number;
3+
private isPaused = false;
34

45
constructor(initialValue = 1) {
5-
if (initialValue <= 0) {
6-
throw new Error("Speed value must be greater than 0");
7-
}
8-
this._value = initialValue;
6+
this.setSpeed(initialValue);
97
}
108

119
// Get the current speed value
1210
get value(): number {
13-
return this._value;
11+
return this.isPaused ? 0 : this._value;
12+
}
13+
14+
setSpeed(value: number) {
15+
if (value <= 0) {
16+
throw new Error("Speed value must be greater than 0");
17+
}
18+
this._value = value;
19+
}
20+
21+
pause() {
22+
this.isPaused = true;
23+
}
24+
25+
unpause() {
26+
this.isPaused = false;
1427
}
1528
}

src/types/graphs/viewgraph.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ export class ViewGraph {
182182
}
183183

184184
getSpeed(): number {
185-
return this.ctx.getCurrentSpeed().value;
185+
return this.ctx.getCurrentSpeed();
186186
}
187187

188188
// Get all connections of a device

src/types/packet.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,6 @@ export class Packet extends Graphics {
3434
private type: string;
3535
private rawPacket: EthernetFrame;
3636

37-
static animationPaused = false;
38-
39-
static pauseAnimation() {
40-
Packet.animationPaused = true;
41-
}
42-
43-
static unpauseAnimation() {
44-
Packet.animationPaused = false;
45-
}
46-
4737
constructor(viewgraph: ViewGraph, type: string, rawPacket: EthernetFrame) {
4838
super();
4939

@@ -164,10 +154,8 @@ export class Packet extends Graphics {
164154
const normalizedSpeed = this.speed / edgeLength;
165155

166156
// Update progress with normalized speed
167-
if (!Packet.animationPaused) {
168-
this.progress +=
169-
(ticker.deltaMS * normalizedSpeed * this.viewgraph.getSpeed()) / 1000;
170-
}
157+
this.progress +=
158+
(ticker.deltaMS * normalizedSpeed * this.viewgraph.getSpeed()) / 1000;
171159

172160
this.updatePosition();
173161
}

src/types/viewportManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export function saveToLocalStorage(ctx: GlobalContext) {
185185
const dataGraph = ctx.getDataGraph();
186186
const graphData = JSON.stringify(dataGraph.toData());
187187
const layer = ctx.getCurrentLayer();
188-
const speedMultiplier = ctx.getCurrentSpeed().value;
188+
const speedMultiplier = ctx.getCurrentSpeed();
189189
const data: LocalStorageData = { graph: graphData, layer, speedMultiplier };
190190
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(data));
191191

0 commit comments

Comments
 (0)