View Javadoc

1   package cz.cuni.amis.pogamut.sposh.engine;
2   
3   import cz.cuni.amis.pogamut.sposh.elements.ActionPattern;
4   import cz.cuni.amis.pogamut.sposh.elements.LapPath;
5   import cz.cuni.amis.pogamut.sposh.elements.LapType;
6   import cz.cuni.amis.pogamut.sposh.elements.PoshPlan;
7   import cz.cuni.amis.pogamut.sposh.elements.PrimitiveCall;
8   import cz.cuni.amis.pogamut.sposh.elements.TriggeredAction;
9   import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
10  
11  /**
12   * Executor for AP. If successfull, return specified result, otherwise FAIL.
13   *
14   * @author Honza
15   */
16  @SuppressWarnings("unchecked")
17  class APExecutor extends AbstractExecutor implements ElementExecutor {
18  
19      /**
20       * Plan this executor is using to resolve actions and so on.
21       */
22      private final PoshPlan plan;
23      /**
24       * The pattern this executor is executing.
25       */
26      private final ActionPattern actionPattern;
27      /**
28       * Index of action that will be executed in the next call of {@link #fire(cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor)
29       * }. At the start, it is 0 (because first action should be exeucted). Once
30       * it is equal to size of {@link ActionPattern#getActions()}, we have
31       * finished this {@link APExecutor}.
32       */
33      private int index = 0;
34      /**
35       * Once this {@link APExecutor} finished all its actions (i.e. all its
36       * actions have properly been fired and surfaced back here), return this.
37       *
38       * TODO: Is this even needed? SURFACE fo all should be sufficient.
39       */
40      private FireResult.Type result;
41  
42      /**
43       * Create a new AP executor
44       *
45       * @param plan plan, we will use it to look up what are actions in ap
46       * @param ap ap that will be executed.
47       * @param result what to return in case of successful AP execution (SURFACE
48       * or FULFILLED)
49       * @param ctx
50       * @param log logger to record actions of this executor
51       */
52      APExecutor(PoshPlan plan, ActionPattern ap, FireResult.Type result, LapPath apPath, VariableContext ctx, EngineLog log) {
53          super(apPath, ctx, log);
54          
55          assert apPath.traversePath(plan) == ap;
56  
57          this.plan = plan;
58          this.actionPattern = ap;
59          this.index = 0;
60          this.result = result;
61      }
62  
63      @Override
64      public FireResult fire(IWorkExecutor workExecuter) {
65          engineLog.pathReached(path);
66          if (index == actionPattern.getActions().size()) {
67              return new FireResult(result);
68          }
69          // index is not incremented here, it should be done only whenever the action finishes its execution,
70          // see createActionExecutor()
71          TriggeredAction action = actionPattern.getActions().get(index);
72          StackElement stackElement = createActionExecutor(action.getActionCall());
73          return new FireResult(FireResult.Type.FOLLOW, stackElement);
74      }
75  
76      /**
77       * Create an executor for the passed action according to what it really is
78       * (C/AP/P).
79       *
80       * @param plan
81       * @param action
82       * @return
83       */
84      private StackElement createActionExecutor(PrimitiveCall actionCall) {
85          LapPath actionPath = path.concat(LapType.ACTION, index);
86          StackElement element = getElement(plan, actionCall, actionPath, 
87                  new Runnable() { // FINISHED CALLBACK
88  
89                      @Override
90                      public void run() {
91                          ++index;
92                      }
93                  },
94                  null,
95                  new Runnable() { // RUNNING ONCE CALLBACK
96  
97                      @Override
98                      public void run() {
99                          ++index;
100                     }
101                 },
102                 null);
103         if (element.getExecutor() instanceof APExecutor) {
104             // APExecutor won't trigger SUCCESS-CALLBACK ... must manually move index of next-to-be-executed action
105             ++index;
106         }
107         return element;
108     }
109 }