From b46057c14d2401b3353df1e8e243c4f9ac9bb6d8 Mon Sep 17 00:00:00 2001
From: unknown <david.antunes-da-silva@etu.univ-tlse2.fr>
Date: Thu, 23 Jun 2022 11:42:18 +0200
Subject: [PATCH] Add ThreeStepCycling scheduler + fix minor bugs/mistakes

---
 src/example/philosophes/MainPhilosophe.java   |   7 +-
 src/example/philosophes/Philosopher.java      |  39 +++----
 src/example/randomants/MainAnt.java           |   2 +-
 .../{base => }/schedulers/AsyncCycling.java   |  20 ++--
 .../{base => }/schedulers/FairCycling.java    |  42 +++----
 .../{base => }/schedulers/FairPosCycling.java |   2 +-
 .../PausableThreadPoolExecutor.java           |   2 +-
 .../variations/ThreeStepCycling.java          | 105 ++++++++++++++++++
 .../variations}/TwoDCycling.java              |   5 +-
 src/mas/ui/SchedulerToolbar.java              |   4 +-
 10 files changed, 167 insertions(+), 61 deletions(-)
 rename src/mas/implementation/{base => }/schedulers/AsyncCycling.java (89%)
 rename src/mas/implementation/{base => }/schedulers/FairCycling.java (80%)
 rename src/mas/implementation/{base => }/schedulers/FairPosCycling.java (93%)
 rename src/mas/implementation/{base => }/schedulers/PausableThreadPoolExecutor.java (97%)
 create mode 100644 src/mas/implementation/schedulers/variations/ThreeStepCycling.java
 rename src/mas/implementation/{base/schedulers => schedulers/variations}/TwoDCycling.java (94%)

diff --git a/src/example/philosophes/MainPhilosophe.java b/src/example/philosophes/MainPhilosophe.java
index d70319a..64e0367 100644
--- a/src/example/philosophes/MainPhilosophe.java
+++ b/src/example/philosophes/MainPhilosophe.java
@@ -1,7 +1,8 @@
 package example.philosophes;
 
 import mas.core.Schedulable;
