feat: Implement initial Process Scheduling Simulator application with core logic, algorithms, UI components, and project setup.
This commit is contained in:
commit
083fc0027e
54 files changed
+8815
No files matched your search
@@ -0,0 +1,62 @@
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
import type { Process, SchedulerConfig } from "@core/types";
|
||||
|
||||
// ============================================================
|
||||
// Defaults
|
||||
// ============================================================
|
||||
|
||||
const DEFAULT_CONFIG: SchedulerConfig = {
|
||||
algorithm: "FCFS",
|
||||
quantum: 2,
|
||||
contextSwitchTime: 0,
|
||||
isPreemptive: false,
|
||||
agingEnabled: false,
|
||||
agingInterval: 5,
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// Store
|
||||
// ============================================================
|
||||
|
||||
interface ProcessStore {
|
||||
processes: Process[];
|
||||
config: SchedulerConfig;
|
||||
|
||||
addProcess: (p: Process) => void;
|
||||
updateProcess: (id: string, updates: Partial<Process>) => void;
|
||||
removeProcess: (id: string) => void;
|
||||
clearProcesses: () => void;
|
||||
setConfig: (updates: Partial<SchedulerConfig>) => void;
|
||||
loadPreset: (processes: Process[], config: SchedulerConfig) => void;
|
||||
}
|
||||
|
||||
export const useProcessStore = create<ProcessStore>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
processes: [],
|
||||
config: DEFAULT_CONFIG,
|
||||
|
||||
addProcess: (p) =>
|
||||
set((s) => ({ processes: [...s.processes, p] })),
|
||||
|
||||
updateProcess: (id, updates) =>
|
||||
set((s) => ({
|
||||
processes: s.processes.map((p) =>
|
||||
p.id === id ? { ...p, ...updates } : p,
|
||||
),
|
||||
})),
|
||||
|
||||
removeProcess: (id) =>
|
||||
set((s) => ({ processes: s.processes.filter((p) => p.id !== id) })),
|
||||
|
||||
clearProcesses: () => set({ processes: [] }),
|
||||
|
||||
setConfig: (updates) =>
|
||||
set((s) => ({ config: { ...s.config, ...updates } })),
|
||||
|
||||
loadPreset: (processes, config) => set({ processes, config }),
|
||||
}),
|
||||
{ name: "pss:session" },
|
||||
),
|
||||
);
|
||||
@@ -0,0 +1,69 @@
|
||||
import { create } from "zustand";
|
||||
import { SimulationEngine } from "@core/engine";
|
||||
import type { Process, SchedulerConfig, SimTick } from "@core/types";
|
||||
|
||||
// ============================================================
|
||||
// Types
|
||||
// ============================================================
|
||||
|
||||
export type SimStatus = "idle" | "running" | "paused" | "finished";
|
||||
|
||||
interface SimulationStore {
|
||||
status: SimStatus;
|
||||
ticks: SimTick[];
|
||||
// Mutable engine instance — reactivity comes from ticks[] and status, not engine itself
|
||||
engine: SimulationEngine | null;
|
||||
// Saved so reset() can recreate the engine without coupling to processStore
|
||||
_processes: Process[];
|
||||
_config: SchedulerConfig | null;
|
||||
|
||||
init: (processes: Process[], config: SchedulerConfig) => void;
|
||||
stepOnce: () => void;
|
||||
play: () => void;
|
||||
pause: () => void;
|
||||
reset: () => void;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Store
|
||||
// ============================================================
|
||||
|
||||
export const useSimulationStore = create<SimulationStore>()((set, get) => ({
|
||||
status: "idle",
|
||||
ticks: [],
|
||||
engine: null,
|
||||
_processes: [],
|
||||
_config: null,
|
||||
|
||||
init: (processes, config) => {
|
||||
const engine = new SimulationEngine(processes, config);
|
||||
set({
|
||||
engine,
|
||||
ticks: [],
|
||||
status: "paused",
|
||||
_processes: processes,
|
||||
_config: config,
|
||||
});
|
||||
},
|
||||
|
||||
stepOnce: () => {
|
||||
const { engine, ticks, status } = get();
|
||||
if (!engine || engine.isFinished || status === "finished") return;
|
||||
const tick = engine.step();
|
||||
set({
|
||||
ticks: [...ticks, tick],
|
||||
status: engine.isFinished ? "finished" : status,
|
||||
});
|
||||
},
|
||||
|
||||
play: () => set({ status: "running" }),
|
||||
|
||||
pause: () => set({ status: "paused" }),
|
||||
|
||||
reset: () => {
|
||||
const { _processes, _config } = get();
|
||||
if (_processes.length === 0 || _config === null) return;
|
||||
const engine = new SimulationEngine(_processes, _config);
|
||||
set({ engine, ticks: [], status: "paused" });
|
||||
},
|
||||
}));
|
||||
@@ -0,0 +1,28 @@
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
|
||||
// ============================================================
|
||||
// Speed options
|
||||
// ============================================================
|
||||
|
||||
export const SPEED_OPTIONS = [0.25, 0.5, 1, 2, 4] as const;
|
||||
export type SpeedOption = (typeof SPEED_OPTIONS)[number];
|
||||
|
||||
// ============================================================
|
||||
// Store
|
||||
// ============================================================
|
||||
|
||||
interface UiStore {
|
||||
speed: number;
|
||||
setSpeed: (speed: number) => void;
|
||||
}
|
||||
|
||||
export const useUiStore = create<UiStore>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
speed: 1,
|
||||
setSpeed: (speed) => set({ speed }),
|
||||
}),
|
||||
{ name: "pss:ui" },
|
||||
),
|
||||
);
|
||||
Reference in new issue
Block a user