Start dynamic network

This commit is contained in:
william 2022-06-12 20:28:04 -04:00
parent be21c33755
commit 9445638440
9 changed files with 158 additions and 41 deletions

View File

@ -41,7 +41,7 @@ public class XmlConfigurationParser implements ConfigurationParser {
Document document = parseDocument(file);
Map<String, BuildingMetadata> buildingsMetadata = parseBuildingsMetadata(document);
SimulationData simulationData = parseSimulationData(document);
SimulationData simulationData = parseSimulationData(document, buildingsMetadata);
return new SimulationConfiguration(buildingsMetadata, simulationData);
}
@ -149,7 +149,7 @@ public class XmlConfigurationParser implements ConfigurationParser {
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);
Collection<Building> buildings = new ArrayList<>();
@ -157,7 +157,7 @@ public class XmlConfigurationParser implements ConfigurationParser {
for (Element elem : new IterableElementList(dataNode.getChildNodes())) {
switch (elem.getNodeName()) {
case TAG_BUILDING -> buildings.add(parseBuilding(elem));
case TAG_BUILDING -> buildings.add(parseBuilding(elem, buildingMetadata));
case TAG_ROUTES -> routes = parseRoutes(elem);
}
}
@ -165,15 +165,17 @@ public class XmlConfigurationParser implements ConfigurationParser {
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);
int id = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_ID));
int x = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_X));
int y = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_Y));
BuildingMetadata metadata = buildingMetadata.get(type);
return type.equals(BuildingMetadata.TYPE_WAREHOUSE) ?
new Warehouse(id, type, x, y) :
new Factory(id, type, x, y);
new Warehouse(id, type, x, y, (WarehouseMetadata) metadata) :
new Factory(id, type, x, y, (FactoryMetadata) metadata);
}
private Collection<Route> parseRoutes(Element routesElement) {

View File

@ -1,5 +1,7 @@
package simulation;
import java.util.Optional;
public abstract class Building {
protected final int id;
protected final String type;
@ -15,6 +17,7 @@ public abstract class Building {
}
public abstract void processInput(Component input);
public abstract Optional<Component> update();
public int getId() {
return id;

View File

@ -2,8 +2,6 @@ package simulation;
import java.util.Objects;
// TODO WN: Check if we can use records
public class Component {
private final ComponentType type;

View File

@ -1,16 +1,31 @@
package simulation;
public class ComponentRoute {
private final Component component;
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.x = x;
this.y = y;
}
public void sendComponent(Component component) {
public Component getComponent() {
return component;
}
private void outputComponent(Component component) {
outputBuilding.processInput(component);
public Building getOutputBuilding() {
return outputBuilding;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}

View File

@ -1,15 +1,70 @@
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 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);
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
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;
}
}

View File

@ -9,11 +9,17 @@ import java.util.ArrayList;
import java.util.Collection;
public class Warehouse extends Building implements WarehouseSubject {
private final WarehouseMetadata metadata;
private final Collection<Component> planes = 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);
this.metadata = metadata;
}
@Override
public void update() {
}
@Override

View File

@ -4,15 +4,17 @@ import javax.swing.*;
public class Environment extends SwingWorker<Object, String> {
private static final int DELAY = 100;
public static final String TICK_PROPERTY_NAME = "tick";
private boolean active = true;
private long tick = 0L;
@Override
protected Object doInBackground() throws Exception {
while (active) {
Thread.sleep(DELAY);
firePropertyChange("TEST", null, "Ceci est un test");
firePropertyChange(TICK_PROPERTY_NAME, tick, ++tick);
}
return null;
}

View File

@ -4,30 +4,40 @@ import configuration.SimulationConfiguration;
import configuration.SimulationConfigurationSingleton;
import configuration.SimulationData;
import metadata.BuildingMetadata;
import simulation.Building;
import simulation.BuildingState;
import simulation.Route;
import simulation.*;
import simulation.Component;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.Serial;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
public class MainPanel extends JPanel {
@Serial
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 Collection<ComponentRoute> componentRoutes = new ArrayList<>();
private SimulationConfiguration configuration;
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() {
configuration = SimulationConfigurationSingleton.getInstance().getConfiguration();
simulationData = configuration.getSimulationData();
@ -35,16 +45,20 @@ public class MainPanel extends JPanel {
buildingsById.clear();
simulationData.getBuildings().forEach(b -> buildingsById.put(b.getId(), b));
icons.clear();
buildingIcons.clear();
configuration.getMetadata().values().forEach(m -> {
try {
loadImage(m);
loadBuildingImage(m);
} catch (IOException e) {
System.err.println("Could not load simulation icons");
}
});
}
private final float componentSpeed = 1f;
private int componentX = 0;
private int componentY = 0;
@Override
public void paint(Graphics g) {
super.paint(g);
@ -57,32 +71,55 @@ public class MainPanel extends JPanel {
simulationData.getRoutes().forEach(r -> paintRoute(r, 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) {
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);
}
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) {
Building fromBuilding = buildingsById.get(route.getFrom());
Image fromIcon = icons.get(fromBuilding.getType());
Image fromIcon = buildingIcons.get(fromBuilding.getType());
Building toBuilding = buildingsById.get(route.getTo());
Image toIcon = icons.get(toBuilding.getType());
Image toIcon = buildingIcons.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
);
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 {
private void paintComponentRoute(ComponentRoute route, Graphics g) {
ComponentType componentType = route.getComponent().getType();
Image componentIcon = componentsIcons.get(componentType);
Vector
}
private void loadBuildingImage(BuildingMetadata metadata) throws IOException {
String iconPath = metadata.getIconsPaths().get(BuildingState.EMPTY);
BufferedImage image = ImageIO.read(new File(iconPath));
Image image = loadImage(iconPath);
icons.put(metadata.getType(), image);
buildingIcons.put(metadata.getType(), image);
}
private Image loadImage(String path) throws IOException {
return ImageIO.read(new File(path));
}
}

View File

@ -36,9 +36,8 @@ public class MainWindow extends JFrame implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals("TEST")) {
if (event.getPropertyName().equals(Environment.TICK_PROPERTY_NAME)) {
repaint();
// System.out.println(event.getNewValue());
}
}
}