Compare commits

...

2 Commits

Author SHA1 Message Date
william 704b40ecc9 Add static network 2022-06-07 21:07:49 -04:00
william 8a0d743e6d Add static network 2022-06-07 21:06:20 -04:00
50 changed files with 296 additions and 63 deletions

View File

@ -1,11 +1,13 @@
package configuration; package configuration;
import java.io.File;
public interface ConfigurationParser { public interface ConfigurationParser {
/** /**
* Analyse et lit une configuration de simulation depuis un fichier au chemin donné. * Analyse et lit une configuration de simulation depuis un fichier.
* *
* @param path Le chemin vers le fichier de configuration. * @param file Le fichier de configuration.
* @return La configuration de simulation correspondant au contenu du fichier. * @return La configuration de simulation correspondant au contenu du fichier.
*/ */
SimulationConfiguration parseConfiguration(String path) throws ConfigurationParsingException; SimulationConfiguration parseConfiguration(File file) throws ConfigurationParsingException;
} }

View File

@ -1,6 +1,6 @@
package configuration; package configuration;
import model.metadata.BuildingMetadata; import metadata.BuildingMetadata;
import java.util.Map; import java.util.Map;

View File

@ -0,0 +1,26 @@
package configuration;
public class SimulationConfigurationSingleton {
private static SimulationConfigurationSingleton instance;
public static SimulationConfigurationSingleton getInstance() {
if (instance == null) {
instance = new SimulationConfigurationSingleton();
}
return instance;
}
private SimulationConfiguration configuration;
private SimulationConfigurationSingleton() {
}
public void setConfiguration(SimulationConfiguration config) {
this.configuration = config;
}
public SimulationConfiguration getConfiguration() {
return configuration;
}
}

View File

@ -1,7 +1,7 @@
package configuration; package configuration;
import model.Building; import simulation.Building;
import model.Route; import simulation.Route;
import java.util.Collection; import java.util.Collection;

View File

