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.PoshPlan;
6   import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
7   import java.util.Set;
8   import java.util.logging.Logger;
9   
10  /**
11   * This class is responsible for executing the valid posh plan.
12   * 
13   * @author Honza
14   */
15  public class PoshEngine {
16  
17      public enum EvaluationResult {
18          GOAL_SATISFIED,
19          ELEMENT_FIRED,
20          NO_ELEMENT_FIRED
21      }
22      
23      public static class EvaluationResultInfo {
24      	
25      	public EvaluationResult result;
26      	public FireResult.Type type;
27      	
28      	public EvaluationResultInfo(EvaluationResult result, FireResult.Type type) {
29      		this.result = result;
30      		this.type = type;
31      	}
32      	
33      }
34  
35      protected PoshPlan plan;
36      protected ITimer timer;
37      protected Logger log;
38      private DCExecutor dcExecutor;
39  
40      public PoshEngine(PoshPlan plan) {
41          this(plan, new SystemClockTimer());
42      }
43  
44      public PoshEngine(PoshPlan plan, ITimer timer) {
45          this(plan, timer, null);
46      }
47  
48      public PoshEngine(PoshPlan plan, ITimer timer, Logger log) {
49          this.plan = plan;
50          this.timer = timer;
51          this.log = log;
52          reset();
53      }
54  
55      /**
56       * Reset the posh engine, all stacks and variables will be reseted.
57       * Use this to return engine to former state, it had when first initialized.
58       */
59      public final synchronized void reset() {
60          dcExecutor = new DCExecutor(plan, new VariableContext(), timer, log);
61      }
62  
63      public synchronized EvaluationResultInfo evaluatePlan(IWorkExecutor workExecuter) {
64          EvaluationResultInfo ret = dcExecutor.fire(workExecuter);
65          // DO NOT REMOVE. For details see javadoc of the method.
66          evaluatePlanExit();
67          return ret;
68      }
69  
70      /**
71       * <em>DO NOT REMOVE!!!</em> This method is here as a workaround of slow
72       * Netbeans breakpoint API. The API is quite fast when adding a breakpoint
73       * of {@link MethodBreakpoint#TYPE_METHOD_ENTRY} type, but <em>very
74       * slow</em> (about 1.2 seconds penalty) when using the
75       * {@link MethodBreakpoint#TYPE_METHOD_EXIT}. As a workaround, I am adding
76       * an {@link MethodBreakpoint#TYPE_METHOD_ENTRY entry type} breakpoint to
77       * this method that is used directly before returning from
78       * {@link PoshEngine#evaluatePlan(cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor)
79       * }.
80       */
81      private void evaluatePlanExit() {
82          // intentionally left empty
83      }
84      
85      ElementStackTrace getStackForDE(String name) {
86          return dcExecutor.getStackForDE(name);
87      }
88  
89      
90      ElementStackTrace getStackForDE(int index) {
91          return dcExecutor.getStackForDE(index);
92      }
93      
94      int getDECount() {
95      	return dcExecutor.getDECount();
96      }
97      
98      String getDEName(int index) {
99      	return dcExecutor.getDEName(index);
100     }
101     
102     public Logger getLog() {
103     	return log;
104     }
105 
106     /**
107      * Get plan of this engine (serialize the parsed plane and return it). DO 
108      * NOT MODIFY ANYTHING IN RETURNED PLAN!
109      * @return
110      */
111     public final PoshPlan getPlan() {
112         return plan;
113     }
114 
115     /**
116      * Convert posh tree into posh plan (textual representation) and return it.
117      * @return Textual representation of the posh tree.
118      */
119     public final String getPoshPlan() {
120         return plan.toString();
121     }
122     
123     /**
124      * Return serialized state of the engine. 
125      * @return
126      */
127     public String getState() {
128         StringBuilder sb = new StringBuilder();
129         for (DEExecutor de : dcExecutor.deExecutors) {
130             sb.append("/Root:");
131             sb.append(plan.getDriveCollection().getName());
132             sb.append("/Drive:");
133             sb.append(de.getName());
134             TriggerResult triggerResult = de.getTriggerResult();
135             if (triggerResult != null) {
136                 for (SenseResult senseResult : triggerResult) {
137                     sb.append('[');
138                     sb.append(senseResult.name);
139                     sb.append(':');
140                     sb.append(senseResult.wasSuccessful() ? '1' : '0');
141                     sb.append(']');
142                 }
143             }
144             sb.append(de.getStackTrace().toString());
145             sb.append('\n');
146         }
147         return sb.toString();
148     }
149 }