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);
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
inputsCount.put(input.getType(), inputCount);
|
||||
|
||||
if (hasEnoughComponents()) {
|
||||
startProduction();
|
||||
}
|
||||
}
|
||||
|
||||
private void buildComponent() {
|
||||
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;
|
||||
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
String iconPath = metadata.getIconsPaths().get(BuildingState.EMPTY);
|
||||
BufferedImage image = ImageIO.read(new File(iconPath));
|
||||
private void paintComponentRoute(ComponentRoute route, Graphics g) {
|
||||
ComponentType componentType = route.getComponent().getType();
|
||||
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
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
if (event.getPropertyName().equals("TEST")) {
|
||||
if (event.getPropertyName().equals(Environment.TICK_PROPERTY_NAME)) {
|
||||
repaint();
|
||||
// System.out.println(event.getNewValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue