From a4e4082bc596f3fc9d833d8098af62f8001f159f Mon Sep 17 00:00:00 2001
From: DAAVVE <--global>
Date: Wed, 3 Jul 2019 17:13:28 +0200
Subject: [PATCH] Added ISaveHelper and SaveHelperDummy

---
 .../src/fr/irit/smac/amak/ui/MainWindow.java  |  6 +-
 .../src/experiments/AdvancedMain.java         |  8 +--
 AMOEBAonAMAK/src/experiments/Benchmark.java   |  2 +-
 .../src/experiments/BenchmarkThreading.java   |  4 +-
 .../nDimensionsLaunchers/F_N_Launcher.java    |  8 +--
 AMOEBAonAMAK/src/gui/AmoebaWindow.java        |  4 +-
 .../src/gui/saveExplorer/SaveExplorer.java    |  7 +-
 AMOEBAonAMAK/src/kernel/AMOEBA.java           |  8 ++-
 .../src/kernel/{ => backup}/BackupSystem.java |  4 +-
 .../kernel/{ => backup}/IBackupSystem.java    |  2 +-
 .../src/kernel/backup/ISaveHelper.java        | 72 +++++++++++++++++++
 .../src/kernel/backup/SaveHelperDummy.java    | 61 ++++++++++++++++
 .../SaveHelperImpl.java}                      | 70 +++++++++---------
 AMOEBAonAMAK/tests/utils/TestSetup.java       |  6 +-
 documentation/py4j_demo/cart_pole.py          | 52 +++++++++-----
 documentation/py4j_demo/clean.sh              |  2 +-
 documentation/py4j_demo/lunar_lander.py       | 18 +++--
 documentation/py4j_demo/requirements.txt      |  1 +
 documentation/py4j_demo/setup.sh              |  3 +-
 documentation/ros_demo/clean.sh               |  2 +-
 documentation/ros_demo/setup.sh               |  2 +-
 documentation/ros_demo/start.sh               |  2 +-
 documentation/ros_demo/start_amoebas.sh       |  2 +-
 documentation/ros_demo/stop.sh                |  2 +-
 24 files changed, 250 insertions(+), 98 deletions(-)
 rename AMOEBAonAMAK/src/kernel/{ => backup}/BackupSystem.java (99%)
 rename AMOEBAonAMAK/src/kernel/{ => backup}/IBackupSystem.java (97%)
 create mode 100644 AMOEBAonAMAK/src/kernel/backup/ISaveHelper.java
 create mode 100644 AMOEBAonAMAK/src/kernel/backup/SaveHelperDummy.java
 rename AMOEBAonAMAK/src/kernel/{SaveHelper.java => backup/SaveHelperImpl.java} (80%)

