~tapaal-contributor/tapaal/disappearing-tokens-1940098

« back to all changes in this revision

Viewing changes to src/pipe/gui/Animator.java

  • Committer: Kenneth Yrke Jørgensen
  • Date: 2011-04-12 09:50:16 UTC
  • mfrom: (329.1.188 tapaal-1.5)
  • Revision ID: mail@yrke.dk-20110412095016-e4hqdgab5596ja09
Merged with branch addning support for new 1.5 features

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
package pipe.gui;
2
2
 
3
3
import java.awt.Container;
4
 
import java.awt.event.ActionEvent;
5
 
import java.awt.event.ActionListener;
6
4
import java.math.BigDecimal;
7
 
import java.math.MathContext;
8
 
import java.text.DecimalFormat;
9
5
import java.util.ArrayList;
10
 
import java.util.HashMap;
11
6
import java.util.Iterator;
12
7
import java.util.List;
13
 
import java.util.Random;
14
8
 
15
9
import javax.swing.BoxLayout;
16
 
import javax.swing.JComboBox;
17
10
import javax.swing.JOptionPane;
18
 
import javax.swing.Timer;
19
11
 
20
 
import pipe.dataLayer.Arc;
21
 
import pipe.dataLayer.ColoredDiscreteFiringAction;
22
12
import pipe.dataLayer.DataLayer;
23
 
import pipe.dataLayer.DiscreetFiringAction;
24
 
import pipe.dataLayer.FiringAction;
25
 
import pipe.dataLayer.Place;
26
 
import pipe.dataLayer.TAPNTrace;
27
 
import pipe.dataLayer.TAPNTransition;
28
 
import pipe.dataLayer.TimeDelayFiringAction;
29
 
import pipe.dataLayer.TimedPlace;
30
13
import pipe.dataLayer.Transition;
31
 
import pipe.dataLayer.colors.ColoredToken;
32
 
import pipe.exception.InvariantViolatedAnimationException;
33
14
import pipe.gui.widgets.AnimationSelectmodeDialog;
34
15
import pipe.gui.widgets.EscapableDialog;
35
 
import dk.aau.cs.debug.Logger;
36
 
 
37
 
 
38
 
/**
39
 
 * This class is used to process clicks by the user to manually step 
40
 
 * through enabled transitions in the net. 
41
 
 * 
42
 
 * @author unspecified  wrote this code
43
 
 * @author David Patterson fixed a bug with double-firing transitions
44
 
 *         in the doRandomFiring method. I also renamed the fireTransition
45
 
 *         method to recordFiredTransition to better describe what it does.
46
 
 *
47
 
 * @author Pere Bonet modified the recordFiredTransition method to
48
 
 * fix the unexcepted behaviour observed during animation playback.
49
 
 * The method is renamed back to fireTransition. 
50
 
 * 
51
 
 * @author Edwin Chung fixed the bug where users can still step forward to 
52
 
 * previous firing sequence even though it has been reset. The issue where an 
53
 
 * unexpected behaviour will occur when the firing sequence has been altered 
54
 
 * has been resolved. The problem where animation will freeze halfway while 
55
 
 * stepping back a firing sequence has also been fixed (Feb 2007) 
56
 
 *
57
 
 * @author Dave Patterson The code now outputs an error message in the status 
58
 
 * bar if there is no transition to be found when picking a random transition 
59
 
 * to fire. This is related to the problem described in bug 1699546.
60
 
 * 
61
 
 * @author Joakim Byg Edited the code so that it can animate time passing in 
62
 
 * TAPN. This include refactoring lastFiredTransition so that it also 
63
 
 * contains timePasses. The rest of the code is altered so that it takes 
64
 
 * this into account (count is renamed to currentAction). (Feb 2009)
65
 
 */
 
16
import dk.aau.cs.gui.TabContent;
 
17
import dk.aau.cs.model.tapn.NetworkMarking;
 
18
import dk.aau.cs.model.tapn.TimedToken;
 
19
import dk.aau.cs.model.tapn.TimedTransition;
 
20
import dk.aau.cs.model.tapn.simulation.FiringMode;
 
21
import dk.aau.cs.model.tapn.simulation.OldestFiringMode;
 
22
import dk.aau.cs.model.tapn.simulation.RandomFiringMode;
 
23
import dk.aau.cs.model.tapn.simulation.TAPNNetworkTrace;
 
24
import dk.aau.cs.model.tapn.simulation.TAPNNetworkTraceStep;
 
25
import dk.aau.cs.model.tapn.simulation.TAPNNetworkTimeDelayStep;
 
26
import dk.aau.cs.model.tapn.simulation.TAPNNetworkTimedTransitionStep;
 
27
import dk.aau.cs.model.tapn.simulation.YoungestFiringMode;
 
28
import dk.aau.cs.util.RequireException;
66
29
 
67
30
public class Animator {
68
 
 
69
 
        Timer timer;
70
 
        int numberSequences;   
71
 
        private ArrayList<FiringAction> actionHistory;
 
31
        private ArrayList<TAPNNetworkTraceStep> actionHistory;
72
32
        private int currentAction;
73
 
        private ArrayList<HashMap<TimedPlace, ArrayList<BigDecimal>>> markingHistory;
74
 
 
75
 
        public Firingmode firingmode = new RandomFiringmode();
76
 
 
77
 
