Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • main
1 result

Target

Select target project
  • g23beaum/tp-train
  • a23celer/tp-train
2 results
Select Git revision
  • main
1 result
Show changes
Commits on Source (10)
......@@ -48,3 +48,4 @@ replay_pid*
.DS_Store
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,java
/bin/
# TP Train (TP 11 - 15)
_Groupe composé de XXX xxx, YYY yyy._
_Groupe composé de CELERIER Auguste, ACHARD Romain._
## Introduction
Ce projet s'inscrit dans le cadre du cours sur les logiciels concurrents. Il consiste en la modélisation en Java du déplacement de trains sur des rails.
- Éditeur utilisé : `XXX (au choix)`
- Éditeur utilisé : Eclipse
## Réponses aux questions
### Question 1.1
Réponse
La classe Position est la plus importante pour gérer le mouvement des trains. En effet, elle contient les information sur l'Element actuel sur lequel le train se situe, et la Direction de son mouvement. La classe Railway gère la liste d'éléments que les trains peuvent parcourir, et permet donc de déterminer le prochain élément sur la trajectoire du train
### Question 1.2
Ouvrir le fichier trains.drawio avec le site https://app.diagrams.net/
Voir fichier trains.drawio
### Question 1.3
etc...
Voir code
###Question 2.1
Voir code
###Question 2.2
Les variables qui permettent d'exprimer l'invariant de sûreté sont la présence ou non d'un train dans une section, le nombre de trains présents dans une station et la direction globale des trains sur la ligne
###Question 2.3
Voir code
###Question 2.4
Les actions critiques qu'un train peut exécuter, c'est-à-dire les actions qui modifie l'état du système partagé, sont entrer ou quitter une section, entrer ou quitter une station et changer de direction
###Question 2.5
Ces méthodes doivent être rajoutées respectivement dans Section et Station, et les méthodes de gestion de la direction dans la classe Railway
###Question 2.6
Il faut ajouter des méthodes synchronisées dans les classes Railway et Position pour gérer les mouvements des trains de manière synchronisée, pour autoriser ou non leur déplacement
###Question 2.7
Voir code
### Question 2.8
Voir code
......@@ -20,4 +20,8 @@ public enum Direction {
return "from right to left";
}
};
public Direction turn() {
return this == LR ? RL : LR;
}
}
......@@ -4,11 +4,8 @@ package train;
* Cette classe abstraite est la représentation générique d'un élément de base d'un
* circuit, elle factorise les fonctionnalités communes des deux sous-classes :
* l'entrée d'un train, sa sortie et l'appartenance au circuit.<br/>
* Les deux sous-classes sont :
* <ol>
* <li>La représentation d'une gare : classe {@link Station}</li>
* <li>La représentation d'une section de voie ferrée : classe {@link Section}</li>
* </ol>
*
*
*
* @author Fabien Dagnat <fabien.dagnat@imt-atlantique.fr>
* @author Philippe Tanguy <philippe.tanguy@imt-atlantique.fr>
......
......@@ -21,7 +21,7 @@ package train;
*/
public class Position implements Cloneable {
private final Direction direction;
private final Element pos;
private Element pos;
public Position(Element elt, Direction d) {
if (elt == null || d == null)
......@@ -44,7 +44,38 @@ public class Position implements Cloneable {
public Element getPos() {
return pos;
}
public void move(Train t, Railway railway) throws InterruptedException {
if (railway == null) {
throw new NullPointerException("Railway cannot be null.");
}
try {
// Get the next element based on the current position and direction
Element nextElement = railway.nextElement(this.pos, this.direction);
if (nextElement instanceof Section) {
((Section) nextElement).enterSection(t, direction, railway);
} else if (nextElement instanceof Station) {
((Station) nextElement).enterStation(t, direction, railway); //On vérifie d'abord si on peut accéder à l'élément suiant
}
if (pos instanceof Section) {
((Section) pos).leaveSection(t, railway);
} else if (pos instanceof Station) {
((Station) pos).leaveStation(t, direction, railway); //On indique ensuite quitter l'élément sur lequel on se trouve
}
this.pos = nextElement; //On modifie l'élement sur lequel le train se trouve
} catch (IllegalArgumentException e) {
// If no next element exists, reverse the direction
this.direction.turn();
}
}
@Override
public String toString() {
StringBuilder result = new StringBuilder(this.pos.toString());
......
......@@ -10,6 +10,11 @@ package train;
*/
public class Railway {
private final Element[] elements;
private Direction currentDirection = null; //Paramètre pour controller la direction actuelle des trains en circulation
private int movingTrains = 0; //Nombre de trains en circulations
private int trainsWaitingRL = 0;
private int trainsWaitingLR = 0;
public Railway(Element[] elements) {
if(elements == null)
......@@ -26,11 +31,58 @@ public class Railway {
boolean first = true;
for (Element e : this.elements) {
if (first)
first = false;
first = false;
else
result.append("--");
result.append(e);
}
return result.toString();
}
public Element nextElement(Element currentElement, Direction direction) {
if (currentElement == null || direction == null) {
throw new NullPointerException("Current element or direction cannot be null.");
}
for (int i = 0; i < elements.length; i++) {
if (elements[i] == currentElement) {
if (direction == Direction.LR && i < elements.length - 1) {
return elements[i + 1];
} else if (direction == Direction.RL && i > 0) {
return elements[i - 1];
}
}
}
throw new IllegalArgumentException("Current element is not part of the railway or no next element exists in the given direction.");
}
public synchronized void requestToMove(Train t, Direction d) throws InterruptedException {
// Augmente le nombre de trains en attente
if (d == Direction.LR) trainsWaitingLR++;
else trainsWaitingRL++;
// Attente si un train circule déjà en sens inverse
while (movingTrains > 0 && currentDirection != d && (trainsWaitingRL <= trainsWaitingLR)) {
wait();
}
// Réduit le nombre de trains en attente
if (d == Direction.LR) trainsWaitingLR--;
else trainsWaitingRL--;
// Met à jour la direction actuelle
currentDirection = d;
movingTrains++;
}
public synchronized void trainStopped(Train t) {
movingTrains--;
if (movingTrains == 0) {
currentDirection = null; // Réinitialisation de la direction globale quand plus aucun train ne circule
}
notifyAll(); // Réveille les trains en attente
}
}
......@@ -8,7 +8,36 @@ package train;
* @author Philippe Tanguy <philippe.tanguy@imt-atlantique.fr>
*/
public class Section extends Element {
private Train currentTrain = null;
private Direction currentDirection = null;
public Section(String name) {
super(name);
this.currentTrain = null;
this.currentDirection = null;
}
public synchronized void enterSection(Train t, Direction d, Railway railway) throws InterruptedException {
railway.requestToMove(t, d);
while (currentTrain != null || (currentDirection != null && currentDirection != d)) {
wait();
}
currentTrain = t;
currentDirection = d;
}
public synchronized void leaveSection(Train t, Railway railway) {
if (currentTrain == t) {
currentTrain = null;
currentDirection = null;
notifyAll(); // Réveille les trains bloqués
}
railway.trainStopped(t);
}
}
......@@ -9,12 +9,36 @@ package train;
* @author Philippe Tanguy <philippe.tanguy@imt-atlantique.fr>
*/
public class Station extends Element {
private final int size;
private int currentTrain = 0; //nombre de trains présent dans la station
private final int size;
private int trainsGoingLR = 0; // Différenciation des trains selon leur direction
private int trainsGoingRL = 0;
public Station(String name, int size) {
super(name);
if(name == null || size <=0)
throw new NullPointerException();
this.size = size;
this.currentTrain = 0;
this.trainsGoingLR = 0;
this.trainsGoingRL = 0;
}
public synchronized void enterStation(Train t, Direction d, Railway railway) throws InterruptedException {
railway.requestToMove(t, d);
while (currentTrain >= size || (d == Direction.LR && trainsGoingRL > 0) || (d == Direction.RL && trainsGoingLR > 0)) {
wait();
}
currentTrain++; // On ajoute le train dans la gare
if (d == Direction.LR) trainsGoingLR++;
else trainsGoingRL++;
}
public synchronized void leaveStation(Train t, Direction d, Railway railway) {
currentTrain--;
if (d == Direction.LR) trainsGoingLR--;
else trainsGoingRL--;
notifyAll(); // Réveille les trains en attente
railway.trainStopped(t);
}
}
......@@ -42,4 +42,14 @@ public class Train {
result.append(this.pos);
return result.toString();
}
public void run(Railway railway) {
try {
while (true) {
Thread.sleep(50);
this.pos.move(this, railway);
Thread.sleep(50);
}
} catch (InterruptedException e) {}
}
}