From 4165037512f11caa53cea467c8482706ad45efef Mon Sep 17 00:00:00 2001
From: unknown <david.antunes-da-silva@irit.fr>
Date: Wed, 13 Jul 2022 14:41:29 +0200
Subject: [PATCH] Made FairCycling a generic Class + some performance
 improvements + some minor fixes

---
 src/example/philosophes/MainPhilosophe.java   | 11 +--
 src/example/philosophes/Philosopher.java      | 12 +++
 src/mas/core/Sleepable.java                   |  6 +-
 .../schedulers/FairCycling.java               | 24 +++---
 .../schedulers/FairPosCycling.java            | 10 +--
 .../{variations => }/ThreeStepCycling.java    | 74 ++++++-------------
 .../schedulers/variations/TwoDCycling.java    | 17 ++---
 7 files changed, 69 insertions(+), 85 deletions(-)
 rename src/mas/implementation/schedulers/{variations => }/ThreeStepCycling.java (53%)

diff --git a/src/example/philosophes/MainPhilosophe.java b/src/example/philosophes/MainPhilosophe.java
index 3f35581..a93df0d 100644
--- a/src/example/philosophes/MainPhilosophe.java
+++ b/src/example/philosophes/MainPhilosophe.java
@@ -1,7 +1,9 @@
 package example.philosophes;
 
 import mas.core.Cyclable;
+import mas.core.ThreeStepCyclable;
 import mas.implementation.schedulers.FairCycling;
