diff --git a/.idea/libraries/jfreechart_1_6_0.xml b/.idea/libraries/jfreechart_1_6_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..81658e8f4cb20872e84ae720403f783b6878c836 --- /dev/null +++ b/.idea/libraries/jfreechart_1_6_0.xml @@ -0,0 +1,9 @@ +<component name="libraryTable"> + <library name="jfreechart-1.6.0"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/libs/jfreechart-1.6.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> +</component> \ No newline at end of file diff --git a/executablecode/Makefile.src b/executablecode/Makefile.src index 10b9edc5f5c133db845361973a875e085fa48d5f..2b21a39070bcbe168dfc79673113a530049f595d 100755 --- a/executablecode/Makefile.src +++ b/executablecode/Makefile.src @@ -1 +1 @@ -SRCS = generated_src/main.c generated_src/Receiver.c generated_src/Forwarder.c generated_src/Sender.c \ No newline at end of file +SRCS = generated_src/main.c generated_src/System.c generated_src/Bob.c generated_src/Alice.c \ No newline at end of file diff --git a/launcher/src/main/launcher.iml b/launcher/src/main/launcher.iml index 350eeee3b31b2565a828c07d5f8e87856f692dd3..77beed6a0ca8b773555c54f75a8f0f0abae7ba5e 100644 --- a/launcher/src/main/launcher.iml +++ b/launcher/src/main/launcher.iml @@ -10,5 +10,6 @@ <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="module" module-name="shared" /> + <orderEntry type="library" name="jfreechart-1.6.0" level="project" /> </component> </module> \ No newline at end of file diff --git a/libs/jfreechart-1.6.0.jar b/libs/jfreechart-1.6.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..2878c7168d1bf7b87d4fe01cb48cecea45581641 Binary files /dev/null and b/libs/jfreechart-1.6.0.jar differ diff --git a/modeling/AVATAR/CoffeeMachine_Avatar.xml b/modeling/AVATAR/CoffeeMachine_Avatar.xml index ff5c4f080a101d2b6c4824fc743e86b4561b893d..489d7a4c0a2da7fc274317d0074b3877c4adb951 100644 --- a/modeling/AVATAR/CoffeeMachine_Avatar.xml +++ b/modeling/AVATAR/CoffeeMachine_Avatar.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<TURTLEGMODELING version="1.0beta" ANIMATE_INTERACTIVE_SIMULATION="false" ACTIVATE_PENALTIES="true" UPDATE_INFORMATION_DIPLO_SIM="false" ANIMATE_WITH_INFO_DIPLO_SIM="true" OPEN_DIAG_DIPLO_SIM="false" LAST_SELECTED_MAIN_TAB="1" LAST_SELECTED_SUB_TAB="0"> +<TURTLEGMODELING version="1.0beta" ANIMATE_INTERACTIVE_SIMULATION="false" ACTIVATE_PENALTIES="true" UPDATE_INFORMATION_DIPLO_SIM="false" ANIMATE_WITH_INFO_DIPLO_SIM="true" OPEN_DIAG_DIPLO_SIM="false" LAST_SELECTED_MAIN_TAB="1" LAST_SELECTED_SUB_TAB="1"> <Modeling type="Avatar Requirement" nameTab="AVATAR Requirements" > <AvatarRDPanel name="AVATAR RD" minX="10" maxX="1900" minY="10" maxY="1400" zoom="1.0" > @@ -1279,7 +1279,7 @@ <MainCode value="}"/> <Optimized value="true" /> <considerTimingOperators value="true" /> -<Validated value="" /> +<Validated value="Wallet;CoffeeMachine;TeaButton;CoffeeButton;" /> <Ignored value="" /> <CONNECTOR type="5002" id="695" > diff --git a/src/main/java/avatartranslator/directsimulation/AvatarSimulationRunner.java b/src/main/java/avatartranslator/directsimulation/AvatarSimulationRunner.java new file mode 100644 index 0000000000000000000000000000000000000000..751aa045633635c7e87641c47b78952401ebaf7a --- /dev/null +++ b/src/main/java/avatartranslator/directsimulation/AvatarSimulationRunner.java @@ -0,0 +1,129 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ + + +package avatartranslator.directsimulation; + +import avatartranslator.AvatarBlock; +import avatartranslator.AvatarSpecification; +import avatartranslator.AvatarStateMachineElement; +import myutil.TraceManager; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.Vector; + +/** + * Class AvatarSimulationRunner + * Executor for multiple simulations + * Creation: 08/01/2021 + * + * @author Ludovic APVRILLE + * @version 1.0 08/01/2021 + */ + +public class AvatarSimulationRunner { + + private AvatarSpecification as; + + public ArrayList<AvatarSpecificationSimulation> listOfSimulations; + + public AvatarSimulationRunner(AvatarSpecification _as) { + as = _as; + } + + public synchronized void runXSimulation(int nbOfSimulations, AvatarSimulationRunnerListener listener) { + if (nbOfSimulations < 1) { + return; + } + + listOfSimulations = new ArrayList<>(nbOfSimulations); + + for (int simulationIndex=0; simulationIndex<nbOfSimulations; simulationIndex++) { + //TraceManager.addDev("Simulation #" + simulationIndex); + listener.setSimulationDone(simulationIndex); + AvatarSpecificationSimulation ass = new AvatarSpecificationSimulation(as, null); + listOfSimulations.add(ass); + ass.runSimulationToCompletion(); + } + } + + public synchronized long getMinSimulationTime() { + if (listOfSimulations == null) { + return -1; + } + long minSimTime = Long.MAX_VALUE; + for(AvatarSpecificationSimulation ass: listOfSimulations) { + minSimTime = Math.min(ass.getClockValue(), minSimTime); + } + return minSimTime; + } + + public synchronized long getMaxSimulationTime() { + if (listOfSimulations == null) { + return -1; + } + long maxSimTime = -1; + for(AvatarSpecificationSimulation ass: listOfSimulations) { + maxSimTime = Math.max(ass.getClockValue(), maxSimTime); + } + return maxSimTime; + } + + public synchronized double getAverageSimulationTime() { + if (listOfSimulations == null) { + return -1; + } + double averageSimTime = 0; + for(AvatarSpecificationSimulation ass: listOfSimulations) { + averageSimTime += ass.getClockValue() / listOfSimulations.size(); + } + return averageSimTime; + } + + public synchronized double[] getSimulationTimes() { + double[] values = new double[listOfSimulations.size()]; + for(int i=0; i< listOfSimulations.size(); i++) { + values[i] = listOfSimulations.get(i).getClockValue(); + } + return values; + } + + +} diff --git a/src/main/java/avatartranslator/directsimulation/AvatarSimulationTransaction.java b/src/main/java/avatartranslator/directsimulation/AvatarSimulationTransaction.java index 38b52722c0916277adadb4c6c7681a6522f8d94e..83c52358d5bfe3b2e22ecee8c9f1d67a75135429 100644 --- a/src/main/java/avatartranslator/directsimulation/AvatarSimulationTransaction.java +++ b/src/main/java/avatartranslator/directsimulation/AvatarSimulationTransaction.java @@ -1,26 +1,26 @@ /* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille - * + * * ludovic.apvrille AT enst.fr - * + * * This software is a computer program whose purpose is to allow the * edition of TURTLE analysis, design and deployment diagrams, to * allow the generation of RT-LOTOS or Java code from this diagram, * and at last to allow the analysis of formal validation traces * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP * from INRIA Rhone-Alpes. - * + * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". - * + * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. - * + * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, @@ -31,15 +31,12 @@ * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. - * + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. */ - - - package avatartranslator.directsimulation; import avatartranslator.AvatarBlock; @@ -50,13 +47,14 @@ import java.util.LinkedList; import java.util.Vector; /** - * Class AvatarSimulationTransaction - * Avatar: notion of transaction in simulation - * Creation: 14/12/2010 - * @version 1.0 14/12/2010 - * @author Ludovic APVRILLE + * Class AvatarSimulationTransaction + * Avatar: notion of transaction in simulation + * Creation: 14/12/2010 + * + * @author Ludovic APVRILLE + * @version 1.0 14/12/2010 */ -public class AvatarSimulationTransaction { +public class AvatarSimulationTransaction { public static long ID; public static Hashtable<AvatarStateMachineElement, Integer> hashOfAllElements; @@ -82,7 +80,7 @@ public class AvatarSimulationTransaction { public Vector<String> attributeValues; public Vector<String> actions; - public int x,y; // for graphical representation only + public int x, y; // for graphical representation only public long stamp; public AvatarSimulationAsynchronousTransaction sentMessage; @@ -113,22 +111,22 @@ public class AvatarSimulationTransaction { if (val == null) { hashOfAllElements.put(_asme, new Integer(1)); } else { - hashOfAllElements.put(_asme, new Integer(1+val.intValue())); + hashOfAllElements.put(_asme, new Integer(1 + val.intValue())); } } public static void removeExecutedElement(AvatarStateMachineElement _asme) { if (!allExecutedElements.contains(_asme)) { - return ; + return; } Integer val = hashOfAllElements.get(_asme); if (val == null) { - return ; + return; } - hashOfAllElements.put(_asme, new Integer(val.intValue()-1)); + hashOfAllElements.put(_asme, new Integer(val.intValue() - 1)); } @@ -144,7 +142,7 @@ public class AvatarSimulationTransaction { } public String toString() { - String res = "" + id + " bunchid:" + bunchid + " @" + clockValueWhenFinished + "/ " + duration + ": " +executedElement + " in block " + block.getName(); + String res = "" + id + " bunchid:" + bunchid + " @" + clockValueWhenFinished + "/ " + duration + ": " + executedElement + " in block " + block.getName(); if (silent) { res += " (silent)"; } @@ -156,20 +154,45 @@ public class AvatarSimulationTransaction { } } res += "\nattributes="; - for(String s: attributeValues) { + for (String s : attributeValues) { res += s + " "; } if (actions != null) { int cpt = 0; - res+= "\n"; - for(String action: actions) { + res += "\n"; + for (String action : actions) { res += "action#" + cpt + ": " + action + " "; - cpt ++; + cpt++; } } return res; } + public String getAttributesString() { + String res = ""; + for (String s : attributeValues) { + res += s + " "; + } + return res; + } + + public String getActionsString() { + if ((actions == null) || (actions.size() == 0)) { + return "null"; + } + + String res = ""; + + int cpt = 0; + //res+= "\n"; + for (String action : actions) { + res += "action#" + cpt + ": " + action + " "; + cpt++; + } + + return res; + } + public boolean setAttributeValue(int _index, String _value) { if (_index >= attributeValues.size()) { return false; diff --git a/src/main/java/avatartranslator/directsimulation/AvatarSpecificationSimulation.java b/src/main/java/avatartranslator/directsimulation/AvatarSpecificationSimulation.java index 13bfbedd912055476c1eb7af5c306ea39250d638..ea34e94d50c3e066300e69dd829aef9fef7607a2 100644 --- a/src/main/java/avatartranslator/directsimulation/AvatarSpecificationSimulation.java +++ b/src/main/java/avatartranslator/directsimulation/AvatarSpecificationSimulation.java @@ -56,6 +56,9 @@ import java.util.Vector; * @version 1.0 13/12/2010 */ public class AvatarSpecificationSimulation { + + public final static String COMMA = ", "; + public static int MAX_TRANSACTION_IN_A_ROW = 1000; public static int MAX_TRANSACTIONS = 100000; @@ -227,6 +230,25 @@ public class AvatarSpecificationSimulation { // Control function + public void runSimulationToCompletion() { + Thread t = new Thread() { + public void run() { + runSimulation(); + } + }; + + t.start(); + goSimulation(); + try { + while(getState() != TERMINATED) { + Thread.currentThread().sleep(25); + //TraceManager.addDev("Waiting for termination"); + }; + killSimulation(); + t.join(); + } catch (InterruptedException ie) {} + } + public void runSimulation() { int index[]; Vector<AvatarSimulationPendingTransaction> selectedTransactions; @@ -350,18 +372,18 @@ public class AvatarSpecificationSimulation { break; case TERMINATED: - TraceManager.addDev("-> -> TERMINATED"); + //TraceManager.addDev("-> -> TERMINATED"); waitForResetOrNewState(); break; case KILLED: - TraceManager.addDev("-> -> KILLED"); - TraceManager.addDev("Simulation killed"); + //TraceManager.addDev("-> -> KILLED"); + //TraceManager.addDev("Simulation killed"); return; default: TraceManager.addDev("-> -> UNKNOWN"); - TraceManager.addDev("Unknown state"); + //TraceManager.addDev("Unknown state"); setState(KILLED); } @@ -1586,4 +1608,64 @@ public class AvatarSpecificationSimulation { return found; } + + public String toCSV() { + StringBuffer sb = new StringBuffer(); + + sb.append("ID, block, element ID, linked transaction ID, initial clock value, final clock value, duration, attributes, actions\n"); + for(AvatarSimulationTransaction ast: allTransactions) { + append(sb, ast.id); + append(sb, ast.block); + append(sb, ast.executedElement); + append(sb, ast.linkedTransaction); + append(sb, ast.initialClockValue); + append(sb, ast.clockValueWhenFinished); + append(sb, ast.duration); + append(sb, ast.getAttributesString()); + sb.append(ast.getActionsString()); + sb.append("\n"); + } + + + return sb.toString(); + } + + public void append(StringBuffer sb, String s) { + if ((s == null) || (s.length() ==0)) { + sb.append("null" + COMMA); + } else { + sb.append(s + COMMA); + } + } + + public void append(StringBuffer sb, long s) { + sb.append(s + COMMA); + } + + public void append(StringBuffer sb, AvatarBlock b) { + if (b == null) { + sb.append("__Unknown" + COMMA); + } else { + sb.append(b.getName() + COMMA); + } + } + + public void append(StringBuffer sb, AvatarStateMachineElement asme) { + if (asme == null) { + sb.append("-1" + COMMA); + } else { + sb.append(asme.getID() + COMMA); + } + } + + public void append(StringBuffer sb, AvatarSimulationTransaction ast) { + if (ast == null) { + sb.append("-1" + COMMA); + } else { + sb.append(ast.bunchid + COMMA); + } + } + + + } diff --git a/src/main/java/cli/Action.java b/src/main/java/cli/Action.java index c12ae2b97694780b64db497c5e26e4930490944c..b6323645fe5c4c763a4895939e48a8c1a0d99065 100644 --- a/src/main/java/cli/Action.java +++ b/src/main/java/cli/Action.java @@ -40,6 +40,7 @@ package cli; import avatartranslator.AvatarSpecification; +import avatartranslator.directsimulation.AvatarSpecificationSimulation; import avatartranslator.modelchecker.AvatarModelChecker; import avatartranslator.modelchecker.CounterexampleQueryReport; import avatartranslator.modelchecker.SpecificationActionLoop; @@ -97,6 +98,7 @@ public class Action extends Command { private final static String DIPLO_UPPAAL = "diplodocus-uppaal"; private final static String DIPLO_REMOVE_NOC = "diplodocus-remove-noc"; + private final static String NAVIGATE_PANEL_TO_LEFT = "navigate-panel-to-left"; private final static String NAVIGATE_PANEL_TO_RIGHT = "navigate-panel-to-right"; @@ -106,7 +108,10 @@ public class Action extends Command { private final static String AVATAR_RG_GENERATION = "avatar-rg"; private final static String AVATAR_UPPAAL_VALIDATE = "avatar-rg-validate"; + private final static String AVATAR_SIMULATION_TO_BRK = "avatar-simulation-to-brk"; + + private AvatarSpecificationSimulation ass; public Action() { @@ -751,6 +756,12 @@ public class Action extends Command { } }; + + + + + + // PANEL manipulation Command selectPanel = new Command() { public String getCommand() { return SELECT_PANEL; @@ -1259,6 +1270,58 @@ public class Action extends Command { } }; + // AVATAR + Command avatarSimulationToBrk = new Command() { + public String getCommand() { + return AVATAR_SIMULATION_TO_BRK; + } + + public String getShortCommand() { + return "astb"; + } + + public String getDescription() { + return "Simulate an avatar design until a breakpoint or the end"; + } + + public String executeCommand(String command, Interpreter interpreter) { + if (!interpreter.isTToolStarted()) { + return Interpreter.TTOOL_NOT_STARTED; + } + + AvatarSpecification as = interpreter.mgui.gtm.getAvatarSpecification(); + + if (as == null) { + return "No model for simulation"; + } + + ass = new AvatarSpecificationSimulation(as, null); + ass.runSimulationToCompletion(); + + /*Thread t = new Thread() { + public void run() { + ass.runSimulation(); + } + }; + + t.start(); + ass.goSimulation(); + try { + while(ass.getState() != ass.TERMINATED) { + Thread.currentThread().sleep(25); + //TraceManager.addDev("Waiting for termination"); + }; + ass.killSimulation(); + t.join(); + } catch (InterruptedException ie) {}*/ + + TraceManager.addUser("Simulation terminated. End time=" + ass.getClockValue()); + + + return null; + } + }; + Command generic = new Generic(); @@ -1289,6 +1352,7 @@ public class Action extends Command { addAndSortSubcommand(movePanelToTheRightPanel); addAndSortSubcommand(selectPanel); addAndSortSubcommand(compareUppaal); + addAndSortSubcommand(avatarSimulationToBrk); addAndSortSubcommand(generic); } diff --git a/src/main/java/ui/avatarinteractivesimulation/AvatarInteractiveSimulationActions.java b/src/main/java/ui/avatarinteractivesimulation/AvatarInteractiveSimulationActions.java index ae9950ed37186e9eb5f037c0e9a73c965886efdb..3e5226420c6cb8b1c27ae1e252501be393950dc9 100755 --- a/src/main/java/ui/avatarinteractivesimulation/AvatarInteractiveSimulationActions.java +++ b/src/main/java/ui/avatarinteractivesimulation/AvatarInteractiveSimulationActions.java @@ -76,6 +76,7 @@ public class AvatarInteractiveSimulationActions extends AbstractAction { public static final int ACT_SAVE_SD_PNG = 10; public static final int ACT_SAVE_SVG = 11; public static final int ACT_SAVE_TXT = 12; + public static final int ACT_SAVE_CSV = 37; public static final int ACT_PRINT_BENCHMARK = 26; public static final int ACT_SAVE_BENCHMARK = 27; @@ -104,7 +105,8 @@ public class AvatarInteractiveSimulationActions extends AbstractAction { public static final int ACT_DOWN_ASYNC_MSG = 34; public static final int ACT_ADD_LATENCY = 35; public static final int ACT_REMOVE_ALL_TRANS = 36; - public static final int NB_ACTION = 37; + + public static final int NB_ACTION = 38; private static final TAction[] actions = new TAction[NB_ACTION]; @@ -164,6 +166,9 @@ public class AvatarInteractiveSimulationActions extends AbstractAction { actions[ACT_SAVE_SD_PNG] = new TAction("save-sd-png", "Save SD trace in PNG format", IconManager.imgic5104, IconManager.imgic5104, "Save SD trace in PNG format", "Save SD trace in PNG format", '0'); actions[ACT_SAVE_SVG] = new TAction("save-svg", "Save trace in SVG format", IconManager.imgic1328, IconManager.imgic1328, "Save trace in SVG format", "Save trace in SVG format", 'R'); actions[ACT_SAVE_TXT] = new TAction("save-txt", "Save trace in TXT format", IconManager.imgic1314, IconManager.imgic1314, "Save trace in TXT format", "Save trace in TXT format", 'R'); + actions[ACT_SAVE_CSV] = new TAction("save-csv", "Save trace in CSV format", IconManager.imgic1334, IconManager.imgic1334, "Save trace in " + + "CSV " + + "format", "Save trace in CSV format", 'V'); actions[ACT_SAVE_STATE] = new TAction("save-state", "Save simulation state in File", IconManager.imgic341, IconManager.imgic341, "Save simulation state in File", "Save simulation state in File", 'R'); actions[ACT_RESTORE_STATE] = new TAction("restore-state", "Restore simulation state from File", IconManager.imgic339, IconManager.imgic339, "Restore simulation state from File", "Restore simulation state from File", 'R'); diff --git a/src/main/java/ui/avatarinteractivesimulation/AvatarSaveCommandsToolBar.java b/src/main/java/ui/avatarinteractivesimulation/AvatarSaveCommandsToolBar.java index de049ddf1473237dc800a146281a58da10f5e8fe..f35ba92a96c847d47aa55b6917e1ec9c49624fd5 100755 --- a/src/main/java/ui/avatarinteractivesimulation/AvatarSaveCommandsToolBar.java +++ b/src/main/java/ui/avatarinteractivesimulation/AvatarSaveCommandsToolBar.java @@ -61,6 +61,7 @@ public class AvatarSaveCommandsToolBar extends AvatarInteractiveSimulationBar { jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_SD_PNG].setEnabled(b); jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_SVG].setEnabled(b); jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_TXT].setEnabled(b); + jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_CSV].setEnabled(b); } protected void setButtons() { @@ -78,6 +79,11 @@ public class AvatarSaveCommandsToolBar extends AvatarInteractiveSimulationBar { button = this.add(jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_TXT]); button.addMouseListener(jfais.mouseHandler); + + this.addSeparator(); + + button = this.add(jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_CSV]); + button.addMouseListener(jfais.mouseHandler); } } // Class diff --git a/src/main/java/ui/avatarinteractivesimulation/AvatarSimulationStatisticsPanel.java b/src/main/java/ui/avatarinteractivesimulation/AvatarSimulationStatisticsPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..1c6ebff8ca6b8a2e9119aa1dfd751d44442bee39 --- /dev/null +++ b/src/main/java/ui/avatarinteractivesimulation/AvatarSimulationStatisticsPanel.java @@ -0,0 +1,267 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ + + + + + +package ui.avatarinteractivesimulation; + +import avatartranslator.*; +import avatartranslator.directsimulation.*; +import myutil.GraphicLib; +import myutil.TraceManager; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.data.statistics.HistogramDataset; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import ui.ColorManager; +import ui.MainGUI; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Vector; + +/** + * Class AvatarSimulationStatisticsPanel + * Avatar: panel for performing simulations and displaying statistics + * Creation: 08/01/2021 + * @version 1.0 08/01/2021 + * @author Ludovic APVRILLE + */ +public class AvatarSimulationStatisticsPanel extends JPanel implements ActionListener, AvatarSimulationRunnerListener { + private MainGUI mgui; + + // Graphical components + private JButton runSimulations; + private JTextField nbOfSimulationsText; + + + private JLabel simulationsDone; + private JLabel totalSimulations; + + private JLabel minSimulationTime; + private JLabel averageSimulationTime; + private JLabel maxSimulationTime; + + private JButton showSimulationTimeHistogram; + + + // Simulation data structures + private int totalNbOfSimulations; + private AvatarSimulationRunner sr; + + + + + public AvatarSimulationStatisticsPanel(MainGUI _mgui) { + mgui = _mgui; + makeComponents(); + } + + public void makeComponents() { + + + GridBagLayout gridbag2 = new GridBagLayout(); + GridBagConstraints c2 = new GridBagConstraints(); + setLayout(gridbag2); + //setBorder(new javax.swing.border.TitledBorder("Managing transactions")); + + // Simulations + c2.weighty = 1.0; + c2.weightx = 1.0; + c2.fill = GridBagConstraints.HORIZONTAL; + c2.gridheight = 1; + c2.gridwidth = 1; + runSimulations = new JButton("Execute"); + runSimulations.addActionListener(this); + add(runSimulations, c2); + nbOfSimulationsText = new JTextField("100", 10); + add(nbOfSimulationsText, c2); + c2.gridwidth = GridBagConstraints.REMAINDER; + add(new JLabel("simulations"), c2); + + add(new JLabel(""), c2); + add(new JLabel("Simulation progression"), c2); + c2.gridwidth = 1; + simulationsDone = new JLabel ("-"); + totalSimulations = new JLabel("-"); + add(simulationsDone, c2); + add(new JLabel("/"), c2); + c2.gridwidth = GridBagConstraints.REMAINDER; + add(totalSimulations, c2); + + // **** Stats **** + + // Simulation time + add(new JLabel("Simulation time (min, max, average)"), c2); + c2.gridwidth = 1; + minSimulationTime = new JLabel("-"); + add(minSimulationTime, c2); + averageSimulationTime = new JLabel("-"); + add(averageSimulationTime, c2); + c2.gridwidth = GridBagConstraints.REMAINDER; + maxSimulationTime = new JLabel("-"); + add(maxSimulationTime, c2); + + showSimulationTimeHistogram = new JButton("Show simulation time stats"); + add(showSimulationTimeHistogram, c2); + showSimulationTimeHistogram.setEnabled(false); + showSimulationTimeHistogram.addActionListener(this); + + + } + + public void actionPerformed(ActionEvent ae) { + if (ae.getSource() == runSimulations) { + runSimulations(); + } else if (ae.getSource() == showSimulationTimeHistogram) { + showTimeHistogram(); + } + } + + private void showTimeHistogram() { + TraceManager.addDev("Show time histogram"); + JPanel panel = new JPanel(new BorderLayout()); + + /*XYSeries series = new XYSeries("XYGraph"); + series.add(1, 1); + series.add(1, 2); + series.add(2, 1); + series.add(3, 9); + series.add(4, 10); + +// Add the series to your data set + XYSeriesCollection dataset = new XYSeriesCollection(); + dataset.addSeries(series); + +// Generate the graph + JFreeChart chart = ChartFactory.createXYLineChart( + "XY Chart", // Title + "x-axis", // x-axis Label + "y-axis", // y-axis Label + dataset, // Dataset + PlotOrientation.VERTICAL, // Plot Orientation + true, // Show Legend + true, // Use tooltips + false // Configure chart to generate URLs? + );*/ + + HistogramDataset dataset = new HistogramDataset(); + double []values = sr.getSimulationTimes(); + dataset.addSeries("key", values, 20); + + JFreeChart histogram = ChartFactory.createHistogram("Histogram: Simulation times", + "Simulation times", "Frequency", dataset); + + ChartPanel myChart = new ChartPanel(histogram); + myChart.setMouseWheelEnabled(true); + panel.add(myChart,BorderLayout.CENTER); + panel.validate(); + JFrame frame = new JFrame(); + frame.setTitle("Simulation times"); + frame.setSize(500, 500); + frame.setContentPane(panel); + frame.setVisible(true); + TraceManager.addDev("Frame is now visible"); + } + + + private void runSimulations() { + if (mgui.gtm.getAvatarSpecification() == null) { + return; + } + + int nbOfsimulations; + + try { + nbOfsimulations = new Integer(nbOfSimulationsText.getText()).intValue(); + } catch (Exception e) { + return; + } + + if (nbOfsimulations < 1) { + return; + } + + runSimulations.setEnabled(false); + sr = new AvatarSimulationRunner(mgui.gtm.getAvatarSpecification()); + + totalNbOfSimulations = nbOfsimulations; + totalSimulations.setText(""+nbOfsimulations); + + Thread simuExecutor = new Thread(() -> sr.runXSimulation(nbOfsimulations, this)); + simuExecutor.start(); + + + + } + + public void printStats() { + long minSimTime = sr.getMinSimulationTime(); + minSimulationTime.setText(""+minSimTime); + + double averageSimTime = sr.getAverageSimulationTime(); + averageSimulationTime.setText(""+averageSimTime); + + long maxSimTime = sr.getMaxSimulationTime(); + maxSimulationTime.setText(""+maxSimTime); + + showSimulationTimeHistogram.setEnabled(true); + } + + + @Override + public void setSimulationDone(int nb) { + simulationsDone.setText(""+(nb+1)); + if (nb >= (totalNbOfSimulations-1)) { + runSimulations.setEnabled(true); + printStats(); + } + } +} diff --git a/src/main/java/ui/avatarinteractivesimulation/JFrameAvatarInteractiveSimulation.java b/src/main/java/ui/avatarinteractivesimulation/JFrameAvatarInteractiveSimulation.java index 060fd547cd80d8c57ae55b58676278637bffd57c..458dc6cd7a5a190cd593a3a0646c2499ebbb2aec 100755 --- a/src/main/java/ui/avatarinteractivesimulation/JFrameAvatarInteractiveSimulation.java +++ b/src/main/java/ui/avatarinteractivesimulation/JFrameAvatarInteractiveSimulation.java @@ -542,6 +542,10 @@ public class JFrameAvatarInteractiveSimulation extends JFrame implements AvatarS jp01.add(jp02, BorderLayout.CENTER); + AvatarSimulationStatisticsPanel assp = new AvatarSimulationStatisticsPanel(mgui); + commandTab.addTab("Statistics", null, assp, "Run x simulations and perform statistics"); + + // Benchmark commands /*jp01 = new JPanel(new BorderLayout()); @@ -1287,6 +1291,7 @@ public class JFrameAvatarInteractiveSimulation extends JFrame implements AvatarS actions[AvatarInteractiveSimulationActions.ACT_SAVE_SD_PNG].setEnabled(b); actions[AvatarInteractiveSimulationActions.ACT_SAVE_SVG].setEnabled(b); actions[AvatarInteractiveSimulationActions.ACT_SAVE_TXT].setEnabled(b); + actions[AvatarInteractiveSimulationActions.ACT_SAVE_CSV].setEnabled(b); actions[AvatarInteractiveSimulationActions.ACT_PRINT_BENCHMARK].setEnabled(b); actions[AvatarInteractiveSimulationActions.ACT_SAVE_BENCHMARK].setEnabled(b); actions[AvatarInteractiveSimulationActions.ACT_ZOOM_IN].setEnabled(b); @@ -1842,6 +1847,67 @@ public class JFrameAvatarInteractiveSimulation extends JFrame implements AvatarS //ass.printExecutedTransactions(); } + public void actSaveCSV() { + TraceManager.addDev("Saving in CSV format"); + String fileName = saveFileName.getText().trim(); + + if (fileName.length() == 0) { + fileName += "simulationtrace_fromttool.csv"; + } + + if (ConfigurationTTool.isConfigured(ConfigurationTTool.IMGPath)) { + fileName = ConfigurationTTool.IMGPath + System.getProperty("file.separator") + fileName; + } else { + // Using model directory + String path = mgui.getModelFileFullPath(); + fileName = path.substring(0, path.lastIndexOf(File.separator) + 1) + fileName; + TraceManager.addDev("New Filename = " + fileName); + } + + + boolean ok = true; + + try { + ok = FileUtils.checkFileForSave(new File(fileName)); + } catch (Exception e) { + TraceManager.addDev("Exception=" + e.getMessage()); + ok = false; + } + + if (!ok) { + JOptionPane.showMessageDialog(this, + "The capture could not be performed: the file name or path is not valid", + "Error", + JOptionPane.INFORMATION_MESSAGE); + return; + } + + + try { + FileUtils.saveFile(fileName, ass.toCSV()); + + } catch (Exception e) { + JOptionPane.showMessageDialog(this, + "The simulation trace in text format could not be saved: " + e.getMessage(), + "Error", + JOptionPane.INFORMATION_MESSAGE); + return; + } + + /*JOptionPane.showMessageDialog(this, + "Simulation trace was saved in " + fileName, + "Error", + JOptionPane.INFORMATION_MESSAGE);*/ + + String shortFileName; + File f = new File(fileName); + shortFileName = f.getName(); + SimulationTrace st = new SimulationTrace(shortFileName, SimulationTrace.TXT_AVATAR, fileName); + mgui.addSimulationTrace(st); + + //ass.printExecutedTransactions(); + } + public void actSaveSvg() { TraceManager.addDev("Saving in svg format"); @@ -2119,6 +2185,10 @@ public class JFrameAvatarInteractiveSimulation extends JFrame implements AvatarS actSaveTxt(); return; + } else if (command.equals(actions[AvatarInteractiveSimulationActions.ACT_SAVE_CSV].getActionCommand())) { + actSaveCSV(); + return; + } else if (command.equals(actions[AvatarInteractiveSimulationActions.ACT_SAVE_SD_PNG].getActionCommand())) { actSaveSDPNG(); return; diff --git a/src/main/java/ui/util/IconManager.java b/src/main/java/ui/util/IconManager.java index 6675fdbff283e35db60e15788d2169a6aab52752..68b8a5bdf74286beab79d4535fd70b514f6c9bdd 100755 --- a/src/main/java/ui/util/IconManager.java +++ b/src/main/java/ui/util/IconManager.java @@ -136,7 +136,7 @@ public class IconManager { public static ImageIcon imgic1300, imgic1302, imgic1304, imgic1306, imgic1308; public static ImageIcon imgic1310, imgic1312, imgic1314, imgic1316, imgic1318; public static ImageIcon imgic1320, imgic1322, imgic1324, imgic1326, imgic1328; - public static ImageIcon imgic1330, imgic1332; + public static ImageIcon imgic1330, imgic1332, imgic1334; // SMD diagram @@ -572,6 +572,7 @@ public class IconManager { private static String icon1328 = "savesvg24.gif"; private static String icon1330 = "stepforwardx24.gif"; private static String icon1332 = "savexml24.gif"; + private static String icon1334 = "savecsv24.gif"; // SMD diagrams private static String icon2000 = "prosmdsendmsg.gif"; @@ -1108,6 +1109,7 @@ public class IconManager { imgic1328 = getIcon(icon1328); imgic1330 = getIcon(icon1330); imgic1332 = getIcon(icon1332); + imgic1334 = getIcon(icon1334); imgic2000 = getIcon(icon2000); imgic2002 = getIcon(icon2002); diff --git a/src/main/resources/ui/util/savecsv24.gif b/src/main/resources/ui/util/savecsv24.gif new file mode 100644 index 0000000000000000000000000000000000000000..eb025b9264d643a37b4f71248e1e528a94c645a6 Binary files /dev/null and b/src/main/resources/ui/util/savecsv24.gif differ diff --git a/ttool-cli/ttool-cli.iml b/ttool-cli/ttool-cli.iml index 9f33527513989b508cf5b042246ea37a9e28df99..a3dbeaba4633013bf288bd3693a6abc62b37c923 100644 --- a/ttool-cli/ttool-cli.iml +++ b/ttool-cli/ttool-cli.iml @@ -12,5 +12,6 @@ <orderEntry type="module" module-name="shared" /> <orderEntry type="library" name="Gradle: json-java" level="project" /> <orderEntry type="library" name="libs" level="project" /> + <orderEntry type="library" name="jfreechart-1.6.0" level="project" /> </component> </module> \ No newline at end of file diff --git a/ttool/build.gradle b/ttool/build.gradle index ec9c987a0cd69501ea1105a70e7c0b5a4fa7e197..9884471a976d8866a9adc59adff9d201ed5883c7 100644 --- a/ttool/build.gradle +++ b/ttool/build.gradle @@ -52,6 +52,7 @@ dependencies { compile name: 'jgrapht-ext-1.3.0' compile name: 'jgrapht-io-1.3.0' compile name: 'jgraphx-3.4.1.3' + compile name: 'jfreechart-1.6.0' // Use JUnit test framework diff --git a/ttool/src/main/ttool.iml b/ttool/src/main/ttool.iml index 20494ba032313760324154edee0713b4b7b0c3c4..251a16403910e1bcc980f539886e9d952bb4ec6c 100644 --- a/ttool/src/main/ttool.iml +++ b/ttool/src/main/ttool.iml @@ -34,5 +34,6 @@ </orderEntry> <orderEntry type="library" name="Gradle: json-java" level="project" /> <orderEntry type="library" name="libs" level="project" /> + <orderEntry type="library" name="jfreechart-1.6.0" level="project" /> </component> </module> \ No newline at end of file diff --git a/ttool/ttool.txt b/ttool/ttool.txt index 9582490f79cee1c66410a17aeabd7ae22e5af437..8950236ff453ae83fe7ce2edec6c8dc215e42f11 100755 --- a/ttool/ttool.txt +++ b/ttool/ttool.txt @@ -1,2 +1,2 @@ Main-Class: Main -Class-Path: ./opencloud.jar ./JavaPlot.jar ./derbynet.jar ./commons-math3-3.6.1.jar ./jsoup-1.8.1.jar ./commons-codec-1.10.jar ./gs-core-2.0.jar ./gs-core-2.0.jar ./gs-ui-swing-2.0.jar ./commons-io-2.5.jar ./batik-codec.jar ./batik-constants.jar ./batik-xml.jar ./batik-ext.jar ./batik-extensions.jar ./batik-util.jar ./batik-svggen.jar ./batik-dom.jar ./batik-awt-util.jar xml-apis.jar ./jautomata-core.jar ./com.microsoft.z3.jar ./jgrapht-core-1.3.0.jar ./jgrapht-ext-1.3.0.jar ./jgrapht-io-1.3.0.jar ./jgraphx-3.4.1.3.jar ./json-java.jar +Class-Path: ./opencloud.jar ./JavaPlot.jar ./derbynet.jar ./commons-math3-3.6.1.jar ./jsoup-1.8.1.jar ./commons-codec-1.10.jar ./gs-core-2.0.jar ./gs-core-2.0.jar ./gs-ui-swing-2.0.jar ./commons-io-2.5.jar ./batik-codec.jar ./batik-constants.jar ./batik-xml.jar ./batik-ext.jar ./batik-extensions.jar ./batik-util.jar ./batik-svggen.jar ./batik-dom.jar ./batik-awt-util.jar xml-apis.jar ./jautomata-core.jar ./com.microsoft.z3.jar ./jgrapht-core-1.3.0.jar ./jgrapht-ext-1.3.0.jar ./jgrapht-io-1.3.0.jar ./jgraphx-3.4.1.3.jar ./json-java.jar ./jfreechart-1.6.0.jar