        public Animator(){
78
 
                actionHistory = new ArrayList<FiringAction>();
79
 
 
80
 
                timer = new Timer(0, new ActionListener() {
81
 
                        public void actionPerformed(ActionEvent evt) {
82
 
                                if ((getNumberSequences() < 1) ||
83
 
                                                !CreateGui.getView().isInAnimationMode()) {
84
 
                                        timer.stop();
85
 
                                        CreateGui.getApp().setRandomAnimationMode(false);
86
 
                                        return;
87
 
                                }
88
 
                                doRandomFiring();
89
 
                                setNumberSequences(getNumberSequences() - 1);
90
 
                        }
91
 
                });
 
33
        private ArrayList<NetworkMarking> markings;
 
34
        private int currentMarkingIndex = 0;
 
35
 
 
36
        public FiringMode firingmode = new RandomFiringMode();
 
37
        private TabContent tab;
 
38
        private NetworkMarking initialMarking;
 
39
 
 
40
        private boolean isDisplayingUntimedTrace = false;
 
41
 
 
42
        public Animator() {
 
43
                actionHistory = new ArrayList<TAPNNetworkTraceStep>();
92
44
                currentAction = -1;
93
 
                markingHistory = new ArrayList<HashMap<TimedPlace,ArrayList<BigDecimal>>>();
94
 
 
95
 
        }
96
 
 
97
 
        public void SetTrace(TAPNTrace trace){
98
 
                if(trace.isConcreteTrace()){
 
45
                markings = new ArrayList<NetworkMarking>();
 
46
        }
 
47
 
 
48
        public void setTabContent(TabContent tab) {
 
49
                this.tab = tab;
 
50
        }
 
51
 
 
52
        private NetworkMarking currentMarking() {
 
53
                return markings.get(currentMarkingIndex);
 
54
        }
 
55
 
 
56
        public void SetTrace(TAPNNetworkTrace trace) {
 
57
                if (trace.isConcreteTrace()) {
99
58
                        setTimedTrace(trace);
100
 
                }else{
 
59
                } else {
101
60
                        setUntimedTrace(trace);
 
61
                        isDisplayingUntimedTrace = true;
102
62
                }
 
63
                currentAction = -1;
 
64
                currentMarkingIndex = 0;
 
65
                CreateGui.getAnimationHistory().setSelectedIndex(0);
 
66
                CreateGui.getAnimationController().setAnimationButtonsEnabled();
103
67
        }
104
68
 
105
 
        private void setUntimedTrace(TAPNTrace trace) {
106
 
                CreateGui.addAbstractAnimationPane();
107
 
                AnimationHistory untimedAnimationHistory = CreateGui.getAbstractAnimationPane();
108
 
                for(FiringAction action : trace){
109
 
                        String transitionName = action instanceof ColoredDiscreteFiringAction ? ((ColoredDiscreteFiringAction)action).getTransition().getName() : ((DiscreetFiringAction)action).getTransition().getName();
110
 
                        untimedAnimationHistory.addHistoryItemDontChange(transitionName);
 
69
        private void setUntimedTrace(TAPNNetworkTrace trace) {
 
70
                tab.addAbstractAnimationPane();
 
71
                AnimationHistoryComponent untimedAnimationHistory = CreateGui.getAbstractAnimationPane();
 
72
 
 
73
                for(TAPNNetworkTraceStep step : trace){
 
74
                        untimedAnimationHistory.addHistoryItem(step.toString());
111
75
                }
 
76
 
 
77
                CreateGui.getAbstractAnimationPane().setSelectedIndex(0);
112
78
                setFiringmode("Manual");
113
79
 
114
80
                JOptionPane.showMessageDialog(CreateGui.getApp(),
115
 
                                "The verification process returned an untimed trace.\n\n"+
116
 
                                "This means that with appropriate time delays the displayed\n"+
117
 
                                "sequence of discrete transitions can become a concrete trace.\n"+
118
 
                                "In case of liveness properties (EG, AF) the untimed trace\n"+
119
 
                                "either ends in a deadlock, or time divergent computation without\n" +
120
 
                                "any discrete transitions, or it loops back to some earlier configuration.\n"+
121
 
                                "The user may experiment in the simulator with different time delays\n"+
122
 
                                "in order to realize the suggested untimed trace in the model.",
123
 
                                "Verification Information",
124
 
                                JOptionPane.INFORMATION_MESSAGE);
 
81
                                "The verification process returned an untimed trace.\n\n"
 
82
                                + "This means that with appropriate time delays the displayed\n"
 
83
                                + "sequence of discrete transitions can become a concrete trace.\n"
 
84
                                + "In case of liveness properties (EG, AF) the untimed trace\n"
 
85
                                + "either ends in a deadlock, a time divergent computation without\n"
 
86
                                + "any discrete transitions, or it loops back to some earlier configuration.\n"
 
87
                                + "The user may experiment in the simulator with different time delays\n"
 
88
                                + "in order to realize the suggested untimed trace in the model.",
 
89
                                "Verification Information", JOptionPane.INFORMATION_MESSAGE);
125
90
        }
126
91
 
127
 
        private void setTimedTrace(TAPNTrace trace) {
128
 
                for(FiringAction action : trace){
129
 
                        if(action instanceof TimeDelayFiringAction)
130
 
                                manipulatehistory(((TimeDelayFiringAction)action).getDealy());
131
 
                        else if(action instanceof DiscreetFiringAction){
132
 
                                manipulatehistory((DiscreetFiringAction)action);
133
 
                        }else if(action instanceof ColoredDiscreteFiringAction){
134
 
                                manipulatehistory((ColoredDiscreteFiringAction)action);
135
 
                        }
 
92
        private void setTimedTrace(TAPNNetworkTrace trace) {
 
93
                for (TAPNNetworkTraceStep step : trace) {
 
94
                        addMarking(step, step.performStepFrom(currentMarking()));
136
95
                }
137
96
        }
138
97
 
139
 
 
 
98
        public NetworkMarking getInitialMarking(){
 
99
                return initialMarking;
 
100
        }
 
101
        
140
102
        /**
141
103
         * Highlights enabled transitions
142
104
         */
143
 
        public void highlightEnabledTransitions(){
144
 
                /* rewritten by wjk 03/10/2007 */
145
 
                DataLayer current = CreateGui.currentPNMLData();
146
 
 
147
 
                //current.setEnabledTransitions();      
 
105
        public void highlightEnabledTransitions() {
 
106
                DataLayer current = activeGuiModel();
148
107
 
149
108
                Iterator<Transition> transitionIterator = current.returnTransitions();
150
109
                while (transitionIterator.hasNext()) {
156
115
                }
157
116
        }
158
117
 
159
 
 
160
118
        /**
161
119
         * Called during animation to unhighlight previously highlighted transitions
162
120
         */
163
 
        public void unhighlightDisabledTransitions(){
164
 
                DataLayer current = CreateGui.currentPNMLData();
165
 
 
166
 
                //current.setEnabledTransitions();      
 
121
        public void unhighlightDisabledTransitions() {
 
122
                DataLayer current = activeGuiModel();
167
123
 
168
124
                Iterator<Transition> transitionIterator = current.returnTransitions();
169
125
                while (transitionIterator.hasNext()) {
175
131
                }
176
132
        }
177
133
 
178
 
 
179
134
        /**
180
 
         * Called at end of animation and resets all Transitions to false and 
 
135
         * Called at end of animation and resets all Transitions to false and
181
136
         * unhighlighted
182
137
         */
183
 
        private void disableTransitions(){
184
 
                Iterator<Transition> transitionIterator = 
185
 
                        CreateGui.currentPNMLData().returnTransitions();
 
138
        private void disableTransitions() {
 
139
                Iterator<Transition> transitionIterator = activeGuiModel()
 
140
                .returnTransitions();
186
141
                while (transitionIterator.hasNext()) {
187
142
                        Transition tempTransition = transitionIterator.next();
188
143
                        tempTransition.setEnabledFalse();
189
 
                        CreateGui.currentPNMLData().notifyObservers();
 
144
                        activeGuiModel().notifyObservers();
190
145
                        tempTransition.repaint();
191
146
                }
192
147
        }
193
148
 
194
 
 
195
149
        /**
196
150
         * Stores model at start of animation
197
151
         */
198
 
        public void storeModel(){
199
 
                CreateGui.setupModelForSimulation();
200
 
                CreateGui.currentPNMLData().storeState();
 
152
        public void storeModel() {
 
153
                initialMarking = tab.network().marking();
 
154
                resethistory();
 
155
                markings.add(initialMarking);
201
156
        }
202
157
 
203
 
 
204
158
        /**
205
 
         * Restores model at end of animation and sets all transitions to false and 
 
159
         * Restores model at end of animation and sets all transitions to false and
206
160
         * unhighlighted
207
161
         */
208
 
        public void restoreModel(){
209
 
                CreateGui.restoreModelForEditing();
210
 
                CreateGui.currentPNMLData().restoreState();
 
162
        public void restoreModel() {
211
163
                disableTransitions();
 
164
                tab.network().setMarking(initialMarking);
212
165
                currentAction = -1;
213
166
        }
214
167
 
215
 
 
216
 
        public void startRandomFiring(){      
217
 
                if (getNumberSequences() > 0) {
218
 
                        // stop animation
219
 
                        setNumberSequences(0);
220
 
                } else {
221
 
                        try {
222
 
                                String s = JOptionPane.showInputDialog(
223
 
                                                "Enter number of firings to perform", "1");
224
 
                                this.numberSequences=Integer.parseInt(s);
225
 
                                s = JOptionPane.showInputDialog(
226
 
                                                "Enter time delay between firing /ms", "50");
227
 
                                timer.setDelay(Integer.parseInt(s));
228
 
                                timer.start();
229
 
                        } catch (NumberFormatException e) {
230
 
                                CreateGui.getApp().setRandomAnimationMode(false);
231
 
                        }
232
 
                }
233
 
        }
234
 
 
235
 
 
236
 
        public void stopRandomFiring() {
237
 
                numberSequences = 0;
238
 
        }
239
 
 
240
 
 
241
 
        /**
242
 
         * This method randomly fires one of the enabled transitions. It then records 
243
 
         * the information about this by calling the recordFiredTransition method.
244
 
         * 
245
 
         * @author Dave Patterson Apr 29, 2007
246
 
         * I changed the code to keep the random transition found by the DataLayer.
247
 
         * If it is not null, I call the fireTransition method, otherwise I put 
248
 
         * out an error message in the status bar. 
249
 
         */
250
 
        public void doRandomFiring() {
251
 
                DataLayer data = CreateGui.currentPNMLData();
252
 
                Transition t = data.fireRandomTransition(); //revisar
253
 
                //CreateGui.getAnimationHistory().clearStepsForward(); //ok - igual
254
 
                //removeStoredTransitions(); //ok - igual
255
 
                if (t != null) {
256
 
                        fireTransition(t); //revisar
257
 
                        //unhighlightDisabledTransitions();
258
 
                        //highlightEnabledTransitions();
259
 
                } else {
260
 
                        CreateGui.getApp().getStatusBar().changeText( 
261
 
                        "ERROR: No transition to fire." );
262
 
                }
263
 
        }
264
 
 
265
 
 
266
168
        /**
267
169
         * Steps back through previously fired transitions
 
170
         * 
268
171
         * @author jokke refactored and added backwards firing for TAPNTransitions
269
172
         */
270
 
        public void stepBack(){
271
 
 
272
 
                if ( ! actionHistory.isEmpty() ){
273
 
 
274
 
                        if (actionHistory.get(currentAction) instanceof DiscreetFiringAction){
275
 
                                TAPNTransition transition = (TAPNTransition)((DiscreetFiringAction)actionHistory.get(currentAction)).getTransition(); // XXX - unsafe cast
276
 
                                HashMap<TimedPlace, ArrayList<BigDecimal>> markingToGoBackTo = markingHistory.get(currentAction);
277
 
 
278
 
                                if (markingToGoBackTo == null){
279
 
                                        System.err.println("No marking to go back to, ERROR!");
280
 
                                }
281
 
 
282
 
                                HashMap<TimedPlace, ArrayList<BigDecimal>> presetMarking = new HashMap<TimedPlace, ArrayList<BigDecimal>>();
283
 
                                for (Arc a : transition.getPreset() ){
284
 
                                        TimedPlace place = (TimedPlace)a.getSource();
285
 
                                        presetMarking.put(place, (ArrayList<BigDecimal>)markingToGoBackTo.get(place).clone());
286
 
                                }
287
 
 
288
 
                                HashMap<TimedPlace, ArrayList<BigDecimal>> postsetMarking = new HashMap<TimedPlace, ArrayList<BigDecimal>>();
289
 
                                for (Arc a : transition.getPostset() ){
290
 
                                        TimedPlace place = (TimedPlace)a.getTarget();
291
 
                                        postsetMarking.put(place, (ArrayList<BigDecimal>)markingToGoBackTo.get(place).clone());
292
 
                                }
293
 
 
294
 
                                CreateGui.currentPNMLData().fireTimedTransitionBackwards(presetMarking, postsetMarking, transition);
295
 
 
296
 
                                //If untimed simulation
297
 
                                if (CreateGui.getAbstractAnimationPane() != null){
298
 
 
299
 
                                        AnimationHistory untimedAnimationHistory = CreateGui.getAbstractAnimationPane();
300
 
                                        int current = untimedAnimationHistory.getCurrentItem();
301
 
                                        if ((untimedAnimationHistory.getElement(current)).trim().equals(transition.getName())){ //Possible null pointer exception
302
 
                                                //It is fired
303
 
                                                untimedAnimationHistory.stepBackwards();         
304
 
                                        }
305
 
 
306
 
                                }
307
 
 
308
 
                        }else if(actionHistory.get(currentAction) instanceof ColoredDiscreteFiringAction){
309
 
                                CreateGui.currentPNMLData().fireColoredTransitionBackwards((ColoredDiscreteFiringAction)actionHistory.get(currentAction));
310
 
                        }else if (actionHistory.get(currentAction) instanceof Transition ){
311
 
 
312
 
                        }else if ( actionHistory.get(currentAction) instanceof TimeDelayFiringAction){
313
 
                                BigDecimal timeDelay = ((TimeDelayFiringAction)actionHistory.get(currentAction)).getDealy();
314
 
                                try {
315
 
                                        CreateGui.getModel().letTimePass(timeDelay.negate());
316
 
                                } catch (InvariantViolatedAnimationException e) {
317
 
                                        //                                       XXX - kyrke, An error can not come here as this is valid states stored in animator
318
 
                                        e.printStackTrace();
319
 
                                }
320
 
 
321
 
                        }else{
322
 
                                System.err.println("problem in Animator");
 
173
 
 
174
        public void stepBack() {
 
175
                if (!actionHistory.isEmpty()){
 
176
                        TAPNNetworkTraceStep lastStep = actionHistory.get(currentAction);
 
177
                        if(isDisplayingUntimedTrace && lastStep instanceof TAPNNetworkTimedTransitionStep){
 
178
                                AnimationHistoryComponent untimedAnimationHistory = tab.getUntimedAnimationHistory();
 
179
                                String previousInUntimedTrace = untimedAnimationHistory.getElement(untimedAnimationHistory.getSelectedIndex());
 
180
                                if(previousInUntimedTrace.equals(lastStep.toString())){
 
181
                                        untimedAnimationHistory.stepBackwards();
 
182
                                }
323
183
                        }
324
 
 
325
 
 
326
 
 
327
 
 
328
 
                        CreateGui.currentPNMLData().setEnabledTransitions();
 
184
                        
 
185
                        tab.network().setMarking(markings.get(currentMarkingIndex - 1));
 
186
 
 
187
                        activeGuiModel().repaintPlaces();
329
188
                        unhighlightDisabledTransitions();
330
189
                        highlightEnabledTransitions();
331
190
                        currentAction--;
 
191
                        currentMarkingIndex--;
332
192
                }
333
193
        }
334
194
 
335
 
 
336
195
        /**
337
196
         * Steps forward through previously fired transitions
338
197
         */
339
 
        public void stepForward(){
340
 
                if ( currentAction < actionHistory.size()-1 ) {
341
 
 
342
 
 
343
 
                        //Marking history did not contain anything, so we must calculate the next marking
344
 
                        //We do this using hacked firingmode. 
345
 
 
346
 
                        if ( actionHistory.get(currentAction+1) instanceof DiscreetFiringAction){
347
 
                                TAPNTransition nextTransition = (TAPNTransition)((DiscreetFiringAction)actionHistory.get(currentAction+1)).getTransition(); // XXX - unsafe cast
348
 
 
349
 
                                // Before we firer the transition we need to setup Select firing mode, and 
350
 
                                // firer the transition with the same tokens as in the DiscreetFiringAction
351
 
                                // IT IS A HACK TO USE FIRING MODEL SELECT TO THIS !!! -- kyrke
352
 
 
353
 
                                //Setup firingmode
354
 
 
355
 
                                //If this marking is not saved in marking history (e.g. its a uppaal trace)
356
 
 
357
 
                                if (markingHistory.get(currentAction+1)==null){
358
 
                                        Logger.log("Marking is null, we will fix it");
359
 
 
360
 
                                        HashMap<TimedPlace, ArrayList<BigDecimal>> currentmakring = CreateGui.currentPNMLData().getCurrentMarking();
361
 
                                        markingHistory.set(currentAction+1, currentmakring);
362
 
                                }
363
 
 
364
 
                                HashMap<Place, ArrayList<BigDecimal>> consumedTokens = ((DiscreetFiringAction)actionHistory.get(currentAction+1)).getConsumedTokensList();
365
 
 
366
 
                                CreateGui.currentPNMLData().fireTransition(nextTransition, consumedTokens);
367
 
 
368
 
                                CreateGui.currentPNMLData().setEnabledTransitions();
369
 
                                unhighlightDisabledTransitions();
370
 
                                highlightEnabledTransitions();
371
 
                                currentAction++;
372
 
 
373
 
                                //If untimed simulation
374
 
                                if (CreateGui.getAbstractAnimationPane() != null){
375
 
 
376
 
                                        AnimationHistory untimedAnimationHistory = CreateGui.getAbstractAnimationPane();
377
 
                                        int current = untimedAnimationHistory.getCurrentItem();
378
 
                                        if ((untimedAnimationHistory.getElement(current+1)).trim().equals(nextTransition.getName())){ //Possible null pointer exception
379
 
                                                //It is fired
380
 
                                                untimedAnimationHistory.stepForward();
381
 
                                        }
382
 
 
383
 
                                }
384
 
 
385
 
 
386
 
                        }else if(actionHistory.get(currentAction+1) instanceof ColoredDiscreteFiringAction){
387
 
                                ColoredDiscreteFiringAction action = (ColoredDiscreteFiringAction)actionHistory.get(currentAction+1);
388
 
                                CreateGui.currentPNMLData().fireTransition(action);
389
 
                                CreateGui.currentPNMLData().setEnabledTransitions();
390
 
                                unhighlightDisabledTransitions();
391
 
                                highlightEnabledTransitions();
392
 
                                currentAction++;
393
 
                        }else if (actionHistory.get(currentAction+1) instanceof TimeDelayFiringAction){
394
 
                                BigDecimal timeDelay = ((TimeDelayFiringAction)actionHistory.get(currentAction+1)).getDealy();
395
 
 
396
 
                                //If this marking is not saved in marking history (e.g. its a uppaal trace)
397
 
 
398
 
                                if (markingHistory.get(currentAction+1)==null){
399
 
                                        Logger.log("Marking is null, we will fix it");
400
 
 
401
 
                                        HashMap<TimedPlace, ArrayList<BigDecimal>> currentmakring = CreateGui.currentPNMLData().getCurrentMarking();
402
 
                                        markingHistory.set(currentAction+1, currentmakring);
403
 
                                }
404
 
 
405
 
                                try {
406
 
                                        CreateGui.getModel().letTimePass(timeDelay);
407
 
                                } catch (InvariantViolatedAnimationException e) {
408
 
                                        // XXX - kyrke, An error can con come here as this is valid states stored in animator 
409
 
                                        e.printStackTrace();
410
 
                                }
411
 
                                CreateGui.currentPNMLData().setEnabledTransitions();
412
 
                                unhighlightDisabledTransitions();
413
 
                                highlightEnabledTransitions();
414
 
                                currentAction++;
 
198
 
 
199
        public void stepForward() {
 
200
                if (currentAction < actionHistory.size() - 1) {
 
201
                        TAPNNetworkTraceStep nextStep = actionHistory.get(currentAction+1);
 
202
                        if(isDisplayingUntimedTrace && nextStep instanceof TAPNNetworkTimedTransitionStep){
 
203
                                AnimationHistoryComponent untimedAnimationHistory = tab.getUntimedAnimationHistory();
 
204
                                String nextInUntimedTrace = untimedAnimationHistory.getElement(untimedAnimationHistory.getSelectedIndex()+1);
 
205
                                if(nextInUntimedTrace.equals(nextStep.toString())){
 
206
                                        untimedAnimationHistory.stepForward();
 
207
                                }
415
208
                        }
416
 
                        CreateGui.currentPNMLData().redrawVisibleTokenLists();
 
209
                        
 
210
                        tab.network().setMarking(markings.get(currentMarkingIndex + 1));
 
211
                        
 
212
                        activeGuiModel().repaintPlaces();
 
213
                        unhighlightDisabledTransitions();
 
214
                        highlightEnabledTransitions();
 
215
                        currentAction++;
 
216
                        currentMarkingIndex++;
 
217
                        activeGuiModel().redrawVisibleTokenLists();
 
218
 
417
219
                }
418
220
        }
419
221
 
420
 
        /** This method keeps track of a fired transition in the AnimationHistory 
421
 
         * object, enables transitions after the recent firing, and properly displays 
422
 
         * the transitions.
423
 
         * 
424
 
         * @author David Patterson renamed this method and changed the 
425
 
         * AnimationHandler to make it fire the transition before calling this method.
426
 
         * This prevents double-firing a transition.
427
 
         * 
428
 
         * @author Pere Bonet modified this method so that it now stores transitions 
429
 
         * that has just been fired in an array so that it can be accessed during 
430
 
         * backwards and stepping to fix the unexcepted behaviour observed during 
431
 
         * animation playback.
432
 
         * The method is renamed back to fireTransition.
433
 
         * 
434
 
         * 
435
 
         */
436
 
        public void fireTransition(Transition transition){
437
 
 
438
 
                Animator animator = CreateGui.getAnimator();
439
 
 
440
 
                HashMap<TimedPlace, ArrayList<BigDecimal>> currentmakring = CreateGui.currentPNMLData().getCurrentMarking();
441
 
 
442
 
                //If untimed simulation
443
 
                if (CreateGui.getAbstractAnimationPane() != null){
444
 
 
445
 
                        AnimationHistory untimedAnimationHistory = CreateGui.getAbstractAnimationPane();
446
 
                        int current = untimedAnimationHistory.getCurrentItem();
447
 
                        
448
 
                        //Only make this check if we have more steps in the untimed trace, if we dont the user can do whatever he like
449
 
                        if (untimedAnimationHistory.isStepForwardAllowed()){
450
 
                                if ((untimedAnimationHistory.getElement(current+1)).trim().equals(transition.getName())){ //Possible null pointer exception
451
 
                                        //It is fired
452
 
                                        untimedAnimationHistory.stepForward();   
 
222
        
 
223
        // TODO: Clean up this method
 
224
        public void fireTransition(TimedTransition transition) {
 
225
                NetworkMarking next = null;
 
226
                try{
 
227
                        if (getFiringmode() != null) {
 
228
                                next = currentMarking().fireTransition(transition, getFiringmode());
 
229
                        } else {
 
230
                                List<TimedToken> tokensToConsume = showSelectSimulatorDialogue(transition);
 
231
                                if(tokensToConsume == null) return; // Cancelled
 
232
                                next = currentMarking().fireTransition(transition, tokensToConsume);
 
233
                        }
 
234
                }catch(RequireException e){
 
235
                        JOptionPane.showMessageDialog(CreateGui.getApp(), "There was an error firing the transition. Reason: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
 
236
                        return;
 
237
                }
 
238
 
 
239
                // It is important that this comes after the above, since 
 
240
                // cancelling the token selection dialogue above should not result in changes 
 
241
                // to the untimed animation history
 
242
                if (isDisplayingUntimedTrace){
 
243
                        AnimationHistoryComponent untimedAnimationHistory = tab.getUntimedAnimationHistory();
 
244
                        if(untimedAnimationHistory.isStepForwardAllowed()){
 
245
                                String nextFromUntimedTrace = untimedAnimationHistory.getElement(untimedAnimationHistory.getSelectedIndex()+1);
 
246
                                
 
247
                                if(nextFromUntimedTrace.equals(transition.model().name() + "." + transition.name())){
 
248
                                        untimedAnimationHistory.stepForward();
453
249
                                }else{
454
 
                                        int fireTransition = JOptionPane.showConfirmDialog( CreateGui.getApp().getRootPane(),
455
 
                                                        "Are you sure you want to fire a transition which does not follow the untimed trace?\n" +
456
 
                                                        "Firing this transition will discard the untimed trace and revert to standard simulation.",
457
 
                                                        "Discrading Untimed Trace",
458
 
                                                        JOptionPane.YES_NO_OPTION );
459
 
                                        if (fireTransition > 0){
 
250
                                        int fireTransition = JOptionPane.showConfirmDialog(CreateGui.getApp(),
 
251
                                                        "Are you sure you want to fire a transition which does not follow the untimed trace?\n"
 
252
                                                        + "Firing this transition will discard the untimed trace and revert to standard simulation.",
 
253
                                                        "Discrading Untimed Trace", JOptionPane.YES_NO_OPTION );
 
254
 
 
255
                                        if (fireTransition == JOptionPane.NO_OPTION){
460
256
                                                return;
461
257
                                        }else{
462
258
                                                CreateGui.removeAbstractAnimationPane();
463
 
                                                CreateGui.updateLeftPanel();
 
259
                                                isDisplayingUntimedTrace = false;
464
260
                                        }
465
261
                                }
466
262
                        }
467
263
                }
468
 
 
469
 
                CreateGui.getAnimationHistory().addHistoryItem(transition.getName());
470
 
                FiringAction fired;
471
 
                fired = CreateGui.currentPNMLData().fireTransition(transition);
472
 
 
473
 
 
474
 
                if ( currentAction < actionHistory.size()-1 ){
475
 
                        removeStoredActions(currentAction+1);
476
 
                        addToHistory( fired,  currentmakring);
477
 
                }else{
478
 
                        addToHistory( fired, currentmakring );  
479
 
                }
480
 
 
481
 
                CreateGui.currentPNMLData().setEnabledTransitions();
482
 
                animator.highlightEnabledTransitions();
483
 
                animator.unhighlightDisabledTransitions();
484
 
 
485
 
        }
486
 
 
487
 
        public void letTimePass(BigDecimal timeToPass) throws InvariantViolatedAnimationException{
488
 
                Animator animator = CreateGui.getAnimator();
489
 
 
490
 
                if (CreateGui.currentPNMLData().canTimePass(timeToPass)){
491
 
 
492
 
                        if ( currentAction < actionHistory.size()-1 ){
493
 
                                removeStoredActions(currentAction+1);
494
 
                                addToHistory( new TimeDelayFiringAction(timeToPass), CreateGui.currentPNMLData().getCurrentMarking() );
495
 
                        }else{
496
 
                                addToHistory( new TimeDelayFiringAction(timeToPass), CreateGui.currentPNMLData().getCurrentMarking() );  
497
 
                        }
498
 
 
499
 
                        try {
500
 
 
501
 
                                //Catch exception and dont add history, throw exception again 
502
 
                                // to alow handling further on. 
503
 
                                //Stripping too long decimals
504
 
 
505
 
                                //This is a trick to get locals (, vs .) right in the text box.
506
 
                                DecimalFormat df = new DecimalFormat();
507
 
                                df.setMaximumFractionDigits(Pipe.AGE_DECIMAL_PRECISION);
508
 
                                df.setMinimumFractionDigits(Pipe.AGE_DECIMAL_PRECISION);
509
 
 
510
 
                                BigDecimal strippedTimeDelay = new BigDecimal(timeToPass.toString(), new MathContext(Pipe.AGE_PRECISION));
511
 
 
512
 
                                CreateGui.currentPNMLData().letTimePass(strippedTimeDelay);
513
 
 
514
 
                                CreateGui.getAnimationHistory().addHistoryItem("Time delay: "+ df.format(strippedTimeDelay));
515
 
 
516
 
 
517
 
                        } catch (InvariantViolatedAnimationException e) {
518
 
                                throw e;
519
 
                        } 
520
 
 
521
 
 
522
 
 
523
 
                        for (Place p : CreateGui.getModel().getPlaces()){
524
 
                                p.repaint();
525
 
                        }
526
 
 
527
 
 
528
 
                        CreateGui.currentPNMLData().setEnabledTransitions();
529
 
                        animator.highlightEnabledTransitions();
530
 
                        animator.unhighlightDisabledTransitions();
531
 
 
532
 
                }
533
 
 
534
 
 
535
 
        }
536
 
 
537
 
        public void resethistory(){
538
 
                markingHistory.clear();
 
264
                
 
265
                addMarking(new TAPNNetworkTimedTransitionStep(transition, null), next);
 
266
                tab.network().setMarking(currentMarking());
 
267
 
 
268
                activeGuiModel().repaintPlaces();
 
269
                highlightEnabledTransitions();
 
270
                unhighlightDisabledTransitions();
 
271
 
 
272
        }
 
273
 
 
274
        public void letTimePass(BigDecimal delay) {
 
275
                if (currentMarking().isDelayPossible(delay)) {
 
276
                        addMarking(new TAPNNetworkTimeDelayStep(delay), currentMarking().delay(delay));
 
277
                        tab.network().setMarking(currentMarking());
 
278
                }
 
279
 
 
280
                activeGuiModel().repaintPlaces();
 
281
                highlightEnabledTransitions();
 
282
                unhighlightDisabledTransitions();
 
283
        }
 
284
 
 
285
        private DataLayer activeGuiModel() {
 
286
                return tab.activeTemplate().guiModel();
 
287
        }
 
288
 
 
289
        public void resethistory() {
539
290
                actionHistory.clear();
 
291
                markings.clear();
540
292
                currentAction = -1;
541
 
        }
542
 
 
543
 
        public void manipulatehistory(ColoredDiscreteFiringAction dfa){
544
 
 
545
 
 
546
 
                markingHistory.add(null);
547
 
 
548
 
                actionHistory.add(dfa); // newAction = the transition to fire
549
 
                CreateGui.getAnimationHistory().addHistoryItemDontChange(dfa.getTransition().getName()); 
550
 
 
551
 
                CreateGui.animControlerBox.setAnimationButtonsEnabled();
552
 
        }
553
 
 
554
 
        public void manipulatehistory(DiscreetFiringAction dfa){
555
 
 
556
 
 
557
 
                markingHistory.add(null);
558
 
 
559
 
                actionHistory.add(dfa); // newAction = the transition to fire
560
 
                CreateGui.getAnimationHistory().addHistoryItemDontChange(dfa.getTransition().getName()); 
561
 
 
562
 
                CreateGui.animControlerBox.setAnimationButtonsEnabled();
563
 
        }
564
 
        public void manipulatehistory(BigDecimal delay){
565
 
                markingHistory.add(null); 
566
 
                actionHistory.add(new TimeDelayFiringAction(delay)); 
567
 
 
568
 
                CreateGui.getAnimationHistory().addHistoryItemDontChange("Time delay: "+ delay);
569
 
 
570
 
                CreateGui.animControlerBox.setAnimationButtonsEnabled();
571
 
        }
572
 
 
573
 
        public Firingmode getFiringmode() {
 
293
                currentMarkingIndex = 0;
 
294
                tab.getAnimationHistory().reset();
 
295
                if(tab.getUntimedAnimationHistory() != null){
 
296
                        tab.getUntimedAnimationHistory().reset();
 
297
                }
 
298
        }
 
299
 
 
300
        public FiringMode getFiringmode() {
574
301
                return firingmode;
575
302
        }
576
303
 
577
 
 
578
 
        //removes stored markings and actions from index "startWith" (included)
 
304
        // removes stored markings and actions from index "startWith" (included)
579
305
        private void removeStoredActions(int startWith) {
580
 
                int lastIndex = actionHistory.size()-1;
581
 
                for (int i=startWith; i<=lastIndex; i++){
 
306
                int lastIndex = actionHistory.size() - 1;
 
307
                for (int i = startWith; i <= lastIndex; i++) {
582
308
                        removeLastHistoryStep();
583
309
                }
584
310
        }
585
311
 
586
 
        public synchronized int getNumberSequences() {
587
 
                return numberSequences;
588
 
        }
589
 
 
590
 
        public synchronized void setNumberSequences(int numberSequences) {
591
 
                this.numberSequences = numberSequences;
592
 
        }
593
 
 
594
 
        private void addToHistory(FiringAction newAction, HashMap<TimedPlace, ArrayList<BigDecimal>> currentMarking){
595
 
                actionHistory.add(newAction);
596
 
                markingHistory.add(currentMarking);
 
312
        private void addMarking(TAPNNetworkTraceStep action, NetworkMarking marking) {
 
313
                if (currentAction < actionHistory.size() - 1)
 
314
                        removeStoredActions(currentAction + 1);
 
315
 
 
316
                CreateGui.getAnimationHistory().addHistoryItem(action.toString());
 
317
                actionHistory.add(action);
 
318
                markings.add(marking);
597
319
                currentAction++;
598
 
        }
599
 
 
600
 
        private void removeLastHistoryStep(){
601
 
                actionHistory.remove(actionHistory.size()-1);
602
 
                markingHistory.remove(markingHistory.size()-1);
603
 
        }
604
 
 
605
 
 
606
 
 
607
 
        public void setFiringmode(String t){
608
 
 
609
 
                if (t.equals("Random")){
610
 
                        firingmode = new RandomFiringmode();
611
 
                } else if (t.equals("Youngest")){
612
 
                        firingmode = new YoungestFiringmode();
613
 
                } else if (t.equals("Oldest")){
614
 
                        firingmode = new OldestFiringmode();
615
 
                } else if (t.equals("Manual")){
616
 
                        firingmode = new SelectFiringmode();
 
320
                currentMarkingIndex++;
 
321
        }
 
322
 
 
323
        private void removeLastHistoryStep() {
 
324
                actionHistory.remove(actionHistory.size() - 1);
 
325
                markings.remove(markings.size() - 1);
 
326
        }
 
327
 
 
328
        public void setFiringmode(String t) {
 
329
                if (t.equals("Random")) {
 
330
                        firingmode = new RandomFiringMode();
 
331
                } else if (t.equals("Youngest")) {
 
332
                        firingmode = new YoungestFiringMode();
 
333
                } else if (t.equals("Oldest")) {
 
334
                        firingmode = new OldestFiringMode();
 
335
                } else if (t.equals("Manual")) {
 
336
                        firingmode = null;
617
337
                } else {
618
 
                        System.err.println("Iligal firing mode mode: " + t + " not found.");
619
 
                }
620
 
 
621
 
                CreateGui.animControlerBox.updateFiringModeComboBox();
622
 
        }
623
 
 
624
 
        public interface Firingmode {
625
 
 
626
 
                public ColoredToken fire(List<ColoredToken> tokens);
627
 
                public BigDecimal fire(List<BigDecimal> tokens);
628
 
                public String getName();
629
 
 
630
 
        }
631
 
 
632
 
        public class OldestFiringmode implements Firingmode {
633
 
 
634
 
                public BigDecimal fire(List<BigDecimal> tokens) {
635
 
                        BigDecimal max=tokens.get(0);
636
 
                        for (BigDecimal a : tokens){
637
 
                                if (a.compareTo(max) > 0){
638
 
                                        max = a;
639
 
                                }
640
 
                        }
641
 
                        return max;
642
 
                }
643
 
 
644
 
                public String getName() {
645
 
                        return "Oldest";
646
 
                }
647
 
 
648
 
                public ColoredToken fire(List<ColoredToken> tokens) {
649
 
                        ColoredToken oldest = tokens.get(0);
650
 
                        for(ColoredToken token : tokens){
651
 
                                if(token.getAge().compareTo(oldest.getAge()) > 0){
652
 
                                        oldest = token;
653
 
                                }
654
 
                        }
655
 
 
656
 
                        return oldest;
657
 
                }
658
 
 
659
 
        }
660
 
 
661
 
        public class YoungestFiringmode implements Firingmode {
662
 
 
663
 
                public BigDecimal fire(List<BigDecimal> tokens) {
664
 
                        BigDecimal min=tokens.get(0);
665
 
                        for (BigDecimal a : tokens){
666
 
                                if (a.compareTo(min) < 0){
667
 
                                        min = a;
668
 
                                }
669
 
                        }
670
 
                        return min;
671
 
                }
672
 
 
673
 
                public String getName() {
674
 
                        return "Youngest";
675
 
                }
676
 
 
677
 
                public ColoredToken fire(List<ColoredToken> tokens) {
678
 
                        ColoredToken youngest = tokens.get(0);
679
 
                        for(ColoredToken token : tokens){
680
 
                                if(token.getAge().compareTo(youngest.getAge()) < 0){
681
 
                                        youngest = token;
682
 
                                }
683
 
                        }
684
 
 
685
 
                        return youngest;
686
 
                }                        
687
 
        }
688
 
 
689
 
 
690
 
 
691
 
        public class RandomFiringmode implements Firingmode {
692
 
 
693
 
                public BigDecimal fire(List<BigDecimal> tokens) {
694
 
                        Random generator = new Random();
695
 
 
696
 
                        int random = generator.nextInt(tokens.size());
697
 
 
698
 
                        return tokens.get(random);
699
 
                }
700
 
 
701
 
                public String getName() {
702
 
                        return "Random";
703
 
                }
704
 
 
705
 
                public ColoredToken fire(List<ColoredToken> tokens) {
706
 
                        Random generator = new Random();
707
 
                        int random = generator.nextInt(tokens.size());
708
 
                        return tokens.get(random);
709
 
                }
710
 
 
711
 
        }
712
 
        public class SelectFiringmode implements Firingmode {
713
 
 
714
 
                ArrayList<Integer> tokensToFire = new ArrayList<Integer>();
715
 
 
716
 
 
717
 
 
718
 
 
719
 
                public void setTokensToFire( ArrayList<Integer> a){
720
 
                        tokensToFire = a;
721
 
                }
722
 
 
723
 
 
724
 
                public BigDecimal fire(List<BigDecimal> tokens) {
725
 
 
726
 
                        BigDecimal toReturn = tokens.get(tokensToFire.get(0));
727
 
                        tokensToFire.remove(0);
728
 
 
729
 
                        return toReturn;
730
 
                }
731
 
 
732
 
                public String getName() {
733
 
                        return "Manual";
734
 
                }
735
 
 
736
 
                public ColoredToken fire(List<ColoredToken> tokens) {
737
 
                        ColoredToken token = tokens.get(tokensToFire.get(0));
738
 
                        tokensToFire.remove(0);
739
 
 
740
 
                        return token;
741
 
                }
742
 
        }
743
 
 
744
 
 
745
 
        public boolean showSelectSimulatorDialogue(Transition t){
746
 
                EscapableDialog guiDialog = 
747
 
                        new EscapableDialog(CreateGui.getApp(), Pipe.getProgramName(), true);
 
338
                        System.err
 
339
                        .println("Illegal firing mode mode: " + t + " not found.");
 
340
                }
 
341
 
 
342
                CreateGui.getAnimationController().updateFiringModeComboBox();
 
343
        }
 
344
 
 
345
        public List<TimedToken> showSelectSimulatorDialogue(TimedTransition transition) {
 
346
                EscapableDialog guiDialog = new EscapableDialog(CreateGui.getApp(), Pipe.getProgramName(), true);
748
347
 
749
348
                Container contentPane = guiDialog.getContentPane();
750
 
 
751
 
 
752
 
                contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));      
753
 
 
754
 
 
755
 
                AnimationSelectmodeDialog animationSelectmodeDialog = new AnimationSelectmodeDialog(t); 
 
349
                contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));
 
350
                AnimationSelectmodeDialog animationSelectmodeDialog = new AnimationSelectmodeDialog(transition);
756
351
                contentPane.add(animationSelectmodeDialog);
757
 
 
758
 
                guiDialog.setResizable(true);     
 
352
                guiDialog.setResizable(true);
759
353
 
760
354
                // Make window fit contents' preferred size
761
355
                guiDialog.pack();
764
358
                guiDialog.setLocationRelativeTo(null);
765
359
                guiDialog.setVisible(true);
766
360
 
767
 
                if(!animationSelectmodeDialog.cancelled()){
768
 
                        ArrayList<Integer> intlist = new ArrayList<Integer>();
769
 
                        for (JComboBox jb : animationSelectmodeDialog.presetPanels){
770
 
                                intlist.add(jb.getSelectedIndex());
771
 
                        }
772
 
                        ((SelectFiringmode)firingmode).setTokensToFire(intlist);
773
 
                }
774
 
                
775
 
                return !animationSelectmodeDialog.cancelled();
 
361
                return animationSelectmodeDialog.getTokens();
776
362
        }
777
 
        
 
363
 
778
364
        public void reset(){
779
 
                currentAction = -1;
780
 
                actionHistory.clear();
781
 
                markingHistory.clear();
 
365
                resethistory();
 
366
                isDisplayingUntimedTrace = false;
782
367
        }
783
368
}