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 final PoshPlan plan;
21      private final Competence competence;
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.plan = plan;
44          this.competence = competence;
45          this.goalExecutor = new SenseListExecutor<Competence>(competencePath, ctx, log);
46  
47          int choiceId = 0;
48          for (CompetenceElement ce : competence.getChildDataNodes()) {
49              LapPath choicePath = competencePath.concat(LapType.COMPETENCE_ELEMENT, choiceId++);
50              CEExecutor choiceExecutor = new CEExecutor(plan, competence, ce, choicePath, ctx, log);
51              
52              ceExecutors.add(choiceExecutor);
53          }
54      }
55  
56      /**
57       * Checks whether competence goal has been met.
58       *
59       * @param workExecutor
60       * @return
61       */
62      public boolean isGoalSatisfied(IWorkExecutor workExecutor) {
63          if (goalExecutor == null) {
64              return false;
65          }
66          return goalExecutor.fire(workExecutor, false).wasSuccess();
67      }
68  
69      /**
70       * Check if goal is not satisfied, if it is, there is no need to continue to
71       * execute this competence (return {@link Type#FULFILLED}). <p> For all CE
72       * in priority order: Check if CE retry limit hasn't been exceeded and if
73       * the CE trigger is valid. If element is primitive, fire it. If it is AP or
74       * C, return it as next element on the stack
75       *
76       * If none of CE can be fired, the C failed and there is no need to continue {@link Type#FAILED};
77       *
78       * @param workExecuter
79       * @return
80       */
81      @Override
82      public FireResult fire(IWorkExecutor workExecuter) {
83          engineLog.pathReached(path);
84          // is goal satisfied?
85          // TODO: What should I do with goal of competence? It would be best to remove it completely.
86          TriggerResult goalResult = goalExecutor.fire(workExecuter, false);
87          if (goalResult.wasSuccess()) {
88              return new FireResult(FireResult.Type.FULFILLED);
89          }
90  
91          for (CEExecutor ceExecutor : ceExecutors) {
92              TriggerResult triggerResult = ceExecutor.isReady(workExecuter);
93              if (triggerResult.wasSuccess()) {
94                  StackElement stackElement = new StackElement(CompetenceElement.class, ceExecutor.getName(), ceExecutor);
95                  return new FireResult(FireResult.Type.FOLLOW, stackElement);
96              }
97          }
98          // If no element was fired, we have failed
99          return new FireResult(FireResult.Type.FAILED);
100     }
101 }