diff --git a/AMOEBAonAMAK/src/agents/AmoebaAgent.java b/AMOEBAonAMAK/src/agents/AmoebaAgent.java index 45a2c6c1ba8e1985d2d4a11c0c2075cfeff62fb5..8ae90bc81b63ebea93836dfe2a4d0c0d07bab4fc 100644 --- a/AMOEBAonAMAK/src/agents/AmoebaAgent.java +++ b/AMOEBAonAMAK/src/agents/AmoebaAgent.java @@ -1,109 +1,110 @@ -package agents; - -import agents.percept.Percept; -import fr.irit.smac.amak.Agent; -import fr.irit.smac.amak.tools.Loggable; -import gui.RenderStrategy; -import kernel.AMOEBA; -import kernel.World; - -/** - * The base class for all AMOEBA agents - */ -public abstract class AmoebaAgent extends Agent<AMOEBA, World> implements Loggable { - // Attributes - protected String name; - private boolean dying; - - protected RenderStrategy renderStrategy; - - /** - * Instantiate a new agent attached to an amoeba - * @param the amoeba - */ - public AmoebaAgent(AMOEBA amas, Object... params) { - super(amas, params); - this.dying = false; - } - - @Override - protected void onReady() { - super.onReady(); - logger().debug("CYCLE "+getAmas().getCycle(), "Agent %s ready.", toString()); - } - - @Override - protected void onDecide() { - } - - @Override - protected void onRenderingInitialization() { - if(renderStrategy != null) { - renderStrategy.initialize(); - } - } - - @Override - public void onUpdateRender() { - amas.getEnvironment().incrementNbActivatedAgent(); - if(renderStrategy != null && !isDying()) { - if (amas.isRenderUpdate()) { - renderStrategy.render(); - } - } - } - - /** - * Set the name of the agent. Useful for visualization, and essential for {@link Percept}. - * @param name - */ - public void setName(String name) { - this.name = name; - } - - @Override - public void destroy() { - dying = true; - if(renderStrategy != null) { - renderStrategy.delete(); - } - super.destroy(); - logger().debug("CYCLE "+getAmas().getCycle(), "Agent %s destroyed.", toString()); - } - - /** - * Get the name of the agent. Useful for visualization, and essential for {@link Percept}. - * @param name - */ - public String getName() { - return name; - } - - /** - * Tell if the agent is dying. A dying agent no longer perform any useful action, but is not yet removed from its system. - * @return - */ - public boolean isDying() { - return dying; - } - - /** - * Set the render strategy of an agent.<br/> - * {@link RenderStrategy#delete()} the old one, and {@link RenderStrategy#initialize()} the new one. - * @param renderStrategy - * @see RenderStrategy - */ - public void setRenderStrategy(RenderStrategy renderStrategy) { - if(this.renderStrategy != null) this.renderStrategy.delete(); - this.renderStrategy = renderStrategy; - if(this.renderStrategy != null) this.renderStrategy.initialize(); - } - - /** - * Get the render strategy of an agent. - * @return - */ - public RenderStrategy getRenderStrategy() { - return renderStrategy; - } -} +package agents; + +import agents.percept.Percept; +import fr.irit.smac.amak.Agent; +import fr.irit.smac.amak.tools.Loggable; +import gui.RenderStrategy; +import kernel.AMOEBA; +import kernel.World; + +/** + * The base class for all AMOEBA agents + */ +public abstract class AmoebaAgent extends Agent<AMOEBA, World> implements Loggable { + // Attributes + protected String name; + private boolean dying; + + protected RenderStrategy renderStrategy; + + /** + * Instantiate a new agent attached to an amoeba + * @param the amoeba + */ + public AmoebaAgent(AMOEBA amas, Object... params) { + super(amas, params); + this.dying = false; + } + + @Override + protected void onReady() { + super.onReady(); + logger().debug("CYCLE "+getAmas().getCycle(), "Agent %s ready.", toString()); + } + + @Override + protected void onDecide() { + } + + @Override + protected void onRenderingInitialization() { + if(renderStrategy != null) { + renderStrategy.initialize(getAmas().getVUIMulti()); + + } + } + + @Override + public void onUpdateRender() { + amas.getEnvironment().incrementNbActivatedAgent(); + if(renderStrategy != null && !isDying()) { + if (amas.isRenderUpdate()) { + renderStrategy.render(); + } + } + } + + /** + * Set the name of the agent. Useful for visualization, and essential for {@link Percept}. + * @param name + */ + public void setName(String name) { + this.name = name; + } + + @Override + public void destroy() { + dying = true; + if(renderStrategy != null) { + renderStrategy.delete(); + } + super.destroy(); + logger().debug("CYCLE "+getAmas().getCycle(), "Agent %s destroyed.", toString()); + } + + /** + * Get the name of the agent. Useful for visualization, and essential for {@link Percept}. + * @param name + */ + public String getName() { + return name; + } + + /** + * Tell if the agent is dying. A dying agent no longer perform any useful action, but is not yet removed from its system. + * @return + */ + public boolean isDying() { + return dying; + } + + /** + * Set the render strategy of an agent.<br/> + * {@link RenderStrategy#delete()} the old one, and {@link RenderStrategy#initialize()} the new one. + * @param renderStrategy + * @see RenderStrategy + */ + public void setRenderStrategy(RenderStrategy renderStrategy) { + if(this.renderStrategy != null) this.renderStrategy.delete(); + this.renderStrategy = renderStrategy; + if(this.renderStrategy != null) this.renderStrategy.initialize(getAmas().getVUIMulti()); + } + + /** + * Get the render strategy of an agent. + * @return + */ + public RenderStrategy getRenderStrategy() { + return renderStrategy; + } +} diff --git a/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_LauncherMultiUI.java b/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_LauncherMultiUI.java new file mode 100644 index 0000000000000000000000000000000000000000..7b50124964d5a245386f9ffdf49c536d5720112c --- /dev/null +++ b/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_LauncherMultiUI.java @@ -0,0 +1,265 @@ +package experiments.nDimensionsLaunchers; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; + +import experiments.FILE; +import fr.irit.smac.amak.Configuration; +import fr.irit.smac.amak.examples.randomantsMultiUi.AntHillExampleMultiUI; +import fr.irit.smac.amak.examples.randomantsMultiUi.WorldExampleMultiUI; +import fr.irit.smac.amak.ui.AmasMultiUIWindow; +import fr.irit.smac.amak.ui.VUI; +import fr.irit.smac.amak.ui.VUIMulti; +import gui.AmoebaMultiUIWindow; +import gui.AmoebaWindow; +import javafx.application.Application; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.scene.control.Slider; +import javafx.stage.Stage; +import kernel.AMOEBA; +import kernel.StudiedSystem; +import kernel.backup.BackupSystem; +import kernel.backup.IBackupSystem; +import kernel.backup.SaveHelperImpl; + + +/** + * The Class BadContextLauncherEasy. + */ +public class F_N_LauncherMultiUI extends Application implements Serializable { + + + public static final double oracleNoiseRange = 0.5; + public static final double learningSpeed = 0.01; + public static final int regressionPoints = 100; + public static final int dimension = 2; + public static final double spaceSize = 50.0 ; + public static final int nbOfModels = 3 ; + public static final int normType = 2 ; + public static final boolean randomExploration = true; + public static final boolean limitedToSpaceZone = true; + //public static final double mappingErrorAllowed = 0.07; // BIG SQUARE + public static double mappingErrorAllowed = 0.03; // MULTI + public static final double explorationIncrement = 1.0 ; + public static final double explorationWidht = 0.5 ; + + public static final int nbCycle = 1000; + + + + public static void main(String[] args) throws IOException { + + + Application.launch(args); + + + } + + @Override + public void start(Stage arg0) throws Exception, IOException { + + Configuration.multiUI=true; + Configuration.commandLineMode = false; + Configuration.allowedSimultaneousAgentsExecution = 1; + Configuration.waitForGUI = true; + Configuration.plotMilliSecondsUpdate = 20000; + + VUIMulti amoebaVUI = VUIMulti.get("2D"); + AmoebaMultiUIWindow amoebaUI = new AmoebaMultiUIWindow("ELLSA", amoebaVUI); + AMOEBA amoeba = new AMOEBA(amoebaUI, amoebaVUI); + + StudiedSystem studiedSystem = new F_N_Manager(spaceSize, dimension, nbOfModels, normType, randomExploration, explorationIncrement,explorationWidht,limitedToSpaceZone, oracleNoiseRange); + amoeba.setStudiedSystem(studiedSystem); + IBackupSystem backupSystem = new BackupSystem(amoeba); + File file = new File("resources/twoDimensionsLauncher.xml"); + backupSystem.load(file); + + amoeba.saver = new SaveHelperImpl(amoeba); + amoeba.allowGraphicalScheduler(true); + amoeba.setRenderUpdate(true); + amoeba.data.learningSpeed = learningSpeed; + amoeba.data.numberOfPointsForRegression = regressionPoints; + amoeba.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed); + + // Exemple for adding a tool in the toolbar + Slider slider = new Slider(0.01, 0.1, mappingErrorAllowed); + slider.setShowTickLabels(true); + slider.setShowTickMarks(true); + + slider.valueProperty().addListener(new ChangeListener<Number>() { + @Override + public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { + System.out.println("new Value "+newValue); + mappingErrorAllowed = (double)newValue; + amoeba.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed); + } + }); + amoebaUI.addToolbar(slider); + + studiedSystem.playOneStep(); + amoeba.learn(studiedSystem.getOutput()); + + VUIMulti amoebaVUI2 = VUIMulti.get("2D"); + AmoebaMultiUIWindow amoebaUI2 = new AmoebaMultiUIWindow("ELLSA", amoebaVUI2); + AMOEBA amoeba2 = new AMOEBA(amoebaUI2, amoebaVUI2); + + StudiedSystem studiedSystem2 = new F_N_Manager(spaceSize, dimension, nbOfModels, normType, randomExploration, explorationIncrement,explorationWidht,limitedToSpaceZone, oracleNoiseRange); + amoeba2.setStudiedSystem(studiedSystem2); + IBackupSystem backupSystem2 = new BackupSystem(amoeba2); + File file2 = new File("resources/twoDimensionsLauncher.xml"); + backupSystem2.load(file2); + + amoeba2.saver = new SaveHelperImpl(amoeba2); + amoeba2.allowGraphicalScheduler(true); + amoeba2.setRenderUpdate(true); + amoeba2.data.learningSpeed = learningSpeed; + amoeba2.data.numberOfPointsForRegression = regressionPoints; + amoeba2.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed); + + // Exemple for adding a tool in the toolbar + Slider slider2 = new Slider(0.01, 0.1, mappingErrorAllowed); + slider2.setShowTickLabels(true); + slider2.setShowTickMarks(true); + + slider2.valueProperty().addListener(new ChangeListener<Number>() { + @Override + public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { + System.out.println("new Value "+newValue); + mappingErrorAllowed = (double)newValue; + amoeba2.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed); + } + }); + amoebaUI2.addToolbar(slider2); + + studiedSystem2.playOneStep(); + amoeba2.learn(studiedSystem2.getOutput()); + + + + } + + public static void launch() throws IOException{ + + + + + // Set AMAK configuration before creating an AMOEBA + + + AMOEBA amoeba = new AMOEBA(null, VUIMulti.get("2D")); + StudiedSystem studiedSystem = new F_N_Manager(spaceSize, dimension, nbOfModels, normType, randomExploration, explorationIncrement,explorationWidht,limitedToSpaceZone, oracleNoiseRange); + amoeba.setStudiedSystem(studiedSystem); + IBackupSystem backupSystem = new BackupSystem(amoeba); + File file = new File("resources/twoDimensionsLauncher.xml"); + backupSystem.load(file); + + + amoeba.saver = new SaveHelperImpl(amoeba); + amoeba.allowGraphicalScheduler(true); + amoeba.setRenderUpdate(true); + amoeba.data.learningSpeed = learningSpeed; + amoeba.data.numberOfPointsForRegression = regressionPoints; + amoeba.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed); + + // Exemple for adding a tool in the toolbar + Slider slider = new Slider(0.01, 0.1, mappingErrorAllowed); + slider.setShowTickLabels(true); + slider.setShowTickMarks(true); + + slider.valueProperty().addListener(new ChangeListener<Number>() { + @Override + public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { + System.out.println("new Value "+newValue); + mappingErrorAllowed = (double)newValue; + amoeba.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed); + } + }); + AmoebaWindow.addToolbar(slider); + + studiedSystem.playOneStep(); + amoeba.learn(studiedSystem.getOutput()); + + /* AUTOMATIC */ +// long start = System.currentTimeMillis(); +// for (int i = 0; i < nbCycle; ++i) { +// studiedSystem.playOneStep(); +// amoeba.learn(studiedSystem.getOutput()); +// } +// long end = System.currentTimeMillis(); +// System.out.println("Done in : " + (end - start) ); +// +// start = System.currentTimeMillis(); +// for (int i = 0; i < nbCycle; ++i) { +// studiedSystem.playOneStep(); +// amoeba.request(studiedSystem.getOutput()); +// } +// end = System.currentTimeMillis(); +// System.out.println("Done in : " + (end - start) ); + + +// /* XP PIERRE */ +// +// String fileName = fileName(new ArrayList<String>(Arrays.asList("GaussiennePierre"))); +// +// FILE Pierrefile = new FILE("Pierre",fileName); +// for (int i = 0; i < nbCycle; ++i) { +// studiedSystem.playOneStep(); +// amoeba.learn(studiedSystem.getOutput()); +// if(amoeba.getHeadAgent().isActiveLearning()) { +// studiedSystem.setActiveLearning(true); +// studiedSystem.setSelfRequest(amoeba.getHeadAgent().getSelfRequest()); +// +// } +// } +// +// for (int i = 0; i < 10; ++i) { +// studiedSystem.playOneStep(); +// System.out.println(studiedSystem.getOutput()); +// System.out.println(amoeba.request(studiedSystem.getOutput())); +// +// +// } +// +// Pierrefile.write(new ArrayList<String>(Arrays.asList("ID contexte","Coeff Cte","Coeff X0","Coeff X1","Min Value","Max Value"))); +// +// for(Context ctxt : amoeba.getContexts()) { +// +// writeMessage(Pierrefile, ctxt.toStringArrayPierre()); +// +// } +// +// +// Pierrefile.close(); + + + } + + public static String fileName(ArrayList<String> infos) { + String fileName = ""; + + for(String info : infos) { + fileName += info + "_"; + } + + return fileName; + } + + public static void writeMessage(FILE file, ArrayList<String> message) { + + file.initManualMessage(); + + for(String m : message) { + file.addManualMessage(m); + } + + file.sendManualMessage(); + + } + + + + +} diff --git a/AMOEBAonAMAK/src/gui/AmoebaMultiUIWindow.java b/AMOEBAonAMAK/src/gui/AmoebaMultiUIWindow.java new file mode 100644 index 0000000000000000000000000000000000000000..43f23e59b758a7bd6fb77dd2068b388db48c6874 --- /dev/null +++ b/AMOEBAonAMAK/src/gui/AmoebaMultiUIWindow.java @@ -0,0 +1,166 @@ +package gui; + +import java.util.HashMap; + +import javax.management.InstanceAlreadyExistsException; + +import fr.irit.smac.amak.tools.Log; +import fr.irit.smac.amak.tools.RunLaterHelper; +import fr.irit.smac.amak.ui.AmakPlot; +import fr.irit.smac.amak.ui.AmakPlot.ChartType; +import fr.irit.smac.amak.ui.AmasMultiUIWindow; +import fr.irit.smac.amak.ui.MainWindow; +import fr.irit.smac.amak.ui.SchedulerToolbar; +import fr.irit.smac.amak.ui.VUI; +import fr.irit.smac.amak.ui.VUIMulti; +import fr.irit.smac.amak.ui.drawables.Drawable; +import javafx.application.Application; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.control.Button; +import javafx.scene.control.Menu; +import javafx.scene.control.Slider; +import javafx.scene.control.ToggleButton; +import javafx.scene.control.Tooltip; +import javafx.scene.paint.Color; +import kernel.AMOEBA; +import kernel.backup.SaveHelperImpl; + +/** + * The main window for AMOEBA GUI. + * @author Hugo + * + */ +public class AmoebaMultiUIWindow extends AmasMultiUIWindow{ + + protected HashMap<String, AmakPlot> plots = new HashMap<>(); + + /** + * The main {@link VUI} for AMOEBA, by default it's the 2D representation of the contexts. + */ + public VUIMulti mainVUI; + + public Drawable point; + public Drawable rectangle; + public ToggleButton toggleRender; + public SchedulerToolbar schedulerToolbar; + public DimensionSelector dimensionSelector; + public Menu windowMenu; + + public AmoebaMultiUIWindow(String title, VUIMulti vui) { + super(title); + mainVUI = vui; + } + + public void initialize(AMOEBA amoeba) { + + + mainVUI.setDefaultView(200, 0, 0); + addTabbedPanel("2D VUI", mainVUI.getPanel()); + + // scheduler toolbar + schedulerToolbar = new SchedulerToolbar("AMOEBA", amoeba.getScheduler()); + addToolbar(schedulerToolbar); + + // plots + point = mainVUI.createAndAddPoint(0, 0); + point.setName("Cursor"); + rectangle = mainVUI.createAndAddRectangle(10, 10, 10, 10); + rectangle.setName("Neighborhood"); + rectangle.setColor(new Color(1, 1, 1, 0)); + + plots.put("This loop NCS", new AmakPlot(this, "This loop NCS", ChartType.LINE, "Cycle", "Number of NCS")); + plots.put("All time NCS", new AmakPlot(this, "All time NCS", ChartType.LINE, "Cycle", "Number of NCS")); + plots.put("Number of agents", new AmakPlot(this, "Number of agents", ChartType.LINE, "Cycle", "Number of agents")); + plots.put("Errors", new AmakPlot(this, "Errors", ChartType.LINE, "Cycle", "Coefficients")); + plots.put("Distances to models", new AmakPlot(this, "Distances to models", ChartType.LINE, "Cycle", "Distances")); + plots.put("Global Mapping Criticality", new AmakPlot(this, "Global Mapping Criticality", ChartType.LINE, "Cycle", "Criticalities")); + plots.put("Time Execution", new AmakPlot(this, "Time Execution", ChartType.LINE, "Cycle", "Times")); + plots.put("Criticalities", new AmakPlot(this, "Criticalities", ChartType.LINE, "Cycle", "Criticalities")); + + // update render button + toggleRender = new ToggleButton("Allow Rendering"); + toggleRender.setOnAction(evt -> { + amoeba.setRenderUpdate(toggleRender.isSelected()); + if(amoeba.isRenderUpdate()) { + amoeba.updateAgentsVisualisation(); + amoeba.nextCycleRunAllAgents(); + } + }); + toggleRender.setSelected(amoeba.isRenderUpdate()); + addToolbar(toggleRender); + + // dimension selector + dimensionSelector = new DimensionSelector(amoeba.getPercepts(), new EventHandler<ActionEvent>() { + @Override + public void handle(ActionEvent event) { + amoeba.updateAgentsVisualisation(); + } + }); + RunLaterHelper.runLater(()->mainVUI.toolbar.getItems().add(dimensionSelector)); + + // contextMenu "Request Here" on VUI + new ContextMenuVUI(amoeba, mainVUI); //the ContextMenu add itself to the VUI + + // manual save button + addToolbar(newManualSaveButton(amoeba)); + + Slider slider = new Slider(0, 0.1, 0.1); + slider.setShowTickLabels(true); + slider.setShowTickMarks(true); + slider.valueProperty().addListener(new ChangeListener<Number>() { + @Override + public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { + amoeba.getEnvironment().mappingErrorAllowed = newValue.doubleValue(); + } + }); + addToolbar(slider); + } + + + + /** + * Get an existing {@link AmakPlot}. + * @param name name of the plot to get + * @return an existing plot. + * @see AmoebaMultiUIWindow#addPlot(String, AmakPlot) + */ + public AmakPlot getPlot(String name) { + return plots.get(name); + } + + /** + * Add an {@link AmakPlot} to le map of plots. Allowing for easy access with {@code AmoebaWindow.instance().getPlot(name)} + * @param name name of the plot to add + * @param plot the plot to add + * @see AmoebaMultiUIWindow#getPlot(String) + */ + public void addPlot(String name, AmakPlot plot) { + plots.put(name, plot); + } + + /** + * Create a button 'Quick Save' button, when clicked create a manual save point using an amoeba's saver. + * @param amoeba + * @return + * @see AMOEBA#saver + * @see SaveHelperImpl#newManualSave(String) + */ + public Button newManualSaveButton(AMOEBA amoeba) { + Button button = new Button("Quick save"); + button.setTooltip(new Tooltip("Create a new save point. You will be able to find it in 'Save Explorer' -> 'Manual Saves'")); + button.setOnAction(new EventHandler<ActionEvent>() { + @Override + public void handle(ActionEvent event) { + if(amoeba.saver != null) { + amoeba.saver.newManualSave("manualSaveButton"); + } else { + Log.defaultLog.error("Main Window", "Cannot make a save point of an amoeba without saver"); + } + } + }); + return button; + } +} diff --git a/AMOEBAonAMAK/src/gui/ContextMenuVUI.java b/AMOEBAonAMAK/src/gui/ContextMenuVUI.java index aad5e8bf8af3891878e442f441183af8bd3948f8..80ef51de949fa701b6045a4a830da0682e53c04f 100644 --- a/AMOEBAonAMAK/src/gui/ContextMenuVUI.java +++ b/AMOEBAonAMAK/src/gui/ContextMenuVUI.java @@ -6,6 +6,7 @@ import java.util.Optional; import agents.percept.Percept; import fr.irit.smac.amak.tools.Log; import fr.irit.smac.amak.ui.VUI; +import fr.irit.smac.amak.ui.VUIMulti; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.control.Button; @@ -38,7 +39,7 @@ public class ContextMenuVUI extends ContextMenu { * @param amoeba the amoeba where {@link AMOEBA#request(HashMap)} and {@link AMOEBA#learn(HashMap)} will be executed. * @param vui the {@link VUI} hosting the {@link ContextMenuVUI} */ - public ContextMenuVUI(AMOEBA amoeba, VUI vui) { + public ContextMenuVUI(AMOEBA amoeba, VUIMulti vui) { // "request here" menu item setupRequestHereMenuItem(amoeba, vui); @@ -56,7 +57,7 @@ public class ContextMenuVUI extends ContextMenu { }); } - private void setupRequestHereMenuItem(AMOEBA amoeba, VUI vui) { + private void setupRequestHereMenuItem(AMOEBA amoeba, VUIMulti vui) { MenuItem reqHere = new MenuItem("Request Here"); reqHere.setOnAction(new EventHandler<ActionEvent>() { @Override @@ -78,7 +79,7 @@ public class ContextMenuVUI extends ContextMenu { * @param amoeba * @param vui */ - private void reqTwoDimension(AMOEBA amoeba, VUI vui) { + private void reqTwoDimension(AMOEBA amoeba, VUIMulti vui) { double x = vui.screenToWorldX(reqHereX); double y = vui.screenToWorldY(reqHereY); HashMap<String, Double> req = new HashMap<String, Double>(); @@ -95,7 +96,7 @@ public class ContextMenuVUI extends ContextMenu { * @param amoeba * @param vui */ - private void reqNDimension(AMOEBA amoeba, VUI vui) { + private void reqNDimension(AMOEBA amoeba, VUIMulti vui) { double x = vui.screenToWorldX(reqHereX); double y = vui.screenToWorldY(reqHereY); @@ -143,7 +144,7 @@ public class ContextMenuVUI extends ContextMenu { }); } - private void setupLearnHereMenuItem(AMOEBA amoeba, VUI vui) { + private void setupLearnHereMenuItem(AMOEBA amoeba, VUIMulti vui) { MenuItem learnHere = new MenuItem("Learn Here"); learnHere.setOnAction(new EventHandler<ActionEvent>() { @Override @@ -165,7 +166,7 @@ public class ContextMenuVUI extends ContextMenu { * @param amoeba * @param vui */ - private void learnTwoDimension(AMOEBA amoeba, VUI vui) { + private void learnTwoDimension(AMOEBA amoeba, VUIMulti vui) { double x = vui.screenToWorldX(reqHereX); double y = vui.screenToWorldY(reqHereY); HashMap<String, Double> req = new HashMap<String, Double>(); @@ -181,7 +182,7 @@ public class ContextMenuVUI extends ContextMenu { * @param amoeba * @param vui */ - private void learnNDimebsion(AMOEBA amoeba, VUI vui) { + private void learnNDimebsion(AMOEBA amoeba, VUIMulti vui) { double x = vui.screenToWorldX(reqHereX); double y = vui.screenToWorldY(reqHereY); diff --git a/AMOEBAonAMAK/src/gui/ContextRendererFX.java b/AMOEBAonAMAK/src/gui/ContextRendererFX.java index 75ddf4125607f21b3ef19ca0dcaaea006105be4d..cd4843863eeedd8f763e1103d6246ff541d681f2 100644 --- a/AMOEBAonAMAK/src/gui/ContextRendererFX.java +++ b/AMOEBAonAMAK/src/gui/ContextRendererFX.java @@ -2,6 +2,7 @@ package gui; import agents.context.Context; import agents.percept.Percept; +import fr.irit.smac.amak.ui.VUIMulti; import fr.irit.smac.amak.ui.drawables.DrawableRectangle; import gui.utils.ContextColor; import javafx.scene.paint.Color; @@ -64,8 +65,8 @@ public class ContextRendererFX extends RenderStrategy { * window. */ @Override - public void initialize() { - getDrawable().setName(context.toString()); // create the drawable if it does not exist + public void initialize(VUIMulti vui) { + getDrawable(vui).setName(context.toString()); // create the drawable if it does not exist } @@ -81,10 +82,10 @@ public class ContextRendererFX extends RenderStrategy { * * @return */ - public DrawableRectangle getDrawable() { + public DrawableRectangle getDrawable(VUIMulti vui) { if (!context.isDying() && drawable == null) { drawable = new DrawableContext(0, 0, 0, 0, context); - AmoebaWindow.instance().mainVUI.add(drawable); + vui.add(drawable); } return drawable; } diff --git a/AMOEBAonAMAK/src/gui/RenderStrategy.java b/AMOEBAonAMAK/src/gui/RenderStrategy.java index d6bf4f7424a9b9166fb9d1ffe30ae5a34d740e99..7552c9518486d3050b687bb8f78114e2d274e774 100644 --- a/AMOEBAonAMAK/src/gui/RenderStrategy.java +++ b/AMOEBAonAMAK/src/gui/RenderStrategy.java @@ -1,5 +1,7 @@ package gui; +import fr.irit.smac.amak.ui.VUIMulti; + /** * Strategy on how to render an object. * See {@link ContextRendererFX} for example on how to extends this class. @@ -16,7 +18,8 @@ public abstract class RenderStrategy { /** * Called when the rendered object need to be initialized */ - abstract public void initialize(); + //abstract public void initialize(); + abstract public void initialize(VUIMulti vui); /** * Called to render the object. diff --git a/AMOEBAonAMAK/src/kernel/AMOEBA.java b/AMOEBAonAMAK/src/kernel/AMOEBA.java index dd2b1e7a6e324d66aac411429f0a847ac00ce42b..bf1b2c6299a6ea8f207ce0eac336f62eefc8d771 100644 --- a/AMOEBAonAMAK/src/kernel/AMOEBA.java +++ b/AMOEBAonAMAK/src/kernel/AMOEBA.java @@ -23,6 +23,8 @@ import fr.irit.smac.amak.Scheduling; import fr.irit.smac.amak.tools.Log; import fr.irit.smac.amak.tools.RunLaterHelper; import fr.irit.smac.amak.ui.AmakPlot; +import fr.irit.smac.amak.ui.VUIMulti; +import gui.AmoebaMultiUIWindow; import gui.AmoebaWindow; import gui.DimensionSelector; import kernel.backup.IBackupSystem; @@ -38,6 +40,9 @@ import utils.PrintOnce; */ public class AMOEBA extends Amas<World> implements IAMOEBA { // -- Attributes + + + public VUIMulti vuiMulti; /** * Utility to save, autosave, and load amoebas. */ @@ -48,6 +53,8 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { */ public StudiedSystem studiedSystem; + public AmoebaMultiUIWindow multiUIWindow; + private Head head; private TypeLocalModel localModel = TypeLocalModel.MILLER_REGRESSION; private HashMap<String, Double> perceptions = new HashMap<String, Double>(); @@ -82,8 +89,9 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { * @param studiedSystem * the studied system */ - public AMOEBA() { - super(new World(), Scheduling.HIDDEN); + public AMOEBA(AmoebaMultiUIWindow window, VUIMulti vui) { + super(window, vui, new World(), Scheduling.HIDDEN); + vuiMulti = vui; } /** @@ -91,8 +99,9 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { * * @param path path to the config file. */ - public AMOEBA(String path, StudiedSystem studiedSystem) { - super(new World(), Scheduling.HIDDEN); + public AMOEBA(AmoebaMultiUIWindow window, VUIMulti vui, String path, StudiedSystem studiedSystem) { + super(window, vui, new World(), Scheduling.HIDDEN); + vuiMulti = vui; this.studiedSystem = studiedSystem; setRenderUpdate(true); saver = new SaveHelperImpl(this); @@ -112,23 +121,22 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { @Override protected void onRenderingInitialization() { - AmoebaWindow.instance().initialize(this); + ((AmoebaMultiUIWindow) amasMultiUIWindow).initialize(this); } @Override protected void onUpdateRender() { // Update statistics - if(AmoebaWindow.isInstance()) { - AmoebaWindow window = AmoebaWindow.instance(); - - AmakPlot loopNCS = window.getPlot("This loop NCS"); - AmakPlot allNCS = window.getPlot("All time NCS"); - AmakPlot nbAgent = window.getPlot("Number of agents"); - AmakPlot errors = window.getPlot("Errors"); - AmakPlot distancesToModels = window.getPlot("Distances to models"); - AmakPlot gloabalMappingCriticality = window.getPlot("Global Mapping Criticality"); - AmakPlot timeExecution = window.getPlot("Time Execution"); - AmakPlot criticalities = window.getPlot("Criticalities"); + if(amasMultiUIWindow!=null) { + + AmakPlot loopNCS = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("This loop NCS"); + AmakPlot allNCS = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("All time NCS"); + AmakPlot nbAgent = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Number of agents"); + AmakPlot errors = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Errors"); + AmakPlot distancesToModels = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Distances to models"); + AmakPlot gloabalMappingCriticality = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Global Mapping Criticality"); + AmakPlot timeExecution = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Time Execution"); + AmakPlot criticalities = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Criticalities"); boolean notify = isRenderUpdate(); @@ -174,7 +182,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { } if (isRenderUpdate()) { - AmoebaWindow.instance().mainVUI.updateCanvas(); + ((AmoebaMultiUIWindow)amasMultiUIWindow).mainVUI.updateCanvas(); updateAgentsVisualisation(); RunLaterHelper.runLater(() -> {resetCycleWithoutRender();}); } @@ -454,7 +462,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { */ public void allowGraphicalScheduler(boolean allow) { if (!Configuration.commandLineMode) { - AmoebaWindow.instance().schedulerToolbar.setDisable(!allow); + ((AmoebaMultiUIWindow)amasMultiUIWindow).schedulerToolbar.setDisable(!allow); } } @@ -476,7 +484,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { super.addPendingAgents(); nextCycleRunAllAgents(); if(!Configuration.commandLineMode) { - AmoebaWindow.instance().dimensionSelector.update(getPercepts()); + ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.update(getPercepts()); updateAgentsVisualisation(); } } @@ -504,7 +512,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { public void setRenderUpdate(boolean renderUpdate) { if (!Configuration.commandLineMode) { this.renderUpdate = renderUpdate; - AmoebaWindow.instance().toggleRender.setSelected(renderUpdate); + ((AmoebaMultiUIWindow)amasMultiUIWindow).toggleRender.setSelected(renderUpdate); if(renderUpdate == true) nextCycleRunAllAgents(); } @@ -595,13 +603,13 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { for(Agent<? extends Amas<World>, World> a : getAgents()) { a.onUpdateRender(); } - AmoebaWindow.instance().point.move(AmoebaWindow.instance().dimensionSelector.d1().getValue(), AmoebaWindow.instance().dimensionSelector.d2().getValue()); - AmoebaWindow.instance().rectangle.setHeight(2*getEnvironment().getContextCreationNeighborhood(null, AmoebaWindow.instance().dimensionSelector.d2())); - AmoebaWindow.instance().rectangle.setWidth(2*getEnvironment().getContextCreationNeighborhood(null, AmoebaWindow.instance().dimensionSelector.d1())); - AmoebaWindow.instance().rectangle.move(AmoebaWindow.instance().dimensionSelector.d1().getValue() - getEnvironment().getContextCreationNeighborhood(null, AmoebaWindow.instance().dimensionSelector.d1()), AmoebaWindow.instance().dimensionSelector.d2().getValue() - getEnvironment().getContextCreationNeighborhood(null, AmoebaWindow.instance().dimensionSelector.d2())); - AmoebaWindow.instance().mainVUI.updateCanvas(); - AmoebaWindow.instance().point.toFront(); - AmoebaWindow.instance().point.setInfo(getCursorInfo()); + ((AmoebaMultiUIWindow)amasMultiUIWindow).point.move(((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d1().getValue(), ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d2().getValue()); + ((AmoebaMultiUIWindow)amasMultiUIWindow).rectangle.setHeight(2*getEnvironment().getContextCreationNeighborhood(null, ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d2())); + ((AmoebaMultiUIWindow)amasMultiUIWindow).rectangle.setWidth(2*getEnvironment().getContextCreationNeighborhood(null, ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d1())); + ((AmoebaMultiUIWindow)amasMultiUIWindow).rectangle.move(((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d1().getValue() - getEnvironment().getContextCreationNeighborhood(null, ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d1()), ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d2().getValue() - getEnvironment().getContextCreationNeighborhood(null, ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d2())); + ((AmoebaMultiUIWindow)amasMultiUIWindow).mainVUI.updateCanvas(); + ((AmoebaMultiUIWindow)amasMultiUIWindow).point.toFront(); + ((AmoebaMultiUIWindow)amasMultiUIWindow).point.setInfo(getCursorInfo()); } /** @@ -609,7 +617,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA { * @return */ public DimensionSelector getDimensionSelector() { - return AmoebaWindow.instance().dimensionSelector; + return ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector; } /** diff --git a/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java b/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java index b2258c51d799c99816a3b9d049b84901f5374c1f..152a7433223b7797e72c658192964cb5cbf59d3e 100644 --- a/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java +++ b/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java @@ -11,6 +11,7 @@ import java.util.List; import fr.irit.smac.amak.Configuration; import fr.irit.smac.amak.ui.MainWindow; +import gui.AmoebaMultiUIWindow; import gui.AmoebaWindow; import gui.saveExplorer.SaveExplorer; import javafx.event.ActionEvent; @@ -33,6 +34,9 @@ public class SaveHelperImpl implements ISaveHelper{ public static final String autosaveDirName = "autosave"; public static final String manualsaveDirName = "manual"; + + public AmoebaMultiUIWindow amoebaMultiUIWindow; + /** * The backup system used by the SaveHelper. */ @@ -116,6 +120,51 @@ public class SaveHelperImpl implements ISaveHelper{ setupGraphicalTool(); } } + + public SaveHelperImpl(AMOEBA amoeba, AmoebaMultiUIWindow window) { + amoebaMultiUIWindow = window; + autoSave = !Configuration.commandLineMode; + this.amoeba = amoeba; + backupSystem = new BackupSystem(amoeba); + String dirName = amoeba.toString() + "_" + System.currentTimeMillis(); + dir = Paths.get(savesRoot, dirName); + if (autoSave) { + dirAuto = Paths.get(dir.toString(), autosaveDirName); + try { + Files.createDirectories(dirAuto); + } catch (IOException e) { + e.printStackTrace(); + System.err.println("Cannot create auto save directory. Auto saving is disabled."); + dirAuto = null; + autoSave = false; + } + } + dirManual = Paths.get(dir.toString(), manualsaveDirName); + try { + Files.createDirectories(dirManual); + } catch (IOException e) { + e.printStackTrace(); + System.err.println("Cannot create manual save directory."); + dirManual = null; + } + + // add graphical element if relevant + if (AmoebaWindow.isInstance()) { + SaveExplorer se = new SaveExplorer(amoeba); + AmoebaWindow.addTabbedPanel("Save Explorer", se); + AmoebaWindow.addOnCloseAction(()-> { + if(deleteFolderOnClose) { + try { + DeleteDirectory.deleteDirectoryRecursion(dir); + } catch (IOException e) { + e.printStackTrace(); + System.err.println("Failed to delete saves files on close."); + } + } + }); + setupGraphicalTool(); + } + } @Override public void load(String path) { @@ -187,7 +236,7 @@ public class SaveHelperImpl implements ISaveHelper{ * Add save/load options in the main window. */ private void setupGraphicalTool() { - MainWindow mw = AmoebaWindow.instance(); + AmoebaMultiUIWindow mw = amoebaMultiUIWindow; // TODO remove if they exist items Save and Load in menu Option. FileChooser fileChooser = new FileChooser(); fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("XML", "*.xml"), @@ -198,7 +247,7 @@ public class SaveHelperImpl implements ISaveHelper{ @Override public void handle(ActionEvent event) { amoeba.getScheduler().stop(); - File file = fileChooser.showOpenDialog(mw.stage); + File file = fileChooser.showOpenDialog(mw); if (file != null) backupSystem.load(file); } @@ -210,7 +259,7 @@ public class SaveHelperImpl implements ISaveHelper{ @Override public void handle(ActionEvent event) { amoeba.getScheduler().stop(); - File file = fileChooser.showSaveDialog(mw.stage); + File file = fileChooser.showSaveDialog(mw); if (file != null) backupSystem.save(file); }