1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package zeus.actors.rtn;
25
26 import java.util.*;
27 import zeus.util.*;
28
29 public abstract class Graph extends Arc {
30 public static final int READY = 0;
31 public static final int RUNNING = 1;
32 public static final int DONE = 2;
33 public static final int FAILED = 3;
34
35 private static int count = 0;
36
37 protected String[][] nodes = null;
38 protected String start_node = null;
39 protected String next_node = null;
40 protected Node previous_node = null;
41 protected Node begin_node = null;
42 protected int state = READY;
43 protected String node_wakeup_key = null;
44 private Node last_node = null;
45
46 public Graph(String description, String[][] nodes, String start_node) {
47 this.start_node = start_node;
48 this.nodes = nodes;
49 this.description = description + "-" + (count++);
50 Core.DEBUG(3,"New graph " + this.description + " created");
51 }
52
53 public final int getState() { return state; }
54
55 void run1(Engine engine, Graph graph, Node previous_node,
56 Object input, String next_node) {
57
58 context = engine.getAgentContext();
59 this.graph = graph;
60 this.previous_node = previous_node;
61 this.next_node = next_node;
62 start(engine,input);
63 }
64 public void run(Engine engine, Object input) {
65 start(engine,input);
66 }
67 public void run(Engine engine, Node previous_node, Object input,
68 String node_wakeup_key) {
69 this.node_wakeup_key = node_wakeup_key;
70 this.previous_node = previous_node;
71 start(engine,input);
72 }
73 protected void start(Engine engine, Object input) {
74 setState(engine,RUNNING);
75 begin_node = newNode(engine,start_node,previous_node);
76 if ( begin_node == null )
77 fail(engine,"Start node " + start_node + " not found");
78 else {
79 begin_node.setInput(engine,input);
80 engine.add(begin_node);
81 }
82 }
83 void done(Engine engine, Node node) {
84 Core.DEBUG(3,description + " done");
85 setState(engine,DONE);
86
87 if ( graph != null ) {
88 Node next = graph.newNode(engine,next_node,node);
89 if ( next == null ) {
90 setState(engine,RUNNING);
91 node.nextArc(engine);
92 }
93 else {
94 Object local_input = node.getOutput();
95 next.setInput(engine,local_input);
96 engine.add(next);
97 }
98 }
99 else if ( node_wakeup_key != null )
100 engine.wakeup(node_wakeup_key);
101 }
102 void failed(Engine engine, Node node) {
103 if ( node == begin_node ) {
104 setState(engine,FAILED);
105 if ( node_wakeup_key != null )
106 engine.wakeup(node_wakeup_key);
107 }
108 }
109 protected void fail(Engine engine, String reason) {
110 Core.DEBUG(3,description + " failed: " + reason);
111 setState(engine,FAILED);
112 if ( node_wakeup_key != null )
113 engine.wakeup(node_wakeup_key);
114 if ( previous_node != null )
115 previous_node.nextArc(engine);
116 }
117
118 Vector getTerminalNodes() {
119 Vector output;
120 if ( last_node != null ) {
121 if ( (output = last_node.getParentsOfNextNode()) != null )
122 return output;
123 else {
124 output = new Vector();
125 output.addElement(last_node);
126 return output;
127 }
128 }
129 else
130 return new Vector();
131 }
132
133 Node newNode(Engine engine, String name, Node previous) {
134 Vector parents;
135 if ( previous != null ) {
136 Core.DEBUG(3,"NewNode preamble\n\tname = " + name +
137 "\n\tprevious = " + previous +
138 "\n\thasChild = " + previous.hasChildGraph(this) +
139 "\n\tparents = " + previous.getParentsOfNextNode());
140 }
141 if ( previous != null && !previous.hasChildGraph(this) &&
142 (parents = previous.getParentsOfNextNode()) != null )
143 return newNode(engine,name,previous,parents);
144 else
145 return newNode(engine,name,previous,null);
146 }
147
148 Node newNode(Engine engine, String name, Node previous, Vector parents) {
149 Core.DEBUG(3,"NewNode:\n\tname = " + name + "\n\tprev = " + previous +
150 "\n\tparents = " + parents);
151 try {
152 boolean found = false;
153 String[] arcs = null, vertices = null;
154 for(int i = 0; i < nodes.length; i++ ) {
155 if ( nodes[i][0].equals(name) ) {
156 found = true;
157 if ( nodes[i].length%2 != 1 )
158 Core.USER_ERROR("Improperly specified graph description " +
159 description + "at node " + nodes[i][0]);
160 int k = 0;
161 for(int j = 1; j < nodes[i].length; k++ ) {
162 if ( j == 1 ) {
163 arcs = new String[(nodes[i].length-1)/2];
164 vertices = new String[(nodes[i].length-1)/2];
165 }
166 arcs[k] = nodes[i][j++];
167 vertices[k] = nodes[i][j++];
168 }
169 break;
170 }
171 }
172 if ( !found ) {
173 Core.USER_ERROR("Improperly specified graph description " +
174 description + ": No definintion for node " + name);
175 return null;
176 }
177 Class c = Class.forName(name);
178 last_node = (Node)c.newInstance();
179
180 if ( parents != null )
181 last_node.set(this,arcs,vertices,previous,parents);
182 else
183 last_node.set(this,arcs,vertices,previous);
184 engine.notifyNodeMonitors(last_node,Engine.NODE_CREATE);
185 return last_node;
186 }
187 catch(Exception e) {
188 Core.USER_ERROR("Error in graph specification " + description +
189 "\nException: " + e);
190 return null;
191 }
192 }
193 boolean allow_exec() {
194 return state != FAILED;
195 }
196 boolean allow_backtrack(Node node) {
197 return ( node != begin_node || node_wakeup_key == null );
198 }
199 protected boolean exec() {
200 Core.ERROR(null,1,this);
201 return false;
202 }
203 final void setState(Engine engine,int value) {
204 state = value;
205 engine.notifyGraphMonitors(this,Engine.GRAPH_STATE_CHANGE);
206 }
207 protected void finalize() {
208 if ( context != null )
209 context.Engine().notifyGraphMonitors(this,Engine.GRAPH_DISPOSE);
210 }
211 }