diff --git a/AMAKFX/src/fr/irit/smac/amak/ui/MainWindow.java b/AMAKFX/src/fr/irit/smac/amak/ui/MainWindow.java
index f8fe92a2..a38de7c2 100644
--- a/AMAKFX/src/fr/irit/smac/amak/ui/MainWindow.java
+++ b/AMAKFX/src/fr/irit/smac/amak/ui/MainWindow.java
@@ -149,14 +149,14 @@ public class MainWindow extends Application {
 	 *            The action to be executed when the window is closed
 	 */
 	public static void addOnCloseAction(Runnable onClose) {
-		instance().closeActions.add(onClose);
+		Runtime.getRuntime().addShutdownHook(new Thread() {
+		    public void run() { onClose.run(); }
+		});
 	}
 	
-	private List<Runnable> closeActions = new ArrayList<>();
 	@Override
 	public void stop() throws Exception {
 		super.stop();
-		closeActions.forEach(Runnable::run);
 		System.exit(0);
 	}
 
diff --git a/AMOEBAonAMAK/src/experiments/AdvancedMain.java b/AMOEBAonAMAK/src/experiments/AdvancedMain.java
index da18909d..4cc23949 100644
--- a/AMOEBAonAMAK/src/experiments/AdvancedMain.java
+++ b/AMOEBAonAMAK/src/experiments/AdvancedMain.java
@@ -10,10 +10,10 @@ import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.scene.control.Slider;
 import kernel.AMOEBA;
-import kernel.BackupSystem;
-import kernel.IBackupSystem;
-import kernel.SaveHelper;
 import kernel.StudiedSystem;
+import kernel.backup.BackupSystem;
+import kernel.backup.IBackupSystem;
+import kernel.backup.SaveHelperImpl;
 
 /**
  * A more advanced and complete main.
@@ -59,7 +59,7 @@ public class AdvancedMain {
 		
 		// We add an optional saver, allowing us to autosave the amoeba at each cycle.
 		// The SaveHelper also add graphical tools to save and load AMOEBA's state.
-		amoeba.saver = new SaveHelper(amoeba);
+		amoeba.saver = new SaveHelperImpl(amoeba);
 		// Autosave slow execution, if you want fast training, set saver to null,
 		// or saver.autoSave = false.
 
diff --git a/AMOEBAonAMAK/src/experiments/Benchmark.java b/AMOEBAonAMAK/src/experiments/Benchmark.java
index 42eeca65..17c5376e 100644
--- a/AMOEBAonAMAK/src/experiments/Benchmark.java
+++ b/AMOEBAonAMAK/src/experiments/Benchmark.java
@@ -6,8 +6,8 @@ import java.util.ArrayList;
 import fr.irit.smac.amak.Configuration;
 import fr.irit.smac.amak.tools.Log;
 import kernel.AMOEBA;
-import kernel.BackupSystem;
 import kernel.StudiedSystem;
+import kernel.backup.BackupSystem;
 
 public class Benchmark {
 
diff --git a/AMOEBAonAMAK/src/experiments/BenchmarkThreading.java b/AMOEBAonAMAK/src/experiments/BenchmarkThreading.java
index 668b75cd..58529462 100644
--- a/AMOEBAonAMAK/src/experiments/BenchmarkThreading.java
+++ b/AMOEBAonAMAK/src/experiments/BenchmarkThreading.java
@@ -9,10 +9,10 @@ import java.util.function.DoubleBinaryOperator;
 import fr.irit.smac.amak.Configuration;
 import fr.irit.smac.amak.tools.Log;
 import kernel.AMOEBA;
-import kernel.BackupSystem;
 import kernel.IAMOEBA;
-import kernel.IBackupSystem;
 import kernel.StudiedSystem;
+import kernel.backup.BackupSystem;
+import kernel.backup.IBackupSystem;
 
 public class BenchmarkThreading {
 
diff --git a/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_Launcher.java b/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_Launcher.java
index bd8c2737..c185726d 100644
--- a/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_Launcher.java
+++ b/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_Launcher.java
@@ -11,10 +11,10 @@ import experiments.XmlConfigGenerator;
 import fr.irit.smac.amak.Configuration;
 import gui.AmoebaWindow;
 import kernel.AMOEBA;
-import kernel.BackupSystem;
-import kernel.IBackupSystem;
-import kernel.SaveHelper;
 import kernel.StudiedSystem;
+import kernel.backup.BackupSystem;
+import kernel.backup.IBackupSystem;
+import kernel.backup.SaveHelperImpl;
 
 
 // TODO: Auto-generated Javadoc
@@ -66,7 +66,7 @@ public class F_N_Launcher implements Serializable {
 		File file = new File("resources/twoDimensionsLauncher.xml");
 		backupSystem.load(file);
 		
-		amoeba.saver = new SaveHelper(amoeba);
+		amoeba.saver = new SaveHelperImpl(amoeba);
 		amoeba.allowGraphicalScheduler(true);
 		amoeba.setRenderUpdate(true);		
 		amoeba.data.learningSpeed = learningSpeed;
diff --git a/AMOEBAonAMAK/src/gui/AmoebaWindow.java b/AMOEBAonAMAK/src/gui/AmoebaWindow.java
index 25d83511..ba30d2de 100644
--- a/AMOEBAonAMAK/src/gui/AmoebaWindow.java
+++ b/AMOEBAonAMAK/src/gui/AmoebaWindow.java
@@ -24,7 +24,7 @@ import javafx.scene.control.ToggleButton;
 import javafx.scene.control.Tooltip;
 import javafx.scene.paint.Color;
 import kernel.AMOEBA;
-import kernel.SaveHelper;
+import kernel.backup.SaveHelperImpl;
 
 /**
  * The main window for AMOEBA GUI.
@@ -172,7 +172,7 @@ public class AmoebaWindow extends MainWindow {
 	 * @param amoeba
 	 * @return
 	 * @see AMOEBA#saver
-	 * @see SaveHelper#newManualSave(String)
+	 * @see SaveHelperImpl#newManualSave(String)
 	 */
 	public Button newManualSaveButton(AMOEBA amoeba) {
 		Button button = new Button("Quick save");
diff --git a/AMOEBAonAMAK/src/gui/saveExplorer/SaveExplorer.java b/AMOEBAonAMAK/src/gui/saveExplorer/SaveExplorer.java
index 9504d645..1cb91054 100644
--- a/AMOEBAonAMAK/src/gui/saveExplorer/SaveExplorer.java
+++ b/AMOEBAonAMAK/src/gui/saveExplorer/SaveExplorer.java
@@ -26,12 +26,12 @@ import javafx.scene.layout.Priority;
 import javafx.scene.layout.VBox;
 import javafx.util.Callback;
 import kernel.AMOEBA;
-import kernel.SaveHelper;
 import kernel.StudiedSystem;
+import kernel.backup.SaveHelperImpl;
 
 /**
  * Graphical element to browse and load (auto)saves for a specific amoeba. 
- * @see SaveHelper
+ * @see SaveHelperImpl
  * @see AMOEBA
  * @author Hugo
  *
@@ -47,7 +47,7 @@ public class SaveExplorer extends VBox {
 	 * create a SaveExplorer for an AMOEBA.
 	 * The amoeba MUST have a working {@link AMOEBA#saver}.
 	 * @param amoeba
-	 * @see SaveHelper
+	 * @see SaveHelperImpl
 	 */
 	public SaveExplorer(AMOEBA amoeba) {
 		this.amoeba = amoeba;
@@ -258,7 +258,6 @@ public class SaveExplorer extends VBox {
 	public static void main(String[] args) throws ClassNotFoundException, IOException {
 		System.out.println("New AMOEBA launched.");
 		AMOEBA amoeba = new AMOEBA(args[0], (StudiedSystem)SerializeBase64.deserialize(args[1]));
-		amoeba.saver.deleteFolderOnClose = false;
 		//amoeba.allowGraphicalScheduler(false);
 		for(Percept p : amoeba.getPercepts()) {
 			p.setValue(amoeba.getPerceptions(p.getName()));
diff --git a/AMOEBAonAMAK/src/kernel/AMOEBA.java b/AMOEBAonAMAK/src/kernel/AMOEBA.java
index b97bd82a..6e4903ed 100644
--- a/AMOEBAonAMAK/src/kernel/AMOEBA.java
+++ b/AMOEBAonAMAK/src/kernel/AMOEBA.java
@@ -25,6 +25,10 @@ import fr.irit.smac.amak.tools.RunLaterHelper;
 import fr.irit.smac.amak.ui.AmakPlot;
 import gui.AmoebaWindow;
 import gui.DimensionSelector;
+import kernel.backup.IBackupSystem;
+import kernel.backup.ISaveHelper;
+import kernel.backup.SaveHelperDummy;
+import kernel.backup.SaveHelperImpl;
 import ncs.NCS;
 
 /**
@@ -36,7 +40,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 	/**
 	 * Utility to save, autosave, and load amoebas.
 	 */
-	public SaveHelper saver;
+	public ISaveHelper saver = new SaveHelperDummy();
 	
 	/**
 	 * The system studied by the amoeba.
@@ -87,7 +91,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 		super(new World(), Scheduling.HIDDEN);
 		this.studiedSystem = studiedSystem;
 		setRenderUpdate(true);
-		saver = new SaveHelper(this);
+		saver = new SaveHelperImpl(this);
 		saver.load(path);
 	}
 
diff --git a/AMOEBAonAMAK/src/kernel/BackupSystem.java b/AMOEBAonAMAK/src/kernel/backup/BackupSystem.java
similarity index 99%
rename from AMOEBAonAMAK/src/kernel/BackupSystem.java
rename to AMOEBAonAMAK/src/kernel/backup/BackupSystem.java
index ecdd06de..d2cf9a8e 100644
--- a/AMOEBAonAMAK/src/kernel/BackupSystem.java
+++ b/AMOEBAonAMAK/src/kernel/backup/BackupSystem.java
@@ -1,4 +1,4 @@
-package kernel;
+package kernel.backup;
 
 import java.io.File;
 import java.io.FileWriter;
@@ -29,6 +29,8 @@ import agents.context.localModel.LocalModelMillerRegression;
 import agents.context.localModel.TypeLocalModel;
 import agents.head.Head;
 import agents.percept.Percept;
+import kernel.AMOEBA;
+import kernel.AmoebaData;
 import utils.XMLSerialization;
 
 /**
diff --git a/AMOEBAonAMAK/src/kernel/IBackupSystem.java b/AMOEBAonAMAK/src/kernel/backup/IBackupSystem.java
similarity index 97%
rename from AMOEBAonAMAK/src/kernel/IBackupSystem.java
rename to AMOEBAonAMAK/src/kernel/backup/IBackupSystem.java
index 0151a0b1..ec388ff9 100644
--- a/AMOEBAonAMAK/src/kernel/IBackupSystem.java
+++ b/AMOEBAonAMAK/src/kernel/backup/IBackupSystem.java
@@ -1,4 +1,4 @@
-package kernel;
+package kernel.backup;
 
 import java.io.File;
 
diff --git a/AMOEBAonAMAK/src/kernel/backup/ISaveHelper.java b/AMOEBAonAMAK/src/kernel/backup/ISaveHelper.java
new file mode 100644
index 00000000..6b9c17d3
--- /dev/null
+++ b/AMOEBAonAMAK/src/kernel/backup/ISaveHelper.java
@@ -0,0 +1,72 @@
+package kernel.backup;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.List;
+
+/**
+ * An helper class that handle save, autosave, and load needs of an AMOEBA.
+ * @see SaveHelperImpl
+ * @see SaveHelperDummy
+ * @author Hugo
+ *
+ */
+public interface ISaveHelper {
+	
+	/**
+	 * Load a save pointed by path.
+	 * @param path path to the save.
+	 */
+	public void load(String path);
+	
+	/**
+	 * Load a save from file.
+	 * @param path path to the save.
+	 */
+	public void load(File file);
+
+	/**
+	 * Create a save at path.
+	 * @param path path of the new save
+	 */
+	public void save(String path);
+	
+	/**
+	 * Create a save in file.
+	 * @param path path of the new save
+	 */
+	public void save(File file);
+
+	/**
+	 * Add a new save in {@link SaveHelperImpl#dirManual}.
+	 * @param name
+	 */
+	public void newManualSave(String name);
+
+	/**
+	 * Add a new save in {@link SaveHelperImpl#dirAuto}.
+	 */
+	public void autosave();
+
+	/**
+	 * List saves in {@link SaveHelperImpl#dirAuto}.
+	 */
+	public List<Path> listAutoSaves();
+
+	/**
+	 * List saves in {@link SaveHelperImpl#dirManual}.
+	 */
+	public List<Path> listManualSaves();
+	
+	/**
+	 * Activate or deactivate the automatic save system.
+	 * @param value
+	 */
+	public void setAutoSave(boolean value);
+	
+	/**
+	 * Tell if the automatic save system is activated.
+	 * @return
+	 */
+	public boolean getAutoSave();
+}
diff --git a/AMOEBAonAMAK/src/kernel/backup/SaveHelperDummy.java b/AMOEBAonAMAK/src/kernel/backup/SaveHelperDummy.java
new file mode 100644
index 00000000..9166f265
--- /dev/null
+++ b/AMOEBAonAMAK/src/kernel/backup/SaveHelperDummy.java
@@ -0,0 +1,61 @@
+package kernel.backup;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A save helper that does nothing. Useful when one wish to deactivate an amoeba save system.
+ * 
+ * @see SaveHelperImpl
+ * @author Hugo
+ *
+ */
+public class SaveHelperDummy implements ISaveHelper {
+
+	@Override
+	public void load(String path) {
+	}
+
+	@Override
+	public void load(File file) {
+	}
+
+	@Override
+	public void save(String path) {
+	}
+
+	@Override
+	public void save(File file) {
+	}
+
+	@Override
+	public void newManualSave(String name) {
+	}
+
+	@Override
+	public void autosave() {
+	}
+
+	@Override
+	public List<Path> listAutoSaves() {
+		return new ArrayList<Path>();
+	}
+
+	@Override
+	public List<Path> listManualSaves() {
+		return new ArrayList<Path>();
+	}
+
+	@Override
+	public void setAutoSave(boolean value) {
+		
+	}
+
+	@Override
+	public boolean getAutoSave() {
+		return false;
+	}
+
+}
diff --git a/AMOEBAonAMAK/src/kernel/SaveHelper.java b/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java
similarity index 80%
rename from AMOEBAonAMAK/src/kernel/SaveHelper.java
rename to AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java
index 6544059e..b2258c51 100644
--- a/AMOEBAonAMAK/src/kernel/SaveHelper.java
+++ b/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java
@@ -1,4 +1,4 @@
-package kernel;
+package kernel.backup;
 
 import java.io.File;
 import java.io.IOException;
@@ -9,20 +9,23 @@ import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
 
+import fr.irit.smac.amak.Configuration;
 import fr.irit.smac.amak.ui.MainWindow;
 import gui.AmoebaWindow;
 import gui.saveExplorer.SaveExplorer;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.stage.FileChooser;
+import kernel.AMOEBA;
 import utils.DeleteDirectory;
 
 /**
- * An helper class that handle save, autosave, and load needs of an AMOEBA.
+ * The standard implementation of {@link ISaveHelper}
+ * @see SaveHelperDummy
  * @author Hugo
  *
  */
-public class SaveHelper {
+public class SaveHelperImpl implements ISaveHelper{
 	/**
 	 * Path to the saves' root directory. Default is 'saves'.
 	 */
@@ -36,12 +39,13 @@ public class SaveHelper {
 	public IBackupSystem backupSystem;
 	
 	/**
-	 * If false {@link SaveHelper#autosave()} will do nothing.
+	 * If false {@link SaveHelperImpl#autosave()} will do nothing.<br/>
+	 * Default at not( {@link Configuration#commandLineMode} ).
 	 */
 	public boolean autoSave = true;
 	
 	/**
-	 * Will the SaveHelper delete {@link SaveHelper#dir} when closing the MainWindow ?
+	 * Will the SaveHelper delete {@link SaveHelperImpl#dir} when closing the MainWindow ?
 	 */
 	public boolean deleteFolderOnClose = true;
 	
@@ -64,12 +68,13 @@ public class SaveHelper {
 
 	/**
 	 * Create a SaveHelper for an amoeba.<br/>
-	 * Saves are stored in {@link SaveHelper#savesRoot}, under a directory named after the amoeba and creation time of the SaveHelper.<br/>
-	 * Autosave for this SaveHelper can be deactivated with {@link SaveHelper#autoSave}.<br/>
-	 * By default, the save folder for this amoeba is deleted when the application is closed, this can be changed with {@link SaveHelper#deleteFolderOnClose}.
+	 * Saves are stored in {@link SaveHelperImpl#savesRoot}, under a directory named after the amoeba and creation time of the SaveHelper.<br/>
+	 * Autosave for this SaveHelper can be deactivated with {@link SaveHelperImpl#autoSave}.<br/>
+	 * By default, the save folder for this amoeba is deleted when the application is closed, this can be changed with {@link SaveHelperImpl#deleteFolderOnClose}.
 	 * @param amoeba
 	 */
-	public SaveHelper(AMOEBA amoeba) {
+	public SaveHelperImpl(AMOEBA amoeba) {
+		autoSave = !Configuration.commandLineMode;
 		this.amoeba = amoeba;
 		backupSystem = new BackupSystem(amoeba);
 		String dirName = amoeba.toString() + "_" + System.currentTimeMillis();
@@ -112,45 +117,30 @@ public class SaveHelper {
 		}
 	}
 
-	/**
-	 * Load a save pointed by path.
-	 * @param path path to the save.
-	 */
+	@Override
 	public void load(String path) {
 		File f = new File(path);
 		load(f);
 	}
 	
-	/**
-	 * Load a save from file.
-	 * @param path path to the save.
-	 */
+	@Override
 	public void load(File file) {
 		backupSystem.load(file);
 	}
 
-	/**
-	 * Create a save at path.
-	 * @param path path of the new save
-	 */
+	@Override
 	public void save(String path) {
 		File f = new File(path);
 		save(f);
 	}
 	
-	/**
-	 * Create a save in file.
-	 * @param path path of the new save
-	 */
+	@Override
 	public void save(File file) {
 		backupSystem.setLoadPresetContext(true);
 		backupSystem.save(file);
 	}
 
-	/**
-	 * Add a new save in {@link SaveHelper#dirManual}.
-	 * @param name
-	 */
+	@Override
 	public void newManualSave(String name) {
 		String c = (name == null || "".equals(name)) ? "" : ("_" + name);
 		c.replace('/', '-');
@@ -160,9 +150,7 @@ public class SaveHelper {
 		backupSystem.save(p.toFile());
 	}
 
-	/**
-	 * Add a new save in {@link SaveHelper#dirAuto}.
-	 */
+	@Override
 	public void autosave() {
 		if (autoSave) {
 			Path p = Paths.get(dirAuto.toString(), amoeba.getCycle() + "." + backupSystem.getExtension());
@@ -171,9 +159,7 @@ public class SaveHelper {
 		}
 	}
 
-	/**
-	 * List saves in {@link SaveHelper#dirAuto}.
-	 */
+	@Override
 	public List<Path> listAutoSaves() {
 		List<Path> l = new ArrayList<>();
 		try (DirectoryStream<Path> d = Files.newDirectoryStream(dirAuto)){
@@ -185,9 +171,7 @@ public class SaveHelper {
 		return l;
 	}
 
-	/**
-	 * List saves in {@link SaveHelper#dirManual}.
-	 */
+	@Override
 	public List<Path> listManualSaves() {
 		List<Path> l = new ArrayList<>();
 		try (DirectoryStream<Path> d = Files.newDirectoryStream(dirManual)){
@@ -233,4 +217,14 @@ public class SaveHelper {
 		};
 		MainWindow.addOptionsItem("Save", eventSave);
 	}
+
+	@Override
+	public void setAutoSave(boolean value) {
+		autoSave = value;
+	}
+
+	@Override
+	public boolean getAutoSave() {
+		return autoSave;
+	}
 }
diff --git a/AMOEBAonAMAK/tests/utils/TestSetup.java b/AMOEBAonAMAK/tests/utils/TestSetup.java
index d2bc1106..2a234298 100644
--- a/AMOEBAonAMAK/tests/utils/TestSetup.java
+++ b/AMOEBAonAMAK/tests/utils/TestSetup.java
@@ -11,8 +11,8 @@ import org.junit.jupiter.api.BeforeEach;
 import experiments.F_XY_System;
 import fr.irit.smac.amak.Configuration;
 import kernel.AMOEBA;
-import kernel.SaveHelper;
 import kernel.StudiedSystem;
+import kernel.backup.SaveHelperImpl;
 
 public class TestSetup {
 	protected AMOEBA amoeba;
@@ -43,7 +43,7 @@ public class TestSetup {
 		Configuration.commandLineMode = true;
 		StudiedSystem studiedSystem = new F_XY_System(50.0);
 		amoeba = new AMOEBA("resources/twoDimensionsLauncher.xml", studiedSystem);
-		amoeba.saver.autoSave = false;
+		amoeba.saver.setAutoSave(false);
 		for (int i = 0; i < train.length; i++) {
 			studiedSystem.playOneStep();
 			amoeba.learn(train[i]);
@@ -53,7 +53,7 @@ public class TestSetup {
 	@AfterAll
 	public static void clean() {
 		try {
-			DeleteDirectory.deleteDirectoryRecursion(Paths.get(SaveHelper.savesRoot));
+			DeleteDirectory.deleteDirectoryRecursion(Paths.get(SaveHelperImpl.savesRoot));
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
diff --git a/documentation/py4j_demo/cart_pole.py b/documentation/py4j_demo/cart_pole.py
index 974a0ce3..9a325ee1 100644
--- a/documentation/py4j_demo/cart_pole.py
+++ b/documentation/py4j_demo/cart_pole.py
@@ -2,36 +2,52 @@ import gym
 import subprocess
 import time
 import numpy as np
+import matplotlib.pyplot as plt
 
 from py4j.java_gateway import JavaGateway, GatewayParameters, set_field
 
 
+def msg_obj(obs:list, act:list, oracle) -> dict:
+    msg = dict()
+    for i, o in enumerate(obs):
+        msg["p%d" % i] = float(o*1000.0)
+    for i, a in enumerate(act):
+        msg["a%d" % i] = float(a)
+    msg["oracle"] = float(oracle)
+    return msg
+
+
 def chose_next_action(amoeba, state):
-    proposition = [
-        amoeba.request({"p0": state[0]*100, "p1": state[1]*100, "p2": state[2]*100, "p3": state[3]*100, "a0": 1.0, "a1": 0.0, "oracle": 0.0}),
-        amoeba.request({"p0": state[0]*100, "p1": state[1]*100, "p2": state[2]*100, "p3": state[3]*100, "a0": 0.0, "a1": 1.0, "oracle": 0.0})
-    ]
+    proposition = []
+    for i in range(env.action_space.n):
+        act = [0.0]*env.action_space.n
+        act[i] = 1
+        proposition.append(amoeba.request(msg_obj(state, act, 0)))
+
     return np.argmax(proposition)
 
 
 def learn_amoeba(amoeba, state, action, reward):
-    a0 = 1.0 if action == 0 else 0.0
-    a1 = 1.0 if action == 1 else 0.0
-    #a2 = 1.0 if action == 2 else 0.0
-    amoeba.learn({"p0": state[0]*100, "p1": state[1]*100, "p2": state[2]*100, "p3": state[3]*100, "a0": a0, "a1": a1, "oracle": reward})
+    act = [0.0]*env.action_space.n
+    act[action] = 1
+    amoeba.learn(msg_obj(state, act, reward))
 
 
 if __name__ == '__main__':
-    # Make sure to run setup.sh at least once before running this script
 
+    plt.ion()
+
+    # Make sure to run setup.sh at least once before running this script
     subprocess.Popen(["java", "-jar", "amoeba.jar"])
     time.sleep(2)
 
     gateway = JavaGateway(gateway_parameters=GatewayParameters(auto_convert=True, auto_field=True))
     gateway.jvm.py4j.Main.Control.setComandLine(True)
 
-    amoeba = gateway.jvm.kernel.AMOEBA("/home/daavve/AMOEBA3/documentation/py4j_demo/cart_pole.xml", None)
-    set_field(amoeba.saver, "autoSave", False)
+    amoeba = gateway.jvm.kernel.AMOEBA()
+    backup_sys = gateway.jvm.kernel.backup.BackupSystem(amoeba)
+    file = gateway.jvm.java.io.File("cart_pole.xml")
+    backup_sys.load(file)
 
     env = gym.make('CartPole-v1')
     env.reset()
@@ -41,7 +57,7 @@ if __name__ == '__main__':
     ave_reward_list = []
 
     episodes = 1000
-    epsilon = 0.3
+    epsilon = 0
     min_eps = 0
     reduction = 0.01
     for i in range(episodes):
@@ -54,7 +70,7 @@ if __name__ == '__main__':
 
         while not done:
             # Render environment for last five episodes
-            env.render()
+            #env.render()
             #if i >= (episodes - 20):
             #    env.render()
 
@@ -85,12 +101,16 @@ if __name__ == '__main__':
         # Track rewards
         reward_list.append(tot_reward)
 
-        if (i + 1) % 10 == 0:
+        print_delta = 10
+        if (i + 1) % print_delta == 0:
             ave_reward = np.mean(reward_list)
+            ave_reward_list.append(ave_reward)
             reward_list = []
+            print(
+                'Episode {}-{} Average Reward: {} Epsilon: {}'.format(i - print_delta + 1, i + 1, ave_reward, epsilon))
+            plt.plot(ave_reward_list)
+            plt.pause(0.1)
 
-        if (i + 1) % 10 == 0:
-            print('Episode {} Average Reward: {} Epsilon: {}'.format(i + 1, ave_reward, epsilon))
 
     env.close()
 
diff --git a/documentation/py4j_demo/clean.sh b/documentation/py4j_demo/clean.sh
index 188e0edd..a11acd9c 100755
--- a/documentation/py4j_demo/clean.sh
+++ b/documentation/py4j_demo/clean.sh
@@ -1,4 +1,4 @@
-#/bin/sh
+#!/bin/sh
 
 rm amoeba.jar
 rm ./*.log
diff --git a/documentation/py4j_demo/lunar_lander.py b/documentation/py4j_demo/lunar_lander.py
index b2a2045a..18703cee 100644
--- a/documentation/py4j_demo/lunar_lander.py
+++ b/documentation/py4j_demo/lunar_lander.py
@@ -39,10 +39,12 @@ if __name__ == '__main__':
     time.sleep(2)
 
     gateway = JavaGateway(gateway_parameters=GatewayParameters(auto_convert=True, auto_field=True))
-    gateway.jvm.py4j.Main.Control.setComandLine(True)
+    #gateway.jvm.py4j.Main.Control.setComandLine(True)
 
-    amoeba = gateway.jvm.kernel.AMOEBA("/home/daavve/AMOEBA3/documentation/py4j_demo/bipedal_walker.xml", None)
-    set_field(amoeba.saver, "autoSave", False)
+    amoeba = gateway.jvm.kernel.AMOEBA()
+    backup_sys = gateway.jvm.kernel.backup.BackupSystem(amoeba)
+    file = gateway.jvm.java.io.File("lunar_lander.xml")
+    backup_sys.load(file)
 
     env = gym.make('LunarLander-v2')
     env.reset()
@@ -79,9 +81,6 @@ if __name__ == '__main__':
             env.step(action)
             env.step(action)
             env.step(action)
-            env.step(action)
-            env.step(action)
-            env.step(action)
             state2, reward, done, info = env.step(action)
 
             state_action_list.append((state, action))
@@ -102,12 +101,11 @@ if __name__ == '__main__':
         # Track rewards
         reward_list.append(tot_reward)
 
-        if (i + 1) % 10 == 0:
+        print_delta = 10
+        if (i + 1) % print_delta == 0:
             ave_reward = np.mean(reward_list)
             reward_list = []
-
-        if (i + 1) % 10 == 0:
-            print('Episode {} Average Reward: {} Epsilon: {}'.format(i + 1, ave_reward, epsilon))
+            print('Episode {}-{} Average Reward: {} Epsilon: {}'.format(i - print_delta + 1, i + 1, ave_reward, epsilon))
 
     env.close()
 
diff --git a/documentation/py4j_demo/requirements.txt b/documentation/py4j_demo/requirements.txt
index 22f62fa4..9b4cb9d6 100644
--- a/documentation/py4j_demo/requirements.txt
+++ b/documentation/py4j_demo/requirements.txt
@@ -1,3 +1,4 @@
 py4j==0.10.8.1
 gym
 numpy
+matplotlib
diff --git a/documentation/py4j_demo/setup.sh b/documentation/py4j_demo/setup.sh
index b10c6c08..2f4285d2 100755
--- a/documentation/py4j_demo/setup.sh
+++ b/documentation/py4j_demo/setup.sh
@@ -1,4 +1,5 @@
-#/bin/sh
+#!/bin/sh
 
+sh clean.sh
 (cd ../.. && mvn clean compile assembly:single -Dmain.class=py4j.Main && cp AMOEBAonAMAK/target/AMOEBAonAMAK-1.0-jar-with-dependencies.jar documentation/py4j_demo/amoeba.jar)
 echo "Done. If there's no error."
diff --git a/documentation/ros_demo/clean.sh b/documentation/ros_demo/clean.sh
index dc89b978..25c18588 100755
--- a/documentation/ros_demo/clean.sh
+++ b/documentation/ros_demo/clean.sh
@@ -1,4 +1,4 @@
-#/bin/sh
+#!/bin/sh
 
 rm amoeba.jar
 rm ./*.log
diff --git a/documentation/ros_demo/setup.sh b/documentation/ros_demo/setup.sh
index 40e42afd..1b5b7dd7 100755
--- a/documentation/ros_demo/setup.sh
+++ b/documentation/ros_demo/setup.sh
@@ -1,4 +1,4 @@
-#/bin/sh
+#!/bin/sh
 
 (cd ../.. && mvn clean compile assembly:single -Dmain.class=ros.Main && cp AMOEBAonAMAK/target/AMOEBAonAMAK-1.0-jar-with-dependencies.jar documentation/ros_demo/amoeba.jar)
 (cd catkin_ws/ && catkin_make)
diff --git a/documentation/ros_demo/start.sh b/documentation/ros_demo/start.sh
index 71c11df0..47b64389 100755
--- a/documentation/ros_demo/start.sh
+++ b/documentation/ros_demo/start.sh
@@ -1,4 +1,4 @@
-#/bin/sh
+#!/bin/sh
 
 . ./catkin_ws/devel/setup.sh
 roslaunch amoeba_demo turtle_demo.launch &
diff --git a/documentation/ros_demo/start_amoebas.sh b/documentation/ros_demo/start_amoebas.sh
index cf9a3680..3f0316c9 100755
--- a/documentation/ros_demo/start_amoebas.sh
+++ b/documentation/ros_demo/start_amoebas.sh
@@ -1,4 +1,4 @@
-#/bin/sh
+#!/bin/sh
 
 java -jar amoeba.jar ws://localhost:9090 Amoeba_ros_demo.xml /amoeba_lin /amoeba_lin_res amoeba_demo/Amoeba_msg &
 java -jar amoeba.jar ws://localhost:9090 Amoeba_ros_demo.xml /amoeba_rot /amoeba_rot_res amoeba_demo/Amoeba_msg &
diff --git a/documentation/ros_demo/stop.sh b/documentation/ros_demo/stop.sh
index ddea5577..acbecfe7 100755
--- a/documentation/ros_demo/stop.sh
+++ b/documentation/ros_demo/stop.sh
@@ -1,4 +1,4 @@
-#/bin/sh
+#!/bin/sh
 
 for p in $(ps -A | grep ros | awk '{print $1;}')
 do
-- 
GitLab