View Javadoc

1   package cz.cuni.amis.pogamut.sposh.engine;
2   
3   import cz.cuni.amis.pogamut.sposh.engine.timer.SystemClockTimer;
4   import cz.cuni.amis.pogamut.sposh.engine.timer.ITimer;
5   import cz.cuni.amis.pogamut.sposh.elements.DriveCollection;
6   import cz.cuni.amis.pogamut.sposh.elements.DriveElement;
7   import cz.cuni.amis.pogamut.sposh.elements.PoshPlan;
8   import cz.cuni.amis.pogamut.sposh.engine.PoshEngine.EvaluationResult;
9   import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
10  import java.util.ArrayList;
11  import java.util.List;
12  import java.util.logging.Logger;
13  
14  /**
15   * This class is responsible for valuating the DriveCollection element.
16   *
17   * @author HonzaH
18   */
19  final class DCExecutor extends AbstractExecutor {
20  
21      private SenseListExecutor<DriveCollection> goalExecutor;
22      List<DEExecutor> deExecutors = new ArrayList<DEExecutor>();
23      private DEExecutor lastTriggeredDrive = null;
24      private ITimer timer;
25      private TriggerResult triggerResult;
26      
27  
28      /**
29       * Create DCExecutor with SystemClockTimer.
30       *
31       * @param dc
32       * @param ctx
33       */
34      protected DCExecutor(PoshPlan plan, VariableContext ctx) {
35          this(plan, ctx, new SystemClockTimer(), null);
36      }
37  
38      protected DCExecutor(PoshPlan plan, VariableContext ctx, ITimer timer, Logger log) {
39          super(ctx, log);
40  
41          DriveCollection dc = plan.getDriveCollection();
42          this.timer = timer;
43          this.goalExecutor = new SenseListExecutor<DriveCollection>(dc.getGoal(), ctx, log);
44  
45          for (DriveElement de : dc.getDrives()) {
46              deExecutors.add(new DEExecutor(plan, de, ctx, log));
47          }
48      }
49  
50      public synchronized PoshEngine.EvaluationResultInfo fire(IWorkExecutor workExecuter) {
51          FireResult.Type resultType = null;
52          triggerResult = goalExecutor.fire(workExecuter, false);
53          if (triggerResult.wasSuccess()) {
54              return new PoshEngine.EvaluationResultInfo(EvaluationResult.GOAL_SATISFIED, FireResult.Type.FULFILLED);
55          }
56          // TODO: Rework whole engine, currently I need to clear trigger re4sults of DEExecutor every loop
57          // because they would linger, although never fired in the loop
58          for (DEExecutor deExecutor : deExecutors) {
59              deExecutor.clearTriggerResult();
60          }
61  
62          for (DEExecutor deExecutor : deExecutors) {
63              if (deExecutor.isReady(timer.getTime(), workExecuter)) {
64              	if (lastTriggeredDrive != null && lastTriggeredDrive != deExecutor) {
65              		// DRIVE SWITCH
66              		// Some drive that has more priority than "lastTriggeredDrive" has to fire
67              		// => clean up the stack of deExecutor
68              		lastTriggeredDrive.driveInterrupted();            		
69              	}            	
70              	lastTriggeredDrive = deExecutor;
71                  resultType = deExecutor.fire(workExecuter, timer);
72                  return new PoshEngine.EvaluationResultInfo(EvaluationResult.ELEMENT_FIRED, resultType);
73              }
74          }
75          return new PoshEngine.EvaluationResultInfo(EvaluationResult.NO_ELEMENT_FIRED, FireResult.Type.FAILED);
76      }
77      
78      int getDECount() {
79      	return deExecutors.size();
80      }
81      
82      String getDEName(int index) {
83      	return deExecutors.get(index).getName();
84      }
85  
86      ElementStackTrace getStackForDE(int index) {
87          return deExecutors.get(index).getStackTrace();
88      }
89  
90      /**
91       * Get ElementStackTrace for the drive element with name "name." If there
92       * are two drive elements with same name, throw IllegalStateException.
93       *
94       * @param name name of drive element we are looking for
95       * @return stacktrace for element if element with such name exists, else
96       * null.
97       */
98      ElementStackTrace getStackForDE(String name) {
99          DEExecutor result = null;
100         for (DEExecutor de : deExecutors) {
101             boolean equal = de.getName() == null ? name == null : de.getName().equals(name);
102             if (equal) {
103                 if (result == null) {
104                     result = de;
105                 } else {
106                     throw new IllegalStateException("Two drive elements with name \"" + name + "\".");
107                 }
108             }
109         }
110         if (result != null) {
111             return result.getStackTrace();
112         }
113 
114         return null;
115     }
116 
117     // TODO: Change DC executor into an ElementExecutor
118     public TriggerResult getTriggerResult() {
119         return triggerResult;
120     }
121 }