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
16
17
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
30
31
32
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
57
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
66
67
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
92
93
94
95
96
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
118 public TriggerResult getTriggerResult() {
119 return triggerResult;
120 }
121 }