View Javadoc

1   package cz.cuni.amis.pogamut.sposh.engine;
2   
3   import cz.cuni.amis.pogamut.sposh.elements.Goal;
4   import cz.cuni.amis.pogamut.sposh.elements.Sense;
5   import cz.cuni.amis.pogamut.sposh.elements.Sense.SenseCall;
6   import cz.cuni.amis.pogamut.sposh.elements.Triggers;
7   import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
8   import java.util.ArrayList;
9   import java.util.Collections;
10  import java.util.Iterator;
11  import java.util.LinkedList;
12  import java.util.List;
13  import java.util.logging.Logger;
14  
15  /**
16   * Class that immutably stores the result of evaluation of trigger. Trigger is 
17   * basically a list of sense calls (i.e. {@link SenseListExecutor}).
18   */
19  class TriggerResult implements Iterable<SenseResult> {
20      private final List<SenseResult> senses;
21      private final boolean success;
22  
23      /**
24       * Create new result of trigger
25       * @param senses list of results, what did each sense ended up as
26       * @param success was the trigger as a whole successful
27       */
28      public TriggerResult(List<SenseResult> senses, boolean success) {
29          this.success = success;
30          this.senses = Collections.unmodifiableList(new ArrayList<SenseResult>(senses));
31      }
32  
33      /**
34       * Create new result of trigger, without specifying any senses. 
35       * @param success was the trigger successful
36       */
37      public TriggerResult(boolean success) {
38          this(Collections.<SenseResult>emptyList(), success);
39      }
40      
41      public boolean wasSuccess() {
42          return success;
43      }
44  
45      /**
46       * Get iterator to the all senses of this trigger. Unmodifiable.
47       * @return iterator to the start of sens's list.
48       */
49      @Override
50      public Iterator<SenseResult> iterator() {
51          return senses.iterator();
52      }
53  }
54  
55  /**
56   * Executor that decicdes if goal or trigger are fulfilled. That happens only
57   * is all its senses are fired.
58   * 
59   * @author Honza
60   */
61  final class SenseListExecutor extends AbstractExecutor {
62  
63      private List<SenseExecutor> sensesExecutors = new ArrayList<SenseExecutor>();
64  
65      /**
66       * Create executor for goal.
67       * @param goal null for empty SenseListExecutor or source of senses
68       * @param log logger to record actions of this executor, can be null
69       */
70      SenseListExecutor(Goal goal, VariableContext ctx, Logger log) {
71          super(ctx, log);
72          if (goal == null) {
73              return;
74          }
75  
76          for (Sense sense : goal.getSenses()) {
77              sensesExecutors.add(new SenseExecutor(sense, ctx, log));
78          }
79      }
80  
81      /**
82       * Create executor for triggers.
83       * @param triggers source of senses, can be null, then no senses will be used.
84       * @param log logger to record actions of this executor, can be null
85       */
86      SenseListExecutor(Triggers triggers, VariableContext ctx, Logger log) {
87          super(ctx, log);
88          if (triggers == null) {
89              return;
90          }
91  
92          for (Sense sense : triggers.getSenses()) {
93              sensesExecutors.add(new SenseExecutor(sense, ctx, log));
94          }
95      }
96  
97      /**
98       * Create executor for triggers.
99       * @param triggers source of senses, can be null, then no senses will be used.
100      * @param log logger to record actions of this executor, can be null
101      */
102     SenseListExecutor(List<Sense> triggers, VariableContext ctx, Logger log) {
103         super(ctx, log);
104 
105         for (Sense sense : triggers) {
106             sensesExecutors.add(new SenseExecutor(sense, ctx, log));
107         }
108     }
109 
110     /**
111      * Evaluate all senses until first one fails. 
112      * If no senses were specified, consider it a fail.
113      * @param defaultReturn what to return if no senses were specified. In trigger true, in goal false
114      * @return Result of the senselist. The result is true if none of senses fails, false if at least one fails.
115      */
116     public TriggerResult fire(IWorkExecutor workExecuter, boolean defaultReturn) {
117         List<SenseResult> senses = new LinkedList<SenseResult>();
118         
119         for (SenseExecutor senseExecutor : sensesExecutors) {
120             defaultReturn = true;
121             
122             SenseResult res = senseExecutor.fire(workExecuter);
123             senses.add(res);
124             
125             if (!res.wasSuccessful()) {
126                 return new TriggerResult(senses, false);
127             }
128         }
129         return new TriggerResult(senses, defaultReturn);
130     }
131 }