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 class PGraph extends Graph {
30 protected Vector done_nodes = new Vector();
31 protected Vector failed_nodes = new Vector();
32 protected Node[] start_nodes = null;
33 protected boolean first = true;
34 protected int min_done = -1;
35 protected int max_fail = 0;
36
37 public PGraph(String description, String[][] nodes, String start_node) {
38 super(description,nodes,start_node);
39 }
40 public PGraph(String description, String[][] nodes, String start_node,
41 int min_done) {
42 super(description,nodes,start_node);
43 this.min_done = min_done;
44 }
45 protected void start(Engine engine, Object input) {
46 state = RUNNING;
47 Object[] local_input = (Object[]) input;
48 start_nodes = new Node[local_input.length];
49 if ( min_done != -1 )
50 max_fail = local_input.length - min_done;
51
52 for(int i = 0; i < local_input.length; i++ ) {
53 start_nodes[i] = newNode(engine,start_node,previous_node);
54 if ( start_nodes[i] == null ) {
55 fail(engine,"Start node not found");
56 return;
57 }
58 }
59 for(int i = 0; i < local_input.length; i++ ) {
60 start_nodes[i].setInput(engine,local_input[i]);
61 engine.add(start_nodes[i]);
62 }
63 }
64 void done(Engine engine, Node node) {
65 done_nodes.addElement(node);
66 Core.DEBUG(3,description + " no: " + done_nodes.size() + " done");
67 if ( done_nodes.size() + failed_nodes.size() == start_nodes.length )
68 doSucceed(engine);
69 }
70
71 protected void doSucceed(Engine engine) {
72 setState(engine,DONE);
73 if ( graph != null ) {
74 Node next = graph.newNode(engine,next_node,previous_node,getTerminalNodes());
75 if ( next == null ) {
76 fail(engine,"next_node - " + next_node + " - not found");
77 return;
78 }
79 Object[] local_input = new Object[done_nodes.size()];
80 for(int i = 0; i < done_nodes.size(); i++ )
81 local_input[i] = ((Node)done_nodes.elementAt(i)).getOutput();
82 next.setInput(engine,local_input);
83 engine.add(next);
84 }
85 else if ( node_wakeup_key != null )
86 engine.wakeup(node_wakeup_key);
87 }
88
89 void failed(Engine engine, Node node) {
90 if ( state != FAILED ) {
91 for(int i = 0; i < start_nodes.length; i++ ) {
92 if ( start_nodes[i] == node ) {
93 failed_nodes.addElement(node);
94 if ( failed_nodes.size() > max_fail )
95 setState(engine,FAILED);
96 break;
97 }
98 }
99 if ( state == FAILED ) {
100 for(int i = 0; i < done_nodes.size(); i++ )
101 ((Node)done_nodes.elementAt(i)).fail(engine,true,"Parallel branch failed");
102 }
103 }
104 else {
105 for(int i = 0; i < start_nodes.length; i++ ) {
106 if ( start_nodes[i] == node ) {
107 failed_nodes.addElement(node);
108 break;
109 }
110 }
111 }
112 if ( first && failed_nodes.size() == start_nodes.length ) {
113 first = false;
114 fail(engine,"Parallel graph failed");
115 }
116 else if ( failed_nodes.size() + done_nodes.size() == start_nodes.length )
117 doSucceed(engine);
118 }
119 Node newNode(Engine engine, String name, Node previous) {
120 if ( state == FAILED ) return null;
121 else return super.newNode(engine,name,previous);
122 }
123
124 Vector getTerminalNodes() {
125 Vector out = new Vector();
126 Node node;
127 Vector local;
128
129 Core.DEBUG(3,"PGraph: getTerminalNodes for: " + description);
130 for(int i = 0; i < done_nodes.size(); i++ ) {
131 node = (Node)done_nodes.elementAt(i);
132 Core.DEBUG(3,"\tConsidering done_node: " + node);
133 if ( (local = node.getParentsOfNextNode()) != null )
134 out = Misc.union(out,local);
135 else
136 out.addElement(node);
137 Core.DEBUG(3,"\tCurrent terminals: " + out);
138 }
139 for(int i = 0; i < failed_nodes.size(); i++ ) {
140 node = (Node)failed_nodes.elementAt(i);
141 Core.DEBUG(3,"\tConsidering failed_node: " + node);
142 if ( (local = node.getParentsOfNextNode()) != null )
143 out = Misc.union(out,local);
144 else
145 out.addElement(node);
146 Core.DEBUG(3,"\tCurrent terminals: " + out);
147 }
148 Core.DEBUG(3,"\tFinal terminals: " + out);
149 return out;
150 }
151 boolean allow_backtrack(Node node) {
152 for(int i = 0; i < start_nodes.length; i++ )
153 if ( start_nodes[i] == node )
154 return false;
155 return true;
156 }
157 }