View Javadoc

1   package cz.cuni.amis.pogamut.sposh.engine;
2   
3   import cz.cuni.amis.pogamut.sposh.elements.Competence;
4   import cz.cuni.amis.pogamut.sposh.elements.CompetenceElement;
5   import cz.cuni.amis.pogamut.sposh.elements.LapPath;
6   import cz.cuni.amis.pogamut.sposh.elements.LapType;
7   import cz.cuni.amis.pogamut.sposh.elements.PoshPlan;
8   import cz.cuni.amis.pogamut.sposh.engine.FireResult.Type;
9   import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
10  import java.util.ArrayList;
11  import java.util.List;
12  
13  /**
14   * Executor for competence.
15   *
16   * @author Honza
17   */
18  final class CExecutor extends AbstractExecutor implements ElementExecutor {
19  
20      private boolean executorWasEvalued = false;
21      
22      /**
23       * Remnant from time when *POSH has goal of competence.
24       */
25      @Deprecated
26      private final SenseListExecutor goalExecutor;
27      private final List<CEExecutor> ceExecutors = new ArrayList<CEExecutor>();
28  
29      /**
30       * Create new competence executor
31       *
32       * @param plan plan used to resolve names of primitives into S/A/AP/C
33       * @param competence competence to execute
34       * @param competencePath Path to the competence.
35       * @param ctx variable context of competence
36       * @param log logger to record actions of this executor
37       */
38      public CExecutor(PoshPlan plan, Competence competence, LapPath competencePath, VariableContext ctx, EngineLog log) {
39          super(competencePath, ctx, log);
40  
41          assert competencePath.traversePath(plan) == competence;
42  
43          this.goalExecutor = new SenseListExecutor<Competence>(competencePath, ctx, log);
44  
45          int choiceId = 0;
46          for (CompetenceElement ce : competence.getChildDataNodes()) {
47              LapPath choicePath = competencePath.concat(LapType.COMPETENCE_ELEMENT, choiceId++);
48              CEExecutor choiceExecutor = new CEExecutor(plan, competence, ce, choicePath, ctx, log);
49              
50              ceExecutors.add(choiceExecutor);
51          }
52      }
53  
54      /**
55       * Checks whether competence goal has been met.
56       *
57       * @param workExecutor
58       * @return
59       */
60      public boolean isGoalSatisfied(IWorkExecutor workExecutor) {
61          if (goalExecutor == null) {
62              return false;
63          }
64          return goalExecutor.fire(workExecutor, false).wasSuccess();
65      }
66  
67      /**
68       * Check if goal is not satisfied, if it is, there is no need to continue to
69       * execute this competence (return {@link Type#FULFILLED}). <p> For all CE
70       * in priority order: Check if CE retry limit hasn't been exceeded and if
71       * the CE trigger is valid. If element is primitive, fire it. If it is AP or
72       * C, return it as next element on the stack
73       *
74       * If none of CE can be fired, the C failed and there is no need to continue {@link Type#FAILED};
75       *
76       * @param workExecuter
77       * @return
78       */
79      @Override
80      public FireResult fire(IWorkExecutor workExecuter) {
81          engineLog.pathReached(path);
82          
83          if (executorWasEvalued) {
84              return new FireResult(Type.SURFACE_CONTINUE);
85          }
86          executorWasEvalued = true;
87          
88          // is goal satisfied?
89          // TODO: What should I do with goal of competence? It would be best to remove it completely.
90          TriggerResult goalResult = goalExecutor.fire(workExecuter, false);
91          if (goalResult.wasSuccess()) {
92              return new FireResult(FireResult.Type.FULFILLED);
93          }
94  
95          for (CEExecutor ceExecutor : ceExecutors) {
96              TriggerResult triggerResult = ceExecutor.isReady(workExecuter);
97              if (triggerResult.wasSuccess()) {
98                  StackElement stackElement = new StackElement(CompetenceElement.class, ceExecutor.getName(), ceExecutor);
99                  return new FireResult(FireResult.Type.FOLLOW, stackElement);
100             }
101         }
102         // If no element was fired, we have failed
103         return new FireResult(FireResult.Type.FAILED);
104     }
105 }