1 package cz.cuni.amis.pogamut.shady;
2
3 import cz.cuni.amis.pogamut.sposh.engine.VariableContext;
4 import cz.cuni.amis.pogamut.sposh.exceptions.MissingRootException;
5 import cz.cuni.amis.pogamut.sposh.exceptions.NoEligibleElementException;
6 import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
7 import java.math.BigDecimal;
8 import java.util.Collections;
9 import java.util.List;
10 import java.util.SortedMap;
11 import java.util.TreeMap;
12
13
14
15
16
17
18
19
20
21
22
23
24 public class ShadeEngine<EXECUTOR extends IWorkExecutor> {
25
26 private final ShadeTree plan;
27 private final EXECUTOR executor;
28
29
30
31
32
33
34 public ShadeEngine(ShadeTree plan, EXECUTOR executor) {
35 this.plan = plan;
36 this.executor = executor;
37 }
38
39
40
41
42
43 public void evaluate() throws MissingRootException, NoEligibleElementException {
44 ShadeNode node = plan.getRoot();
45
46 NodeCall call = selectCall(node);
47
48
49 }
50
51
52
53
54
55
56
57
58
59 protected NodeCall selectCall(ShadeNode node) throws NoEligibleElementException {
60
61 NodeElement elem = getSelectedElement(node);
62 NodeCall call = elem.getCall();
63 ShadeNode childNode = plan.findNode(call.getName());
64
65 if (childNode != null) {
66 return selectCall(childNode);
67 }
68 return call;
69 }
70
71
72
73
74
75
76
77 protected NodeElement getSelectedElement(ShadeNode node) throws NoEligibleElementException {
78
79 SortedMap<BigDecimal, NodeElement> elements =
80 new TreeMap<BigDecimal, NodeElement>(Collections.reverseOrder());
81 for (NodeElement elem : node.getElements()) {
82 BigDecimal elementPriority = elem.getPriority().execute(executor);
83 elements.put(elementPriority, elem);
84 }
85
86
87
88 for (NodeElement elem : elements.values()) {
89 BigDecimal triggerResult = elem.getTrigger().execute(executor);
90
91
92 if (!BigDecimal.ZERO.equals(triggerResult)) {
93 return elem;
94 }
95 }
96 throw new NoEligibleElementException("Node \"" + node.getName() + "\" doesn't have even one elegible element.");
97 }
98
99 protected BigDecimal executeCall(NodeCall call) {
100 VariableContext ctx = new VariableContext();
101 List<IArgument> args = call.getArgs();
102
103 for (int argIdx = 0; argIdx < args.size(); ++argIdx) {
104 ctx.put(Integer.toString(argIdx), args.get(argIdx).getValue());
105 }
106 Object result;
107
108
109
110 try {
111 result = executor.executeSense(call.getName(), ctx);
112 } catch (Exception e) {
113 result = executor.executeAction(call.getName(), ctx);
114 }
115
116 return (BigDecimal) result;
117 }
118 }
119
120
121
122
123
124
125 class CallContext {
126
127
128
129
130 private final String name;
131
132
133
134
135 private final List<IArgument> ctx;
136
137
138
139
140
141
142
143
144
145 public CallContext(NodeCall call, List<IArgument> ctx) {
146 this.name = call.getName();
147 this.ctx = ctx;
148 }
149 }