diff options
Diffstat (limited to 'src/main/java/simulator/engine/HeadlessSimulationEngine.java')
| -rw-r--r-- | src/main/java/simulator/engine/HeadlessSimulationEngine.java | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/main/java/simulator/engine/HeadlessSimulationEngine.java b/src/main/java/simulator/engine/HeadlessSimulationEngine.java new file mode 100644 index 0000000..36a64a7 --- /dev/null +++ b/src/main/java/simulator/engine/HeadlessSimulationEngine.java @@ -0,0 +1,116 @@ +package simulator.engine; + +import core.*; +import prefs.VSPrefs; +import events.internal.VSMessageReceiveEvent; +import simulator.VSLogging; + +/** + * Headless implementation of the simulation engine that runs without any GUI dependencies. + * This engine focuses purely on simulation logic without any visualization concerns. + */ +public class HeadlessSimulationEngine extends AbstractSimulationEngine { + + public HeadlessSimulationEngine(VSPrefs prefs, VSLogging loging) { + super(prefs, loging); + } + + @Override + protected long calculateDeliveryTime(VSMessage message) { + // Get source process + VSInternalProcess source = (VSInternalProcess) message.getSendingProcess(); + + if (source == null) { + return time; // Deliver immediately if process not found + } + + // Calculate network delay + long networkDelay = prefs.getLong("sim.network.delay"); + long variability = prefs.getLong("sim.network.variability"); + + // Add random variability + if (variability > 0) { + long variance = (long)(Math.random() * variability * 2) - variability; + networkDelay += variance; + } + + // Ensure minimum delay + if (networkDelay < 0) { + networkDelay = 0; + } + + // Calculate delivery time based on source process time + return source.getTime() + networkDelay; + } + + @Override + protected void scheduleMessageDelivery(VSMessage message, long deliveryTime) { + // In DS-Sim, messages are broadcast to all processes + VSInternalProcess sendingProcess = (VSInternalProcess) message.getSendingProcess(); + boolean recvOwn = prefs.getBoolean("sim.message.own.recv"); + + // Schedule delivery to all processes + for (VSInternalProcess receiverProcess : processes) { + if (receiverProcess.equals(sendingProcess)) { + // Only deliver to self if configured + if (!recvOwn) { + continue; + } + } + + // Create receive event for this process + VSMessageReceiveEvent receiveEvent = new VSMessageReceiveEvent(message); + VSTask task = new VSTask(deliveryTime, receiverProcess, receiveEvent, VSTask.GLOBAL); + taskManager.addTask(task); + + if (loging != null) { + loging.log("Message scheduled for delivery to process " + + receiverProcess.getProcessNum() + "; ID: " + + message.getMessageID() + "; Time: " + deliveryTime); + } + } + } + + /** + * Run one simulation step. + * This method advances time and executes all tasks scheduled for the current time. + */ + public void runStep() { + if (isPaused || hasFinished) { + return; + } + + // Sync all process times + for (VSInternalProcess process : processes) { + process.syncTime(time); + } + + // Run tasks for current time + taskManager.runTasks(time, 0, time - 1); + + // Check if simulation has finished + // TODO: Implement proper finish detection + // For now, rely on external control or time limits + } + + /** + * Run the simulation for a specified duration. + * @param duration Duration in milliseconds + */ + public void runFor(long duration) { + long endTime = time + duration; + + while (time < endTime && !hasFinished) { + runStep(); + time++; + } + } + + /** + * Check if any protocols are still active. + * TODO: Implement this when protocol tracking is available + */ + private boolean hasActiveProtocols() { + return false; // For now, assume no active protocols + } +}
\ No newline at end of file |