-import mas.implementation.base.schedulers.FairCycling;
+import mas.implementation.schedulers.FairCycling;
+import mas.implementation.schedulers.variations.ThreeStepCycling;
 
 public class MainPhilosophe {
 
@@ -27,8 +28,8 @@ public class MainPhilosophe {
             philosophers[i].setRightPhilosopher(philosophers[(i+1) % nAgents]);
         }
 
-        Schedulable scheduler = new FairCycling(philosophers);
-        scheduler.setSleep(2);
+        Schedulable scheduler = new ThreeStepCycling(philosophers);
+        scheduler.setSleep(100);
         scheduler.start();
 
         try {
diff --git a/src/example/philosophes/Philosopher.java b/src/example/philosophes/Philosopher.java
index d683258..18831e4 100644
--- a/src/example/philosophes/Philosopher.java
+++ b/src/example/philosophes/Philosopher.java
@@ -65,19 +65,13 @@ public class Philosopher extends Agent {
 
     @Override
     public void perceive() {
-        //System.out.println("Philosopher num " + id + " perceive");
+        System.out.println("Philosopher num " + id + " perceive");
         criticallity = computeCriticallity();
     }
 
     @Override
     public void decide() {
-        //System.out.println("Philosopher num " + id + " decide");
-
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
+        System.out.println("Philosopher num " + id + " decide");
 
         State nextState = state;
         switch (state) {
@@ -116,12 +110,24 @@ public class Philosopher extends Agent {
 
         state = nextState;
         //System.out.println("Philospher n°" + id + " / State " + state);
-        System.out.println(
+        /*System.out.println(
                 "\tPhilosopher num " + id + " : " + state + " / " + criticallity + " / " + eatenPastas
-                /* + "\n\t\t Right Fk : " + rightFork.getTakenBy().getId() + " / Left Fk : " + leftFork.getTakenBy().getId()*/
-        );
+                 + "\n\t\t Right Fk : " + rightFork.getTakenBy().getId() + " / Left Fk : " + leftFork.getTakenBy().getId()
+        );*/
+    }
+
+    @Override
+    public void act() {
+        System.out.println("Philosopher num " + id + " act");
+        scheduler.addCyclable(new Waste(id));
+    }
+
+    @Override
+    public boolean terminate() {
+        return false;
     }
 
+
     private Philosopher getMostCriticalNeighbor() {
         List<Philosopher> criticalest = new ArrayList<>();
         double maxCriticality = getHungerDuration();
@@ -148,17 +154,6 @@ public class Philosopher extends Agent {
         return -1;
     }
 
-    @Override
-    public void act() {
-        //System.out.println("Philosopher num " + id + " act");
-        scheduler.addCyclable(new Waste(id));
-    }
-
-    @Override
-    public boolean terminate() {
-        return false;
-    }
-
     public Set<Map.Entry<Philosopher,Double>>  getNeighborsCriticallity(){
         Map<Philosopher, Double> criticalities = new HashMap<>();
 
diff --git a/src/example/randomants/MainAnt.java b/src/example/randomants/MainAnt.java
index f7fc3fa..3944436 100644
--- a/src/example/randomants/MainAnt.java
+++ b/src/example/randomants/MainAnt.java
@@ -3,7 +3,7 @@ package example.randomants;
 import mas.core.Agent;
 import mas.core.Cyclable;
 import mas.environment.TwoDContinuosGrid;
-import mas.implementation.base.schedulers.TwoDCycling;
+import mas.implementation.schedulers.variations.TwoDCycling;
 import mas.ui.MainWindow;
 import mas.ui.SchedulerToolbar;
 
diff --git a/src/mas/implementation/base/schedulers/AsyncCycling.java b/src/mas/implementation/schedulers/AsyncCycling.java
similarity index 89%
rename from src/mas/implementation/base/schedulers/AsyncCycling.java
rename to src/mas/implementation/schedulers/AsyncCycling.java
index 343f2fe..2b5073c 100644
--- a/src/mas/implementation/base/schedulers/AsyncCycling.java
+++ b/src/mas/implementation/schedulers/AsyncCycling.java
@@ -1,4 +1,4 @@
-package mas.implementation.base.schedulers;
+package mas.implementation.schedulers;
 
 import mas.core.Cyclable;
 import mas.core.Schedulable;
@@ -17,7 +17,7 @@ public class AsyncCycling implements Schedulable {
     private int sleep = DEFAULT_SLEEP;
 
     boolean mustStop = false;
-    private PausableThreadPoolExecutor executor = new PausableThreadPoolExecutor();
+    protected PausableThreadPoolExecutor executor = new PausableThreadPoolExecutor();
 
     public AsyncCycling(Cyclable... _cyclables){
 
@@ -84,14 +84,10 @@ public class AsyncCycling implements Schedulable {
         this.sleep = sleep;
     }
 
-    private void manageCyclable(Cyclable cyclable){
+    protected void manageCyclable(Cyclable cyclable){
         cyclable.cycle();
 
-        try {
-            Thread.sleep(sleep);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
+        doSleep();
 
         if(!cyclable.terminate() && !mustStop){
             executor.execute(() -> manageCyclable(cyclable));
@@ -100,6 +96,12 @@ public class AsyncCycling implements Schedulable {
         }
     }
 
-
+    protected void doSleep(){
+        try {
+            Thread.sleep(sleep);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
 
 }
diff --git a/src/mas/implementation/base/schedulers/FairCycling.java b/src/mas/implementation/schedulers/FairCycling.java
similarity index 80%
rename from src/mas/implementation/base/schedulers/FairCycling.java
rename to src/mas/implementation/schedulers/FairCycling.java
index 468d989..2383a56 100644
--- a/src/mas/implementation/base/schedulers/FairCycling.java
+++ b/src/mas/implementation/schedulers/FairCycling.java
@@ -1,4 +1,4 @@
-package mas.implementation.base.schedulers;
+package mas.implementation.schedulers;
 
 import mas.core.Cyclable;
 import mas.core.Schedulable;
@@ -11,21 +11,21 @@ import java.util.concurrent.*;
  */
 public class FairCycling implements Schedulable {
 
-    private Set<Cyclable> cyclables = new LinkedHashSet<>();
-    private Queue<Cyclable> pendingToAddCyclables = new ConcurrentLinkedQueue<>();
+    protected Set<Cyclable> cyclables = new LinkedHashSet<>();
+    protected Queue<Cyclable> pendingToAddCyclables = new ConcurrentLinkedQueue<>();
 
-    private int sleep = DEFAULT_SLEEP;
+    protected int sleep = DEFAULT_SLEEP;
 
-    private int nbOfCycles = 0;
+    protected int nbOfCycles = 0;
 
     protected boolean mustStop = false;
 
     protected boolean mustPause = false;
 
-    ExecutorService executor = Executors.newCachedThreadPool();
+    protected ExecutorService executor = Executors.newCachedThreadPool();
 
-    CountDownLatch pauseLatch;
-    CountDownLatch latch;
+    protected CountDownLatch pauseLatch;
+    protected CountDownLatch cycleLatch;
 
     public FairCycling(Cyclable... _cyclables) {
 
@@ -88,7 +88,7 @@ public class FairCycling implements Schedulable {
 
         treatPendingCyclables();
 
-        latch = new CountDownLatch(cyclables.size());
+        cycleLatch = new CountDownLatch(cyclables.size());
 
         for (Cyclable cyclable : cyclables) {
 
@@ -97,20 +97,14 @@ public class FairCycling implements Schedulable {
                 if(!cyclable.terminate()){
                     pendingToAddCyclables.add(cyclable);
                 }
-                latch.countDown();
+                cycleLatch.countDown();
             });
         }
 
-        if (getSleep() != 0) {
-            try {
-                Thread.sleep(getSleep());
-            } catch (final InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
+        doSleep();
 
         try {
-            latch.await();
+            cycleLatch.await();
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
         }
@@ -138,12 +132,22 @@ public class FairCycling implements Schedulable {
         }
     }
 
-    private void treatPendingCyclables() {
+    protected void treatPendingCyclables() {
         Queue<Cyclable> buffer = new ConcurrentLinkedQueue<>(pendingToAddCyclables);
         cyclables.addAll(buffer);
         pendingToAddCyclables.clear();
     }
 
+    protected void doSleep(){
+        if (getSleep() != 0) {
+            try {
+                Thread.sleep(getSleep());
+            } catch (final InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
     public int getNbOfCycles() {
         return nbOfCycles;
     }
diff --git a/src/mas/implementation/base/schedulers/FairPosCycling.java b/src/mas/implementation/schedulers/FairPosCycling.java
similarity index 93%
rename from src/mas/implementation/base/schedulers/FairPosCycling.java
rename to src/mas/implementation/schedulers/FairPosCycling.java
index 3100732..59bec2b 100644
--- a/src/mas/implementation/base/schedulers/FairPosCycling.java
+++ b/src/mas/implementation/schedulers/FairPosCycling.java
@@ -1,4 +1,4 @@
-package mas.implementation.base.schedulers;
+package mas.implementation.schedulers;
 
 import mas.core.Cyclable;
 import mas.core.Schedulable;
diff --git a/src/mas/implementation/base/schedulers/PausableThreadPoolExecutor.java b/src/mas/implementation/schedulers/PausableThreadPoolExecutor.java
similarity index 97%
rename from src/mas/implementation/base/schedulers/PausableThreadPoolExecutor.java
rename to src/mas/implementation/schedulers/PausableThreadPoolExecutor.java
index 8529943..cc2dc64 100644
--- a/src/mas/implementation/base/schedulers/PausableThreadPoolExecutor.java
+++ b/src/mas/implementation/schedulers/PausableThreadPoolExecutor.java
@@ -1,4 +1,4 @@
-package mas.implementation.base.schedulers;
+package mas.implementation.schedulers;
 
 import java.util.concurrent.*;
 import java.util.concurrent.locks.Condition;
diff --git a/src/mas/implementation/schedulers/variations/ThreeStepCycling.java b/src/mas/implementation/schedulers/variations/ThreeStepCycling.java
new file mode 100644
index 0000000..4730051
--- /dev/null
+++ b/src/mas/implementation/schedulers/variations/ThreeStepCycling.java
@@ -0,0 +1,105 @@
+package mas.implementation.schedulers.variations;
+
+import mas.core.ThreeStepCyclable;
+import mas.implementation.schedulers.FairCycling;
+
+import java.util.LinkedHashSet;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Execution cadencé en 3 phases (tous perception puis tous decision puis tous action)
+ */
+
+
+public class ThreeStepCycling extends FairCycling {
+
+    protected Set<ThreeStepCyclable> threeStepCyclables = new LinkedHashSet<>();
+    protected Queue<ThreeStepCyclable> pendingToAddThreeStepCyclabes = new ConcurrentLinkedQueue<>();
+
+    protected CountDownLatch perceptionLatch;
+    protected CountDownLatch decicionLatch;
+
+    public ThreeStepCycling(ThreeStepCyclable... _threeStepCyclables){
+        for(ThreeStepCyclable threeStepCyclable : _threeStepCyclables){
+            addThreeStepCyclable(threeStepCyclable);
+        }
+    }
+
+    @Override
+    protected void step() {
+        nbOfCycles++;
+
+        treatPendingCyclables();
+
+        cycleLatch = new CountDownLatch(threeStepCyclables.size());
+        perceptionLatch = new CountDownLatch(threeStepCyclables.size());
+        decicionLatch = new CountDownLatch(threeStepCyclables.size());
+
+        for(ThreeStepCyclable threeStepCyclable : threeStepCyclables){
+
+            executor.execute(() -> {
+                threeStepCyclable.perceive();
+
+                waitPerception();
+
+                threeStepCyclable.decide();
+
+                waitDecision();
+
+                threeStepCyclable.act();
+
+                if(!threeStepCyclable.terminate()){
+                    pendingToAddThreeStepCyclabes.add(threeStepCyclable);
+                }
+                cycleLatch.countDown();
+            });
+        }
+
+        doSleep();
+
+        try {
+            cycleLatch.await();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+
+        cyclables.clear();
+
+        onCycleEnds();
+    }
+
+    @Override
+    protected void treatPendingCyclables() {
+        Queue<ThreeStepCyclable> buffer = new ConcurrentLinkedQueue<>(pendingToAddThreeStepCyclabes);
+        threeStepCyclables.addAll(buffer);
+        pendingToAddThreeStepCyclabes.clear();
+    }
+
+    public void addThreeStepCyclable(ThreeStepCyclable threeStepCyclable){
+        threeStepCyclable.setScheduler(this);
+        pendingToAddThreeStepCyclabes.add(threeStepCyclable);
+    }
+
+    protected  void waitPerception(){
+        perceptionLatch.countDown();
+
+        try {
+            perceptionLatch.await();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+     protected void waitDecision(){
+         decicionLatch.countDown();
+
+         try {
+             decicionLatch.await();
+         } catch (InterruptedException e) {
+             throw new RuntimeException(e);
+         }
+     }
+}
diff --git a/src/mas/implementation/base/schedulers/TwoDCycling.java b/src/mas/implementation/schedulers/variations/TwoDCycling.java
similarity index 94%
rename from src/mas/implementation/base/schedulers/TwoDCycling.java
rename to src/mas/implementation/schedulers/variations/TwoDCycling.java
index f1d942c..78cf03a 100644
--- a/src/mas/implementation/base/schedulers/TwoDCycling.java
+++ b/src/mas/implementation/schedulers/variations/TwoDCycling.java
@@ -1,13 +1,14 @@
-package mas.implementation.base.schedulers;
+package mas.implementation.schedulers.variations;
 
 import mas.core.Cyclable;
+import mas.implementation.schedulers.FairCycling;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Consumer;
 
-public class TwoDCycling extends FairCycling{
+public class TwoDCycling extends FairCycling {
 
     /**
      * The state of the scheduler {@link State}
diff --git a/src/mas/ui/SchedulerToolbar.java b/src/mas/ui/SchedulerToolbar.java
index 5cd2b47..eab6a1d 100644
--- a/src/mas/ui/SchedulerToolbar.java
+++ b/src/mas/ui/SchedulerToolbar.java
@@ -1,6 +1,6 @@
 package mas.ui;
 
-import mas.implementation.base.schedulers.TwoDCycling;
+import mas.implementation.schedulers.variations.TwoDCycling;
 
 import javax.swing.*;
 import java.awt.*;
@@ -99,9 +99,7 @@ public class SchedulerToolbar extends JToolBar {
                 if(!source.getValueIsAdjusting()){
                     switch (runController.getValue()) {
                         case 0 -> {
-                            System.out.println("Je commence doOneCycle()");
                             scheduler.doOneCycle();
-                            System.out.println("Je termine doOneCycle()");
                         }
                         case 2 -> {
                             scheduler.startWithSleep(1000);
-- 
GitLab