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