diff --git a/main/src/main/java/sd/IntersectionProcess.java b/main/src/main/java/sd/IntersectionProcess.java index 3942f0d..2305f44 100644 --- a/main/src/main/java/sd/IntersectionProcess.java +++ b/main/src/main/java/sd/IntersectionProcess.java @@ -12,10 +12,10 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import sd.config.SimulationConfig; +import sd.engine.TrafficLightThread; import sd.model.Intersection; import sd.model.MessageType; import sd.model.TrafficLight; -import sd.model.TrafficLightState; import sd.model.Vehicle; import sd.protocol.MessageProtocol; import sd.protocol.SocketConnection; @@ -173,130 +173,21 @@ public class IntersectionProcess { * Starts all traffic light threads. */ private void startTrafficLights() { - System.out.println("\n[" + intersectionId + "] Starting traffic light threads..."); + System.out.println("\n[" + intersectionId + "] Starting traffic light threads..."); for (TrafficLight light : intersection.getTrafficLights()) { - trafficLightPool.submit(() -> runTrafficLightCycle(light)); + + TrafficLightThread lightTask = new TrafficLightThread(light, this, config); + + + trafficLightPool.submit(lightTask); + System.out.println(" Started thread for: " + light.getDirection()); } } - /** - * The main loop for a traffic light thread. - * Continuously cycles between green and red states. - * - * only one traffic light can be green at any given time in this intersection. - * - * @param light The traffic light to control. - */ - private void runTrafficLightCycle(TrafficLight light) { - System.out.println("[" + light.getId() + "] Traffic light thread started."); - while (running) { - try { - // Acquire coordination lock to become green - trafficCoordinationLock.lock(); - try { - // Wait until no other direction is green - while (currentGreenDirection != null && running) { - trafficCoordinationLock.unlock(); - Thread.sleep(100); // Brief wait before retrying - trafficCoordinationLock.lock(); - } - - if (!running) { - break; // Exit if shutting down - } - - // Mark this direction as the current green light - currentGreenDirection = light.getDirection(); - light.changeState(TrafficLightState.GREEN); - System.out.println("[" + light.getId() + "] State: GREEN"); - - } finally { - trafficCoordinationLock.unlock(); - } - - // Process vehicles while green - processGreenLight(light); - - // Wait for green duration - Thread.sleep((long) (light.getGreenTime() * 1000)); - - // Release coordination lock (turn red) - trafficCoordinationLock.lock(); - try { - light.changeState(TrafficLightState.RED); - currentGreenDirection = null; // Release exclusive access - System.out.println("[" + light.getId() + "] State: RED (RELEASED ACCESS)"); - } finally { - trafficCoordinationLock.unlock(); - } - - // Wait for red duration - Thread.sleep((long) (light.getRedTime() * 1000)); - - } catch (InterruptedException e) { - System.out.println("[" + light.getId() + "] Traffic light thread interrupted."); - break; - } - } - - System.out.println("[" + light.getId() + "] Traffic light thread stopped."); - } - /** - * Processes vehicles when a traffic light is GREEN. - * Dequeues vehicles and sends them to their next destination. - * - * @param light The traffic light that is currently green. - */ - private void processGreenLight(TrafficLight light) { - while (light.getState() == TrafficLightState.GREEN && light.getQueueSize() > 0) { - Vehicle vehicle = light.removeVehicle(); - - if (vehicle != null) { - // Get crossing time based on vehicle type - double crossingTime = getCrossingTimeForVehicle(vehicle); - - // Simulate crossing time - try { - Thread.sleep((long) (crossingTime * 1000)); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; - } - - // Update vehicle statistics - vehicle.addCrossingTime(crossingTime); - - // Update intersection statistics - intersection.incrementVehiclesSent(); - - // Send vehicle to next destination - sendVehicleToNextDestination(vehicle); - } - } - } - - /** - * Gets the crossing time for a vehicle based on its type. - * - * @param vehicle The vehicle. - * @return The crossing time in seconds. - */ - private double getCrossingTimeForVehicle(Vehicle vehicle) { - switch (vehicle.getType()) { - case BIKE: - return config.getBikeVehicleCrossingTime(); - case LIGHT: - return config.getLightVehicleCrossingTime(); - case HEAVY: - return config.getHeavyVehicleCrossingTime(); - default: - return config.getLightVehicleCrossingTime(); - } - } /** * Sends a vehicle to its next destination via socket connection.