summaryrefslogtreecommitdiff
path: root/src/main/java/simulator/engine/HeadlessSimulationEngine.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/simulator/engine/HeadlessSimulationEngine.java')
-rw-r--r--src/main/java/simulator/engine/HeadlessSimulationEngine.java116
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