@ -1,15 +1,16 @@
package configuration; package configuration;
import model.*; import metadata.*;
import model.metadata.*;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import simulation.*;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -36,8 +37,8 @@ public class XmlConfigurationParser implements ConfigurationParser {
public static final String ATTRIBUTE_TO = "vers"; public static final String ATTRIBUTE_TO = "vers";
@Override @Override
public SimulationConfiguration parseConfiguration(String path) throws ConfigurationParsingException { public SimulationConfiguration parseConfiguration(File file) throws ConfigurationParsingException {
Document document = parseDocument(path); Document document = parseDocument(file);
Map<String, BuildingMetadata> buildingsMetadata = parseBuildingsMetadata(document); Map<String, BuildingMetadata> buildingsMetadata = parseBuildingsMetadata(document);
SimulationData simulationData = parseSimulationData(document); SimulationData simulationData = parseSimulationData(document);
@ -45,12 +46,12 @@ public class XmlConfigurationParser implements ConfigurationParser {
return new SimulationConfiguration(buildingsMetadata, simulationData); return new SimulationConfiguration(buildingsMetadata, simulationData);
} }
private Document parseDocument(String path) throws ConfigurationParsingException { private Document parseDocument(File file) throws ConfigurationParsingException {
try { try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder(); DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(path); Document document = builder.parse(file);
document.getDocumentElement().normalize(); document.getDocumentElement().normalize();
return document; return document;

View File

@ -1,13 +1,13 @@
package model.metadata; package metadata;
import model.BuildingState; import simulation.BuildingState;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
public abstract class BuildingMetadata { public abstract class BuildingMetadata {
private final String type; protected final String type;
private final Map<BuildingState, String> iconsPaths; protected final Map<BuildingState, String> iconsPaths;
public BuildingMetadata(String type, Map<BuildingState, String> iconsPaths) { public BuildingMetadata(String type, Map<BuildingState, String> iconsPaths) {
this.type = type; this.type = type;

View File

@ -1,6 +1,6 @@
package model.metadata; package metadata;
import model.ComponentType; import simulation.ComponentType;
import java.util.Objects; import java.util.Objects;

View File

@ -1,6 +1,6 @@
package model.metadata; package metadata;
import model.BuildingState; import simulation.BuildingState;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;

View File

@ -1,6 +1,6 @@
package model.metadata; package metadata;
import model.ComponentType; import simulation.ComponentType;
import java.util.Objects; import java.util.Objects;

View File

@ -1,6 +1,6 @@
package model.metadata; package metadata;
import model.ComponentType; import simulation.ComponentType;
import java.util.Objects; import java.util.Objects;

View File

@ -1,6 +1,6 @@
package model.metadata; package metadata;
import model.BuildingState; import simulation.BuildingState;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -13,6 +13,10 @@ public class WarehouseMetadata extends BuildingMetadata {
this.input = input; this.input = input;
} }
public WarehouseInput getInput() {
return input;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

View File

@ -1,14 +0,0 @@
package model;
public class Warehouse extends Building {
public Warehouse(int id, String type, int x, int y) {
super(id, type, x, y);
}
@Override
public void processInput(Component input) {
}
private void sellComponent() {
}
}

BIN
src/ressources/E0%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

BIN
src/ressources/E100%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

BIN
src/ressources/E33%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

BIN
src/ressources/E66%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

BIN
src/ressources/UA0%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

BIN
src/ressources/UA100%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

BIN
src/ressources/UA33%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

BIN
src/ressources/UA66%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

BIN
src/ressources/UM0%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

BIN
src/ressources/UM100%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

BIN
src/ressources/UM33%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

BIN
src/ressources/UM66%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

BIN
src/ressources/UMP0%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

BIN
src/ressources/UMP100%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

BIN
src/ressources/UMP33%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

BIN
src/ressources/UMP66%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

BIN
src/ressources/UT0%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

BIN
src/ressources/UT100%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

BIN
src/ressources/UT33%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

BIN
src/ressources/UT66%.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

BIN
src/ressources/aile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/ressources/avion.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<metadonnees>
<usine type="usine-matiere">
<icones>
<icone type="vide" path="src/ressources/UMP0%.png"/>
<icone type="un-tiers" path="src/ressources/UMP33%.png"/>
<icone type="deux-tiers" path="src/ressources/UMP66%.png"/>
<icone type="plein" path="src/ressources/UMP100%.png"/>
</icones>
<sortie type = "metal"/>
<interval-production>100</interval-production>
</usine>
<usine type="usine-aile">
<icones>
<icone type="vide" path="src/ressources/UT0%.png"/>
<icone type="un-tiers" path="src/ressources/UT33%.png"/>
<icone type="deux-tiers" path="src/ressources/UT66%.png"/>
<icone type="plein" path="src/ressources/UT100%.png"/>
</icones>
<entree type="metal" quantite="2"/>
<sortie type="aile"/>
<interval-production>50</interval-production>
</usine>
<usine type="usine-moteur">
<icones>
<icone type="vide" path="src/ressources/UM0%.png"/>
<icone type="un-tiers" path="src/ressources/UM33%.png"/>
<icone type="deux-tiers" path="src/ressources/UM66%.png"/>
<icone type="plein" path="src/ressources/UM100%.png"/>
</icones>
<entree type="metal" quantite="4"/>
<sortie type="moteur"/>
<interval-production>75</interval-production>
</usine>
<usine type="usine-assemblage">
<icones>
<icone type="vide" path="src/ressources/UA0%.png"/>
<icone type="un-tiers" path="src/ressources/UA33%.png"/>
<icone type="deux-tiers" path="src/ressources/UA66%.png"/>
<icone type="plein" path="src/ressources/UA100%.png"/>
</icones>
<entree type="aile" quantite="2"/>
<entree type="moteur" quantite="4"/>
<sortie type="avion"/>
<interval-production>110</interval-production>
</usine>
<usine type="entrepot">
<icones>
<icone type="vide" path="src/ressources/E0%.png"/>
<icone type="un-tiers" path="src/ressources/E33%.png"/>
<icone type="deux-tiers" path="src/ressources/E66%.png"/>
<icone type="plein" path="src/ressources/E100%.png"/>
</icones>
<entree type="avion" capacite="5"/>
</usine>
</metadonnees>
<simulation>
<usine type="usine-matiere" id="11" x="32" y="32"/>
<usine type="usine-aile" id="21" x="320" y="32"/>
<usine type="usine-assemblage" id="41" x="160" y="192"/>
<usine type="entrepot" id="51" x="640" y="192"/>
<usine type="usine-matiere" id="13" x="544" y="576"/>
<usine type="usine-matiere" id="12" x="96" y="352"/>
<usine type="usine-moteur" id="31" x="320" y="352"/>
<chemins>
<chemin de="11" vers="21" />
<chemin de="21" vers="41" />
<chemin de="41" vers="51" />
<chemin de="12" vers="31" />
<chemin de="13" vers="31" />
<chemin de="31" vers="41" />
</chemins>
</simulation>
</configuration>

BIN
src/ressources/metal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/ressources/moteur.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,11 +1,11 @@
package model; package simulation;
public abstract class Building { public abstract class Building {
private final int id; protected final int id;
private final String type; protected final String type;
private final int x; protected final int x;
private final int y; protected final int y;
private BuildingState state = BuildingState.EMPTY; protected BuildingState state = BuildingState.EMPTY;
protected Building(int id, String type, int x, int y) { protected Building(int id, String type, int x, int y) {
this.id = id; this.id = id;

View File

@ -1,4 +1,4 @@
package model; package simulation;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;

View File

@ -1,4 +1,4 @@
package model; package simulation;
import java.util.Objects; import java.util.Objects;

View File

@ -1,4 +1,4 @@
package model; package simulation;
public class ComponentRoute { public class ComponentRoute {
private final Building outputBuilding; private final Building outputBuilding;

View File

@ -1,4 +1,4 @@
package model; package simulation;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;

View File

@ -1,4 +1,4 @@
package model; package simulation;
public class Factory extends Building { public class Factory extends Building {
public Factory(int id, String type, int x, int y) { public Factory(int id, String type, int x, int y) {

View File

@ -1,4 +1,4 @@
package model; package simulation;
import java.util.Objects; import java.util.Objects;

View File

@ -0,0 +1,40 @@
package simulation;
import configuration.SimulationConfigurationSingleton;
import metadata.WarehouseMetadata;
import java.util.ArrayList;
import java.util.Collection;
public class Warehouse extends Building implements WarehouseSubject {
private final Collection<Component> planes = new ArrayList<>();
private final Collection<WarehouseObserver> observers = new ArrayList<>();
private final int capacity = ((WarehouseMetadata) SimulationConfigurationSingleton.getInstance()
.getConfiguration().getMetadata().get(getType()))
.getInput().getCapacity();
public Warehouse(int id, String type, int x, int y) {
super(id, type, x, y);
}
@Override
public void processInput(Component input) {
planes.add(input);
}
private void sellComponent() {
}
public void attach(WarehouseObserver observer) {
observers.add(observer);
}
public void dettach(WarehouseObserver observer) {
observers.remove(observer);
}
public void notifyObservers() {
boolean isFull = planes.size() >= capacity;
observers.forEach(o -> o.update(isFull));
}
}

View File

@ -0,0 +1,10 @@
package simulation;
public interface WarehouseObserver {
/**
* Méthode appelée lorsque l'état d'un entrepot change.
*
* @param full Si l'entrepot est plein ou non
*/
void update(boolean full);
}

View File

@ -0,0 +1,7 @@
package simulation;
public interface WarehouseSubject {
void attach(WarehouseObserver observer);
void dettach(WarehouseObserver observer);
void notifyObservers();
}

View File

@ -1,23 +1,88 @@
package view; package view;
import configuration.SimulationConfiguration;
import configuration.SimulationConfigurationSingleton;
import configuration.SimulationData;
import metadata.BuildingMetadata;
import simulation.Building;
import simulation.BuildingState;
import simulation.Route;
import javax.imageio.ImageIO;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.Serial; import java.io.Serial;
import java.util.HashMap;
import java.util.Map;
public class MainPanel extends JPanel { public class MainPanel extends JPanel {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Point position = new Point(0, 0); private final Map<String, Image> icons = new HashMap<>();
private Point speed = new Point(1, 1); private final Map<Integer, Building> buildingsById = new HashMap<>();
private int size = 32;
private SimulationConfiguration configuration;
private SimulationData simulationData;
public void reloadSimulation() {
configuration = SimulationConfigurationSingleton.getInstance().getConfiguration();
simulationData = configuration.getSimulationData();
buildingsById.clear();
simulationData.getBuildings().forEach(b -> buildingsById.put(b.getId(), b));
icons.clear();
configuration.getMetadata().values().forEach(m -> {
try {
loadImage(m);
} catch (IOException e) {
System.err.println("Could not load simulation icons");
}
});
}
@Override @Override
public void paint(Graphics g) { public void paint(Graphics g) {
super.paint(g); super.paint(g);
// On ajoute à la position le delta x et y de la vitesse // On ajoute à la position le delta x et y de la vitesse
position.translate(speed.x, speed.y); // position.translate(speed.x, speed.y);
g.fillRect(position.x, position.y, size, size); // g.fillRect(position.x, position.y, size, size);
if (configuration == null) return;
simulationData.getRoutes().forEach(r -> paintRoute(r, g));
simulationData.getBuildings().forEach(b -> paintBuilding(b, g));
}
private void paintBuilding(Building building, Graphics g) {
Image icon = icons.get(building.getType());
g.drawImage(icon, building.getX(), building.getY(), null);
}
private void paintRoute(Route route, Graphics g) {
Building fromBuilding = buildingsById.get(route.getFrom());
Image fromIcon = icons.get(fromBuilding.getType());
Building toBuilding = buildingsById.get(route.getTo());
Image toIcon = icons.get(toBuilding.getType());
g.drawLine(
fromBuilding.getX() + fromIcon.getWidth(null) / 2,
fromBuilding.getY() + fromIcon.getHeight(null) / 2,
toBuilding.getX() + toIcon.getWidth(null) / 2,
toBuilding.getY() + toIcon.getHeight(null) / 2
);
}
private void loadImage(BuildingMetadata metadata) throws IOException {
String iconPath = metadata.getIconsPaths().get(BuildingState.EMPTY);
BufferedImage image = ImageIO.read(new File(iconPath));
icons.put(metadata.getType(), image);
} }
} }

View File

@ -14,7 +14,7 @@ public class MainWindow extends JFrame implements PropertyChangeListener {
public MainWindow() { public MainWindow() {
MainPanel mainPanel = new MainPanel(); MainPanel mainPanel = new MainPanel();
WindowMenu menu = new WindowMenu(); WindowMenu menu = new WindowMenu(mainPanel);
add(mainPanel); add(mainPanel);
add(menu, BorderLayout.NORTH); add(menu, BorderLayout.NORTH);
@ -38,7 +38,7 @@ public class MainWindow extends JFrame implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent event) { public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals("TEST")) { if (event.getPropertyName().equals("TEST")) {
repaint(); repaint();
System.out.println(event.getNewValue()); // System.out.println(event.getNewValue());
} }
} }
} }

View File

@ -1,5 +1,7 @@
package view; package view;
import configuration.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileSystemView;
@ -18,7 +20,12 @@ public class WindowMenu extends JMenuBar {
private static final String MENU_HELP_TITLE = "Aide"; private static final String MENU_HELP_TITLE = "Aide";
private static final String MENU_HELP_ABOUT = "À propos de..."; private static final String MENU_HELP_ABOUT = "À propos de...";
public WindowMenu() { private final ConfigurationParser configParser = new XmlConfigurationParser();
private final MainPanel mainPanel;
public WindowMenu(MainPanel mainPanel) {
this.mainPanel = mainPanel;
addFileMenu(); addFileMenu();
addSimulationMenu(); addSimulationMenu();
addHelpMenu(); addHelpMenu();
@ -42,9 +49,17 @@ public class WindowMenu extends JMenuBar {
int returnValue = fileChooser.showOpenDialog(null); int returnValue = fileChooser.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) { if (returnValue == JFileChooser.APPROVE_OPTION) {
// TODO - Parser le fichier XML sélectionné
File selectedFile = fileChooser.getSelectedFile(); File selectedFile = fileChooser.getSelectedFile();
System.out.println(selectedFile.getAbsoluteFile());
try {
SimulationConfiguration configuration = configParser.parseConfiguration(selectedFile);
SimulationConfigurationSingleton.getInstance().setConfiguration(configuration);
mainPanel.reloadSimulation();
} catch (ConfigurationParsingException ex) {
// TODO WN: Handle exception
throw new RuntimeException("Failed to parse config file", ex);
}
} }
}); });
@ -85,7 +100,7 @@ public class WindowMenu extends JMenuBar {
aboutMenu.addActionListener((ActionEvent e) -> { aboutMenu.addActionListener((ActionEvent e) -> {
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
"<html><p>Application simulation une chaine de production d'avions.</p><br>" + "<html><p>Application de simulation une chaine de production d'avions.</p><br>" +
"<p>&copy; &nbsp; 2017 &nbsp; Ghizlane El Boussaidi</p>" + "<p>&copy; &nbsp; 2017 &nbsp; Ghizlane El Boussaidi</p>" +
"<p>&copy; &nbsp; 2017 &nbsp; Dany Boisvert</p>" + "<p>&copy; &nbsp; 2017 &nbsp; Dany Boisvert</p>" +
"<p>&copy; &nbsp; 2017 &nbsp; Vincent Mattard</p><br>" + "<p>&copy; &nbsp; 2017 &nbsp; Vincent Mattard</p><br>" +