Skip to content

Commit 3bbab32

Browse files
authored
feat: Packet Queue Usage Progress Bar (#185)
This pull request introduces a new progress bar feature to the `DeviceInfo` class and updates related files to support this functionality. The most important changes include the addition of the `ProgressBar` component, modifications to the `DeviceInfo` class to include the progress bar, and the necessary CSS styles. ### New Progress Bar Feature: * **Progress Bar Component**: - Added a new `ProgressBar` class in `src/graphics/renderables/progress_bar.ts` to create and manage the progress bar element. - Introduced `ProgressBarProps` interface to define the properties of the progress bar. * **DeviceInfo Class Updates**: - Updated `DeviceInfo` class in `src/graphics/renderables/device_info.ts` to include a method `addProgressBar` for adding a progress bar with a label. - Imported `ProgressBar` and `TooltipManager` in `src/graphics/renderables/device_info.ts`. ### CSS Styles for Progress Bar: * **Progress Bar Styles**: - Added new CSS styles in `src/styles/progress-bar.css` to style the progress bar container, bar, and text. - Included the new CSS file in `src/styles/index.ts`. ### ViewRouter Class Updates: * **Queue Size and Progress Bar Integration**: - Modified `ViewRouter` class in `src/types/view-devices/vRouter.ts` to add a progress bar showing packet queue usage. - Implemented observer pattern in `PacketQueue` class to notify changes in queue size and update the progress bar accordingly. [[1]](diffhunk://#diff-221c2585585eef7ff9eafd84467d1c0bcef658af348a8673d2d00f752d06e35aR273-R299) [[2]](diffhunk://#diff-221c2585585eef7ff9eafd84467d1c0bcef658af348a8673d2d00f752d06e35aR311) [[3]](diffhunk://#diff-221c2585585eef7ff9eafd84467d1c0bcef658af348a8673d2d00f752d06e35aR321) ### Tooltip Updates: * **Tooltip Constants**: - Added new tooltip keys and content for the packet queue usage in `src/utils/constants/tooltips_constants.ts`. [[1]](diffhunk://#diff-d23a6aa67e252dd864d40b8b3b4cc29db716b0e742da79d7ef8da9b9dc956ce1R48) [[2]](diffhunk://#diff-d23a6aa67e252dd864d40b8b3b4cc29db716b0e742da79d7ef8da9b9dc956ce1R132-R133) related #173
1 parent add0b04 commit 3bbab32

File tree

7 files changed

+188
-2
lines changed

7 files changed

+188
-2
lines changed

src/graphics/renderables/device_info.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { ProgramInfo } from "./program_info";
1010
import { ProgramRunnerInfo } from "./program_runner_info";
1111
import { StyledInfo } from "./styled_info";
1212
import { createParameterGroup } from "./parameter_editor";
13+
import { ProgressBar } from "./progress_bar";
14+
import { TooltipManager } from "./tooltip_manager";
1315

1416
export { ProgramInfo } from "./program_info";
1517

@@ -104,6 +106,43 @@ export class DeviceInfo extends StyledInfo {
104106
this.inputFields.push(toggleButton);
105107
this.inputFields.push(borderedContainer);
106108
}
109+
110+
/**
111+
* Adds a progress bar with a label above it.
112+
* @param label - The text of the label to be displayed above the progress bar.
113+
* @param current - The current value of the progress bar.
114+
* @param max - The maximum value of the progress bar.
115+
* @param subscribe - A function that subscribes to changes in the progress bar.
116+
*/
117+
addProgressBar(
118+
label: string,
119+
current: number,
120+
max: number,
121+
subscribe: (progressBar: ProgressBar) => void,
122+
): void {
123+
// Create the container for the label and the progress bar
124+
const container = document.createElement("div");
125+
container.className = "progress-bar-wrapper";
126+
127+
// Create the label
128+
const labelElement = document.createElement("div");
129+
labelElement.className = "progress-bar-label";
130+
labelElement.textContent = label;
131+
TooltipManager.getInstance().attachTooltip(labelElement, label);
132+
133+
// Create the progress bar
134+
const progressBar = new ProgressBar({ current, max });
135+
136+
// Add the progress bar to the container
137+
container.appendChild(labelElement);
138+
container.appendChild(progressBar.render());
139+
140+
// Add the container to the input fields
141+
this.inputFields.push(container);
142+
143+
// Subscribe to changes in the progress bar
144+
subscribe(progressBar);
145+
}
107146
}
108147

