diff --git a/executablecode/Makefile.src b/executablecode/Makefile.src index 28b9acb23f0af46aef4caec4f72c265800a703d3..1a5aafcafa7abcf094ea1b3c9d8808777263ed3e 100755 --- a/executablecode/Makefile.src +++ b/executablecode/Makefile.src @@ -1 +1 @@ -SRCS = generated_src/main.c generated_src/ObserverProp1.c generated_src/RemotelyControlledMicrowave.c generated_src/RemoteControl.c generated_src/MicroWaveOven.c generated_src/Bell.c generated_src/ControlPanel.c generated_src/Controller.c generated_src/Magnetron.c generated_src/Door.c generated_src/WirelessInterface.c \ No newline at end of file +SRCS = generated_src/main.c generated_src/ObserverProp1.c generated_src/RemotelyControlledMicrowave.c generated_src/MicroWaveOven.c generated_src/WirelessInterface.c generated_src/Door.c generated_src/Magnetron.c generated_src/Controller.c generated_src/ControlPanel.c generated_src/Bell.c generated_src/RemoteControl.c \ No newline at end of file diff --git a/executablecode/src/message.c b/executablecode/src/message.c index bea6d5cc4c756b0d6736425e0bb1fba8dd4ec981..1153a882f51d93d8596621162f82278bc01d7158 100644 --- a/executablecode/src/message.c +++ b/executablecode/src/message.c @@ -1,10 +1,27 @@ #include <stdlib.h> #include <unistd.h> +#include <pthread.h> #include "message.h" #include "myerrors.h" +long __id_message = 0; +pthread_mutex_t __message_mutex; + + +void initMessages() { + if (pthread_mutex_init(&__message_mutex, NULL) < 0) { exit(-1);} +} + +long getMessageID() { + long tmp; + pthread_mutex_lock(&__message_mutex); + tmp = __id_message; + __id_message ++; + pthread_mutex_unlock(&__message_mutex); + return tmp; +} message *getNewMessageWithParams(int nbOfParams) { @@ -13,7 +30,8 @@ message *getNewMessageWithParams(int nbOfParams) { criticalError("Allocation of request failed"); } msg->nbOfParams = nbOfParams; - msg->params = (int *)(malloc(sizeof(int) * nbOfParams));; + msg->params = (int *)(malloc(sizeof(int) * nbOfParams)); + msg->id = getMessageID(); return msg; } @@ -25,6 +43,7 @@ message *getNewMessage(int nbOfParams, int *params) { } msg->nbOfParams = nbOfParams; msg->params = params; + msg->id = getMessageID(); return msg; } diff --git a/executablecode/src/message.h b/executablecode/src/message.h index 59b99e8c903257cf730b6919af983c1f45de4623..700ed07d97f6ae925ceeb6c172238a2f4bd37680 100644 --- a/executablecode/src/message.h +++ b/executablecode/src/message.h @@ -6,12 +6,14 @@ struct message { struct message *next; int nbOfParams; int *params; + long id; }; typedef struct message message; +void initMessages(); message *getNewMessageWithParams(int nbOfParams); -message * getNewMessage(int nbOfParams, int *params); +message *getNewMessage(int nbOfParams, int *params); void destroyMessageWithParams(message *msg); void destroyMessage(message *msg); diff --git a/executablecode/src/request.c b/executablecode/src/request.c index d91bfcf7a348171187b7e0ed5f9b8e678879139b..63d7f7eb8f94166bcafbccdb4950c5b8cdafd81b 100644 --- a/executablecode/src/request.c +++ b/executablecode/src/request.c @@ -30,8 +30,6 @@ void makeNewRequest(request *req, int ID, int type, int hasDelay, long minDelay, req->listOfRequests = NULL; req->nextRequestInList = NULL; - req->linkedTo = NULL; - req->type = type; req->ID = ID; req->hasDelay = hasDelay; diff --git a/executablecode/src/request.h b/executablecode/src/request.h index 61369a80309dcb8e1871bcf65165ce953e817f03..00b93c8e5a007e2eecf6bde40417cdfb9457edc2 100644 --- a/executablecode/src/request.h +++ b/executablecode/src/request.h @@ -43,8 +43,6 @@ struct request { struct request* relatedRequest; // For synchro and broadcast struct syncchannel *syncChannel; struct asyncchannel *asyncChannel; - - struct request *linkedTo; int type; int ID; diff --git a/executablecode/src/request_manager.c b/executablecode/src/request_manager.c index 1b22d997147f459350374f2b8bedd75b8661b577..3976fb17a11ac6cabc26bf8ac7b29a4875d58cd8 100644 --- a/executablecode/src/request_manager.c +++ b/executablecode/src/request_manager.c @@ -9,6 +9,7 @@ #include "mytimelib.h" #include "random.h" #include "asyncchannel.h" +#include "tracemanager.h" @@ -43,7 +44,6 @@ void executeSendSyncTransaction(request *req) { //req->syncChannel->inWaitQueue = removeRequestFromList(req->syncChannel->inWaitQueue, selectedReq); debugMsg("Setting related request"); req->relatedRequest = selectedReq; - req->linkedTo = selectedReq; // Select the selected request, and notify the information selectedReq->selected = 1; @@ -54,6 +54,8 @@ void executeSendSyncTransaction(request *req) { debugMsg("Signaling"); pthread_cond_signal(selectedReq->listOfRequests->wakeupCondition); + + traceSynchroRequest(req, selectedReq); } void executeReceiveSyncTransaction(request *req) { @@ -84,7 +86,6 @@ void executeReceiveSyncTransaction(request *req) { //req->syncChannel->outWaitQueue = removeRequestFromList(req->syncChannel->outWaitQueue, selectedReq); debugMsg("Setting related request"); req->relatedRequest = selectedReq; - selectedReq->linkedTo = req; // Select the request, and notify the information in the channel selectedReq->selected = 1; @@ -95,6 +96,8 @@ void executeReceiveSyncTransaction(request *req) { debugMsg("Signaling"); pthread_cond_signal(selectedReq->listOfRequests->wakeupCondition); + + traceSynchroRequest(selectedReq, req); } @@ -115,6 +118,8 @@ void executeSendAsyncTransaction(request *req) { pthread_cond_signal(selectedReq->listOfRequests->wakeupCondition); selectedReq = selectedReq->next; } + + traceAsynchronousSendRequest(req); } void executeReceiveAsyncTransaction(request *req) { @@ -131,6 +136,8 @@ void executeReceiveAsyncTransaction(request *req) { *(req->params[i]) = req->msg->params[i]; } + traceAsynchronousReceiveRequest(req); + // unallocate message destroyMessageWithParams(req->msg); @@ -192,6 +199,7 @@ void executeSendBroadcastTransaction(request *req) { while(currentReq != NULL) { cpt ++; pthread_cond_signal(currentReq->listOfRequests->wakeupCondition); + traceSynchroRequest(req, currentReq); currentReq = currentReq->relatedRequest; } diff --git a/executablecode/src/tracemanager.c b/executablecode/src/tracemanager.c index 7e2e9c0f014653b38e7ae2562c81eba2b734dfe5..ffc0af0b174a9c2e5d21b1f38cb8cf5aab78aba1 100644 --- a/executablecode/src/tracemanager.c +++ b/executablecode/src/tracemanager.c @@ -55,7 +55,7 @@ void addInfo(char *dest, char *info) { void writeInTrace(char *info) { - mutex_lock(&__traceMutex); + pthread_mutex_lock(&__traceMutex); char s[CHAR_ALLOC_SIZE]; addInfo(s, info); //printf("Write in file\n"); @@ -66,7 +66,7 @@ void writeInTrace(char *info) { fprintf(file, s); fflush(file); } - mutex_unlock(&__traceMutex); + pthread_mutex_unlock(&__traceMutex); } @@ -148,6 +148,75 @@ void traceVariableModification(char *block, char *var, int value, int type) { } +void traceSynchroRequest(request *from, request *to) { + char s[1024]; + int i; + + sprintf(s, "block=%s blockdestination=%s type=synchro channel=%s params=", from->listOfRequests->owner, to->listOfRequests->owner, from->syncChannel->outname); + for(i=0; i<from->nbOfParams; i++) { + if (i>0) { + sprintf(s, "%s,", s); + } + sprintf(s, "%s%d", s, *(from->params[i])); + } + sprintf(s, "%s\n", s); + + debugMsg("Trace request synchro"); + + + // Saving trace + writeInTrace(s); +} + + +void traceAsynchronousSendRequest(request *req) { + char s[1024]; + int i; + + + sprintf(s, "block=%s type=send_async channel=%s msgid=%ld params=", req->listOfRequests->owner, req->asyncChannel->outname, req->msg->id); + if (req->msg != NULL) { + debugMsg("Computing params"); + for(i=0; i<req->msg->nbOfParams; i++) { + if (i>0) { + sprintf(s, "%s,", s); + } + sprintf(s, "%s%d", s, req->msg->params[i]); + } + } + sprintf(s, "%s\n", s); + + + + // Saving trace + writeInTrace(s); +} + + +void traceAsynchronousReceiveRequest(request *req) { + char s[1024]; + int i; + + + sprintf(s, "block=%s type=receive_async channel=%s msgid=%ld params=", req->listOfRequests->owner, req->asyncChannel->outname, req->msg->id); + if (req->msg != NULL) { + debugMsg("Computing params"); + for(i=0; i<req->msg->nbOfParams; i++) { + if (i>0) { + sprintf(s, "%s,", s); + } + sprintf(s, "%s%d", s, req->msg->params[i]); + } + } + sprintf(s, "%s\n", s); + + + + // Saving trace + writeInTrace(s); +} + + void traceRequest(char *myname, request *req) { char s[1024]; @@ -164,28 +233,27 @@ void traceRequest(char *myname, request *req) { // Build corresponding char*; switch(req->type) { - case SEND_SYNC_REQUEST: + case SEND_SYNC_REQUEST: debug2Msg("Sync channel", req->syncChannel->outname); - //sprintf(s, "block=%s type=send_synchro channel=%s blockdestination=%s\n", myname, req->syncChannel->outname, req->linkedTo->listOfRequests->owner); - sprintf(s, "block=%s type=send_synchro channel=%s blockdestination=%s params=", myname, req->syncChannel->outname, req->linkedTo->listOfRequests->owner); - for(i=0; i<req->nbOfParams; i++) { - if (i>0) { - sprintf(s, "%s,", s); - } - sprintf(s, "%s%d", s, *(req->params[i])); + sprintf(s, "block=%s type=send_synchro channel=%s params=", myname, req->syncChannel->outname); + for(i=0; i<req->nbOfParams; i++) { + if (i>0) { + sprintf(s, "%s,", s); } - sprintf(s, "%s\n", s); + sprintf(s, "%s%d", s, *(req->params[i])); + } + sprintf(s, "%s\n", s); break; case RECEIVE_SYNC_REQUEST: sprintf(s, "block=%s type=receive_synchro channel=%s\n", myname, req->syncChannel->inname); break; - case SEND_ASYNC_REQUEST: + case SEND_ASYNC_REQUEST: debug2Msg("Async channel", req->asyncChannel->outname); - sprintf(s, "block=%s type=send_async channel=%s\n", myname, req->asyncChannel->outname); + sprintf(s, "block=%s type=send_async_2 channel=%s\n", myname, req->asyncChannel->outname); break; - case RECEIVE_ASYNC_REQUEST: - sprintf(s, "block=%s type=receive_async channel=%s\n", myname, req->asyncChannel->inname); + case RECEIVE_ASYNC_REQUEST: + sprintf(s, "block=%s type=receive_async_2 channel=%s\n", myname, req->asyncChannel->inname); break; case SEND_BROADCAST_REQUEST: debug2Msg("Sync channel", req->syncChannel->outname); diff --git a/executablecode/src/tracemanager.h b/executablecode/src/tracemanager.h index 45f4ecb341078f7d3214b71775ce79645dc47613..fb92d9fe6c0509167c7019eec365a08146ab62f1 100644 --- a/executablecode/src/tracemanager.h +++ b/executablecode/src/tracemanager.h @@ -12,8 +12,9 @@ void traceRequest(char *myname, request *req); void traceFunctionCall(char *block, char *func, char* params); void traceVariableModification(char *block, char *var, int value, int type); // type=0: int type = 1:bool void traceStateEntering(char *myname, char *statename); - - +void traceSynchroRequest(request *from, request *to); +void traceAsynchronousSendRequest(request *req); +void traceAsynchronousReceiveRequest(request *req); #endif diff --git a/src/avatartranslator/AvatarBlock.java b/src/avatartranslator/AvatarBlock.java index 2543b60cb926c975020a50b878906544de075488..d6f7a8486e5059e5470b0e76c6626b70befbc72f 100644 --- a/src/avatartranslator/AvatarBlock.java +++ b/src/avatartranslator/AvatarBlock.java @@ -361,8 +361,14 @@ public class AvatarBlock extends AvatarElement { } } + + // Modify the state machine - asm.removeTimers(this); + if (asm.removeTimers(this, "__timerValue")) { + // Add an attribute for the timer value + value = new AvatarAttribute("__timerValue", AvatarType.INTEGER, getReferenceObject()); + addAttribute(value); + } // Remove Timer attribute LinkedList<AvatarAttribute> tmps = attributes; diff --git a/src/avatartranslator/AvatarBlockTemplate.java b/src/avatartranslator/AvatarBlockTemplate.java index edf3142a845b3d4bcf26de06a9df06e08ad1d445..b62d207239b7d28aa4f67c14fe0c4b0aacadb565 100644 --- a/src/avatartranslator/AvatarBlockTemplate.java +++ b/src/avatartranslator/AvatarBlockTemplate.java @@ -59,12 +59,12 @@ public class AvatarBlockTemplate { public static AvatarBlock getTimerBlock(String _name, Object _referenceBlock, Object _referenceSet, Object _referenceExpire, Object _referenceReset) { AvatarBlock ab = new AvatarBlock(_name, _referenceBlock); - AvatarAttribute aa2 = new AvatarAttribute("toto", AvatarType.INTEGER, _referenceBlock); - ab.addAttribute(aa2); + /*AvatarAttribute aa2 = new AvatarAttribute("toto", AvatarType.INTEGER, _referenceBlock); + ab.addAttribute(aa2);*/ AvatarAttribute aa = new AvatarAttribute("value", AvatarType.INTEGER, _referenceBlock); ab.addAttribute(aa); - AvatarAttribute aa1 = new AvatarAttribute("__value", AvatarType.INTEGER, _referenceBlock); - ab.addAttribute(aa1); + /*AvatarAttribute aa1 = new AvatarAttribute("__value", AvatarType.INTEGER, _referenceBlock); + ab.addAttribute(aa1);*/ AvatarSignal set = new AvatarSignal("set", AvatarSignal.IN, _referenceBlock); AvatarSignal reset = new AvatarSignal("reset", AvatarSignal.IN, _referenceBlock); diff --git a/src/avatartranslator/AvatarStateMachine.java b/src/avatartranslator/AvatarStateMachine.java index 0c5a61bb71bb2a8a437a4e345be04fcf57d414a3..8bdc036f680df21727cbd6102143fb037e0cd2bb 100644 --- a/src/avatartranslator/AvatarStateMachine.java +++ b/src/avatartranslator/AvatarStateMachine.java @@ -407,7 +407,8 @@ public class AvatarStateMachine extends AvatarElement { return null; } - public void removeTimers(AvatarBlock _block) { + // Return true iff at least one timer was removed + public boolean removeTimers(AvatarBlock _block, String timerAttributeName) { AvatarSetTimer ast; AvatarTimerOperator ato; @@ -420,10 +421,23 @@ public class AvatarStateMachine extends AvatarElement { if (elt instanceof AvatarSetTimer) { ast = (AvatarSetTimer)elt; AvatarActionOnSignal aaos = new AvatarActionOnSignal(elt.getName(), _block.getAvatarSignalWithName("set__" + ast.getTimer().getName()), elt.getReferenceObject()); - aaos.addValue(ast.getTimerValue()); + aaos.addValue(timerAttributeName); olds.add(elt); news.add(aaos); + // Modifying the transition just before + LinkedList<AvatarStateMachineElement> previous = getPreviousElementsOf(ast); + if (previous.size() == 1) { + if (previous.get(0) instanceof AvatarTransition) { + AvatarTransition at = (AvatarTransition)(previous.get(0)); + at.addAction(timerAttributeName + " = " + ast.getTimerValue()); + } else { + TraceManager.addError("The element before a set time is not a transition!"); + } + } else { + TraceManager.addError("More than one transition before a set time!"); + } + // Reset timer } else if (elt instanceof AvatarResetTimer) { ato = (AvatarTimerOperator)elt; @@ -447,6 +461,8 @@ public class AvatarStateMachine extends AvatarElement { newelt = news.get(i); replace(oldelt, newelt); } + + return (olds.size() > 0); } public void replace(AvatarStateMachineElement oldone, AvatarStateMachineElement newone) { @@ -738,5 +754,16 @@ public class AvatarStateMachine extends AvatarElement { } return name + id; } + + public void handleUnfollowedStartState() { + if (startState.nbOfNexts() == 0) { + AvatarStopState stopState = new AvatarStopState("__StopState", startState.getReferenceObject()); + AvatarTransition at = new AvatarTransition("__toStop", startState.getReferenceObject()); + addElement(stopState); + addElement(at); + startState.addNext(at); + at.addNext(stopState); + } + } } diff --git a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java index 85b68a00c885daf060e410d99617a61f62eb0ca2..aa776902be9bdb3d82068f4e6909ea1b9a207f2a 100755 --- a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java +++ b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java @@ -354,7 +354,7 @@ public class AVATAR2CPOSIX { // Making start state AvatarStateMachine asm = _block.getStateMachine(); s += "case STATE__START__STATE: " + CR; - s += traceStateEntering("__myname", "start state"); + s += traceStateEntering("__myname", "__StartState"); s += makeBehaviourFromElement(_block, asm.getStartState(), true); s += "break;" + CR + CR; @@ -679,6 +679,9 @@ public class AVATAR2CPOSIX { mainFile.appendToMainCode("/* Initializing the main mutex */" + CR); mainFile.appendToMainCode("if (pthread_mutex_init(&__mainMutex, NULL) < 0) { exit(-1);}" + CR + CR); + mainFile.appendToMainCode("/* Initializing mutex of messages */" + CR); + mainFile.appendToMainCode("initMessages();" + CR); + mainFile.appendToMainCode(CR + CR + mainDebugMsg("Starting tasks")); for(TaskFile taskFile: taskFiles) { diff --git a/src/myutil/Conversion.java b/src/myutil/Conversion.java index da55109c4c2136e273c927e6bb5776e3dd55c4df..0bb72b7c5cd73c2286f2855b18c814470bf335b0 100755 --- a/src/myutil/Conversion.java +++ b/src/myutil/Conversion.java @@ -105,6 +105,17 @@ public class Conversion { return output + s; } + public static String removeStartingCharacters(String s, String toRemove) { + if (s == null) { + return s; + } + if (s.startsWith(toRemove)) { + return removeStartingCharacters(s.substring(toRemove.length(), s.length()), toRemove); + } + + return s; + } + public static String replaceRecursiveAllString(String s, String input, String snew) { int index; while((index = s.indexOf(input)) > -1 ) { diff --git a/src/ui/AvatarDesignPanelTranslator.java b/src/ui/AvatarDesignPanelTranslator.java index d544860b3039d40a59e5addd40ac67eb4cc65df5..7d12ef0c9e6505082637544e8f5db7de9f4bd9ae 100644 --- a/src/ui/AvatarDesignPanelTranslator.java +++ b/src/ui/AvatarDesignPanelTranslator.java @@ -1097,6 +1097,8 @@ public class AvatarDesignPanelTranslator { } } } + + asm.handleUnfollowedStartState(); } diff --git a/src/ui/avatarinteractivesimulation/AvatarSpecificationSimulationSDPanel.java b/src/ui/avatarinteractivesimulation/AvatarSpecificationSimulationSDPanel.java index 1f59cbc28f472b2e570279a5919775f08913aef4..f00836fe8e59603ff415fdf14dc86080315bc592 100644 --- a/src/ui/avatarinteractivesimulation/AvatarSpecificationSimulationSDPanel.java +++ b/src/ui/avatarinteractivesimulation/AvatarSpecificationSimulationSDPanel.java @@ -632,8 +632,13 @@ public class AvatarSpecificationSimulationSDPanel extends JPanel implements Mous } private void drawInfo(Graphics g) { + String timeValue = "@" + clockValueMouse; + Color c = g.getColor(); + g.setColor(ColorManager.AVATAR_ACTION); GraphicLib.dashedLine(g, spaceAtEnd, yMouse, maxX-spaceAtEnd, yMouse); - g.drawString("@" + clockValueMouse, 10, yMouse+g.getFontMetrics().getHeight()/2); + g.drawString(timeValue, 10, yMouse+g.getFontMetrics().getHeight()/2); + g.drawString(timeValue, maxX-spaceAtEnd + 1, yMouse+g.getFontMetrics().getHeight()/2); + /*if (minIdValueMouse == maxIdValueMouse) { g.drawString("ID: " + minIdValueMouse, 10, yMouse+(g.getFontMetrics().getHeight()/2)+12); } else { @@ -651,6 +656,7 @@ public class AvatarSpecificationSimulationSDPanel extends JPanel implements Mous g.drawString(name, x + ((spaceBetweenLifeLines-w)/2), yMouse - spaceVerticalText); x += spaceBetweenLifeLines; } + g.setColor(c); } private void drawIDInfo(Graphics g, int _x, int _y, long _id) { diff --git a/src/ui/interactivesimulation/GenericTransaction.java b/src/ui/interactivesimulation/GenericTransaction.java index d121a0f6771ef4582af7c0982464e743e0c96877..7a3b7d9a89e18815c6da676ddb1af187dc50b65c 100755 --- a/src/ui/interactivesimulation/GenericTransaction.java +++ b/src/ui/interactivesimulation/GenericTransaction.java @@ -59,6 +59,9 @@ public class GenericTransaction { public final static int STATE_ENTERING = 2; public final static int VAR_MODIFICATION = 3; public final static int SEND_SYNCHRO = 4; + public final static int SYNCHRO = 5; + public final static int SEND_ASYNCHRO = 6; + public final static int RECEIVE_ASYNCHRO = 7; public int ID; public int type; @@ -66,6 +69,7 @@ public class GenericTransaction { public String otherEntityName; /* name of destination in synchro, etc. */ public String name; /* Used for channel names */ public String params; /* values separated with commas */ + public String messageID; /* Used for identifiying asynchronous messages */ public String action; public long startingTime; public long finishTime; diff --git a/src/ui/interactivesimulation/JFrameSimulationSDPanel.java b/src/ui/interactivesimulation/JFrameSimulationSDPanel.java index 5a37f61662b840e711e396e373c5c112c233d2a6..e0f301a2f2ee07f0566c05f1895e3ba1546e65a4 100755 --- a/src/ui/interactivesimulation/JFrameSimulationSDPanel.java +++ b/src/ui/interactivesimulation/JFrameSimulationSDPanel.java @@ -151,7 +151,7 @@ public class JFrameSimulationSDPanel extends JFrame implements ActionListener { framePanel.add(topPanel, BorderLayout.NORTH); // Simulation panel - sdpanel = new JSimulationSDPanel(); + sdpanel = new JSimulationSDPanel(this); JScrollPane jsp = new JScrollPane(sdpanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); sdpanel.setMyScrollPanel(jsp); jsp.setWheelScrollingEnabled(true); @@ -197,7 +197,7 @@ public class JFrameSimulationSDPanel extends JFrame implements ActionListener { public void actionPerformed(ActionEvent evt) { String command = evt.getActionCommand(); - TraceManager.addDev("Command:" + command); + //TraceManager.addDev("Command:" + command); if (command.equals(actions[InteractiveSimulationActions.ACT_STOP_ALL].getActionCommand())) { close(); @@ -225,6 +225,18 @@ public class JFrameSimulationSDPanel extends JFrame implements ActionListener { } } + public void setCurrentTime(long timeValue) { + status.setText("time = " + timeValue); + } + + public void setStatus(String _status) { + status.setText(_status); + } + + public void setNbOfTransactions(int x, long minTime, long maxTime) { + status.setText("" + x + " transactions, min time=" + minTime + ", max time=" + maxTime); + } + diff --git a/src/ui/interactivesimulation/JSimulationSDPanel.java b/src/ui/interactivesimulation/JSimulationSDPanel.java index f26d5e73a8641285789726a538dd622c8cb6f46d..345baf3ed41f4ce932c6efa1528c6ece99c6fa36 100644 --- a/src/ui/interactivesimulation/JSimulationSDPanel.java +++ b/src/ui/interactivesimulation/JSimulationSDPanel.java @@ -105,6 +105,7 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R private long clockDiviser = 1000000; //ms private Vector<Point> points; private Vector<GenericTransaction> transactionsOfPoints; + private Hashtable<String, Point> asyncMsgs; // List of entities ... List is discovered progressively // Or the list is described in the trace (header information) @@ -118,16 +119,21 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R Vector<GenericTransaction> transactions; + JFrameSimulationSDPanel jfssdp; - public JSimulationSDPanel() { + + public JSimulationSDPanel(JFrameSimulationSDPanel _jfssdp) { //points = new Vector<Point>(); //transactionsOfPoints = new Vector<AvatarSimulationTransaction>(); + jfssdp = _jfssdp; entityNames = new Vector <String>(); transactions = new Vector<GenericTransaction>(); transactionsOfPoints = new Vector<GenericTransaction>(); points = new Vector<Point>(); + asyncMsgs = new Hashtable<String, Point>(); + mode = NO_MODE; setBackground(Color.WHITE); @@ -135,6 +141,8 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R addMouseMotionListener(this); + + } public void setMyScrollPanel(JScrollPane _jsp) { @@ -250,13 +258,22 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R points.clear(); transactionsOfPoints.clear(); + //TraceManager.addDev("Clearing hash"); + //asyncMsgs.clear(); + if (gt.type == gt.STATE_ENTERING) { newCurrentY = drawState(g, gt, xOfBlock, currentY); } else if (gt.type == gt.FUNCTION_CALL) { newCurrentY = drawFunctionCall(g, gt, xOfBlock, currentY); } else if (gt.type == gt.SEND_SYNCHRO) { + //newCurrentY = drawSendSynchro(g, gt, xOfBlock, currentY); + } else if (gt.type == gt.SYNCHRO) { newCurrentY = drawSendSynchro(g, gt, xOfBlock, currentY); + } else if (gt.type == gt.SEND_ASYNCHRO) { + newCurrentY = drawSendAsynchro(g, gt, xOfBlock, currentY); + } else if (gt.type == gt.RECEIVE_ASYNCHRO) { + newCurrentY = drawReceiveAsynchro(g, gt, xOfBlock, currentY); } if ((yMouse>= currentY) && (yMouse <= newCurrentY)) { @@ -276,11 +293,17 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R xOfBlock += spaceBetweenLifeLines; } if (gt.finishTime != clockValue) { + boolean alsoText = false; + if ((gt.finishTime / clockDiviser) != (clockValue / clockDiviser)) { + alsoText = true; + } clockValue = gt.finishTime; if (yMouse >= newCurrentY) { clockValueMouse = clockValue; } - g.drawString("@" + clockValue/clockDiviser, 10, newCurrentY+g.getFontMetrics().getHeight()/2); + if (alsoText) { + g.drawString("@" + clockValue/clockDiviser, 10, newCurrentY+g.getFontMetrics().getHeight()/2); + } } } @@ -389,6 +412,110 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R return currentY; } + private int drawSendAsynchro(Graphics g, GenericTransaction _gt, int currentX, int currentY) { + int w; + int x, y, width, height; + String messageName; + + g.drawLine(currentX, currentY, currentX, currentY+verticalLink); + currentY += verticalLink; + + messageName = _gt.name + "(" + _gt.params + ")"; + + Color c = g.getColor(); + + x = currentX; + y = currentY; + + int xOf2ndBlock = x + 2*spaceBetweenLifeLines/3; + + g.setColor(ColorManager.AVATAR_RECEIVE_SIGNAL); + g.drawLine(xOf2ndBlock, currentY-1, currentX, currentY-1); + g.setColor(c); + GraphicLib.arrowWithLine(g, 1, 2, 10, currentX, currentY, xOf2ndBlock, currentY, false); + transactionsOfPoints.add(_gt); + points.add(new Point(currentX, currentY)); + TraceManager.addDev("Putting " + _gt.messageID + " in hash"); + asyncMsgs.put(_gt.messageID, new Point(currentX, currentY)); + + // Putting the message name + w = g.getFontMetrics().stringWidth(messageName); + int xtmp = (xOf2ndBlock + currentX)/2 - w/2; + g.drawString(messageName, xtmp, currentY-2); + + currentY += 10; + + // Vertical line of receiving block + g.drawLine(currentX, currentY-20, currentX, currentY); + return currentY; + } + + private int drawReceiveAsynchro(Graphics g, GenericTransaction _gt, int currentX, int currentY) { + int w; + int x, y, width, height; + String messageName; + + g.drawLine(currentX, currentY, currentX, currentY+verticalLink); + currentY += verticalLink; + + messageName = _gt.name + "(" + _gt.params + ")"; + + Color c = g.getColor(); + + x = currentX; + y = currentY; + + int xOf2ndBlock = x - 2*spaceBetweenLifeLines/3; + + g.setColor(ColorManager.AVATAR_RECEIVE_SIGNAL); + g.drawLine(xOf2ndBlock, currentY-1, currentX, currentY-1); + g.setColor(c); + GraphicLib.arrowWithLine(g, 1, 2, 10, xOf2ndBlock, currentY, currentX, currentY, false); + transactionsOfPoints.add(_gt); + points.add(new Point(currentX, currentY)); + + // Putting the message name + w = g.getFontMetrics().stringWidth(messageName); + int xtmp = (xOf2ndBlock + currentX)/2 - w/2; + g.drawString(messageName, xtmp, currentY-2); + + + // Linking to sender? + Point p = asyncMsgs.get(_gt.messageID); + TraceManager.addDev("Testing " + _gt.messageID + " in hash = " + p + " hashsize=" + asyncMsgs.size() ); + if (p != null) { + x = p.x; + y = p.y; + int lengthAsync = 2*spaceBetweenLifeLines/3; + + if ((x + lengthAsync) < (currentX-lengthAsync)) { + // Forward + g.setColor(ColorManager.AVATAR_RECEIVE_SIGNAL); + GraphicLib.dashedLine(g, x + lengthAsync - 1, y, x + lengthAsync-1, currentY); + GraphicLib.dashedLine(g, x + lengthAsync, currentY-1, currentX-lengthAsync, currentY-1); + g.setColor(c); + GraphicLib.dashedLine(g, x + lengthAsync, y, x + lengthAsync, currentY); + GraphicLib.dashedLine(g, x + lengthAsync, currentY, currentX-lengthAsync, currentY); + } else { + // Backward + g.setColor(ColorManager.AVATAR_RECEIVE_SIGNAL); + GraphicLib.dashedLine(g, x + lengthAsync-1, y, x + lengthAsync-1, y+7); + GraphicLib.dashedLine(g, x + lengthAsync, y+6, currentX-lengthAsync, y+6); + GraphicLib.dashedLine(g, currentX-lengthAsync-1, currentY, currentX-lengthAsync-1, y+7); + g.setColor(c); + GraphicLib.dashedLine(g, x + lengthAsync, y, x + lengthAsync, y+7); + GraphicLib.dashedLine(g, x + lengthAsync, y+7, currentX-lengthAsync, y+7); + GraphicLib.dashedLine(g, currentX-lengthAsync, currentY, currentX-lengthAsync, y+7); + } + } + + currentY += 10; + + // Vertical line of receiving block + g.drawLine(currentX, currentY-20, currentX, currentY); + return currentY; + } + /*private int drawTransition(Graphics g, AvatarTransition at, AvatarSimulationTransaction ast, int currentX, int currentY) { int w; int x, y, width, height; @@ -719,13 +846,12 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R } private void drawInfo(Graphics g) { + String timeValue = "@" + clockValueMouse/clockDiviser; + Color c = g.getColor(); + g.setColor(ColorManager.AVATAR_ACTION); GraphicLib.dashedLine(g, spaceAtEnd, yMouse, maxX-spaceAtEnd, yMouse); - g.drawString("@" + clockValueMouse/clockDiviser, 10, yMouse+g.getFontMetrics().getHeight()/2); - /*if (minIdValueMouse == maxIdValueMouse) { - g.drawString("ID: " + minIdValueMouse, 10, yMouse+(g.getFontMetrics().getHeight()/2)+12); - } else { - g.drawString("ID: " + minIdValueMouse + " to " + maxIdValueMouse, 10, yMouse+(g.getFontMetrics().getHeight()/2)+12); - }*/ + g.drawString(timeValue, 10, yMouse+g.getFontMetrics().getHeight()/2); + g.drawString(timeValue, maxX-spaceAtEnd + 1, yMouse+g.getFontMetrics().getHeight()/2); int w; int x = spaceAtEnd; @@ -735,6 +861,7 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R g.drawString(name, x + ((spaceBetweenLifeLines-w)/2), yMouse - spaceVerticalText); x += spaceBetweenLifeLines; } + g.setColor(c); } private void drawIDInfo(Graphics g, int _x, int _y, long _id) { @@ -767,20 +894,22 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R t.start(); } - public void refresh() { + public synchronized void refresh() { if (mode == FILE_MODE) { entityNames.clear(); transactions.clear(); transactionsOfPoints.clear(); points.clear(); - Thread t = new Thread(this); - t.start(); - repaint(); + if (t == null) { + Thread t = new Thread(this); + t.start(); + repaint(); + } } } public void run() { - TraceManager.addDev("Reading file"); + //TraceManager.addDev("Reading file"); go = true; Thread t; @@ -796,6 +925,7 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R // Read the content of the file // Read line by line // Upate the graphic regularly + jfssdp.setStatus("Reading " + fileReference); try{ // Open the file that is the first // command line parameter @@ -807,7 +937,7 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R //Read File Line By Line while ((strLine = br.readLine()) != null) { // Print the content on the console - TraceManager.addDev("Computing transaction:" + strLine); + //TraceManager.addDev("Computing transaction:" + strLine); addGenericTransaction(strLine); } //Close the input stream @@ -815,7 +945,21 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R } catch (Exception e){//Catch exception if any TraceManager.addDev("Reading file Error: " + e.getMessage()); } + + if (jfssdp != null) { + updateInfoOnTransactions(); + } } + + t = null; + } + + private void updateInfoOnTransactions() { + if (transactions.size() == 0) { + jfssdp.setNbOfTransactions(transactions.size(), 0, 0); + } else { + jfssdp.setNbOfTransactions(transactions.size(), transactions.get(0).startingTime/clockDiviser, transactions.get(transactions.size()-1).finishTime/clockDiviser); + } } public void addGenericTransaction(String trans) { @@ -856,10 +1000,11 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R try { index0 = tmp.indexOf('.'); if (index0 == -1) { + TraceManager.addDev("Invalid time value"); return; } tmp1 = tmp.substring(0, index0); - tmp2 = tmp.substring(index0+1, tmp.length()); + tmp2 = Conversion.removeStartingCharacters(tmp.substring(index0+1, tmp.length()), "0"); //TraceManager.addDev("2 tmp1=" + tmp1 + " tmp2=" + tmp2); value1 = Integer.decode(tmp1).intValue(); value2 = Integer.decode(tmp2).intValue(); @@ -867,6 +1012,7 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R gt.startingTime = value; gt.finishTime = value; } catch (Exception e) { + TraceManager.addDev("Exception: " + e.getMessage()); return; } @@ -878,6 +1024,8 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R return; } + //TraceManager.addDev("4"); + addEntityNameIfApplicable(tmp); gt.entityName = tmp; @@ -899,6 +1047,18 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R gt.type = GenericTransaction.SEND_SYNCHRO; } + if (tmp.compareTo("synchro") == 0) { + gt.type = GenericTransaction.SYNCHRO; + } + + if (tmp.compareTo("send_async") == 0) { + gt.type = GenericTransaction.SEND_ASYNCHRO; + } + + if (tmp.compareTo("receive_async") == 0) { + gt.type = GenericTransaction.RECEIVE_ASYNCHRO; + } + // State of the transaction? tmp = extract(trans, "state"); @@ -928,6 +1088,7 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R tmp = extract(trans, "blockdestination"); if (tmp != null) { gt.otherEntityName = tmp; + addEntityNameIfApplicable(tmp); } // Channel of the transaction? @@ -941,8 +1102,13 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R gt.params = tmp; } + tmp = extract(trans, "msgid"); + if (tmp != null) { + gt.messageID = tmp; + } + transactions.add(gt); - TraceManager.addDev("One transactions added"); + //TraceManager.addDev("One transactions added"); } @@ -965,11 +1131,13 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R public void addEntityNameIfApplicable(String _entityName) { for(String name: entityNames) { + //TraceManager.addDev("Examining name= " + name + " entityName=" + _entityName); if (name.compareTo(_entityName) ==0) { return; } } + //TraceManager.addDev("Adding name: " + _entityName); entityNames.add(_entityName); } @@ -987,5 +1155,6 @@ public class JSimulationSDPanel extends JPanel implements MouseMotionListener, R public void setClockDiviser(long _clockDiviser) { clockDiviser = _clockDiviser; + updateInfoOnTransactions(); } } \ No newline at end of file