Implement Priority Round Robin Scheduling Algorithm with Tests

- Added `priority_rr` algorithm to handle scheduling based on priority and round-robin principles.
- Created unit tests for `select()`, `shouldPreempt()`, and `isQuantumExpired()` functions to ensure correct behavior.
- Developed integration tests to validate the scheduling logic under various scenarios, including preemption and round-robin execution.
- Introduced `useExport` hook for exporting process metrics to CSV format.
- Added `useGanttScroll` hook to manage smooth scrolling of the Gantt chart during simulation.
This commit is contained in:
Lucas Rayan committed 2026-03-19 16:45:05 -03:00
1 parent 083fc0027e
commit 51a8a6fa40
38 files changed
+2530 -45

No files matched your search

+113
View File
@@ -0,0 +1,113 @@
import { useCallback, useRef, useState } from "react";
import { useSimulationStore } from "@store/simulationStore";
import { useProcessStore } from "@store/processStore";
import { useGanttScroll } from "@hooks/useGanttScroll";
import GanttRow from "./GanttRow";
import GanttLegend from "./GanttLegend";
import GanttTooltip, { type TooltipData } from "./GanttTooltip";
import { CELL_H, CELL_W } from "./constants";
// ── GanttChart ────────────────────────────────────────────────
const GanttChart = () => {
const ticks = useSimulationStore((s) => s.ticks);
const status = useSimulationStore((s) => s.status);
const processes = useProcessStore((s) => s.processes);
// Scrollable container ref for auto-scroll
const scrollRef = useRef<HTMLDivElement>(null);
const currentTickIndex = ticks.length - 1;
useGanttScroll(scrollRef, currentTickIndex, status === "running");
// Tooltip state
const [tooltip, setTooltip] = useState<TooltipData | null>(null);
const handleMouseLeave = useCallback(() => setTooltip(null), []);
// Empty state
if (ticks.length === 0) {
return (
<div className="border-b border-slate-800 flex items-center justify-center text-slate-600 bg-slate-900/50 text-sm select-none"
style={{ minHeight: 80 }}>
Inicie a simulação para ver o diagrama de Gantt
</div>
);
}
// ── ruler (tick numbers) ──────────────────────────────────
const tickNumbers = ticks.map((t) => t.tick);
const totalWidth = ticks.length * CELL_W;
return (
<div className="border-b border-slate-800 bg-slate-950 flex flex-col">
{/* ── scrollable grid + cursor ── */}
<div
ref={scrollRef}
className="overflow-x-auto overflow-y-hidden gantt-scrollbar relative"
>
<div style={{ width: totalWidth, position: "relative" }}>
{/* Tick ruler */}
<div className="flex sticky top-0 z-10 bg-slate-950 border-b border-slate-800">
{/* Spacer for sticky process labels column */}
<div className="sticky left-0 z-20 bg-slate-950 border-r border-slate-700 shrink-0" style={{ width: 48, height: 16 }} />
{tickNumbers.map((t) => (
<div
key={t}
className="shrink-0 text-center text-[9px] text-slate-500 font-mono select-none"
style={{ width: CELL_W, height: 16, lineHeight: "16px" }}
>
{t % 5 === 0 ? t : ""}
</div>
))}
</div>
{/* Process rows */}
<div className="relative">
{processes.map((process) => (
<div key={process.id} className="flex items-center border-b border-white/5 last:border-b-0">
{/* Process label (sticky on the left) */}
<div
className="sticky left-0 z-20 bg-slate-900 border-r border-slate-700 px-2 flex items-center shrink-0"
style={{ width: 48, height: CELL_H }}
>
<span className="text-[10px] font-bold truncate" style={{ color: process.color }}>
{process.name}
</span>
</div>
<GanttRow
process={process}
ticks={ticks}
onCellMouseEnter={setTooltip}
onCellMouseLeave={handleMouseLeave}
/>
</div>
))}
{/* Current-tick cursor line */}
{currentTickIndex >= 0 && (
<div
className="gantt-cursor absolute top-0 bottom-0 w-px bg-white/20 pointer-events-none"
style={{ left: 48 + currentTickIndex * CELL_W + CELL_W / 2 }}
/>
)}
</div>
</div>
</div>
{/* ── process name labels (sticky left, overlay) ── */}
{/* Rendered OUTSIDE the scrollable div so they stay fixed on the left */}
{/* We achieve this with a separate absolute-positioned column */}
{/* ── legend ── */}
<GanttLegend />
{/* ── tooltip ── */}
{tooltip && <GanttTooltip data={tooltip} />}
</div>
);
};
export default GanttChart;