View Javadoc

1   package cz.cuni.amis.pogamut.sposh.engine;
2   
3   import java.util.logging.Logger;
4   
5   import cz.cuni.amis.pogamut.sposh.elements.ActionPattern;
6   import cz.cuni.amis.pogamut.sposh.elements.Competence;
7   import cz.cuni.amis.pogamut.sposh.elements.PoshPlan;
8   import cz.cuni.amis.pogamut.sposh.elements.PrimitiveCall;
9   import cz.cuni.amis.pogamut.sposh.elements.TriggeredAction;
10  import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
11  
12  /**
13   * Executor for AP.
14   * If successfull, return specified result, otehrwise FAIL.
15   * @author Honza
16   */
17  @SuppressWarnings("unchecked")
18  class APExecutor extends AbstractExecutor implements ElementExecutor {
19      private ActionPattern actionPattern;
20      private PoshPlan plan;
21      private int index = 0;
22      private FireResult.Type result;
23  
24      /**
25       * Create a new AP executor
26       * @param plan plan, we will use it to look up what are actions in ap
27       * @param ap ap that will be executed.
28       * @param result what to return in case of successful AP execution (SURFACE or FULFILLED)
29       * @param ctx
30       * @param log logger to record actions of this executor, can be null
31       */
32      APExecutor(PoshPlan plan, ActionPattern ap, FireResult.Type result, VariableContext ctx, Logger log) {
33          super(ctx, log);
34  
35          this.result = result;
36          this.index = 0;
37  
38          this.plan = plan;
39          this.actionPattern = ap;
40      }
41  
42      @Override
43      public FireResult fire(IWorkExecutor workExecuter) {
44          if (index == actionPattern.getActions().size()) {
45              return new FireResult(result);
46          }
47          // index is not incremented here, it should be done only whenever the action finishes its execution,
48          // see createActionExecutor()
49          TriggeredAction action = actionPattern.getActions().get(index);
50          StackElement stackElement = createActionExecutor(plan, action.getActionCall());
51          return new FireResult(FireResult.Type.FOLLOW, stackElement);
52      }
53  
54      /**
55       * Create an executor for the passed action according to what it really is (C/AP/P).
56       * @param plan
57       * @param action
58       * @return
59       */    
60  	private StackElement createActionExecutor(PoshPlan plan, PrimitiveCall actionCall) {
61  		StackElement element = getElement(plan, actionCall, 
62  						  FireResult.Type.SURFACE_CONTINUE, 
63  						  FireResult.Type.SURFACE,
64  						  FireResult.Type.SURFACE,
65  						  FireResult.Type.FAILED,
66  			              new Runnable() { // FINISHED CALLBACK
67  							@Override
68  							public void run() {
69  								++index;
70  							}
71  			              },
72  		                  null,
73  		                  new Runnable() { // RUNNING ONCE CALLBACK
74  							@Override
75  							public void run() {
76  								++index;
77  							}
78  			              },
79  		                  null
80  				);        
81  		if (element.getExecutor() instanceof APExecutor) {
82  			// APExecutor won't trigger SUCCESS-CALLBACK ... must manually move index of next-to-be-executed action
83  			++index;
84  		}
85  		return element;
86      }
87  
88      /**
89       * AP has no triggers so return satisfied trigger
90       * @return 
91       */
92      @Override
93      public TriggerResult getTriggerResult() {
94          // XXX: Is it ok to always create new instance, maybe static field would be better
95          return new TriggerResult(true);
96      }
97  }