FreeWRL / FreeX3D 4.3.0
Browser.java
1// Specification of the External Interface for a VRML applet browser.
2// FreeWRL Viewer Interface - bypass netscape and go directly
3// to the viewer.
4
5package vrml.external;
6
7import java.util.*;
8import java.applet.*;
9//JAS import java.awt.*;
10import java.net.*;
11import java.io.*;
12//JAS import java.lang.reflect.*;
13import vrml.external.Node;
14//JAS import vrml.external.field.EventOut;
15import vrml.external.field.EventOutObserver;
16import vrml.external.field.EventIn;
17import vrml.external.field.EventInMFNode;
18import vrml.external.FreeWRLEAI.EAIoutThread;
19import vrml.external.FreeWRLEAI.EAIinThread;
20import vrml.external.FreeWRLEAI.EAIAsyncThread;
21import vrml.external.exception.InvalidNodeException;
22import vrml.external.exception.InvalidVrmlException;
23import vrml.external.BrowserGlobals;
24import java.lang.System;
25//JAS - no longer using Netscape import netscape.security.*;
26
27public class Browser implements BrowserInterface, IBrowser
28
29{
30
31 //====================================================================
32 // Threads:
33
34 // Replies from FreeWRL.
35 static Thread FreeWRLThread; // of type EAIinThread
36
37 // Send commands to FreeWRL.
38 static EAIoutThread EAIoutSender;
39
40 // Handle Async communications from FreeWRL (eg, Regisered Listeners)
41 static EAIAsyncThread RL_Async;
42
43
44 //====================================================================
45 // Communication Paths:
46
47 // FreeWRLThread to Browser - responses from commands to FreeWRL.
48 PrintWriter EAIinThreadtoBrowser;
49 PipedWriter EAIinThreadtoBrowserPipe = null;
50
51 //
52 static BufferedReader BrowserfromEAI = null;
53 PipedReader BrowserfromEAIPipe = null;
54
55
56
57
58 // The following are used to send to/from the FreeWRL Browser by:
59 // - EAIinThread
60
61 Socket EAISocket;
62 Socket sock;
63 static PrintWriter EAIout;
64
65
66 // The following pipe listens for replies to events sent to
67 // the FreeWRL VRML viewer via the EAI port.
68
69
70 private String reply = "";
71
72
73 // Query Number as sent to the FreeWRL Browser.
74 static int queryno = 1;
75
76
77 // for setDescription/ getDescription
78 private String descript = "";
79
80 // Sending to FreeWRL needs to synchronize on an object;
81 static Object FreeWRLToken = new Object();
82
83
84 // Interface methods.
85 public int get_Browser_EVtype (int event)
86 {
87 //System.out.println ("get_Browser_EVtype is returning " +
88 // BrowserGlobals.EVtype[event] +
89 // " for event " + event);
90 return BrowserGlobals.EVtype[event];
91 }
92
93 public EventOutObserver get_Browser_EVObserver (int eventno)
94 {
95 // System.out.println ("get_Browser_EVObserver is returning " +
96 // BrowserGlobals.EVObserver[eventno]);
97 return BrowserGlobals.EVObserver[eventno];
98 }
99
100 public void Browser_RL_Async_send (String EVentreply, int eventno)
101 {
102 int EVcounter;
103 for (EVcounter=0; EVcounter<BrowserGlobals.EVno; EVcounter++) {
104 if (BrowserGlobals.EVarray[EVcounter] == eventno) {
105 break;
106 }
107 }
108 //System.out.println ("Browser_RL_Async_send sending " + EVentreply + " to number " + EVcounter);
109 RL_Async.send(EVentreply, EVcounter);
110 }
111
112 // Associates this instance with the first embedded plugin in the current frame.
113 public Browser(Applet pApplet, int portnum) {
114 int counter;
115
116 // Create a socket here for an EAI server on localhost
117 int incrport = -1;
118 EAISocket = null;
119
120 counter = 1;
121 while (EAISocket == null) {
122 try {
123 EAISocket = new Socket("localhost",portnum);
124 } catch (IOException e) {
125 // wait up to 30 seconds for FreeWRL to answer.
126 counter = counter + 1;
127 if (counter == 60) {
128 System.out.println ("EAI: Java code timed out finding FreeWRL");
129 System.exit(1);
130 }
131 try {Thread.sleep (500);} catch (InterruptedException f) { }
132 }
133 }
134
135 sock = EAISocket; //JAS - these are the same now...
136
137
138
139 //===================================================================
140 // create the EAIinThread to Browser.
141
142 // Open the pipe for EAI replies to be sent to us...
143 try {
144 EAIinThreadtoBrowserPipe = new PipedWriter();
145 BrowserfromEAIPipe = new PipedReader(EAIinThreadtoBrowserPipe);
146 } catch (IOException ie) {
147 System.out.println ("EAI: caught error in new PipedReader: " + ie);
148 }
149
150 EAIinThreadtoBrowser = new PrintWriter(EAIinThreadtoBrowserPipe);
151 BrowserfromEAI = new BufferedReader (BrowserfromEAIPipe);
152
153 // Start the readfrom FREEWRL thread...
154
155
156 //===================================================================
157 // create the EAIinThread to Browser.
158
159 // Open the pipe for EAI replies to be sent to us...
160 try {
161 EAIinThreadtoBrowserPipe = new PipedWriter();
162 BrowserfromEAIPipe = new PipedReader(EAIinThreadtoBrowserPipe);
163 } catch (IOException ie) {
164 System.out.println ("EAI: caught error in new PipedReader: " + ie);
165 }
166
167 EAIinThreadtoBrowser = new PrintWriter(EAIinThreadtoBrowserPipe);
168 BrowserfromEAI = new BufferedReader (BrowserfromEAIPipe);
169
170 // Start the readfrom FREEWRL thread...
171 FreeWRLThread = new Thread ( new EAIinThread(sock, pApplet,
172 EAIinThreadtoBrowser, this));
173 FreeWRLThread.start();
174
175
176 //====================================================================
177 // Start the thread that allows Registered Listenered
178 // updates to come in.
179 RL_Async = new EAIAsyncThread();
180 RL_Async.start();
181
182
183 //====================================================================
184 // create the EAIoutThread - send data to FreeWRL.
185 try {
186 EAIout = new PrintWriter (sock.getOutputStream());
187 } catch (IOException e) {
188 System.out.print ("EAI: Problem in handshaking with Browser");
189 }
190
191
192 // Start the SendTo FREEWRL thread...
193 EAIoutSender = new EAIoutThread(EAIout);
194 EAIoutSender.start();
195
196
197
198 //====================================================================
199 // Browser is "gotten", and is started.
200 return;
201 }
202
203 // Associates this instance with the first embedded plugin in the current frame.
204 public Browser(Applet pApplet) {
205 int counter;
206
207 // Create a socket here for an EAI server on localhost
208 int incrport = -1;
209 EAISocket = null;
210
211 counter = 1;
212 while (EAISocket == null) {
213 try {
214 EAISocket = new Socket("localhost",9877);
215 } catch (IOException e) {
216 // wait up to 30 seconds for FreeWRL to answer.
217 counter = counter + 1;
218 if (counter == 60) {
219 System.out.println ("EAI: Java code timed out finding FreeWRL");
220 System.exit(1);
221 }
222 try {Thread.sleep (500);} catch (InterruptedException f) { }
223 }
224 }
225
226 sock = EAISocket; //JAS - these are the same now...
227
228
229
230 //===================================================================
231 // create the EAIinThread to Browser.
232
233 // Open the pipe for EAI replies to be sent to us...
234 try {
235 EAIinThreadtoBrowserPipe = new PipedWriter();
236 BrowserfromEAIPipe = new PipedReader(EAIinThreadtoBrowserPipe);
237 } catch (IOException ie) {
238 System.out.println ("EAI: caught error in new PipedReader: " + ie);
239 }
240
241 EAIinThreadtoBrowser = new PrintWriter(EAIinThreadtoBrowserPipe);
242 BrowserfromEAI = new BufferedReader (BrowserfromEAIPipe);
243
244 // Start the readfrom FREEWRL thread...
245 FreeWRLThread = new Thread ( new EAIinThread(sock, pApplet,
246 EAIinThreadtoBrowser, this));
247 FreeWRLThread.start();
248
249
250 //====================================================================
251 // Start the thread that allows Registered Listenered
252 // updates to come in.
253 RL_Async = new EAIAsyncThread();
254 RL_Async.start();
255
256
257 //====================================================================
258 // create the EAIoutThread - send data to FreeWRL.
259 try {
260 EAIout = new PrintWriter (sock.getOutputStream());
261 } catch (IOException e) {
262 System.out.print ("EAI: Problem in handshaking with Browser");
263 }
264
265
266 // Start the SendTo FREEWRL thread...
267 EAIoutSender = new EAIoutThread(EAIout);
268 EAIoutSender.start();
269
270
271
272 //====================================================================
273 // Browser is "gotten", and is started.
274 return;
275 }
276
277 // construct an instance of the Browser class
278 // If frameName is NULL, current frame is assumed.
279 public Browser(Applet pApplet, String frameName, int index) {
280 System.out.println ("Browser2 Not Implemented");
281
282 }
283
284 // Get the browser name
285 public String getName() {
286 String retval;
287 synchronized (FreeWRLToken) {
288 EAIoutSender.send ("" + queryno + "K\n");
289 retval = getVRMLreply(queryno);
290 queryno += 1;
291 }
292 return retval;
293 }
294
295 public String getVersion() {
296 String retval;
297 synchronized (FreeWRLToken) {
298 EAIoutSender.send ("" + queryno + "L\n");
299 retval = getVRMLreply(queryno);
300 queryno += 1;
301 }
302 return retval;
303 }
304
305 // Get the current file type; check the specs for correct numbers.
306 public int getEncoding() {
307 String retval;
308 synchronized (FreeWRLToken) {
309 EAIoutSender.send ("" + queryno + "Y\n");
310 retval = getVRMLreply(queryno);
311 queryno += 1;
312 }
313 return Integer.valueOf(retval).intValue();
314 }
315 // Get the current velocity of the bound viewpoint in meters/sec,
316 public float getCurrentSpeed() {
317 String retval;
318 synchronized (FreeWRLToken) {
319 EAIoutSender.send ("" + queryno + "M\n");
320 retval = getVRMLreply(queryno);
321 queryno += 1;
322 }
323 return Float.valueOf(retval).floatValue();
324 }
325
326 // Get the current frame rate of the browser, or 0.0 if not available
327 public float getCurrentFrameRate() {
328 String retval;
329 synchronized (FreeWRLToken) {
330 EAIoutSender.send ("" + queryno + "N\n");
331 retval = getVRMLreply(queryno);
332 queryno += 1;
333 }
334 return Float.valueOf(retval).floatValue();
335 }
336
337 // Get the URL for the root of the current world, or an empty string
338 // if not available
339 public String getWorldURL() {
340 String retval;
341 synchronized (FreeWRLToken) {
342 EAIoutSender.send ("" + queryno + "O\n");
343 retval = getVRMLreply(queryno);
344 queryno += 1;
345 }
346 return retval;
347 }
348
349 // Get rendering properties.
350 public String getRenderingProperties() {
351 String retval;
352 synchronized (FreeWRLToken) {
353 EAIoutSender.send ("" + queryno + "X\n");
354 retval = getVRMLreply(queryno);
355 queryno += 1;
356 }
357 return retval;
358 }
359
360 // Replace the current world with the passed array of nodes
361 public void replaceWorld(Node[] nodes)
362 throws IllegalArgumentException {
363
364 String SysString = "";
365 String retval;
366 int count;
367
368 for (count=0; count<nodes.length; count++) {
369 SysString = SysString + " " + nodes[count].nodeptr;
370 }
371
372 synchronized (FreeWRLToken) {
373 EAIoutSender.send ("" + queryno + "P" + SysString);
374 retval = getVRMLreply(queryno);
375 queryno += 1;
376 }
377
378 }
379
380
381 // Load the given URL with the passed parameters (as described
382 // in the Anchor node)
383 public void loadURL(String[] url, String[] parameter) {
384 String SysString = "";
385 String retval;
386 int count;
387
388 // send along sizes of the Strings
389 SysString = "" + url.length + " " + parameter.length;
390
391 for (count=0; count<url.length; count++) {
392 SysString = SysString + " :loadURLStringBreak:" + url[count];
393 }
394
395 for (count=0; count<parameter.length; count++) {
396 SysString = SysString + " :loadURLStringBreak:" + parameter[count];
397 }
398
399 synchronized (FreeWRLToken) {
400 EAIoutSender.send ("" + queryno + "Q" + SysString);
401 retval = getVRMLreply(queryno);
402 queryno += 1;
403 }
404 }
405
406 // Viewpoint code. Command "R" to FreeWRL, with "FIRST" "NEXT" "PREV" "LAST" in it
407 static void do_vp(String vp) {
408 String retval;
409
410 synchronized (FreeWRLToken) {
411 EAIoutSender.send ("" + queryno + "R " + vp);
412 retval = getVRMLreply(queryno);
413 queryno += 1;
414 }
415 return;
416 }
417
418 public void firstViewpoint() {do_vp("FIRST");}
419 public void lastViewpoint() {do_vp("LAST");}
420 public void nextViewpoint() {do_vp("NEXT");}
421 public void previousViewpoint() {do_vp("PREV");}
422
423
424
425 // Set the description of the current world in a browser-specific
426 // manner. To clear the description, pass an empty string as argument
427 // note that FreeWRL does not display descriptions anywhere, so this
428 // command has no freewrl EAI connectivity.
429 public void setDescription(String description) {
430 descript = description;
431 return;
432 }
433
434 public String getDescription() {
435 return descript;
436 }
437
438
439 // Parse STRING into a X3D scene and return the list of root
440 // nodes for the resulting scene
441 public Node[] createX3DFromString(String vrmlSyntax)
442 throws InvalidVrmlException {
443
444 Node[] x = new Node[100];
445 StringTokenizer tokens;
446 String retval;
447 String temp;
448 int count;
449
450 synchronized (FreeWRLToken) {
451 EAIoutSender.send ("" +queryno + "o \n"+vrmlSyntax+"\nEOT\n");
452 retval = getVRMLreply(queryno);
453
454 //System.out.println ("Browser.java - got " + retval);
455
456 tokens = new StringTokenizer (retval);
457
458 // We return a (node-index C-pointer) pair, so we have to divide by two
459 x = new Node[tokens.countTokens()];
460 count = 0;
461
462 // Lets go through the output, and temporarily store it
463 // XXX - is there a better way? ie, using a vector?
464 while (tokens.hasMoreTokens()) {
465 x[count] = new Node();
466 x[count].nodeptr = Integer.parseInt(tokens.nextToken());
467 x[count].offset = 0;
468 x[count].datasize = 4;
469 x[count].datatype = "h"; // see CFuncs/EAIServ.c for a complete desc.
470
471 //System.out.println ("CVS - for this one, we have NODE" +
472 // " pointer:" + x[count].nodeptr + " offset:" + x[count].offset +
473 // " datasize: " + x[count].datasize + " datatype:" + x[count].datatype);
474
475 count ++;
476 if (count == 100) {
477 count = 99;
478 System.out.println ("EAI: createX3DFromString - warning, tied to 100 nodes");
479 }
480 }
481 queryno += 1;
482 }
483 return x;
484 }
485 // Parse STRING into a VRML scene and return the list of root
486 // nodes for the resulting scene
487 public Node[] createVrmlFromString(String vrmlSyntax)
488 throws InvalidVrmlException {
489
490 Node[] x = new Node[100];
491 StringTokenizer tokens;
492 String retval;
493 String temp;
494 int count;
495
496 synchronized (FreeWRLToken) {
497 EAIoutSender.send ("" +queryno + "S #VRML V2.0 utf8\n"+vrmlSyntax+"\nEOT\n");
498 retval = getVRMLreply(queryno);
499
500 //System.out.println ("Browser.java - got " + retval);
501
502 tokens = new StringTokenizer (retval);
503
504 // We return a (node-index C-pointer) pair, so we have to divide by two
505 x = new Node[tokens.countTokens()];
506 count = 0;
507
508 // Lets go through the output, and temporarily store it
509 // XXX - is there a better way? ie, using a vector?
510 while (tokens.hasMoreTokens()) {
511 x[count] = new Node();
512 x[count].nodeptr = Integer.parseInt(tokens.nextToken());
513 x[count].offset = 0;
514 x[count].datasize = 4;
515 x[count].datatype = "h"; // see CFuncs/EAIServ.c for a complete desc.
516
517 //System.out.println ("CVS - for this one, we have NODE" +
518 // " pointer:" + x[count].nodeptr + " offset:" + x[count].offset +
519 // " datasize: " + x[count].datasize + " datatype:" + x[count].datatype);
520
521 count ++;
522 if (count == 100) {
523 count = 99;
524 System.out.println ("EAI: createVrmlFromString - warning, tied to 100 nodes");
525 }
526 }
527 queryno += 1;
528 }
529 return x;
530 }
531
532
533 // for SAI coding
534 public String createNode (String name) {
535 String retval;
536
537 synchronized (FreeWRLToken) {
538 EAIoutSender.send ("" + queryno + "a" + name + "\n");
539 retval = getVRMLreply(queryno);
540 }
541 return retval;
542 }
543
544
545 // for SAI coding
546 public String createProto (String name) {
547 String retval;
548
549 synchronized (FreeWRLToken) {
550 EAIoutSender.send ("" + queryno + "b" + name + "\n");
551 retval = getVRMLreply(queryno);
552 }
553 return retval;
554 }
555
556 // for SAI coding
557 public String updateNamedNode (String name, Node node) {
558 String retval;
559
560 synchronized (FreeWRLToken) {
561 EAIoutSender.send ("" + queryno + "c" + name + " " + node.nodeptr + "\n");
562 retval = getVRMLreply(queryno);
563 }
564 return retval;
565 }
566
567 // for SAI coding
568 public String removeNamedNode (String name) {
569 String retval;
570
571 synchronized (FreeWRLToken) {
572 EAIoutSender.send ("" + queryno + "d" + name + "\n");
573 retval = getVRMLreply(queryno);
574 }
575 return retval;
576 }
577
578
579 // for SAI coding
580 public String getProtoDeclaration (String name) {
581 String retval;
582
583 synchronized (FreeWRLToken) {
584 EAIoutSender.send ("" + queryno + "e" + name + "\n");
585 retval = getVRMLreply(queryno);
586 }
587 return retval;
588 }
589
590 // for SAI coding
591 public String updateProtoDeclaration (String name, String newProtoDecl) {
592 String retval;
593
594 synchronized (FreeWRLToken) {
595 EAIoutSender.send ("" + queryno + "f" + name + " " + newProtoDecl + "\n");
596 retval = getVRMLreply(queryno);
597 }
598 return retval;
599 }
600
601 // for SAI coding
602 public String removeProtoDeclaration (String name) {
603 String retval;
604
605 synchronized (FreeWRLToken) {
606 EAIoutSender.send ("" + queryno + "g" + name + "\n");
607 retval = getVRMLreply(queryno);
608 }
609 return retval;
610 }
611
612 // for SAI coding
613 public String getNodeFieldDefs (Node myn) {
614 String retval;
615 synchronized (FreeWRLToken) {
616 EAIoutSender.send ("" + queryno + "h" + myn.nodeptr + "\n");
617 retval = getVRMLreply(queryno);
618 }
619 return retval;
620 }
621
622 // for SAI coding
623 public String getNodeDEFName (Node myn) {
624 String retval;
625
626 synchronized (FreeWRLToken) {
627 EAIoutSender.send ("" + queryno + "i" + myn.nodeptr + "\n");
628 retval = getVRMLreply(queryno);
629 }
630 return retval;
631 }
632
633 // for SAI coding
634 public String getRoutes () {
635 String retval;
636
637 synchronized (FreeWRLToken) {
638 EAIoutSender.send ("" + queryno + "j\n");
639 retval = getVRMLreply(queryno);
640 }
641 return retval;
642 }
643
644 // for SAI coding
645 public String getNodeType (Node myn) {
646 String retval;
647
648 synchronized (FreeWRLToken) {
649 EAIoutSender.send ("" + queryno + "k " + myn.nodeptr + "\n");
650 retval = getVRMLreply(queryno);
651 }
652 return retval;
653 }
654
655
656
657 // Tells the browser to load a VRML scene from the passed URL or
658 // URLs. After the scene is loaded, an event is sent to the MFNode
659 // eventIn in node NODE named by the EVENT argument
660 public void createVrmlFromURL(String[] url,
661 Node node,
662 String event) {
663
664 EventInMFNode Evin;
665 String retval;
666 Node[] x = new Node[1];
667 StringTokenizer tokens;
668 int count;
669
670
671 synchronized (FreeWRLToken) {
672 EAIoutSender.send ("" + queryno + "T " + url[0] + "\n");
673
674 retval = getVRMLreply(queryno);
675
676 tokens = new StringTokenizer (retval);
677 count = 0;
678 x = new Node[tokens.countTokens()];
679
680 while (tokens.hasMoreTokens()) {
681 x[count] = new Node();
682 x[count].nodeptr = Integer.parseInt(tokens.nextToken());
683 x[count].offset = 0;
684 x[count].datasize = 4;
685 x[count].datatype = "h"; // see CFuncs/EAIServ.c for a complete desc.
686 //System.out.println ("CVU - for this one, we have NODE" +
687 // " pointer:" + x[count].nodeptr + " offset:" + x[count].offset +
688 // " datasize: " + x[count].datasize + " datatype:" + x[count].datatype);
689
690 count ++;
691 }
692 queryno += 1;
693 }
694
695 // Now, sent the event to the event!
696 Evin = (EventInMFNode) node.getEventIn(event);
697 Evin.setValue(x);
698 }
699
700
701 // Add and delete, respectively, a route between the specified eventOut
702 // and eventIn of the given nodes
703 public void addRoute(Node fromNode, String fromEventOut,
704 Node toNode, String toEventIn) throws
705 IllegalArgumentException {
706 String retval;
707
708 synchronized (FreeWRLToken) {
709 EAIoutSender.send ("" + queryno + "H " + fromNode.nodeptr + " " + fromEventOut +
710 " " + toNode.nodeptr + " " + toEventIn +"\n");
711 retval = getVRMLreply(queryno);
712 queryno += 1;
713 }
714 return;
715 }
716
717
718 public void deleteRoute(Node fromNode, String fromEventOut,
719 Node toNode, String toEventIn)
720 throws IllegalArgumentException {
721 String retval;
722
723 synchronized (FreeWRLToken) {
724 EAIoutSender.send ("" + queryno + "J " + fromNode.nodeptr + " " + fromEventOut +
725 " " + toNode.nodeptr + " " + toEventIn +"\n");
726 retval = getVRMLreply(queryno);
727 queryno += 1;
728 }
729 return;
730 }
731
732 // begin and end an update cycle
733 public void beginUpdate() {}
734 public void endUpdate() {}
735
736 // called after the scene is loaded, before the first event is processed
737 public void initialize() {
738 System.out.println ("EAI: Initialize Not Implemented");
739
740 }
741
742
743 // called just before the scene is unloaded
744 public void shutdown() {
745 System.out.println ("EAI: Shutdown Not Implemented");
746
747 }
748
749 // return an instance of the Browser class
750 // This returns the first embedded plugin in the current frame.
751 static public Browser getBrowser(Applet pApplet) {
752 return (new Browser(pApplet));
753 }
754
755 static public Browser getBrowser(Applet pApplet, int portnum) {
756 return (new Browser(pApplet, portnum));
757 }
758
759 // return an instance of the Browser class
760 // If frameName is NULL, current frame is assumed.
761 static public Browser getBrowser(Applet pApplet, String frameName, int index) {
762 // We don't have frames and indexes yet...
763 Browser x = getBrowser(pApplet);
764 System.out.println ("EAI: getBrowser possibly Not Implemented");
765
766 return x;
767 }
768
769
770 // Get a DEFed node by name. Nodes given names in the root scene
771 // graph must be made available to this method. DEFed nodes in inlines,
772 // as well as DEFed nodes returned from createVrmlFromString/URL, may
773 // or may not be made available to this method, depending on the
774 // browser's implementation
775
776 public Node getNode (String getName) throws InvalidNodeException
777 {
778 Node temp;
779 StringTokenizer tokens;
780 String retval;
781
782 temp = new Node();
783
784 synchronized (FreeWRLToken) {
785 EAIoutSender.send ("" + queryno + "A " + getName + "\n");
786 retval = getVRMLreply(queryno);
787 }
788
789 tokens = new StringTokenizer (retval);
790
791 temp.nodeptr = Integer.parseInt(tokens.nextToken());
792 queryno += 1;
793
794 if (temp.nodeptr == 0)
795 throw new InvalidNodeException(getName + " undefined");
796
797 return temp;
798 }
799
800
801
802
803 //
804 // Send Event to the VRML Browser. Note the different methods, depending
805 // on the parameters.
806 //
807 public static void SendChildEvent (int parent, int offset, String FieldName, int Child) {
808 String retval;
809
810 // System.out.println ("SendChildEvent: sending to " + parent + " ofs:" +
811 // offset + " field " + FieldName + " child: " + Child);
812
813 synchronized (FreeWRLToken) {
814 EAIoutSender.send ("" + queryno + "C " + parent + " " + offset + " " +
815 FieldName + " "+ Child + "\n");
816 retval = getVRMLreply(queryno);
817 queryno += 1;
818 }
819 return;
820 }
821
822 // Most events don't need us to wait around for it.
823 public static void newSendEvent (EventIn node, String Value) {
824 synchronized (FreeWRLToken) {
825 EAIoutSender.send ("" + queryno + "D" + node.datatype + " " +
826 node.nodeptr + " " + node.offset + " " +node.ScriptType + " " + Value + "\n");
827 queryno += 1;
828 }
829 return;
830 }
831
832
833 protected static String SendNodeEAIType (int nodeptr) {
834
835 // get a type from a particular node.
836
837 String retval;
838
839 synchronized (FreeWRLToken) {
840 EAIoutSender.send ("" + queryno + "B " + nodeptr + "\n");
841 retval = getVRMLreply(queryno);
842 queryno += 1;
843 }
844 return retval;
845}
846 protected static String SendEventType (int nodeptr, String FieldName, String direction) {
847
848 // get a type from a particular node.
849
850 String retval;
851
852 synchronized (FreeWRLToken) {
853 EAIoutSender.send ("" + queryno + "F " + nodeptr + " " +
854 FieldName + " " + direction + "\n");
855 retval = getVRMLreply(queryno);
856 queryno += 1;
857 }
858 return retval;
859}
860
861 public static String SendEventOut (int nodeptr, int offset, int datasize, String datatype,
862 String command) {
863 // get a value from a particular node.
864
865 //System.out.println ("SendEventOut, nodeptr " + nodeptr + " datatype " + datatype);
866
867 String retval;
868 synchronized (FreeWRLToken) {
869 EAIoutSender.send ("" + queryno + "E " + nodeptr + " " + offset + " " + datatype +
870 " " + datasize + "\n");
871
872 retval = getVRMLreply(queryno);
873 queryno += 1;
874 }
875 //System.out.println ("SendEventOut returns " + retval);
876 return retval;
877}
878
879 public static void RegisterListener (EventOutObserver f, Object userData,
880 int nodeptr, int offset, String datatype, int datasize, int EventType)
881 {
882 synchronized (FreeWRLToken) {
883 //System.out.println ("Registering " + queryno + " node: " + nodeptr + " offset:"
884 // + offset + " datatype:" + datatype +
885 //" datasize:" + datasize + "\n");
886
887 EAIoutSender.send ("" + queryno + "G " + nodeptr + " " + offset + " " + datatype +
888 " " + datasize + "\n");
889
890 BrowserGlobals.EVarray [BrowserGlobals.EVno] = queryno;
891 BrowserGlobals.EVtype [BrowserGlobals.EVno] = EventType;
892 BrowserGlobals.EVObject[BrowserGlobals.EVno] = userData;
893 BrowserGlobals.EVObserver[BrowserGlobals.EVno] = f;
894
895 BrowserGlobals.EVno += 1;
896
897 getVRMLreply(queryno);
898 queryno += 1;
899 }
900 }
901
902 public static void unRegisterListener (EventOutObserver f,
903 int nodeptr, int offset, String datatype, int datasize, int EventType)
904 {
905 synchronized (FreeWRLToken) {
906 //System.out.println ("Registering " + queryno + " node: " + nodeptr + " offset:"
907 // + offset + " datatype:" + datatype +
908 //" datasize:" + datasize + "\n");
909
910 EAIoutSender.send ("" + queryno + "W " + nodeptr + " " + offset + " " + datatype +
911 " " + datasize + "\n");
912
913 //BrowserGlobals.EVarray [BrowserGlobals.EVno] = queryno;
914 //BrowserGlobals.EVtype [BrowserGlobals.EVno] = EventType;
915 //BrowserGlobals.EVObject[BrowserGlobals.EVno] = userData;
916 //BrowserGlobals.EVObserver[BrowserGlobals.EVno] = f;
917
918 //BrowserGlobals.EVno += 1;
919
920 getVRMLreply(queryno);
921 queryno += 1;
922 }
923 }
924
925 protected synchronized static String getVRMLreply (int queryno)
926 {
927
928 String req = "0";
929 String rep = "";
930
931
932 // This waits for the correct event toe be returned. Note that
933 // sendevents dont wait, so there is the possibility that
934 // we will have to while away a bit of time waiting...
935
936 while (queryno != Integer.parseInt(req)) {
937 try {
938 req = BrowserfromEAI.readLine();
939 } catch (IOException ie) {
940 System.out.println ("EAI: caught " + ie);
941 return rep;
942 }
943
944 if (queryno != Integer.parseInt(req)) {
945 System.out.println ("EAI: getVRMLreply - REPLIES MIXED UP!!! Expecting "
946 + queryno +
947 " got " + req);
948 }
949
950 try {
951 rep = BrowserfromEAI.readLine();
952 } catch (IOException ie) { System.out.println ("EAI: getVRMLreply failed"); return null; }
953
954
955 }
956
957 return rep;
958 }
959 public void close() {
960 System.out.println("EAI: closing socket");
961 //JAS try {
962 System.exit(1);
963 //JAS EAIoutSender.stopThread();
964 //JAS EAISocket.close();
965 //JAS EAIfromFreeWRLStream.close();
966
967 //JAS } catch (IOException e) {
968 //JAS }
969 }
970}
971