Start dynamic network
This commit is contained in:
parent
be21c33755
commit
9445638440
|
@ -41,7 +41,7 @@ public class XmlConfigurationParser implements ConfigurationParser {
|
||||||
Document document = parseDocument(file);
|
Document document = parseDocument(file);
|
||||||
|
|
||||||
Map<String, BuildingMetadata> buildingsMetadata = parseBuildingsMetadata(document);
|
Map<String, BuildingMetadata> buildingsMetadata = parseBuildingsMetadata(document);
|
||||||
SimulationData simulationData = parseSimulationData(document);
|
SimulationData simulationData = parseSimulationData(document, buildingsMetadata);
|
||||||
|
|
||||||
return new SimulationConfiguration(buildingsMetadata, simulationData);
|
return new SimulationConfiguration(buildingsMetadata, simulationData);
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ public class XmlConfigurationParser implements ConfigurationParser {
|
||||||
return new FactoryOutput(type);
|
return new FactoryOutput(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SimulationData parseSimulationData(Document document) {
|
private SimulationData parseSimulationData(Document document, Map<String, BuildingMetadata> buildingMetadata) {
|
||||||
Node dataNode = document.getElementsByTagName(TAG_SIMULATION_DATA).item(0);
|
Node dataNode = document.getElementsByTagName(TAG_SIMULATION_DATA).item(0);
|
||||||
|
|
||||||
Collection<Building> buildings = new ArrayList<>();
|
Collection<Building> buildings = new ArrayList<>();
|
||||||
|
@ -157,7 +157,7 @@ public class XmlConfigurationParser implements ConfigurationParser {
|
||||||
|
|
||||||
for (Element elem : new IterableElementList(dataNode.getChildNodes())) {
|
for (Element elem : new IterableElementList(dataNode.getChildNodes())) {
|
||||||
switch (elem.getNodeName()) {
|
switch (elem.getNodeName()) {
|
||||||
case TAG_BUILDING -> buildings.add(parseBuilding(elem));
|
case TAG_BUILDING -> buildings.add(parseBuilding(elem, buildingMetadata));
|
||||||
case TAG_ROUTES -> routes = parseRoutes(elem);
|
case TAG_ROUTES -> routes = parseRoutes(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,15 +165,17 @@ public class XmlConfigurationParser implements ConfigurationParser {
|
||||||
return new SimulationData(buildings, routes);
|
return new SimulationData(buildings, routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Building parseBuilding(Element buildingElement) {
|
private Building parseBuilding(Element buildingElement, Map<String, BuildingMetadata> buildingMetadata) {
|
||||||
String type = buildingElement.getAttribute(ATTRIBUTE_TYPE);
|
String type = buildingElement.getAttribute(ATTRIBUTE_TYPE);
|
||||||
int id = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_ID));
|
int id = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_ID));
|
||||||
int x = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_X));
|
int x = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_X));
|
||||||
int y = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_Y));
|
int y = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_Y));
|
||||||
|
|
||||||
|
BuildingMetadata metadata = buildingMetadata.get(type);
|
||||||
|
|
||||||
return type.equals(BuildingMetadata.TYPE_WAREHOUSE) ?
|
return type.equals(BuildingMetadata.TYPE_WAREHOUSE) ?
|
||||||
new Warehouse(id, type, x, y) :
|
new Warehouse(id, type, x, y, (WarehouseMetadata) metadata) :
|
||||||
new Factory(id, type, x, y);
|
new Factory(id, type, x, y, (FactoryMetadata) metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<Route> parseRoutes(Element routesElement) {
|
private Collection<Route> parseRoutes(Element routesElement) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package simulation;
|
package simulation;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public abstract class Building {
|
public abstract class Building {
|
||||||
protected final int id;
|
protected final int id;
|
||||||
protected final String type;
|
protected final String type;
|
||||||
|
@ -15,6 +17,7 @@ public abstract class Building {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void processInput(Component input);
|
public abstract void processInput(Component input);
|
||||||
|
public abstract Optional<Component> update();
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -2,8 +2,6 @@ package simulation;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
// TODO WN: Check if we can use records
|
|
||||||
|
|
||||||
public class Component {
|
public class Component {
|
||||||
private final ComponentType type;
|
private final ComponentType type;
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,31 @@
|
||||||
package simulation;
|
package simulation;
|
||||||
|
|
||||||
public class ComponentRoute {
|
public class ComponentRoute {
|
||||||
|
private final Component component;
|
||||||
private final Building outputBuilding;
|
private final Building outputBuilding;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
|
||||||
public ComponentRoute(Building outputBuilding) {
|
public ComponentRoute(Component component, Building outputBuilding, int x, int y) {
|
||||||
|
this.component = component;
|
||||||
this.outputBuilding = outputBuilding;
|
this.outputBuilding = outputBuilding;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendComponent(Component component) {
|
public Component getComponent() {
|
||||||
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void outputComponent(Component component) {
|
public Building getOutputBuilding() {
|
||||||
outputBuilding.processInput(component);
|
return outputBuilding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,70 @@
|
||||||
package simulation;
|
package simulation;
|
||||||
|
|
||||||
|
import metadata.FactoryInput;
|
||||||
|
import metadata.FactoryMetadata;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class Factory extends Building {
|
public class Factory extends Building {
|
||||||
public Factory(int id, String type, int x, int y) {
|
private final FactoryMetadata metadata;
|
||||||
|
private final Map<ComponentType, Integer> inputsCount = new HashMap<>();
|
||||||
|
|
||||||
|
private boolean isProductionStarted = false;
|
||||||
|
private long productionTicks = 0L;
|
||||||
|
|
||||||
|
public Factory(int id, String type, int x, int y, FactoryMetadata metadata) {
|
||||||
super(id, type, x, y);
|
super(id, type, x, y);
|
||||||
|
this.metadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Component> update() {
|
||||||
|
if (!isProductionStarted) return Optional.empty();
|
||||||
|
|
||||||
|
productionTicks++;
|
||||||
|
|
||||||
|
if (metadata.getProductionInterval() < productionTicks) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
isProductionStarted = false;
|
||||||
|
Component newComponent = new Component(metadata.getOutput().getType());
|
||||||
|
return Optional.of(newComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO WN: Move logic outside model
|
|
||||||
@Override
|
@Override
|
||||||
public void processInput(Component input) {
|
public void processInput(Component input) {
|
||||||
|
int inputCount = 0;
|
||||||
|
if (inputsCount.containsKey(input.getType())) {
|
||||||
|
inputCount = inputsCount.get(input.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildComponent() {
|
inputsCount.put(input.getType(), inputCount);
|
||||||
|
|
||||||
|
if (hasEnoughComponents()) {
|
||||||
|
startProduction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasEnoughComponents() {
|
||||||
|
for (FactoryInput input : metadata.getInputs()) {
|
||||||
|
if (!inputsCount.containsKey(input.getType()) || inputsCount.get(input.getType()) < input.getQuantity()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startProduction() {
|
||||||
|
for (FactoryInput input : metadata.getInputs()) {
|
||||||
|
int inputCount = inputsCount.get(input.getType());
|
||||||
|
inputsCount.put(input.getType(), inputCount - input.getQuantity());
|
||||||
|
}
|
||||||
|
|
||||||
|
isProductionStarted = true;
|
||||||
|
productionTicks = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,17 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public class Warehouse extends Building implements WarehouseSubject {
|
public class Warehouse extends Building implements WarehouseSubject {
|
||||||
|
private final WarehouseMetadata metadata;
|
||||||
private final Collection<Component> planes = new ArrayList<>();
|
private final Collection<Component> planes = new ArrayList<>();
|
||||||
private final Collection<WarehouseObserver> observers = new ArrayList<>();
|
private final Collection<WarehouseObserver> observers = new ArrayList<>();
|
||||||
|
|
||||||
public Warehouse(int id, String type, int x, int y) {
|
public Warehouse(int id, String type, int x, int y, WarehouseMetadata metadata) {
|
||||||
super(id, type, x, y);
|
super(id, type, x, y);
|
||||||
|
this.metadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,15 +4,17 @@ import javax.swing.*;
|
||||||
|
|
||||||
public class Environment extends SwingWorker<Object, String> {
|
public class Environment extends SwingWorker<Object, String> {
|
||||||
private static final int DELAY = 100;
|
private static final int DELAY = 100;
|
||||||
|
public static final String TICK_PROPERTY_NAME = "tick";
|
||||||
|
|
||||||
private boolean active = true;
|
private boolean active = true;
|
||||||
|
private long tick = 0L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object doInBackground() throws Exception {
|
protected Object doInBackground() throws Exception {
|
||||||
while (active) {
|
while (active) {
|
||||||
Thread.sleep(DELAY);
|
Thread.sleep(DELAY);
|
||||||
|
|
||||||
firePropertyChange("TEST", null, "Ceci est un test");
|
firePropertyChange(TICK_PROPERTY_NAME, tick, ++tick);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,30 +4,40 @@ import configuration.SimulationConfiguration;
|
||||||
import configuration.SimulationConfigurationSingleton;
|
import configuration.SimulationConfigurationSingleton;
|
||||||
import configuration.SimulationData;
|
import configuration.SimulationData;
|
||||||
import metadata.BuildingMetadata;
|
import metadata.BuildingMetadata;
|
||||||
import simulation.Building;
|
import simulation.*;
|
||||||
import simulation.BuildingState;
|
import simulation.Component;
|
||||||
import simulation.Route;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
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 final Map<String, Image> icons = new HashMap<>();
|
private final Map<String, Image> buildingIcons = new HashMap<>();
|
||||||
|
private final Map<ComponentType, Image> componentsIcons = new HashMap<>();
|
||||||
private final Map<Integer, Building> buildingsById = new HashMap<>();
|
private final Map<Integer, Building> buildingsById = new HashMap<>();
|
||||||
|
private final Collection<ComponentRoute> componentRoutes = new ArrayList<>();
|
||||||
|
|
||||||
private SimulationConfiguration configuration;
|
private SimulationConfiguration configuration;
|
||||||
private SimulationData simulationData;
|
private SimulationData simulationData;
|
||||||
|
|
||||||
|
public MainPanel() {
|
||||||
|
try {
|
||||||
|
componentsIcons.put(ComponentType.METAL, loadImage("src/ressources/metal.png"));
|
||||||
|
componentsIcons.put(ComponentType.MOTOR, loadImage("src/ressources/moteur.png"));
|
||||||
|
componentsIcons.put(ComponentType.PLANE, loadImage("src/ressources/avion.png"));
|
||||||
|
componentsIcons.put(ComponentType.WING, loadImage("src/ressources/aile.png"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Could not load components icons", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void reloadSimulation() {
|
public void reloadSimulation() {
|
||||||
configuration = SimulationConfigurationSingleton.getInstance().getConfiguration();
|
configuration = SimulationConfigurationSingleton.getInstance().getConfiguration();
|
||||||
simulationData = configuration.getSimulationData();
|
simulationData = configuration.getSimulationData();
|
||||||
|
@ -35,16 +45,20 @@ public class MainPanel extends JPanel {
|
||||||
buildingsById.clear();
|
buildingsById.clear();
|
||||||
simulationData.getBuildings().forEach(b -> buildingsById.put(b.getId(), b));
|
simulationData.getBuildings().forEach(b -> buildingsById.put(b.getId(), b));
|
||||||
|
|
||||||
icons.clear();
|
buildingIcons.clear();
|
||||||
configuration.getMetadata().values().forEach(m -> {
|
configuration.getMetadata().values().forEach(m -> {
|
||||||
try {
|
try {
|
||||||
loadImage(m);
|
loadBuildingImage(m);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.err.println("Could not load simulation icons");
|
System.err.println("Could not load simulation icons");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final float componentSpeed = 1f;
|
||||||
|
private int componentX = 0;
|
||||||
|
private int componentY = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint(Graphics g) {
|
public void paint(Graphics g) {
|
||||||
super.paint(g);
|
super.paint(g);
|
||||||
|
@ -57,32 +71,55 @@ public class MainPanel extends JPanel {
|
||||||
|
|
||||||
simulationData.getRoutes().forEach(r -> paintRoute(r, g));
|
simulationData.getRoutes().forEach(r -> paintRoute(r, g));
|
||||||
simulationData.getBuildings().forEach(b -> paintBuilding(b, g));
|
simulationData.getBuildings().forEach(b -> paintBuilding(b, g));
|
||||||
|
|
||||||
|
Image image = componentsIcons.get(ComponentType.METAL);
|
||||||
|
g.drawImage(image, componentX, componentY, null);
|
||||||
|
|
||||||
|
componentX += 1 * componentSpeed;
|
||||||
|
componentY += 1 * componentSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void paintBuilding(Building building, Graphics g) {
|
private void paintBuilding(Building building, Graphics g) {
|
||||||
Image icon = icons.get(building.getType());
|
building.update().ifPresent(component -> addComponentRoute(component, building.getId()));
|
||||||
|
|
||||||
|
Image icon = buildingIcons.get(building.getType());
|
||||||
g.drawImage(icon, building.getX(), building.getY(), null);
|
g.drawImage(icon, building.getX(), building.getY(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addComponentRoute(Component component, Building fromBuilding) {
|
||||||
|
Route route = simulationData.getRoutes().stream()
|
||||||
|
.filter(r -> r.getFrom() == fromBuilding.getId())
|
||||||
|
.findFirst().get();
|
||||||
|
|
||||||
|
Building toBuilding = buildingsById.get(route.getTo());
|
||||||
|
componentRoutes.add(new ComponentRoute(component, toBuilding, fromBuilding.getX(), fromBuilding.getY()));
|
||||||
|
}
|
||||||
|
|
||||||
private void paintRoute(Route route, Graphics g) {
|
private void paintRoute(Route route, Graphics g) {
|
||||||
Building fromBuilding = buildingsById.get(route.getFrom());
|
Building fromBuilding = buildingsById.get(route.getFrom());
|
||||||
Image fromIcon = icons.get(fromBuilding.getType());
|
Image fromIcon = buildingIcons.get(fromBuilding.getType());
|
||||||
|
|
||||||
Building toBuilding = buildingsById.get(route.getTo());
|
Building toBuilding = buildingsById.get(route.getTo());
|
||||||
Image toIcon = icons.get(toBuilding.getType());
|
Image toIcon = buildingIcons.get(toBuilding.getType());
|
||||||
|
|
||||||
g.drawLine(
|
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);
|
||||||
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 {
|
private void paintComponentRoute(ComponentRoute route, Graphics g) {
|
||||||
String iconPath = metadata.getIconsPaths().get(BuildingState.EMPTY);
|
ComponentType componentType = route.getComponent().getType();
|
||||||
BufferedImage image = ImageIO.read(new File(iconPath));
|
Image componentIcon = componentsIcons.get(componentType);
|
||||||
|
|
||||||
icons.put(metadata.getType(), image);
|
Vector
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadBuildingImage(BuildingMetadata metadata) throws IOException {
|
||||||
|
String iconPath = metadata.getIconsPaths().get(BuildingState.EMPTY);
|
||||||
|
Image image = loadImage(iconPath);
|
||||||
|
|
||||||
|
buildingIcons.put(metadata.getType(), image);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image loadImage(String path) throws IOException {
|
||||||
|
return ImageIO.read(new File(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,8 @@ public class MainWindow extends JFrame implements PropertyChangeListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent event) {
|
public void propertyChange(PropertyChangeEvent event) {
|
||||||
if (event.getPropertyName().equals("TEST")) {
|
if (event.getPropertyName().equals(Environment.TICK_PROPERTY_NAME)) {
|
||||||
repaint();
|
repaint();
|
||||||
// System.out.println(event.getNewValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue