1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package zeus.actors.rtn;
27
28 import java.util.*;
29 import zeus.util.*;
30 import zeus.actors.AgentContext;
31
32 public class Node {
33 public static final int NOT_READY = 0;
34 public static final int READY = 1;
35 public static final int WAITING = 2;
36 public static final int RUNNING = 3;
37 public static final int DONE = 4;
38 public static final int FAILED = 5;
39
40 protected static final int OK = 1;
41 protected static final int FAIL = 2;
42 protected static final int WAIT = 3;
43 protected static final int OK_WAIT = 4;
44
45 private static int count = 0;
46
47 protected String[] arcs = null;
48 protected String[] nodes = null;
49 protected Object input = null;
50 protected Object output = null;
51 protected Node previous_node = null;
52 protected Node[] parents = null;
53 protected Graph graph = null;
54 protected String description = null;
55 protected int state = NOT_READY;
56 protected int current_arc = -1;
57 protected double timeout = 0;
58 protected String msg_wait_key = null;
59 protected AgentContext context = null;
60 protected Vector parents_of_next_node =null;
61
62
63 public String getDesc() {return null;};
64
65 public void finaliser () {
66 finals();
67 }
68
69 public void finals () {
70 if (arcs!=null)
71 for (int count = 0; count< arcs.length; count++) {
72 arcs[count] = null;
73 }
74 arcs = null;
75 if (nodes != null)
76 for (int count = 0; count<nodes.length; count++) {
77 nodes [count] = null;
78 }
79 nodes = null;
80 input = null;
81 output = null;
82 previous_node = null;
83 if (parents!=null)
84 for (int count = 0; count<parents.length; count++){
85
86 parents[count] = null; }
87 parents = null;
88 }
89
90
91 public Node(String description) {
92 this.description = description + "-" + (count++);
93 Core.DEBUG(3,"New node " + this.description + " created");
94 }
95
96 public final String getDescription() { return description; }
97 public final double getTimeout() { return timeout; }
98 public final String getMsgWaitKey() { return msg_wait_key; }
99 public final Object getOutput() { return output; }
100 public final Node getPrevious() { return previous_node; }
101 public final Node[] getParents() { return parents; }
102 public final int getState() { return state; }
103 public final Graph getGraph() { return graph; }
104
105 final void set(Graph graph, String[] arcs, String[] nodes, Node previous) {
106 this.arcs = arcs;
107 this.nodes = nodes;
108 this.graph = graph;
109 this.previous_node = previous;
110
111 if ( previous != null ) {
112 this.parents = new Node[1];
113 this.parents[0] = previous;
114 }
115 }
116
117
118 final void set(Graph graph, String[] arcs, String[] nodes, Node previous,
119 Vector parents) {
120 this.arcs = arcs;
121 this.nodes = nodes;
122 this.graph = graph;
123 this.previous_node = previous;
124
125 this.parents = new Node[parents.size()];
126 for(int i = 0; i < parents.size(); i++ )
127 this.parents[i] = (Node)parents.elementAt(i);
128 }
129
130
131 final void run(Engine engine) {
132 context = engine.getAgentContext();
133
134 switch(state) {
135 case READY:
136 case WAITING:
137 if ( !graph.allow_exec() )
138 fail(engine,false,"Exec refused by graph");
139 else {
140 int result = (state == READY) ? exec() : continue_exec();
141 switch( result ){
142 case OK:
143 setState(engine,RUNNING);
144 engine.add(this);
145 break;
146 case WAIT:
147 engine.waitForMsg(this);
148 setState(engine,WAITING);
149 break;
150 default:
151 fail(engine,false,"Node exec failed");
152 break;
153 }
154 }
155 break;
156 case RUNNING:
157 if ( !graph.allow_exec() )
158 fail(engine,true,"Exec refused by graph");
159 else if ( arcs == null )
160 done(engine,"terminal node reached");
161 else if ( current_arc >= arcs.length )
162 fail(engine,true,"All arcs traversed");
163 else
164 exec_arc(engine);
165 break;
166 default:
167 Core.ERROR(null,2,this);
168 break;
169 }
170 engine = null;
171 context = null;
172 }
173
174
175 private void done(Engine engine, String reason) {
176 Core.DEBUG(3,description + " done: " + reason);
177 setState(engine,DONE);
178 graph.done(engine,this);
179 }
180
181
182 final void fail(Engine engine, boolean reset, String reason) {
183 Thread.yield();
184 Core.DEBUG(3,description + " failed: " + reason);
185 setState(engine,FAILED);
186 Thread.yield();
187 if ( reset ) reset();
188 graph.failed(engine,this);
189 Thread.yield();
190 if ( previous_node != null && graph.allow_backtrack(this) )
191 previous_node.nextArc(engine);
192
193 }
194
195
196 protected int exec() {
197
198 output = input;
199 return OK;
200 }
201 protected int continue_exec() {
202
203 output = input;
204 return OK;
205 }
206 protected void reset() {
207
208 }
209 final void setInput(Engine engine, Object input) {
210 Core.ERROR(state == NOT_READY, 1, this);
211 this.input = input;
212 current_arc = 0;
213 setState(engine,READY);
214 }
215 protected final void exec_arc(Engine engine) {
216 try {
217 Class c = Class.forName(arcs[current_arc]);
218 Arc arc = (Arc) c.newInstance();
219 engine.notifyArcMonitors(arc,this,Engine.ARC_CREATE);
220 arc.run1(engine,graph,this,output,nodes[current_arc]);
221 }
222 catch(Exception e) {
223 Core.USER_ERROR("Arc " + arcs[current_arc] + " cannot be executed" +
224 "\nException " + e);
225 nextArc(engine);
226 }
227 }
228 final void nextArc(Engine engine) {
229 switch(state) {
230
231
232 case DONE:
233 case RUNNING:
234 if ( !graph.allow_exec() )
235 fail(engine,true,"Next arc disallowed by graph");
236 else {
237 if ( state == DONE && arcs == null )
238 fail(engine,true,"All arcs traversed");
239 else {
240 setState(engine,RUNNING);
241 current_arc++;
242 engine.add(this);
243 }
244 }
245 break;
246 default:
247 Core.ERROR(null,3,this);
248 break;
249 }
250 }
251
252
253 final void setState(Engine engine, int value) {
254 state = value;
255 engine.notifyNodeMonitors(this,Engine.NODE_STATE_CHANGE);
256 }
257
258 protected void finalize() throws Throwable {
259 if ( context != null )
260 context.Engine().notifyNodeMonitors(this,Engine.NODE_DISPOSE);
261 arcs = null;
262 nodes = null;
263 input = null;
264 output = null;
265 previous_node = null;
266 parents = null;
267 graph = null;
268 description = null;
269 msg_wait_key = null;
270 parents_of_next_node =null;
271
272 }
273
274 protected Graph createGraph(String name) {
275 try {
276 Class c = Class.forName(name);
277 Graph g = (Graph)c.newInstance();
278 if ( parents_of_next_node == null )
279 parents_of_next_node = new Vector();
280 parents_of_next_node.addElement(g);
281 context.Engine().notifyGraphMonitors(g,Engine.GRAPH_CREATE);
282 return g;
283 }
284 catch(Exception e) {
285 Core.USER_ERROR("Cannot create graph: " + name + "\n" + e);
286 return null;
287 }
288 }
289
290 Vector getParentsOfNextNode() {
291 if ( parents_of_next_node == null || parents_of_next_node.isEmpty() )
292 return null;
293
294 Vector out = new Vector();
295 Graph g;
296 for(int i = 0; i < parents_of_next_node.size(); i++ ) {
297 g = (Graph)parents_of_next_node.elementAt(i);
298 out = Misc.union(out,g.getTerminalNodes());
299 }
300 return out.isEmpty() ? null : out;
301 }
302
303 protected Object createObject(String name) {
304 try {
305 Class c = Class.forName(name);
306 Object g = c.newInstance();
307 return g;
308 }
309 catch(Exception e) {
310 Core.USER_ERROR("Cannot create object: " + name + "\n" + e);
311 return null;
312 }
313 }
314 final boolean hasChildGraph(Graph g) {
315 Core.DEBUG(3,"hasChildGraph: " + g.getDescription() + " " + getDescription());
316 boolean b = parents_of_next_node != null && parents_of_next_node.contains(g);
317 Core.DEBUG(3,"\thasChildGraph = " + b);
318 return b;
319 }
320
321
322 public String toString() { return description; }
323
324
325 /***
326 overwrite this method in a Node to get behaviour from
327 a time out setting
328 */
329 public boolean timeOut () {
330 return false;
331 }
332 }