Browse Source

No more duplicate Edges

TomTroppmann 2 years ago
parent
commit
5a2c2a4581

+ 2 - 10
src/holeg/api/TopologieAlgorithmFramework.java

@@ -10,15 +10,7 @@ import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.math.RoundingMode;
 import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
@@ -813,7 +805,7 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 	/**
 	 * All Nodes have to be in the access map !!
 	 */
-	private void addCables(List<Edge> edges) {
+	private void addCables(Set<Edge> edges) {
 		
 		for (Edge edge : edges) {
 			edge.mode = Edge.EdgeMode.Unlimited;

+ 3 - 1
src/holeg/model/Holon.java

@@ -140,7 +140,9 @@ public class Holon {
             break;
         }
 
-        log.info("energyToSupplyInTheNetwork: " + energyToSupplyInTheNetwork);
+        // STEP 3:
+        // If energy is still left, oversupply
+
         if (energyToSupplyInTheNetwork > 0.0f && (consumerList.size() != 0)) {
             float equalAmountOfEnergyToSupply = energyToSupplyInTheNetwork
                     / ((float) (consumerList.size()));

+ 4 - 16
src/holeg/ui/controller/CanvasController.java

@@ -2,6 +2,7 @@ package holeg.ui.controller;
 
 import java.awt.Point;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.stream.Collectors;
@@ -33,7 +34,6 @@ public class CanvasController {
 	 * 
 	 * @param model
 	 *            the Model
-	 * @param mp
 	 *            the MultipurposeController
 	 */
 	public CanvasController(Model model) {
@@ -132,7 +132,7 @@ public class CanvasController {
 	public void replaceObjectOnCanvas(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) {
 		
 		//Replace edges
-		ListIterator<Edge>  iter = model.getEdgesOnCanvas().listIterator();
+		Iterator<Edge> iter = model.getEdgesOnCanvas().iterator();
 		while(iter.hasNext() ) {
 			Edge edge = iter.next();
 			if(edge.getA() == toBeReplaced && edge.getB() != by) {
@@ -229,23 +229,11 @@ public class CanvasController {
 	 */
 	public void deleteAllObjectsInGroupNode(GroupNode node) {
 		List<AbstractCanvasObject> objectsInGroupNode = node.getAllObjectsRecursive().toList();
-		ListIterator<Edge>  iter = model.getEdgesOnCanvas().listIterator();
-		while(iter.hasNext() ) {
-			Edge edge = iter.next();
-			if(objectsInGroupNode.contains(edge.getA()) || objectsInGroupNode.contains(edge.getB())) {
-				iter.remove();
-			}
-		}
+		model.getEdgesOnCanvas().removeIf(edge -> objectsInGroupNode.contains(edge.getA()) || objectsInGroupNode.contains(edge.getB()));
 	}
 
 	public void removeAllConnectionsFromObject(AbstractCanvasObject obj) {
-		ListIterator<Edge>  iter = model.getEdgesOnCanvas().listIterator();
-		while(iter.hasNext() ) {
-			Edge edge = iter.next();
-			if(edge.getA() == obj || edge.getB() == obj) {
-				iter.remove();
-			}
-		}
+		model.getEdgesOnCanvas().removeIf(edge -> edge.getA() == obj || edge.getB() == obj);
 	}
 	
 }

+ 2 - 2
src/holeg/ui/controller/ClipboardController.java

@@ -68,7 +68,7 @@ public class ClipboardController {
 
             String key = "CVSOBJECT" + store.getNumerator(NUMTYPE.OBJECT);
             file.add(key, GuiSettings.gson.toJsonTree(u, AbstractCanvasObject.class));
-            edgeToJson(EDGETYPE.CONNECTION, file, u.getId(), new ArrayList<>());
+            edgeToJson(EDGETYPE.CONNECTION, file, u.getId(), new HashSet<>());
 
             if (u instanceof HolonObject)
                 store.elementsToJson(TYPE.CANVAS, file, u);
@@ -303,7 +303,7 @@ public class ClipboardController {
     /**
      * Modified Method from LoadController. Slightly different
      */
-    private void edgeToJson(EDGETYPE type, JsonObject file, int id, List<Edge> arr) {
+    private void edgeToJson(EDGETYPE type, JsonObject file, int id, Set<Edge> arr) {
         String k = null;
         boolean b = false;
         JsonObject temp = new JsonObject();

+ 569 - 582
src/holeg/ui/controller/Control.java

@@ -1,37 +1,24 @@
 package holeg.ui.controller;
 
-import java.awt.Point;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-
-import javax.swing.JFrame;
-
-import org.apache.commons.compress.archivers.ArchiveException;
-
 import com.google.gson.JsonParseException;
-
-import holeg.model.AbstractCanvasObject;
-import holeg.model.Edge;
-import holeg.model.GroupNode;
-import holeg.model.HolonElement;
-import holeg.model.HolonObject;
-import holeg.model.Node;
+import holeg.model.*;
 import holeg.ui.model.GuiSettings;
 import holeg.ui.model.Model;
 import holeg.ui.view.dialog.CreateTemplatePopUp;
 import holeg.ui.view.main.Category;
-import holeg.ui.view.main.GUI;
 import holeg.utility.events.Action;
 import holeg.utility.events.Event;
+import org.apache.commons.compress.archivers.ArchiveException;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.*;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
 
 /**
  * The Class represents the controller in the model, controller view Pattern.
@@ -39,562 +26,562 @@ import holeg.utility.events.Event;
  * @author Gruppe14
  */
 public class Control {
-	private static final Logger log = Logger.getLogger(Control.class.getName());
-	
-	
-	private final CategoryController categoryController;
-	private final CanvasController canvasController;
-	private final SaveController saveController;
-	private final LoadController loadController;
-	private final AutoSaveController autoSaveController;
-	private final NodeController nodeController;
-	private final ClipboardController clipboardController;
-	private Model model;
-
-	private SimulationManager simulationManager;
-	private String autosaveDir = "";
-	private String categoryDir = "";
-	private String otherDir = "";
-	private String dimensionsFileName = "dimensions";
-	private int rand;
-
-	public Event OnCategoryChanged = new Event();
-	public Event OnSelectionChanged = new Event();
-	public Event OnCanvasUpdate = new Event();
-	public Action<Boolean> OnGuiSetEnabled = new Action<>(); 
-
-	/**
-	 * Constructor.
-	 *
-	 * @param model the Model
-	 */
-	public Control(Model model) {
-		this.model = model;
-		this.categoryController = new CategoryController(this);
-		this.canvasController = new CanvasController(model);
-		this.saveController = new SaveController(model);
-		this.nodeController = new NodeController(model, canvasController);
-		this.loadController = new LoadController(model, categoryController, canvasController,
-				nodeController);
-		this.simulationManager = new SimulationManager(model);
-		this.autoSaveController = new AutoSaveController();
-		this.clipboardController = new ClipboardController(model, saveController, loadController, canvasController,
-				nodeController, this.simulationManager);
-
-		autosaveDir = System.getProperty("user.home") + "/.config/HolonGUI/Autosave/";
-		categoryDir = System.getProperty("user.home") + "/.config/HolonGUI/Category/";
-		otherDir = System.getProperty("user.home") + "/.config/HolonGUI/Other/";
-		File autoSave = new File(autosaveDir);
-		File category = new File(categoryDir);
-		File other = new File(otherDir);
-		// deleteDirectory(dest);
-		autoSave.mkdirs();
-		category.mkdirs();
-		other.mkdirs();
-		createAutoRandom();
-
-		tryAutoSave();
-	}
-
-	/**
-	 * Generate random number, so that every instance of the program has unique save
-	 * files
-	 */
-	private void createAutoRandom() {
-		rand = (int) (Math.random() * 1000);
-		while (new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
-			rand = (int) Math.random() * 1000;
-		}
-	}
-
-	/**
-	 * Delete a Directory.
-	 *
-	 * @param path to delete
-	 */
-	public void deleteDirectory(File path) {
-		if (path.exists()) {
-			File[] files = path.listFiles();
-			for (File file : files) {
-				if (file.isDirectory()) {
-					deleteDirectory(file);
-				} else {
-					if (file.getName().contains("" + rand))
-						file.delete();
-				}
-			}
-			// path.delete();
-		}
-	}
-
-
-
-
-	
-	
-	public Optional<Category> findCategoryWithName(String name){
-		return GuiSettings.getCategories().stream().filter(cat -> cat.getName().equals(name)).findAny();
-	}
-	
-	
-	/* Operations for Categories and Objects */
-
-	/**
-	 * init default category and objects.
-	 */
-	public void resetCategories() {
-		categoryController.clearCategories();
-		categoryController.initCategories();
-		saveCategory();
-
-	}
-
-	/**
-	 * Adds New Category into Model.
-	 *
-	 * @param cat name of the new Category
-	 * @throws IOException
-	 */
-	public void createCategoryWithName(String cat) {
-		categoryController.createCategoryWithName(cat);
-		saveCategory();
-	}
-
-	/**
-	 * Gives all Category as String
-	 * 
-	 * @return a array of strings from all Categorys
-	 */
-	public String[] getCategoriesStrings() {
-		return GuiSettings.getCategories().stream().map(c -> c.getName()).collect(Collectors.toList())
-				.toArray(new String[GuiSettings.getCategories().size()]);
-	}
-
-	/**
-	 * Add new Holon Object to a Category.
-	 *
-	 * @param cat  Category
-	 * @param obj  New Object Name
-	 * @param list Array of Elements
-	 * @param img  the image Path
-	 * @throws IOException
-	 */
-	public void addObject(Category cat, String obj, List<HolonElement> list, String img){
-		categoryController.addNewHolonObject(cat, obj, list, img);
-		saveCategory();
-	}
-
-	/**
-	 * Add new Holon Switch to a Category.
-	 *
-	 * @param cat Category
-	 * @param obj New Object Name
-	 * @throws IOException
-	 */
-	public void addSwitch(Category cat, String obj) {
-		categoryController.addNewHolonSwitch(cat, obj);
-		saveCategory();
-	}
-
-	public void deleteCategory(Category category) {
-		categoryController.removeCategory(category);
-		saveCategory();
-	}
-
-	/**
-	 * removes a selectedObject from selection.
-	 *
-	 */
-	public void removeObjectsFromSelection(Collection<AbstractCanvasObject> objects) {
-		if(GuiSettings.getSelectedObjects().removeAll(objects)){
-			OnSelectionChanged.broadcast();
-		}
-	}
-
-	/**
-	 * removes a selectedObject from selection.
-	 *
-	 * @param obj Cpsobject
-	 */
-	public void removeObjectFromSelection(AbstractCanvasObject obj) {
-		if(GuiSettings.getSelectedObjects().remove(obj)){
-			OnSelectionChanged.broadcast();
-		}
-	}
-
-	/**
-	 * add an Object to selectedObject.
-	 *
-	 * @param obj AbstractCpsobject
-	 */
-	public void addSelectedObject(AbstractCanvasObject obj) {
-		if(GuiSettings.getSelectedObjects().add(obj)){
-			OnSelectionChanged.broadcast();
-		}
-	}
-
-	public void addSelectedObjects(Collection<AbstractCanvasObject> objects) {
-		if(GuiSettings.getSelectedObjects().addAll(objects)){
-			OnSelectionChanged.broadcast();
-		}
-
-	}
-
-	public void clearSelection() {
-		if (!GuiSettings.getSelectedObjects().isEmpty()) {
-			GuiSettings.getSelectedObjects().clear();
-			OnSelectionChanged.broadcast();
-		}
-	}
-
-	/**
-	 * This method is primarily for the multi-selection. It adds unselected objects
-	 * to the selection and Removes selected objects from the selection. Like the
-	 * normal OS Desktop selection.
-	 * 
-	 * @param objects
-	 */
-	public void toggleSelectedObjects(Collection<AbstractCanvasObject> objects) {
-		Set<AbstractCanvasObject> intersection = new HashSet<>(objects);
-		intersection.retainAll(GuiSettings.getSelectedObjects());
-		GuiSettings.getSelectedObjects().addAll(objects);
-		GuiSettings.getSelectedObjects().removeAll(intersection);
-		OnSelectionChanged.broadcast();
-	}
-
-	/* Operations for Canvas */
-
-	/**
-	 * Add a new Object.
-	 *
-	 * @param object the Object
-	 */
-	public void addObjectCanvas(AbstractCanvasObject object) {
-		canvasController.addNewObject(object);
-		calculateStateAndVisualForTimeStep(model.getCurrentIteration());
-		if (!(object instanceof Node)) {
-			tryAutoSave();
-		}
-	}
-
-	/**
-	 * Deletes an CpsObject on the Canvas and its connections.
-	 *
-	 * @param obj  AbstractCpsObject
-	 * @param save
-	 */
-	public void delCanvasObject(AbstractCanvasObject obj, boolean save) {
-		canvasController.deleteObjectOnCanvas(obj);
-		if (obj instanceof GroupNode groupnode) {
-			canvasController.deleteAllObjectsInGroupNode(groupnode);
-		}
-		calculateStateAndVisualForCurrentTimeStep();
-		if (save) {
-			tryAutoSave();
-		}
-	}
-
-	public void delCanvasObjects(Collection<AbstractCanvasObject> objects) {
-		canvasController.deleteObjectsOnCanvas(objects);
-		calculateStateAndVisualForCurrentTimeStep();
-		tryAutoSave();
-	}
-
-	/**
-	 * Replaces {@code toBeReplaced} by {@code by} on the canvas
-	 * 
-	 * @param toBeReplaced the object that will be replaced
-	 * @param by           the object that will replace it
-	 */
-	public void replaceCanvasObject(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) {
-		canvasController.replaceObjectOnCanvas(toBeReplaced, by);
-		tryAutoSave();
-	}
-
-	/**
-	 * Add an edge to the Canvas.
-	 *
-	 * @param edge the edge
-	 */
-	public void addEdgeOnCanvas(Edge edge) {
-		canvasController.addEdgeOnCanvas(edge);
-		tryAutoSave();
-	}
-
-	/**
-	 * Removes an Edge from the Canvas.
-	 *
-	 * @param edge the edge to remove
-	 */
-	public void removeEdgesOnCanvas(Edge edge) {
-		canvasController.removeEdgesOnCanvas(edge);
-		tryAutoSave();
-	}
-
-
-	/**
-	 * Writes the current State of the Modelling into a JSON File which can be
-	 * loaded.
-	 *
-	 * @param path the Path
-	 * @throws IOException exception
-	 */
-	public void saveFile(String path) throws IOException, ArchiveException {
-		saveController.writeSave(path);
-	}
-
-	/**
-	 * Reads the the Save File and load the state into the Model.
-	 *
-	 * @param path the Path
-	 * @throws IOException      exception
-	 * @throws ArchiveException
-	 */
-	public void loadFile(String path) throws IOException, ArchiveException {
-		loadController.readSave(path);
-		saveCategory();
-		autoSave();
-	}
-
-	/**
-	 * Reads the Json File from Autosave
-	 *
-	 * @param path
-	 * @throws IOException
-	 */
-	public void loadAutoSave(String path) throws IOException {
-		loadController.readJson(path);
-	}
-
-	public ArrayList<Integer> loadSavedWindowDimensionsIfExistent() {
-		try {
-			return loadController.readWindowDimensions(otherDir + dimensionsFileName);
-		} catch (Exception e) {
-			return new ArrayList<>();
-		}
-	}
-
-	/**
-	 * calculates the flow of the edges and the supply for objects for the current
-	 * Timestep.
-	 */
-	public void calculateStateAndVisualForCurrentTimeStep() {
-		calculateStateAndVisualForTimeStep(model.getCurrentIteration());
-	}
-
-	public void calculateStateOnlyForCurrentTimeStep() {
-		simulationManager.calculateStateForTimeStep(model.getCurrentIteration());
-	}
-
-	/**
-	 * calculates the flow of the edges and the supply for objects.
-	 *
-	 * @param x current Iteration
-	 */
-	public void calculateStateAndVisualForTimeStep(int x) {
-		simulationManager.calculateStateForTimeStep(x);
-		OnCanvasUpdate.broadcast();
-	}
-
-	/**
-	 * resets the whole State of the simulation including a reset of all Edges to
-	 * the default "is working" state
-	 */
-	public void resetSimulation() {
-		model.reset();
-	}
-
-	/**
-	 * make an autosave.
-	 *
-	 * @throws IOException Exception
-	 */
-	private void autoSave() throws IOException {
-		autoSaveController.increaseAutoSaveNr();
-		saveController.writeAutosave(autosaveDir + rand + GuiSettings.autoSaveNr);
-		if (autoSaveController.allowed()) {
-			new File(autosaveDir + rand + (GuiSettings.autoSaveNr - GuiSettings.numberOfSaves)).delete();
-		}
-	}
-
-	public void tryAutoSave() {
-		try {
-			autoSave();
-		} catch (IOException e) {
-			log.warning(e.getStackTrace().toString());
-		}
-	}
-
-	/**
-	 * find all old auto save files (with a file-name, that does not contain the
-	 * current rand)
-	 *
-	 * @return a list of files, that are not from the current run
-	 */
-	public ArrayList<File> filterOldAutoSaveFiles() {
-		File[] files = new File(autosaveDir).listFiles();
-		ArrayList<File> oldAutoSaves = new ArrayList<>();
-
-		for (File file : files) {
-			if (!file.getName().contains(String.valueOf(rand)))
-				oldAutoSaves.add(file);
-		}
-
-		return oldAutoSaves;
-	}
-
-	/**
-	 * deletes the old autosave files
-	 */
-	public void deleteObsoleteAutoSaveFiles() {
-		for (File file : filterOldAutoSaveFiles()) {
-			file.delete();
-		}
-	}
-
-	public void saveCategory() {
-		try {
-			saveController.writeCategory(categoryDir + "Category.json");
-		} catch (IOException e) {
-		}
-	}
-
-	public void savePosAndSizeOfWindow(int x, int y, int width, int height) throws IOException, ArchiveException {
-		saveController.writeWindowStatus(otherDir + dimensionsFileName, x, y, width, height);
-	}
-
-	/**
-	 * Returns the undo save.
-	 *
-	 * @return the undo save
-	 */
-	public String getUndoSave() {
-		autoSaveController.decreaseAutoSaveNr();
-		if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
-			autoSaveController.increaseAutoSaveNr();
-		}
-		return autosaveDir + rand + (GuiSettings.autoSaveNr);
-	}
-
-	/**
-	 * Returns the redo save.
-	 *
-	 * @return the redo save
-	 */
-	public String getRedoSave() {
-		autoSaveController.increaseAutoSaveNr();
-		if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
-			autoSaveController.decreaseAutoSaveNr();
-
-			// if it still does not exist, try old autosaves
-			if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
-				ArrayList<File> oldAutoSaves = filterOldAutoSaveFiles();
-				if (oldAutoSaves.size() > 0) {
-					return autosaveDir + oldAutoSaves.get(oldAutoSaves.size() - 1).getName();
-				}
-			}
-		}
-		return autosaveDir + rand + (GuiSettings.autoSaveNr);
-	}
-
-	/**
-	 * Getter for Model.
-	 *
-	 * @return the Model
-	 */
-	public Model getModel() {
-		return model;
-	}
-
-	/**
-	 * get the Simulation Manager.
-	 *
-	 * @return the Simulation Manager
-	 */
-	public SimulationManager getSimManager() {
-		return simulationManager;
-	}
-
-	// ========================== MANAGING TRACKED OBJECTS END ================
-
-	/**
-	 * Controlling GroupNodes
-	 */
-
-	public void addGroupNode(String nodeName, GroupNode groupNode, List<AbstractCanvasObject> toGroup) {
-		nodeController.addGroupNode(nodeName, groupNode, toGroup);
-		tryAutoSave();
-	}
-
-	public void undoGroupNode(GroupNode node, GroupNode groupNode) {
-		nodeController.undoGroupNode(node, groupNode);
-		tryAutoSave();
-	}
-
-	public void addObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
-		nodeController.addObjectInGroupNode(object, groupNode, true);
-		tryAutoSave();
-	}
-
-	public void deleteObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
-		nodeController.deleteObjectInGroupNode(object, groupNode);
-		if (object instanceof GroupNode groupnode) {
-			canvasController.deleteAllObjectsInGroupNode(groupnode);			
-		}
-		tryAutoSave();
-	}
-
-	/**
-	 * Replaces {@code toBePlaced} by {@code by} in {@code upperNode}
-	 * 
-	 * @param toBeReplaced
-	 * @param by
-	 * @param upperNode
-	 */
-	public void replaceObjectInGroupNode(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by, GroupNode upperNode) {
-		nodeController.replaceObjectInUpperNode(toBeReplaced, by, upperNode);
-		tryAutoSave();
-	}
-
-	/**
-	 * Copy all Selected Objects.
-	 */
-	public void copy(GroupNode upperNode) {
-		clipboardController.copy(upperNode);
-	}
-
-	public void paste(GroupNode upperNode, Point point)
-			throws JsonParseException, UnsupportedFlavorException, IOException {
-		clipboardController.paste(upperNode, point);
-		OnSelectionChanged.broadcast();
-		tryAutoSave();
-	}
-
-	public void cut(GroupNode upperNode) {
-		clipboardController.cut(upperNode);
-		OnSelectionChanged.broadcast();
-		tryAutoSave();
-	}
-
-	/**
-	 * creates a new Template for the given cps Object
-	 * 
-	 * @param cps         Object, which should become a template
-	 * @param parentFrame
-	 */
-	public void createTemplate(HolonObject cps, JFrame parentFrame) {
-		CreateTemplatePopUp t = new CreateTemplatePopUp(cps, model, parentFrame, this);
-		t.setVisible(true);
-	}
-
-	public void getObjectsInDepth() {
-		clipboardController.getObjectsInDepth();
-	}
-
-
-	public void guiSetEnabled(boolean state) {
-		log.info("guiDisabled");
-		OnGuiSetEnabled.broadcast(state);
-	}
+    private static final Logger log = Logger.getLogger(Control.class.getName());
+
+
+    private final CategoryController categoryController;
+    private final CanvasController canvasController;
+    private final SaveController saveController;
+    private final LoadController loadController;
+    private final AutoSaveController autoSaveController;
+    private final NodeController nodeController;
+    private final ClipboardController clipboardController;
+    public Event OnCategoryChanged = new Event();
+    public Event OnSelectionChanged = new Event();
+    public Event OnCanvasUpdate = new Event();
+    public Action<Boolean> OnGuiSetEnabled = new Action<>();
+    private Model model;
+    private SimulationManager simulationManager;
+    private String autosaveDir = "";
+    private String categoryDir = "";
+    private String otherDir = "";
+    private String dimensionsFileName = "dimensions";
+    private int rand;
+
+    /**
+     * Constructor.
+     *
+     * @param model the Model
+     */
+    public Control(Model model) {
+        this.model = model;
+        this.categoryController = new CategoryController(this);
+        this.canvasController = new CanvasController(model);
+        this.saveController = new SaveController(model);
+        this.nodeController = new NodeController(model, canvasController);
+        this.loadController = new LoadController(model, categoryController, canvasController,
+                nodeController);
+        this.simulationManager = new SimulationManager(model);
+        this.autoSaveController = new AutoSaveController();
+        this.clipboardController = new ClipboardController(model, saveController, loadController, canvasController,
+                nodeController, this.simulationManager);
+
+        autosaveDir = System.getProperty("user.home") + "/.config/HolonGUI/Autosave/";
+        categoryDir = System.getProperty("user.home") + "/.config/HolonGUI/Category/";
+        otherDir = System.getProperty("user.home") + "/.config/HolonGUI/Other/";
+        File autoSave = new File(autosaveDir);
+        File category = new File(categoryDir);
+        File other = new File(otherDir);
+        // deleteDirectory(dest);
+        autoSave.mkdirs();
+        category.mkdirs();
+        other.mkdirs();
+        createAutoRandom();
+
+        tryAutoSave();
+    }
+
+    /**
+     * Generate random number, so that every instance of the program has unique save
+     * files
+     */
+    private void createAutoRandom() {
+        rand = (int) (Math.random() * 1000);
+        while (new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
+            rand = (int) Math.random() * 1000;
+        }
+    }
+
+    /**
+     * Delete a Directory.
+     *
+     * @param path to delete
+     */
+    public void deleteDirectory(File path) {
+        if (path.exists()) {
+            File[] files = path.listFiles();
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    deleteDirectory(file);
+                } else {
+                    if (file.getName().contains("" + rand))
+                        file.delete();
+                }
+            }
+            // path.delete();
+        }
+    }
+
+
+    public Optional<Category> findCategoryWithName(String name) {
+        return GuiSettings.getCategories().stream().filter(cat -> cat.getName().equals(name)).findAny();
+    }
+
+
+    /* Operations for Categories and Objects */
+
+    /**
+     * init default category and objects.
+     */
+    public void resetCategories() {
+        categoryController.clearCategories();
+        categoryController.initCategories();
+        saveCategory();
+
+    }
+
+    /**
+     * Adds New Category into Model.
+     *
+     * @param cat name of the new Category
+     * @throws IOException
+     */
+    public void createCategoryWithName(String cat) {
+        categoryController.createCategoryWithName(cat);
+        saveCategory();
+    }
+
+    /**
+     * Gives all Category as String
+     *
+     * @return a array of strings from all Categorys
+     */
+    public String[] getCategoriesStrings() {
+        return GuiSettings.getCategories().stream().map(c -> c.getName()).collect(Collectors.toList())
+                .toArray(new String[GuiSettings.getCategories().size()]);
+    }
+
+    /**
+     * Add new Holon Object to a Category.
+     *
+     * @param cat  Category
+     * @param obj  New Object Name
+     * @param list Array of Elements
+     * @param img  the image Path
+     * @throws IOException
+     */
+    public void addObject(Category cat, String obj, List<HolonElement> list, String img) {
+        categoryController.addNewHolonObject(cat, obj, list, img);
+        saveCategory();
+    }
+
+    /**
+     * Add new Holon Switch to a Category.
+     *
+     * @param cat Category
+     * @param obj New Object Name
+     * @throws IOException
+     */
+    public void addSwitch(Category cat, String obj) {
+        categoryController.addNewHolonSwitch(cat, obj);
+        saveCategory();
+    }
+
+    public void deleteCategory(Category category) {
+        categoryController.removeCategory(category);
+        saveCategory();
+    }
+
+    /**
+     * removes a selectedObject from selection.
+     */
+    public void removeObjectsFromSelection(Collection<AbstractCanvasObject> objects) {
+        if (GuiSettings.getSelectedObjects().removeAll(objects)) {
+            OnSelectionChanged.broadcast();
+        }
+    }
+
+    /**
+     * removes a selectedObject from selection.
+     *
+     * @param obj Cpsobject
+     */
+    public void removeObjectFromSelection(AbstractCanvasObject obj) {
+        if (GuiSettings.getSelectedObjects().remove(obj)) {
+            OnSelectionChanged.broadcast();
+        }
+    }
+
+    /**
+     * add an Object to selectedObject.
+     *
+     * @param obj AbstractCpsobject
+     */
+    public void addSelectedObject(AbstractCanvasObject obj) {
+        if (GuiSettings.getSelectedObjects().add(obj)) {
+            OnSelectionChanged.broadcast();
+        }
+    }
+
+    public void addSelectedObjects(Collection<AbstractCanvasObject> objects) {
+        if (GuiSettings.getSelectedObjects().addAll(objects)) {
+            OnSelectionChanged.broadcast();
+        }
+
+    }
+
+    public void clearSelection() {
+        if (!GuiSettings.getSelectedObjects().isEmpty()) {
+            GuiSettings.getSelectedObjects().clear();
+            OnSelectionChanged.broadcast();
+        }
+    }
+
+    /**
+     * This method is primarily for the multi-selection. It adds unselected objects
+     * to the selection and Removes selected objects from the selection. Like the
+     * normal OS Desktop selection.
+     *
+     * @param objects
+     */
+    public void toggleSelectedObjects(Collection<AbstractCanvasObject> objects) {
+        Set<AbstractCanvasObject> intersection = new HashSet<>(objects);
+        intersection.retainAll(GuiSettings.getSelectedObjects());
+        GuiSettings.getSelectedObjects().addAll(objects);
+        GuiSettings.getSelectedObjects().removeAll(intersection);
+        OnSelectionChanged.broadcast();
+    }
+
+    /* Operations for Canvas */
+
+    /**
+     * Add a new Object.
+     *
+     * @param object the Object
+     */
+    public void addObjectCanvas(AbstractCanvasObject object) {
+        canvasController.addNewObject(object);
+        calculateStateAndVisualForTimeStep(model.getCurrentIteration());
+        if (!(object instanceof Node)) {
+            tryAutoSave();
+        }
+    }
+
+    /**
+     * Deletes an CpsObject on the Canvas and its connections.
+     *
+     * @param obj  AbstractCpsObject
+     * @param save
+     */
+    public void delCanvasObject(AbstractCanvasObject obj, boolean save) {
+        canvasController.deleteObjectOnCanvas(obj);
+        if (obj instanceof GroupNode groupnode) {
+            canvasController.deleteAllObjectsInGroupNode(groupnode);
+        }
+        calculateStateAndVisualForCurrentTimeStep();
+        if (save) {
+            tryAutoSave();
+        }
+    }
+
+    public void delCanvasObjects(Collection<AbstractCanvasObject> objects) {
+        canvasController.deleteObjectsOnCanvas(objects);
+        calculateStateAndVisualForCurrentTimeStep();
+        tryAutoSave();
+    }
+
+    /**
+     * Replaces {@code toBeReplaced} by {@code by} on the canvas
+     *
+     * @param toBeReplaced the object that will be replaced
+     * @param by           the object that will replace it
+     */
+    public void replaceCanvasObject(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) {
+        canvasController.replaceObjectOnCanvas(toBeReplaced, by);
+        tryAutoSave();
+    }
+
+    /**
+     * Add an edge to the Canvas.
+     *
+     * @param edge the edge
+     */
+    public boolean addEdgeOnCanvas(Edge edge) {
+        boolean connectsItSelf = edge.getA() == edge.getB();
+        boolean connectionExist = model.getEdgesOnCanvas().stream().anyMatch(e -> (e.getA() == edge.getA() && e.getB() == edge.getB())
+				|| (e.getB() == edge.getA() && e.getA() == edge.getB()));
+        if (connectsItSelf || connectionExist) {
+            return false;
+        }
+        canvasController.addEdgeOnCanvas(edge);
+        tryAutoSave();
+        return true;
+    }
+
+    /**
+     * Removes an Edge from the Canvas.
+     *
+     * @param edge the edge to remove
+     */
+    public void removeEdgesOnCanvas(Edge edge) {
+        canvasController.removeEdgesOnCanvas(edge);
+        tryAutoSave();
+    }
+
+
+    /**
+     * Writes the current State of the Modelling into a JSON File which can be
+     * loaded.
+     *
+     * @param path the Path
+     * @throws IOException exception
+     */
+    public void saveFile(String path) throws IOException, ArchiveException {
+        saveController.writeSave(path);
+    }
+
+    /**
+     * Reads the the Save File and load the state into the Model.
+     *
+     * @param path the Path
+     * @throws IOException      exception
+     * @throws ArchiveException
+     */
+    public void loadFile(String path) throws IOException, ArchiveException {
+        loadController.readSave(path);
+        saveCategory();
+        autoSave();
+    }
+
+    /**
+     * Reads the Json File from Autosave
+     *
+     * @param path
+     * @throws IOException
+     */
+    public void loadAutoSave(String path) throws IOException {
+        loadController.readJson(path);
+    }
+
+    public ArrayList<Integer> loadSavedWindowDimensionsIfExistent() {
+        try {
+            return loadController.readWindowDimensions(otherDir + dimensionsFileName);
+        } catch (Exception e) {
+            return new ArrayList<>();
+        }
+    }
+
+    /**
+     * calculates the flow of the edges and the supply for objects for the current
+     * Timestep.
+     */
+    public void calculateStateAndVisualForCurrentTimeStep() {
+        calculateStateAndVisualForTimeStep(model.getCurrentIteration());
+    }
+
+    public void calculateStateOnlyForCurrentTimeStep() {
+        simulationManager.calculateStateForTimeStep(model.getCurrentIteration());
+    }
+
+    /**
+     * calculates the flow of the edges and the supply for objects.
+     *
+     * @param x current Iteration
+     */
+    public void calculateStateAndVisualForTimeStep(int x) {
+        simulationManager.calculateStateForTimeStep(x);
+        OnCanvasUpdate.broadcast();
+    }
+
+    /**
+     * resets the whole State of the simulation including a reset of all Edges to
+     * the default "is working" state
+     */
+    public void resetSimulation() {
+        model.reset();
+    }
+
+    /**
+     * make an autosave.
+     *
+     * @throws IOException Exception
+     */
+    private void autoSave() throws IOException {
+        autoSaveController.increaseAutoSaveNr();
+        saveController.writeAutosave(autosaveDir + rand + GuiSettings.autoSaveNr);
+        if (autoSaveController.allowed()) {
+            new File(autosaveDir + rand + (GuiSettings.autoSaveNr - GuiSettings.numberOfSaves)).delete();
+        }
+    }
+
+    public void tryAutoSave() {
+        try {
+            autoSave();
+        } catch (IOException e) {
+            log.warning(e.getStackTrace().toString());
+        }
+    }
+
+    /**
+     * find all old auto save files (with a file-name, that does not contain the
+     * current rand)
+     *
+     * @return a list of files, that are not from the current run
+     */
+    public ArrayList<File> filterOldAutoSaveFiles() {
+        File[] files = new File(autosaveDir).listFiles();
+        ArrayList<File> oldAutoSaves = new ArrayList<>();
+
+        for (File file : files) {
+            if (!file.getName().contains(String.valueOf(rand)))
+                oldAutoSaves.add(file);
+        }
+
+        return oldAutoSaves;
+    }
+
+    /**
+     * deletes the old autosave files
+     */
+    public void deleteObsoleteAutoSaveFiles() {
+        for (File file : filterOldAutoSaveFiles()) {
+            file.delete();
+        }
+    }
+
+    public void saveCategory() {
+        try {
+            saveController.writeCategory(categoryDir + "Category.json");
+        } catch (IOException e) {
+        }
+    }
+
+    public void savePosAndSizeOfWindow(int x, int y, int width, int height) throws IOException, ArchiveException {
+        saveController.writeWindowStatus(otherDir + dimensionsFileName, x, y, width, height);
+    }
+
+    /**
+     * Returns the undo save.
+     *
+     * @return the undo save
+     */
+    public String getUndoSave() {
+        autoSaveController.decreaseAutoSaveNr();
+        if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
+            autoSaveController.increaseAutoSaveNr();
+        }
+        return autosaveDir + rand + (GuiSettings.autoSaveNr);
+    }
+
+    /**
+     * Returns the redo save.
+     *
+     * @return the redo save
+     */
+    public String getRedoSave() {
+        autoSaveController.increaseAutoSaveNr();
+        if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
+            autoSaveController.decreaseAutoSaveNr();
+
+            // if it still does not exist, try old autosaves
+            if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
+                ArrayList<File> oldAutoSaves = filterOldAutoSaveFiles();
+                if (oldAutoSaves.size() > 0) {
+                    return autosaveDir + oldAutoSaves.get(oldAutoSaves.size() - 1).getName();
+                }
+            }
+        }
+        return autosaveDir + rand + (GuiSettings.autoSaveNr);
+    }
+
+    /**
+     * Getter for Model.
+     *
+     * @return the Model
+     */
+    public Model getModel() {
+        return model;
+    }
+
+    /**
+     * get the Simulation Manager.
+     *
+     * @return the Simulation Manager
+     */
+    public SimulationManager getSimManager() {
+        return simulationManager;
+    }
+
+    // ========================== MANAGING TRACKED OBJECTS END ================
+
+    /**
+     * Controlling GroupNodes
+     */
+
+    public void addGroupNode(String nodeName, GroupNode groupNode, List<AbstractCanvasObject> toGroup) {
+        nodeController.addGroupNode(nodeName, groupNode, toGroup);
+        tryAutoSave();
+    }
+
+    public void undoGroupNode(GroupNode node, GroupNode groupNode) {
+        nodeController.undoGroupNode(node, groupNode);
+        tryAutoSave();
+    }
+
+    public void addObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
+        nodeController.addObjectInGroupNode(object, groupNode, true);
+        tryAutoSave();
+    }
+
+    public void deleteObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
+        nodeController.deleteObjectInGroupNode(object, groupNode);
+        if (object instanceof GroupNode groupnode) {
+            canvasController.deleteAllObjectsInGroupNode(groupnode);
+        }
+        tryAutoSave();
+    }
+
+    /**
+     * Replaces {@code toBePlaced} by {@code by} in {@code upperNode}
+     *
+     * @param toBeReplaced
+     * @param by
+     * @param upperNode
+     */
+    public void replaceObjectInGroupNode(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by, GroupNode upperNode) {
+        nodeController.replaceObjectInUpperNode(toBeReplaced, by, upperNode);
+        tryAutoSave();
+    }
+
+    /**
+     * Copy all Selected Objects.
+     */
+    public void copy(GroupNode upperNode) {
+        clipboardController.copy(upperNode);
+    }
+
+    public void paste(GroupNode upperNode, Point point)
+            throws JsonParseException, UnsupportedFlavorException, IOException {
+        clipboardController.paste(upperNode, point);
+        OnSelectionChanged.broadcast();
+        tryAutoSave();
+    }
+
+    public void cut(GroupNode upperNode) {
+        clipboardController.cut(upperNode);
+        OnSelectionChanged.broadcast();
+        tryAutoSave();
+    }
+
+    /**
+     * creates a new Template for the given cps Object
+     *
+     * @param cps         Object, which should become a template
+     * @param parentFrame
+     */
+    public void createTemplate(HolonObject cps, JFrame parentFrame) {
+        CreateTemplatePopUp t = new CreateTemplatePopUp(cps, model, parentFrame, this);
+        t.setVisible(true);
+    }
+
+    public void getObjectsInDepth() {
+        clipboardController.getObjectsInDepth();
+    }
+
+
+    public void guiSetEnabled(boolean state) {
+        log.info("guiDisabled");
+        OnGuiSetEnabled.broadcast(state);
+    }
 
 }

+ 1 - 1
src/holeg/ui/controller/LoadController.java

@@ -186,7 +186,7 @@ public class LoadController {
         switch (MODE.valueOf(json.get("MODE").getAsString())) {
             case COMPLETE:
             case PARTIAL:
-                model.setEdgesOnCanvas(new ArrayList<>());
+                model.getEdgesOnCanvas().clear();
                 GuiSettings.canvasSize.setX(json.get("CANVAS_SIZE_X").getAsInt());
                 GuiSettings.canvasSize.setY(json.get("CANVAS_SIZE_Y").getAsInt());
                 IdCounter.setCounter(json.get("IDCOUNTER").getAsInt(), CounterType.Object);

+ 3 - 7
src/holeg/ui/controller/SaveController.java

@@ -25,11 +25,7 @@ import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
 
 /**
  * Controller for Storage.
@@ -210,7 +206,7 @@ public class SaveController {
             String key = "CVSOBJECT" + getNumerator(NUMTYPE.OBJECT);
             file.add(key, GuiSettings.gson.toJsonTree(u, AbstractCanvasObject.class));
             // and its connections too
-            edgeToJson(EDGETYPE.CONNECTION, file, u.getId(), new ArrayList<>());
+            edgeToJson(EDGETYPE.CONNECTION, file, u.getId(), new HashSet<>());
             // if holonobject elements too
             if (u instanceof HolonObject)
                 elementsToJson(TYPE.CANVAS, file, u);
@@ -321,7 +317,7 @@ public class SaveController {
     /**
      * Canvas-Edge, Connections, Node-Edge and Old-Edges to json
      */
-    private void edgeToJson(EDGETYPE type, JsonObject file, int id, List<Edge> arr) {
+    private void edgeToJson(EDGETYPE type, JsonObject file, int id, Set<Edge> arr) {
         String k = null;
         boolean b = false;
         JsonObject temp = new JsonObject();

+ 2 - 10
src/holeg/ui/model/Model.java

@@ -49,7 +49,7 @@ public class Model {
      * Array of all CpsObjects in our canvas. It is set by default as an empty
      * list.
      */
-    private List<Edge> edgesOnCanvas = new ArrayList<>();
+    private Set<Edge> edgesOnCanvas = new HashSet<>();
    
     public Model() {
     	log.fine("Init Model");
@@ -70,18 +70,10 @@ public class Model {
      *
      * @return the edgesOnCanvas
      */
-    public List<Edge> getEdgesOnCanvas() {
+    public Set<Edge> getEdgesOnCanvas() {
         return edgesOnCanvas;
     }
 
-    /**
-     * Sets the edges on the Canvas.
-     *
-     * @param arrayList the edgesOnCanvas to set
-     */
-    public void setEdgesOnCanvas(ArrayList<Edge> arrayList) {
-        this.edgesOnCanvas = arrayList;
-    }
 
     /**
      * Adds an Edge to The Canvas.

+ 7 - 2
src/holeg/ui/view/canvas/Canvas.java

@@ -179,13 +179,18 @@ public class Canvas extends JPanel {
                     }
                 }
                 case EdgeCreation -> {
-                    getObjectAtPosition(lastPosition).ifPresentOrElse(obj -> control.addEdgeOnCanvas(new Edge(selectedOnPressed, obj, GuiSettings.maxCapacityForNewCreatedEdges)), () -> {
+                    getObjectAtPosition(lastPosition).ifPresentOrElse(obj -> {
+                            if(control.addEdgeOnCanvas(new Edge(selectedOnPressed, obj, GuiSettings.maxCapacityForNewCreatedEdges))){
+                                control.calculateStateAndVisualForCurrentTimeStep();
+                            }
+                    }, () -> {
                         Node node = new Node("Node");
                         groupNode.add(node);
                         node.setPosition(new Vec2i(lastPosition));
                         control.addEdgeOnCanvas(new Edge(selectedOnPressed, node, GuiSettings.maxCapacityForNewCreatedEdges));
+                        control.calculateStateAndVisualForCurrentTimeStep();
                     });
-                    control.calculateStateAndVisualForCurrentTimeStep();
+
                 }
             }
             state = State.None;