109148
function getTypeName(device: ViewDevice): string {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export interface ProgressBarProps {
2+
current: number; // Current size of the queue
3+
max: number; // Maximum size of the queue
4+
}
5+
6+
export class ProgressBar {
7+
private container: HTMLElement;
8+
private progress: HTMLElement;
9+
private text: HTMLElement;
10+
11+
constructor(props: ProgressBarProps) {
12+
this.container = document.createElement("div");
13+
this.container.className = "progress-bar-container";
14+
15+
this.progress = document.createElement("div");
16+
this.progress.className = "progress-bar";
17+
18+
this.text = document.createElement("div");
19+
this.text.className = "progress-bar-text";
20+
21+
this.container.appendChild(this.progress);
22+
this.container.appendChild(this.text);
23+
this.update(props.current, props.max);
24+
}
25+
26+
// Updates the progress of the bar
27+
update(current: number, max: number): void {
28+
const fraction = `${current}/${max} bytes`; // Format as fraction
29+
const percentage = Math.min((current / max) * 100, 100); // Limit 100%
30+
this.progress.style.width = `${percentage}%`; // Updates the width of the green bar
31+
this.text.textContent = fraction; // Updates the text to show the fraction
32+
}
33+
34+
// Returns the HTML container of the component
35+
render(): HTMLElement {
36+
return this.container;
37+
}
38+
}

src/styles/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ import "./config.css";
1616
import "./tooltips.css";
1717
import "./dropdown.css";
1818
import "./parameter_editor.css";
19+
import "./progress-bar.css";

src/styles/progress-bar.css

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* Progress bar container */
2+
.progress-bar-container {
3+
width: 100%;
4+
height: 25px; /* Height of the bar */
5+
background-color: #f3f3f3; /* Light gray background */
6+
border: 1px solid #dcdcdc; /* Lighter border */
7+
border-radius: 10px; /* Rounded corners */
8+
overflow: hidden; /* Hides overflowing content */
9+
position: relative; /* Necessary for positioning the text */
10+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* Subtle shadow */
11+
}
12+
13+
/* Progress bar */
14+
.progress-bar {
15+
height: 100%; /* Full height of the container */
16+
background: linear-gradient(90deg, #4caf50, #81c784); /* Green gradient */
17+
width: 0%; /* Initial width */
18+
transition:
19+
width 0.4s ease-in-out,
20+
background-color 0.3s ease; /* Smooth animation */
21+
}
22+
23+
/* Centered text */
24+
.progress-bar-text {
25+
position: absolute; /* Positions the text over the container */
26+
top: 50%; /* Vertically centers */
27+
left: 50%; /* Horizontally centers */
28+
transform: translate(-50%, -50%); /* Adjusts for full centering */
29+
color: black; /* Black text */
30+
font-size: 0.9rem; /* Font size */
31+
font-weight: bold; /* Bold text */
32+
pointer-events: none; /* Prevents text from interfering with events */
33+
z-index: 1; /* Ensures the text is above the green bar */
34+
}
35+
36+
/* Glow effect on the progress bar */
37+
.progress-bar::after {
38+
content: "";
39+
position: absolute;
40+
top: 0;
41+
left: 0;
42+
width: 100%;
43+
height: 100%;
44+
background: linear-gradient(
45+
90deg,
46+
rgba(255, 255, 255, 0.3),
47+
rgba(255, 255, 255, 0)
48+
);
49+
opacity: 0.5;
50+
pointer-events: none;
51+
transform: translateX(-100%);
52+
animation: shine 2s infinite linear; /* Glow effect */
53+
}
54+
55+
/* Progress bar and its label container */
56+
.progress-bar-wrapper {
57+
display: flex;
58+
padding: auto;
59+
flex-direction: column; /* Places the label above the bar */
60+
margin-bottom: 10px; /* Bottom spacing */
61+
}
62+
63+
/* Progress bar label */
64+
.progress-bar-label {
65+
font-weight: bold;
66+
color: #000000; /* Changes the text color to black */
67+
margin-bottom: 10px; /* Spacing between the label and the input */
68+
flex: 1; /* The label takes up the remaining space */
69+
text-align: center; /* Aligns the label text to the center */
70+
overflow: hidden; /* Hides text that doesn't fit */
71+
}

src/types/data-devices/dRouter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class PacketQueue {
177177
}
178178

179179
enqueue(packet: IPv4Packet) {
180-
if (this.queueSizeBytes >= this.maxQueueSizeBytes) {
180+
if (this.queueSizeBytes + packet.totalLength > this.maxQueueSizeBytes) {
181181
return false;
182182
}
183183
this.queue.push(packet);

src/types/view-devices/vRouter.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,21 @@ export class ViewRouter extends ViewNetworkDevice {
5757

5858
info.addEmptySpace();
5959

60+
info.addProgressBar(
61+
TOOLTIP_KEYS.PACKET_QUEUE_USAGE,
62+
this.packetQueue.getCurrentSize(),
63+
this.packetQueue.getMaxQueueSize(),
64+
(progressBar) => {
65+
// Suscribe
66+
this.packetQueue.subscribe(() => {
67+
progressBar.update(
68+
this.packetQueue.getCurrentSize(),
69+
this.packetQueue.getMaxQueueSize(),
70+
);
71+
});
72+
},
73+
);
74+
6075
info.addParameterGroup(TOOLTIP_KEYS.ROUTER_PARAMETERS, [
6176
{
6277
label: TOOLTIP_KEYS.PACKET_QUEUE_SIZE_PARAMETER,
@@ -254,27 +269,45 @@ class PacketQueue {
254269
private queueSizeBytes = 0;
255270
private maxQueueSizeBytes: number;
256271

272+
private observers: (() => void)[] = [];
273+
257274
constructor(maxQueueSizeBytes: number) {
258275
this.maxQueueSizeBytes = maxQueueSizeBytes;
259276
}
260277

278+
// Método para suscribirse a cambios
279+
subscribe(observer: () => void): void {
280+
this.observers.push(observer);
281+
}
282+
283+
// Método para notificar a los observadores
284+
private notifyObservers(): void {
285+
this.observers.forEach((observer) => observer());
286+
}
287+
288+
getCurrentSize(): number {
289+
return this.queueSizeBytes;
290+
}
291+
261292
getMaxQueueSize(): number {
262293
return this.maxQueueSizeBytes;
263294
}
264295
setMaxQueueSize(newSize: number) {
265296
if (newSize >= 0) {
266297
this.maxQueueSizeBytes = newSize;
298+
this.notifyObservers();
267299
} else {
268300
console.warn("Invalid queue size, keeping previous value");
269301
}
270302
}
271303

272304
enqueue(packet: IPv4Packet) {
273-
if (this.queueSizeBytes >= this.maxQueueSizeBytes) {
305+
if (this.queueSizeBytes + packet.totalLength > this.maxQueueSizeBytes) {
274306
return false;
275307
}
276308
this.queue.push(packet);
277309
this.queueSizeBytes += packet.totalLength;
310+
this.notifyObservers();
278311
return true;
279312
}
280313

@@ -284,6 +317,7 @@ class PacketQueue {
284317
}
285318
const packet = this.queue.shift();
286319
this.queueSizeBytes -= packet.totalLength;
320+
this.notifyObservers();
287321
return packet;
288322
}
289323

src/utils/constants/tooltips_constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const TOOLTIP_KEYS = {
4545
HOST_PARAMETERS: "Host Parameters",
4646
PACKET_QUEUE_SIZE_PARAMETER: "Packet queue size (bytes)",
4747
PROCESSING_SPEED_PARAMETER: "Processing speed (ms/byte)",
48+
PACKET_QUEUE_USAGE: "Packet Queue Usage",
4849
} as const;
4950

5051
// Tooltip Content
@@ -128,4 +129,6 @@ export const TOOLTIP_CONTENT = {
128129
"The maximum size of the packet queue in bytes. This parameter determines how many packets can be stored in the queue before they are processed.",
129130
[TOOLTIP_KEYS.PROCESSING_SPEED_PARAMETER]:
130131
"The time taken to process a single byte of data. This parameter affects the speed at which packets are processed and sent.",
132+
[TOOLTIP_KEYS.PACKET_QUEUE_USAGE]:
133+
"The progress bar visually represents the percentage of the queue currently occupied by packets waiting to be processed",
131134
} as const;

0 commit comments

Comments
 (0)