+import mas.implementation.schedulers.ThreeStepCycling;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -10,20 +12,19 @@ public class MainPhilosophe {
 
     public static void main(String[] args) {
 
-        class MyFairCycling extends FairCycling {
+        class MyFairCycling extends FairCycling<Cyclable> {
 
             long startTimeCycle = 0;
 
             List<Long> cycleTime = new ArrayList<>();
 
-            public MyFairCycling(Cyclable... _cyclables){
+            public MyFairCycling(ThreeStepCyclable... _cyclables){
                 super(_cyclables);
-
             }
 
             @Override
             public boolean stopCondition() {
-                return nbOfCycles == 1000;
+                return nbOfCycles == 100;
             }
 
             @Override
@@ -43,7 +44,7 @@ public class MainPhilosophe {
         }
 
         int nAgents = 100;
-        int nbCycles = 1000;
+        int nbCycles = 100;
 
         Philosopher[] philosophers = new Philosopher[nAgents];
         Fork[] forks = new Fork[nAgents];
diff --git a/src/example/philosophes/Philosopher.java b/src/example/philosophes/Philosopher.java
index f9131a3..23c6b04 100644
--- a/src/example/philosophes/Philosopher.java
+++ b/src/example/philosophes/Philosopher.java
@@ -78,6 +78,7 @@ public class Philosopher extends Agent {
 
             case EATING ->{
                 eatenPastas++;
+                //scheduler.addCyclable(new Waste(id));
                 if (new Random().nextInt(101) > 50) {
                     leftFork.release(this);
                     rightFork.release(this);
@@ -119,9 +120,20 @@ public class Philosopher extends Agent {
     @Override
     public void act() {
         //System.out.println("Philosopher num " + id + " act");
+        fibonacciRecursion(23);
         //scheduler.addCyclable(new Waste(id));
     }
 
+    public int fibonacciRecursion(int n){
+        if(n == 0){
+            return 0;
+        }
+        if(n == 1 || n == 2){
+            return 1;
+        }
+        return fibonacciRecursion(n-2) + fibonacciRecursion(n-1);
+    }
+
     @Override
     public boolean terminate() {
         return false;
diff --git a/src/mas/core/Sleepable.java b/src/mas/core/Sleepable.java
index bbe0a8e..a8dfc10 100644
--- a/src/mas/core/Sleepable.java
+++ b/src/mas/core/Sleepable.java
@@ -13,7 +13,7 @@ public interface Sleepable {
     /**
      * Getter for the sleep time.
      *
-     * @return the current time elapsed between each system's cycle
+     * @return the current time elapsed between each cycle
      */
     int getSleep();
 
@@ -21,12 +21,12 @@ public interface Sleepable {
      * Setter for the sleep time.
      *
      * @param sleep
-     *          The time between each system's cycle
+     *          The time between each cycle
      */
     void setSleep(int sleep);
 
     /**
-     * Performs the waiting time between two cycles of the system.
+     * Performs the waiting time between two cycles.
      */
     void doSleep();
 }
diff --git a/src/mas/implementation/schedulers/FairCycling.java b/src/mas/implementation/schedulers/FairCycling.java
index f4ad3f9..b31efae 100644
--- a/src/mas/implementation/schedulers/FairCycling.java
+++ b/src/mas/implementation/schedulers/FairCycling.java
@@ -13,17 +13,17 @@ import java.util.concurrent.*;
  *
  * @author David Antunes
  */
-public class FairCycling implements Schedulable, Sleepable {
+public class FairCycling<T extends Cyclable> implements Schedulable, Sleepable {
 
     /**
      * The cyclable objects handled by the scheduler.
      */
-    protected Set<Cyclable> cyclables = new LinkedHashSet<>();
+    protected Set<T> cyclables = new LinkedHashSet<>();
 
     /**
-     * The cyclables that must be added in the next cycle.
+     * The cyclables that must be add in the next cycle.
      */
-    protected Queue<Cyclable> pendingToAddCyclables = new ConcurrentLinkedQueue<>();
+    protected Queue<T> pendingToAddCyclables = new ConcurrentLinkedQueue<>();
 
     /**
      * Time between two cycles. Default time in {@link Sleepable#DEFAULT_SLEEP}.
@@ -66,9 +66,10 @@ public class FairCycling implements Schedulable, Sleepable {
      * @param _cyclables
      *          The corresponding cyclables
      */
-    public FairCycling(Cyclable... _cyclables) {
+    @SafeVarargs
+    public FairCycling(T... _cyclables) {
 
-        for (Cyclable cyclable : _cyclables) {
+        for (T cyclable : _cyclables) {
             addCyclable(cyclable);
         }
     }
@@ -119,7 +120,7 @@ public class FairCycling implements Schedulable, Sleepable {
     @Override
     public void addCyclable(Cyclable cyclable){
         cyclable.setScheduler(this);
-        pendingToAddCyclables.add(cyclable);
+        pendingToAddCyclables.add((T) cyclable);
     }
 
     @Override
@@ -167,7 +168,7 @@ public class FairCycling implements Schedulable, Sleepable {
 
         cycleLatch = new CountDownLatch(cyclables.size());
 
-        for (Cyclable cyclable : cyclables) {
+        for (T cyclable : cyclables) {
 
             executor.execute(() -> {
                 cyclable.cycle();
@@ -186,10 +187,10 @@ public class FairCycling implements Schedulable, Sleepable {
             throw new RuntimeException(e);
         }
 
-        cyclables.clear();
-
         onCycleEnds();
 
+        cyclables.clear();
+
         nbOfCycles++;
     }
 
@@ -218,8 +219,7 @@ public class FairCycling implements Schedulable, Sleepable {
      * Add the cyclables that are going to be scheduled on the current cycle.
      */
     protected void treatPendingCyclables() {
-        Queue<Cyclable> buffer = new ConcurrentLinkedQueue<>(pendingToAddCyclables);
-        cyclables.addAll(buffer);
+        cyclables.addAll(pendingToAddCyclables);
         pendingToAddCyclables.clear();
     }
 
diff --git a/src/mas/implementation/schedulers/FairPosCycling.java b/src/mas/implementation/schedulers/FairPosCycling.java
index 791060c..283d615 100644
--- a/src/mas/implementation/schedulers/FairPosCycling.java
+++ b/src/mas/implementation/schedulers/FairPosCycling.java
@@ -28,6 +28,11 @@ public class FairPosCycling implements Schedulable, Sleepable {
 
     }
 
+    @Override
+    public void addCyclable(Cyclable cyclable) {
+
+    }
+
     @Override
     public int getSleep() {
         return 0;
@@ -43,11 +48,6 @@ public class FairPosCycling implements Schedulable, Sleepable {
 
     }
 
-    @Override
-    public void addCyclable(Cyclable cyclable) {
-
-    }
-
     @Override
     public boolean stopCondition() {
         return false;
diff --git a/src/mas/implementation/schedulers/variations/ThreeStepCycling.java b/src/mas/implementation/schedulers/ThreeStepCycling.java
similarity index 53%
rename from src/mas/implementation/schedulers/variations/ThreeStepCycling.java
rename to src/mas/implementation/schedulers/ThreeStepCycling.java
index 46bd4f1..61e579d 100644
--- a/src/mas/implementation/schedulers/variations/ThreeStepCycling.java
+++ b/src/mas/implementation/schedulers/ThreeStepCycling.java
@@ -1,12 +1,7 @@
-package mas.implementation.schedulers.variations;
+package mas.implementation.schedulers;
 
 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;
 
 /**
@@ -14,17 +9,7 @@ import java.util.concurrent.CountDownLatch;
  */
 
 
-public class ThreeStepCycling extends FairCycling {
-
-    /**
-     * The cyclable objects handled by the scheduler.
-     */
-    protected Set<ThreeStepCyclable> threeStepCyclables = new LinkedHashSet<>();
-
-    /**
-     * The cyclables that must be added in the next cycle.
-     */
-    protected Queue<ThreeStepCyclable> pendingToAddThreeStepCyclabes = new ConcurrentLinkedQueue<>();
+public class ThreeStepCycling extends FairCycling<ThreeStepCyclable> {
 
     /**
      * Object that synchronize each cyclable every system's cycle for the perception phase.
@@ -43,22 +28,20 @@ public class ThreeStepCycling extends FairCycling {
      *          The corresponding cyclables
      */
     public ThreeStepCycling(ThreeStepCyclable... _threeStepCyclables){
-        for(ThreeStepCyclable threeStepCyclable : _threeStepCyclables){
-            addThreeStepCyclable(threeStepCyclable);
-        }
+        super(_threeStepCyclables);
     }
 
     @Override
     protected void step() {
-        nbOfCycles++;
+        onCycleStarts();
 
         treatPendingCyclables();
 
-        cycleLatch = new CountDownLatch(threeStepCyclables.size());
-        perceptionLatch = new CountDownLatch(threeStepCyclables.size());
-        decicionLatch = new CountDownLatch(threeStepCyclables.size());
+        cycleLatch = new CountDownLatch(cyclables.size());
+        perceptionLatch = new CountDownLatch(cyclables.size());
+        decicionLatch = new CountDownLatch(cyclables.size());
 
-        for(ThreeStepCyclable threeStepCyclable : threeStepCyclables){
+        for(ThreeStepCyclable threeStepCyclable : cyclables){
 
             executor.execute(() -> {
                 threeStepCyclable.perceive();
@@ -71,8 +54,8 @@ public class ThreeStepCycling extends FairCycling {
 
                 threeStepCyclable.act();
 
-                if(!threeStepCyclable.terminate()){
-                    pendingToAddThreeStepCyclabes.add(threeStepCyclable);
+                if(threeStepCyclable.terminate()){
+                    pendingToAddCyclables.add(threeStepCyclable);
                 }
                 cycleLatch.countDown();
             });
@@ -80,33 +63,13 @@ public class ThreeStepCycling extends FairCycling {
 
         doSleep();
 
-        try {
-            cycleLatch.await();
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-
-        cyclables.clear();
+        waitAction();
 
         onCycleEnds();
-    }
 
-    @Override
-    protected void treatPendingCyclables() {
-        Queue<ThreeStepCyclable> buffer = new ConcurrentLinkedQueue<>(pendingToAddThreeStepCyclabes);
-        threeStepCyclables.addAll(buffer);
-        pendingToAddThreeStepCyclabes.clear();
-    }
+        cyclables.clear();
 
-    /**
-     * Add a threeStepCyclable object to the scheduler and starts their cycle as soon as possible.
-     *
-     * @param threeStepCyclable
-     *      The cyclable to add
-     */
-    public void addThreeStepCyclable(ThreeStepCyclable threeStepCyclable){
-        threeStepCyclable.setScheduler(this);
-        pendingToAddThreeStepCyclabes.add(threeStepCyclable);
+        nbOfCycles++;
     }
 
     /**
@@ -134,4 +97,15 @@ public class ThreeStepCycling extends FairCycling {
             throw new RuntimeException(e);
         }
     }
+
+    /**
+     * This method synchronize every cyclable in the action phase.
+     */
+    protected void waitAction(){
+        try {
+            cycleLatch.await();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }
diff --git a/src/mas/implementation/schedulers/variations/TwoDCycling.java b/src/mas/implementation/schedulers/variations/TwoDCycling.java
index 2520eb3..d08bb54 100644
--- a/src/mas/implementation/schedulers/variations/TwoDCycling.java
+++ b/src/mas/implementation/schedulers/variations/TwoDCycling.java
@@ -11,7 +11,7 @@ import java.util.function.Consumer;
 /**
  * Extension of the {@link FairCycling} scheduler made to be used with a GUI.
  */
-public class TwoDCycling extends FairCycling {
+public class TwoDCycling extends FairCycling<Cyclable> {
 
     /**
      * The state of the scheduler {@link State}
@@ -26,9 +26,9 @@ public class TwoDCycling extends FairCycling {
 
     /**
      * The methods called when the speed is changed. Useful to change the value of
-     * the GUI slider of
+     * the GUI slider of {@link mas.ui.SchedulerToolbar}
      */
-    private List<Consumer<TwoDCycling>> onChange = new ArrayList<>();
+    private final List<Consumer<TwoDCycling>> onChange = new ArrayList<>();
 
     protected enum State {
         /**
@@ -104,13 +104,10 @@ public class TwoDCycling extends FairCycling {
         setSleep(_sleep);
 
 
-        switch (state){
-            case PENDING_START -> {
-                start();
-            }
-            default -> {
-                resume();
-            }
+        if (state == State.PENDING_START) {
+            start();
+        } else {
+            resume();
         }
     }
 
-- 
GitLab