KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > proactive > examples > c3d > C3DDispatcher


1 /*
2 * ################################################################
3 *
4 * ProActive: The Java(TM) library for Parallel, Distributed,
5 * Concurrent computing with Security and Mobility
6 *
7 * Copyright (C) 1997-2002 INRIA/University of Nice-Sophia Antipolis
8 * Contact: proactive-support@inria.fr
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * USA
24 *
25 * Initial developer(s): The ProActive Team
26 * http://www.inria.fr/oasis/ProActive/contacts.html
27 * Contributor(s):
28 *
29 * ################################################################
30 */

31 package org.objectweb.proactive.examples.c3d;
32
33 import java.awt.Button JavaDoc;
34 import java.awt.Color JavaDoc;
35 import java.awt.Font JavaDoc;
36 import java.awt.Frame JavaDoc;
37 import java.awt.Graphics JavaDoc;
38 import java.awt.GridBagConstraints JavaDoc;
39 import java.awt.GridBagLayout JavaDoc;
40 import java.awt.Insets JavaDoc;
41 import java.awt.Label JavaDoc;
42 import java.awt.List JavaDoc;
43 import java.awt.Menu JavaDoc;
44 import java.awt.MenuBar JavaDoc;
45 import java.awt.MenuItem JavaDoc;
46 import java.awt.Panel JavaDoc;
47 import java.awt.TextArea JavaDoc;
48 import java.awt.event.ActionEvent JavaDoc;
49 import java.awt.event.ActionListener JavaDoc;
50 import java.awt.event.WindowAdapter JavaDoc;
51 import java.awt.event.WindowEvent JavaDoc;
52 import java.io.FileWriter JavaDoc;
53 import java.io.IOException JavaDoc;
54 import java.io.RandomAccessFile JavaDoc;
55 import java.net.InetAddress JavaDoc;
56 import java.net.UnknownHostException JavaDoc;
57 import java.util.Date JavaDoc;
58 import java.util.Enumeration JavaDoc;
59 import java.util.Hashtable JavaDoc;
60 import java.util.Stack JavaDoc;
61
62 import org.apache.log4j.Logger;
63 import org.objectweb.proactive.ProActive;
64 import org.objectweb.proactive.core.body.request.Request;
65 import org.objectweb.proactive.core.config.ProActiveConfiguration;
66 import org.objectweb.proactive.core.descriptor.data.ProActiveDescriptor;
67 import org.objectweb.proactive.core.descriptor.data.VirtualNode;
68 import org.objectweb.proactive.core.node.Node;
69 import org.objectweb.proactive.core.node.NodeException;
70 import org.objectweb.proactive.examples.c3d.geom.Vec;
71 import org.objectweb.proactive.examples.c3d.prim.Primitive;
72 import org.objectweb.proactive.examples.c3d.prim.Sphere;
73
74 /**
75  * This class decouples the set of user frames from the set of rendering
76  */

77 public class C3DDispatcher implements org.objectweb.proactive.RunActive
78 {
79     static Logger logger = Logger.getLogger(C3DDispatcher.class.getName());
80
81     protected VirtualNode vn;
82     /**
83      * Uses active objects if set to true
84      */

85     private static final boolean ACTIVE = true;
86     /*
87      * Stores the users in a hash table
88      */

89     private Hashtable JavaDoc h_users = new Hashtable JavaDoc();
90
91     /*
92      * Timestamp used to estimate rendering time
93      */

94     private long startTime;
95     /**
96      * Avg time for a rendering
97      */

98     private long avgRender = 0;
99     /**
100      * Number of renderings
101      */

102     private long totalRender = 0;
103     /**
104      * Interval stack; each interval holds information regarding its
105      * height, width and relative position within the whole image
106      */

107     private Stack JavaDoc int_stack = new Stack JavaDoc();
108     /**
109      * Array of rendering engines; each C3DRenderingEngine is a possibly remote,
110      * active object
111      */

112     private C3DRenderingEngine engine[];
113     /**
114      * Hashtable of the rendering engines
115      */

116     private Hashtable JavaDoc h_engines = new Hashtable JavaDoc();
117     /**
118      * Scene to be rendered; set by the first user frame to register;
119      * contains lights, spheres and one view
120      */

121     private Scene scene;
122     /**
123      * Number of rendering engines
124      */

125     private int engines;
126
127     /**
128      * Number of intervals, the whole picture should be divided into; this
129      * value has got an impact on the performance; it should be in
130      * the size of 'three times the number of rendering engines'
131      */

132     private int intervals;
133     /**
134      * Width of the rendering image
135      */

136     private int width;
137     /**
138      * Height of the rendering image
139      */

140     private int height;
141     /**
142      * Height of one rendering interval; provided for convenience only;
143      * carries the value of height / intervals
144      */

145     private int intheight;
146     /**
147      * Pixel array to store the rendered pixels; used to initialize the
148      * image on new-coming user frames, actualized in setPixels
149      */

150     private int[] pixels;
151     /**
152      * Number of intervals not yet rendered; used to determine the progress
153      * of the asynchronous rendering process; may or may not stay in
154      * future versions of live()
155      */

156     private int i_left = 0;
157     private int i_lastuser = 0;
158     private TextArea JavaDoc ta_log;
159     private List JavaDoc li_users;
160     private List JavaDoc li_enginesUsed;
161     private List JavaDoc li_enginesAvailable;
162     private String JavaDoc s_access_url;
163     private String JavaDoc s_hosts;
164     private Button JavaDoc b_addEng = new Button JavaDoc("Add engine");
165     private Button JavaDoc b_rmEng = new Button JavaDoc("Remove engine");
166     private Election election = null;
167     /**
168      * The average pining time for users
169      */

170     private long userPing = 0;
171     /**
172      * The number of User connected from the beginning
173      */

174     private long userTotal = 0;
175     /**
176      * The average pining time for rendering engines
177      */

178     private long enginePing = 0;
179     /**
180      * True if a rendering is going on [init = true because when 1st
181      * user registers, render starts]
182      */

183     private boolean b_render = false;
184     /**
185      * ProactiveDescriptor object for the dispatcher
186      */

187     private ProActiveDescriptor proActiveDescriptor;
188     private String JavaDoc[] rendererNodes;
189
190     /**
191      * The no-argument Constructor as commanded by Java//; otherwise unused
192      */

193     public C3DDispatcher()
194     {
195     }
196
197     /**
198      * Real Constructor
199      */

200     //public C3DDispatcher(String s_hosts)
201
//{
202
//new C3DDispatcherFrame();
203
//this.s_hosts = s_hosts;
204
//}
205

206     /**
207      * Constructor to call when using XML Descriptor
208      */

209     public C3DDispatcher(String JavaDoc [] rendererNodes,VirtualNode vn, ProActiveDescriptor pad)
210     {
211         new C3DDispatcherFrame();
212         this.rendererNodes=rendererNodes;
213         this.vn = vn;
214         this.proActiveDescriptor = pad;
215     }
216     /**
217      * Continues the initialization; called when the first user registers.
218      * It creates a set of rendering engines (one on each machine given by
219      * the Mapping in Utils) and passes a reference to its own stub to
220      * every engine.
221      */

222     public void init()
223     {
224         try
225         {
226             C3DDispatcher d =
227                 (C3DDispatcher) org
228                     .objectweb
229                     .proactive
230                     .ProActive
231                     .getStubOnThis();
232             /* Initializes the pixel array holding the whole image */
233             //Hosts hosts = new Hosts(s_hosts);
234
//engines = hosts.getMachines();
235
//engines = proActiveDescriptor.getVirtualNodeMappingSize()-1;
236
//System.out.println("taille du tableau d'engines "+engines);
237
/* Initializes the array to hold the rendering engines */
238             //engine = new C3DRenderingEngine[engines];
239
Object JavaDoc[] param = { d };
240             /* Creates rendering engines */
241             //for (int n = 1; n <= engines; n++)
242
//{
243
//String node = hosts.getNextNode();
244
//VirtualNode renderer = proActiveDescriptor.getVirtualNode("Renderer");
245
//System.out.println(renderer.getName());
246
//JVMNodeProcess jvmNodeProcess = (JVMNodeProcess)renderer.getVirtualMachine().getProcess();
247
//System.out.println(jvmNodeProcess.getClassname());
248
//renderer.activate();
249
//we have to wait for the creation of the nodes
250

251         //Node[] nodeTab = renderer.getNodes();
252
engines = rendererNodes.length;
253         engine = new C3DRenderingEngine[engines];
254         for (int i = 0; i < rendererNodes.length; i++)
255         {
256             C3DRenderingEngine tmp =
257                     (
258                         C3DRenderingEngine)ProActive
259                             .newActive(
260                         "org.objectweb.proactive.examples.c3d.C3DRenderingEngine",
261                         param,
262                         rendererNodes[i]);
263                 //String nodeURL = nodeTab[i].getNodeInformation().getURL();
264
log("New rendering engine " + i + " created at " + rendererNodes[i]);
265                 
266                 // always have a renderer used when launching the program
267
if (i == 1)
268                     li_enginesUsed.add(rendererNodes[i].toString());
269                 else
270                     li_enginesAvailable.add(rendererNodes[i].toString());
271
272                 // adds the engine in the hashtable
273
h_engines.put(rendererNodes[i], tmp);
274         }
275                 //String nodeURL = node.getNodeInformation().getURL();
276
// C3DRenderingEngine tmp =
277
// (
278
// C3DRenderingEngine)ProActive
279
// .newActive(
280
// "org.objectweb.proactive.examples.c3d.C3DRenderingEngine",
281
// param,
282
// node);
283
// log("New rendering engine " + n + " created at " + nodeURL);
284
//
285
// // always have a renderer used when launching the program
286
// if (n == 1)
287
// li_enginesUsed.add(nodeURL.toString());
288
// else
289
// li_enginesAvailable.add(nodeURL.toString());
290
//
291
// // adds the engine in the hashtable
292
// h_engines.put(nodeURL, tmp);
293
//}
294
}
295         catch (Exception JavaDoc e)
296         {
297             e.printStackTrace();
298             throw new RuntimeException JavaDoc(e.toString());
299         }
300     }
301
302     /**
303      * Appends message to the end of the list
304      */

305     public void log(String JavaDoc s_message)
306     {
307         ta_log.append(s_message + "\n");
308     }
309
310     /**
311      * Does the rendering; creates the interval stack, registers the current
312      * scene with the engines, assigns one initial interval to each engine
313      * and triggers the calculation
314      */

315     private void render()
316     {
317
318         // Checks there are some engines usde
319
if (li_enginesUsed.getItems().length == 0)
320         {
321             showMessageAll("No engines ... contact the dispatcher");
322             return;
323         }
324
325         // Toggles the rendering flag..
326
b_render = true;
327
328         // Benchmarking stuff...
329
startTime = System.currentTimeMillis();
330
331         Interval interval;
332         String JavaDoc keys[] = li_enginesUsed.getItems();
333         engines = keys.length;
334
335         log("Creating " + intervals + " intervals");
336         intervals = 3 * keys.length;
337         intheight = height / intervals;
338
339         /* Sets the number of intervals not yet calculated to 'all' */
340         i_left = intervals;
341
342         /* Creates the interval stack */
343         int_stack = new Stack JavaDoc();
344         for (int i = 0; i < intervals; i++)
345         {
346             // log("Creating inter : "+i);
347
Interval newint =
348                 new Interval(
349                     i,
350                     width,
351                     height,
352                     i * intheight,
353                     (i + 1) * intheight,
354                     intervals);
355             int_stack.push(newint);
356         }
357
358         engine = null;
359         engine = new C3DRenderingEngine[keys.length];
360
361         C3DRenderingEngine tmp;
362         if (keys != null)
363         {
364             for (int e = 0; e < keys.length; e++)
365             {
366
367                 /* Assigns one initial interval to each engine */
368                 if (!int_stack.empty())
369                 {
370                     interval = (Interval) int_stack.pop();
371
372                     tmp = (C3DRenderingEngine) h_engines.get(keys[e]);
373
374                     if (tmp != null)
375                     {
376
377                         tmp.setScene(scene);
378
379                         engine[e] = tmp;
380
381                         /* Triggers the calculation of this interval on engine e */
382                         tmp.render(e, interval);
383
384                         log(
385                             "Interval "
386                                 + interval.number
387                                 + " assigned to engine "
388                                 + keys[e]
389                                 + "["
390                                 + e
391                                 + "]");
392                     }
393                     else
394                     {
395                         log(
396                             "Failed to assign an interval to engine "
397                                 + keys[e]);
398                         h_engines.get(keys[e]);
399                     }
400                 }
401             }
402         }
403         else
404             b_render = false;
405     }
406
407     long previousTime = -1;
408
409     /**
410      * Forwards the newly calculated pixels from the rendering engine to the
411      * redirectors (i.e. the consumers). This method is called directly by
412      * the rendering engines via their reference to this C3DDispatcher.
413      *
414      * @param newpix the newly calculated pixels as int[]
415      * @param interval the interval, the pixels belong to (width, height ...)
416      * @param engine_number number of the engine, that has calculated this
417      * interval; this value is used to assign the next interval to
418      * this same engine
419      */

420     public void setPixels(int[] newpix, Interval interval, int engine_number)
421     {
422         // public void setPixels(int[] newpix, Interval interval, C3DRenderingEngine currentEngine) {
423

424         long elapsed;
425         
426         /* Delivers the new pixels to all user frames */
427         for (Enumeration JavaDoc e = h_users.elements(); e.hasMoreElements();)
428         {
429             User user = (User) e.nextElement();
430             
431             user.getObject().setPixels(newpix, interval);
432         }
433
434         /* Stores the newly rendered interval in <code>pixels</code>; this
435          * is later used to initialize the images of newcoming consumers */

436         System.arraycopy(
437             newpix,
438             0,
439             pixels,
440             interval.width * interval.yfrom,
441             newpix.length);
442         /* Decreases the counter of not yet rendered intervals */
443         i_left--;
444
445         /* Has the next interval rendered by the same engine */
446         Interval nextinterval;
447         if (!int_stack.empty())
448         {
449             nextinterval = (Interval) int_stack.pop();
450             log(
451                 "Next interval ["
452                     + nextinterval.number
453                     + "] assigned to engine "
454                     + engine_number);
455             // new NextInterval(engine_number, engine[engine_number], nextinterval);
456
engine[engine_number].render(engine_number, nextinterval);
457             // currentEngine.render(0, nextinterval);
458

459         }
460         else if (i_left == 0)
461         {
462             // Debugging: estimates the number of milliseconds elapsed
463
elapsed = System.currentTimeMillis() - startTime;
464
465             totalRender++;
466             avgRender += ((elapsed - avgRender) / totalRender);
467
468             showMessageAll("All intervals rendered in " + elapsed + " ms");
469             if (previousTime != -1)
470                 showMessageAll(
471                     "Speed Up : "
472                         + java.lang.Math.rint(
473                             ((double) previousTime / elapsed) * 1000)
474                             / 1000
475                         + "\n");
476             else
477                 showMessageAll("");
478             previousTime = elapsed;
479
480             b_render = false;
481         }
482     }
483
484     /**
485      * Rotates all the objects (spheres, for the moment) by <code>angle</code>
486      * around their y axis; re-renders the image afterwards
487      *
488      * @param angle the angle to rotate the objects in radians, a positive
489      * value means a rotation to the 'right'
490      */

491     private void rotateSceneY(double angle)
492     {
493         int objects = scene.getObjects();
494         Sphere o;
495         /* on every object ... */
496         for (int i = 0; i < objects; i++)
497         {
498             o = (Sphere) scene.getObject(i);
499             Vec c = o.getCenter();
500             double phi = Math.atan2(c.z, c.x);
501             double l = Math.sqrt(c.x * c.x + c.z * c.z);
502             /* ... perform the standard rotation math */
503             c.x = l * Math.cos(phi + angle);
504             c.z = l * Math.sin(phi + angle);
505             o.setCenter(c);
506             scene.setObject(o, i);
507         }
508         /* re-renders the image to reflect the rotation */
509         render();
510     }
511
512     /**
513      * Rotates all the objects (spheres, for the moment) by <code>angle</code>
514      * around their x axis; re-renders the image afterwards
515      *
516      * @param angle the angle to rotate the objects in radians, a positive
517      * value means a rotation to the 'right'
518      */

519     private void rotateSceneX(double angle)
520     {
521         int objects = scene.getObjects();
522         Sphere o;
523         /* on every object ... */
524         for (int i = 0; i < objects; i++)
525         {
526             o = (Sphere) scene.getObject(i);
527             Vec c = o.getCenter();
528             double phi = Math.atan2(c.z, c.y);
529             double l = Math.sqrt(c.y * c.y + c.z * c.z);
530             /* ... perform the standard rotation math */
531             c.y = l * Math.cos(phi + angle);
532             c.z = l * Math.sin(phi + angle);
533             o.setCenter(c);
534             scene.setObject(o, i);
535         }
536         /* re-renders the image to reflect the rotation */
537         render();
538     }
539
540     /**
541      * Rotates all the objects (spheres, for the moment) by <code>angle</code>
542      * around their x axis; re-renders the image afterwards
543      *
544      * @param angle the angle to rotate the objects in radians, a positive
545      * value means a rotation to the 'right'
546      */

547     private void rotateSceneZ(double angle)
548     {
549         int objects = scene.getObjects();
550         Sphere o;
551         /* on every object ... */
552         for (int i = 0; i < objects; i++)
553         {
554             o = (Sphere) scene.getObject(i);
555             Vec c = o.getCenter();
556             double phi = Math.atan2(c.x, c.y);
557             double l = Math.sqrt(c.y * c.y + c.x * c.x);
558             /* ... perform the standard rotation math */
559             c.y = l * Math.cos(phi + angle);
560             c.x = l * Math.sin(phi + angle);
561             o.setCenter(c);
562             scene.setObject(o, i);
563         }
564         /* re-renders the image to reflect the rotation */
565         render();
566     }
567
568     /**
569      * Rotates the objects in the rendering scene by pi/4 to the left
570      *
571      * @param i_user number of the user requesting this rotation; this
572      * value used for the synchronization and notification of several
573      * users
574      */

575     public void rotateLeft(int i_user)
576     {
577         rotateSceneY(-Math.PI / 4);
578     }
579
580     /**
581      * Rotates the objects in the rendering scene by pi/4 to the right
582      *
583      * @param i_user number of the user requesting this rotation; this
584      * value used for the synchronization and notification of several
585      * users
586      */

587     public void rotateRight(int i_user)
588     {
589         rotateSceneY(Math.PI / 4);
590     }
591
592     /**
593      * Rotates the objects in the rendering scene by pi/4 to the left
594      *
595      * @param i_user number of the user requesting this rotation; this
596      * value used for the synchronization and notification of several
597      * users
598      */

599     public void rotateUp(int i_user)
600     {
601         rotateSceneX(Math.PI / 4);
602     }
603
604     /**
605      * Rotates the objects in the rendering scene by pi/4 down
606      *
607      * @param i_user number of the user requesting this rotation; this
608      * value used for the synchronization and notification of several
609      * users
610      */

611     public void rotateDown(int i_user)
612     {
613         rotateSceneX(-Math.PI / 4);
614     }
615
616     /**
617      * Spins clockwise
618      *
619      * @param i_user number of the user requesting this rotation; this
620      * value used for the synchronization and notification of several
621      * users
622      */

623     public void spinClock(int i_user)
624     {
625         rotateSceneZ(Math.PI / 4);
626     }
627
628     /**
629      * Spins the scene un-clockwise
630      *
631      * @param i_user number of the user requesting this rotation; this
632      * value used for the synchronization and notification of several
633      * users
634      */

635     public void spinUnclock(int i_user)
636     {
637         rotateSceneZ(-Math.PI / 4);
638     }
639
640     public void changeColorAll()
641     {
642         logger.info("changeColorAll()");
643         for (Enumeration JavaDoc e = h_users.elements(); e.hasMoreElements();)
644             ((User) e.nextElement())
645                 .getObject()
646                 .getUserFrame()
647                 .getB_left()
648                 .setBackground(
649                 Color.yellow);
650     }
651
652     /**
653      * Java// object life routine
654      * To be remdelled..
655      */

656     public void runActivity(org.objectweb.proactive.Body body)
657     {
658         //registerDispatcher(body.getNodeURL());
659
/* Creates the rendering engines */
660         init();
661         org
662
            .objectweb
663             .proactive
664             .core
665             .body
666             .request
667             .BlockingRequestQueue requestQueue =
668             body.getRequestQueue();
669         /* Loops over lifetime */
670         while (body.isActive())
671         {
672
673                 /* Waits on any method call */
674                 Request r = requestQueue.blockingRemoveOldest();
675                 String JavaDoc methodName = r.getMethodName();
676                 if (methodName.startsWith("rotate")|| methodName.startsWith("spin")){
677                     processRotate(body, methodName, r);
678                 }
679                 else{
680                     if (!Election.isRunning())
681                     {
682                         // No election and the method != up,down,left,right
683
body.serve(r);
684                     }
685                     else if (methodName.equals("addSphere"))
686                     {
687                     // There is an election and addsphere comes..
688
// nothing happens...
689
showMessageAll("Cannot add spheres while an election is running");
690                     }
691                     else
692                     {
693                     // THERE IS a running election and the method name is not left or right..
694

695                     body.serve(r);
696                     }
697                 }
698
699             }
700         //}
701
}
702
703 // private void registerDispatcher(String nodeURL)
704
// {
705
// /* Register this C3DDispatcher, this will serve as entry point to the
706
// * raytracing system for the user frames */
707
//
708
// try
709
// {
710
// org.objectweb.proactive.core.node.Node node =
711
// org.objectweb.proactive.core.node.NodeFactory.getNode(nodeURL);
712
// s_access_url =
713
// "//"
714
// + node.getNodeInformation().getInetAddress().getHostName()
715
// + "/"
716
// + C3D_DISPATCHER_BIND_NAME;
717
// org.objectweb.proactive.ProActive.register(
718
// org.objectweb.proactive.ProActive.getStubOnThis(),
719
// s_access_url);
720
// log("Successfully registered at " + s_access_url + " and ready.");
721
//
722
// }
723
// catch (org.objectweb.proactive.core.node.NodeException e)
724
// {
725
// log("Error: The node of the body cannot be found!");
726
// e.printStackTrace();
727
// }
728
// catch (UnknownHostException e)
729
// {
730
// log("Error: Name of the local host could not be determined!");
731
// e.printStackTrace();
732
// }
733
// catch (java.io.IOException e)
734
// {
735
// log("Error: could not register, RMI registry not found!");
736
// e.printStackTrace();
737
// }
738
// }
739

740     /**
741      * Processes the requests which are relative to rotations
742      * @param body The body of the active object
743      * @param methodName The methodname <font size="-1">Not reconputed in order to gain time</font>
744      * @param r The request object
745      */

746     public void processRotate(
747         org.objectweb.proactive.Body body,
748         String JavaDoc methodName,
749         Request r)
750     {
751         int i_user = 0;
752         try
753         {
754             i_user = ((Integer JavaDoc) r.getParameter(0)).intValue();
755         }
756         catch (Exception JavaDoc e)
757         {
758             e.printStackTrace();
759         }
760         if (methodName.equals("rotateLeft"))
761         {
762             // A user wants to rotate left
763
if (Election.isRunning())
764             {
765                 // There is an election
766
int i_votes = Election.vote(i_user, new Integer JavaDoc(Election.LEFT));
767                 if (i_votes == h_users.size())
768                 {
769                     election.finish();
770                 }
771             }
772             else
773             {
774                 // There is no election
775
if (i_left > 0)
776                 {
777                     showMessage(
778                         i_user,
779                         "Rendering in progress, request invalid");
780                 }
781                 else if (h_users.size() == 1)
782                 {
783                     showMessage(i_user, "Scene is being rotated left");
784                     body.serve(r);
785                 }
786                 else
787                 {
788                     election =
789                         new Election(i_user, new Integer JavaDoc(Election.LEFT), this);
790                 }
791             }
792         }
793         else if (methodName.equals("rotateRight"))
794         {
795             // A user wants to go right
796
if (Election.isRunning())
797             {
798                 // there is an election
799
int i_votes =
800                     Election.vote(i_user, new Integer JavaDoc(Election.RIGHT));
801                 if (i_votes == h_users.size())
802                 {
803                     election.finish();
804                 }
805             }
806             else
807             {
808                 // there is no election
809
if (i_left > 0)
810                 {
811                     showMessage(
812                         i_user,
813                         "Rendering in progress, request invalid");
814                 }
815                 else if (h_users.size() == 1)
816                 {
817                     showMessage(i_user, "Scene is being rotated right");
818                     body.serve(r);
819                 }
820                 else
821                 {
822                     election =
823                         new Election(i_user, new Integer JavaDoc(Election.RIGHT), this);
824                 }
825             }
826         }
827         else if (methodName.equals("rotateUp"))
828         {
829             // A user wants to go up
830
if (Election.isRunning())
831             {
832                 // There is an election
833
int i_votes = Election.vote(i_user, new Integer JavaDoc(Election.UP));
834                 if (i_votes == h_users.size())
835                 {
836                     election.finish();
837                 }
838             }
839             else
840             {
841                 // There is no election
842
if (i_left > 0)
843                 {
844                     showMessage(
845                         i_user,
846                         "Rendering in progress, request invalid");
847                 }
848                 else if (h_users.size() == 1)
849                 {
850                     showMessage(i_user, "Scene is being rotated up");
851                     body.serve(r);
852                 }
853                 else
854                 {
855                     election =
856                         new Election(i_user, new Integer JavaDoc(Election.UP), this);
857                 }
858             }
859         }
860         else if (methodName.equals("rotateDown"))
861         {
862             // An user wants to go down
863
if (Election.isRunning())
864             {
865                 // there is an election
866
int i_votes = Election.vote(i_user, new Integer JavaDoc(Election.DOWN));
867                 if (i_votes == h_users.size())
868                 {
869                     election.finish();
870                 }
871             }
872             else
873             {
874                 // there is no election
875
if (i_left > 0)
876                 {
877                     showMessage(
878                         i_user,
879                         "Rendering in progress, request invalid");
880                 }
881                 else if (h_users.size() == 1)
882                 {
883                     showMessage(i_user, "Scene is being rotated down");
884                     body.serve(r);
885                 }
886                 else
887                 {
888                     election =
889                         new Election(i_user, new Integer JavaDoc(Election.DOWN), this);
890                 }
891             }
892         }
893         else if (methodName.equals("spinClock"))
894         {
895             // A user wants to spin clockwise
896
if (Election.isRunning())
897             {
898                 // There is an election
899
int i_votes =
900                     Election.vote(i_user, new Integer JavaDoc(Election.CLOCKWISE));
901                 if (i_votes == h_users.size())
902                 {
903                     election.finish();
904                 }
905             }
906             else
907             {
908                 // There is no election
909
if (i_left > 0)
910                 {
911                     showMessage(
912                         i_user,
913                         "Rendering in progress, request invalid");
914                 }
915                 else if (h_users.size() == 1)
916                 {
917                     showMessage(i_user, "Scene is being spinned right");
918                     body.serve(r);
919                 }
920                 else
921                 {
922                     election =
923                         new Election(
924                             i_user,
925                             new Integer JavaDoc(Election.CLOCKWISE),
926                             this);
927                 }
928             }
929         }
930         else if (methodName.equals("spinUnclock"))
931         {
932             // An user wants to spin unclock
933
if (Election.isRunning())
934             {
935                 // there is an election
936
int i_votes =
937                     Election.vote(i_user, new Integer JavaDoc(Election.UNCLOCKWISE));
938                 if (i_votes == h_users.size())
939                 {
940                     election.finish();
941                 }
942             }
943             else
944             {
945                 // there is no election
946
if (i_left > 0)
947                 {
948                     showMessage(
949                         i_user,
950                         "Rendering in progress, request invalid");
951                 }
952                 else if (h_users.size() == 1)
953                 {
954                     showMessage(i_user, "Scene is being spinned left");
955                     body.serve(r);
956                 }
957                 else
958                 {
959                     election =
960                         new Election(
961                             i_user,
962                             new Integer JavaDoc(Election.UNCLOCKWISE),
963                             this);
964                 }
965             }
966         }
967     }
968
969     /**
970      * Displays a message at a consumer; convenience method
971      *
972      * @param i_user number of the user frame to show the message on
973      * @param message the message to display
974      */

975     public void showMessage(int i_user, String JavaDoc s_message)
976     {
977         ((User) h_users.get(new Integer JavaDoc(i_user))).getObject().showMessage(
978             s_message);
979     }
980
981     /**
982      * Displays a dialog message at a consumer; convenience method
983      *
984      * @param i_user number of the user frame to show the message on
985      * @param message the message to display
986      */

987     public void showDialog(int i_user, String JavaDoc subject, String JavaDoc s_message)
988     {
989         ((User) h_users.get(new Integer JavaDoc(i_user))).getObject().dialogMessage(
990             subject,
991             s_message);
992     }
993
994     /**
995      * Displays a message sent by another user
996      */

997     public void showUserMessage(int i_user, String JavaDoc s_message)
998     {
999         ((User) h_users.get(new Integer JavaDoc(i_user))).getObject().showUserMessage(
1000            s_message);
1001    }
1002
1003    /**
1004     * Sends message to everybody
1005     * @param s_message the message to display
1006     */

1007    public void showMessageAll(String JavaDoc s_message)
1008    {
1009        log(s_message);
1010        for (Enumeration JavaDoc e = h_users.elements(); e.hasMoreElements();)
1011        {
1012            ((User) e.nextElement()).getObject().showMessage(s_message);
1013        }
1014    }
1015
1016    /* public void setInitialColor() {
1017    for (Enumeration e = h_users.elements() ; e.hasMoreElements() ;) {
1018      ((User) e.nextElement()).getObject().getUserFrame().getB_clock().setBackground(Color.gray);
1019    }
1020    }*/

1021
1022    /**
1023     * Sends a message to everybody except the user
1024     * @param i_user The number of the user
1025     * @param s_message The message
1026     */

1027    public void showMessageExcept(int i_user, String JavaDoc s_message)
1028    {
1029        log(s_message);
1030        int i;
1031        for (Enumeration JavaDoc e = h_users.keys(); e.hasMoreElements();)
1032        {
1033            i = ((Integer JavaDoc) e.nextElement()).intValue();
1034            if (i != i_user)
1035                showMessage(i, s_message);
1036        }
1037    }
1038
1039    /**
1040     * Sends a dialog message to everybody except the user
1041     * @param i_user The number of the user
1042     * @param s_message The message
1043     */

1044    public void showDialogExcept(int i_user, String JavaDoc subject, String JavaDoc s_message)
1045    {
1046        int i;
1047        for (Enumeration JavaDoc e = h_users.keys(); e.hasMoreElements();)
1048        {
1049            i = ((Integer JavaDoc) e.nextElement()).intValue();
1050            if (i != i_user)
1051                showDialog(i, subject, s_message);
1052        }
1053    }
1054
1055    /**
1056     * Sends a message to everybody except the user
1057     * @param i_user The number of the user
1058     * @param s_message The message
1059     */

1060    public void showUserMessageExcept(int i_user, String JavaDoc s_message)
1061    {
1062        log(s_message);
1063        int i;
1064        for (Enumeration JavaDoc e = h_users.keys(); e.hasMoreElements();)
1065        {
1066            i = ((Integer JavaDoc) e.nextElement()).intValue();
1067            if (i != i_user)
1068                showUserMessage(i, s_message);
1069        }
1070    }
1071
1072    /**
1073     * Instanciates a new active C3DDispatcher on the local machine
1074     *
1075     * @param argv Name of the hosts file
1076     */

1077    public static void main(String JavaDoc argv[]) throws NodeException
1078    {
1079        ProActiveDescriptor proActiveDescriptor = null;
1080        ProActiveConfiguration.load();
1081        //if (argv.length < 1)
1082
//{
1083
//System.err.println(
1084
//"Usage: java org.objectweb.proactive.examples.c3d.C3DDispatcher <engineFile> [<nodeURL>]");
1085
//System.exit(0);
1086
//}
1087
Node node = null;
1088        //if (argv.length == 2) {
1089
//node = NodeFactory.getNode("//localhost/dispatcher");
1090
//} else {
1091
//node = NodeFactory.createNode("//localhost/dispatcher");
1092
//}
1093
try
1094        {
1095            proActiveDescriptor =
1096                ProActive.getProactiveDescriptor(
1097                    "file:"+argv[0]);
1098            proActiveDescriptor.activateMappings();
1099            //Thread.sleep(20000);
1100
}
1101        catch (Exception JavaDoc e)
1102        {
1103            e.printStackTrace();
1104            logger.error("Pb in main");
1105        }
1106        
1107        
1108        //Object param[] = new Object[]{ proActiveDescriptor };
1109

1110        VirtualNode dispatcher =
1111            proActiveDescriptor.getVirtualNode("Dispatcher");
1112            
1113            VirtualNode renderer = proActiveDescriptor.getVirtualNode("Renderer");
1114        String JavaDoc[] rendererNodes = renderer.getNodesURL();
1115        Object JavaDoc param[] = new Object JavaDoc[]{rendererNodes,dispatcher, proActiveDescriptor};
1116        //System.out.println("in main"+dispatcher.getVirtualMachine().getProcess().getCommand());
1117
//VirtualNode renderer = proActiveDescriptor.getVirtualNode("Renderer1");
1118
//System.out.println(renderer.getName());
1119
//JVMNodeProcess jvmNodeProcess = (JVMNodeProcess)renderer.getVirtualMachine().getProcess();
1120
//System.out.println(jvmNodeProcess.getParameters());
1121
//dispatcher.activate();
1122
node = dispatcher.getNode();
1123        //System.out.println(node.getNodeInformation().getURL());
1124
//System.out.println(System.getProperty("java.class.path"));
1125
//String nodeURL = node.getNodeInformation().getURL();
1126
try
1127        {
1128            ProActive.newActive(
1129                "org.objectweb.proactive.examples.c3d.C3DDispatcher",
1130                param,
1131                node);
1132        
1133        }
1134        catch (Exception JavaDoc e)
1135        {
1136            e.printStackTrace();
1137        }
1138        // System.exit(0);
1139
}
1140
1141    /**
1142     * The pinging function called by <code>C3DUser and C3DRenderingEngine</code>
1143     * to get the avg. pinging time
1144     */

1145    public int ping()
1146    {
1147        return 0;
1148    }
1149
1150    /**
1151     * Registers a consumer with this C3DDispatcher; called by the user frames
1152     * after initialization.
1153     *
1154     * @param t the User as entry point for subsequent method
1155     * calls, e.g. setPixels
1156     * @param scene the Scene the consumer wants to have rendered, only the
1157     * first Scene is accepted
1158     * @return number (counter) of the consumer at this C3DDispatcher, used to
1159     * distinguish consumers in the display and for subsequent
1160     * method calls, e.g. rotateRight
1161     */

1162    public int registerConsumer(C3DUser c3duser, Scene newscene, String JavaDoc s_name)
1163    {
1164        //System.out.println("User wan in: " + c3duser.getWidth());
1165
c3duser.log("-> Remote call-back: dispatcher found, user registered");
1166
1167        log("New user " + s_name + "(" + i_lastuser + ") has joined");
1168
1169        User newUser = new User(s_name, c3duser);
1170
1171        /* Adds this User to the list */
1172        h_users.put(new Integer JavaDoc(i_lastuser), newUser);
1173        li_users.add(s_name + " (" + i_lastuser + ")");
1174
1175        /**
1176         * Informs the other users of the new user
1177         */

1178
1179        // Updates the remote h_users
1180
for (Enumeration JavaDoc e = h_users.keys(); e.hasMoreElements();)
1181        {
1182            int i = ((Integer JavaDoc) e.nextElement()).intValue();
1183            User oldUser = ((User) h_users.get(new Integer JavaDoc(i)));
1184            if (i != i_lastuser)
1185            {
1186                // Inform the old users
1187
oldUser.getObject().informNewUser(i_lastuser, s_name);
1188                // Inform the new user
1189
newUser.getObject().informNewUser(i, oldUser.getName());
1190            }
1191        }
1192
1193        /**
1194         * Pinging the new User
1195         */

1196        userTotal++;
1197        long elapsed;
1198        long start = System.currentTimeMillis();
1199
1200        // Forces the use of a synchroneous call by using future
1201
if (c3duser.ping() == 0)
1202        {
1203            // avg = avg + ((new-avg)/times)
1204
elapsed = System.currentTimeMillis() - start;
1205            userPing += (elapsed - userPing) / userTotal;
1206            log(
1207                "Pinging user "
1208                    + s_name
1209                    + " in "
1210                    + elapsed
1211                    + " ms. Average: "
1212                    + userPing);
1213        }
1214
1215        /**
1216         * Does some initialization when the first consumer registers
1217         */

1218        if (h_users.size() == 1)
1219        {
1220            /* Sets the scene to the consumers wish */
1221            scene = newscene;
1222            /* Initializes image properties */
1223            width = c3duser.getWidth().intValue();
1224            height = c3duser.getHeight().intValue();
1225            pixels = new int[width * height];
1226            intervals = 3 * engines;
1227            intheight = height / intervals;
1228            int max;
1229
1230            if (s_name.compareTo("Benchmarking bot") == 0)
1231                max = 50;
1232            else
1233                max = 1;
1234
1235            // Performs pings on the remote engines
1236
int engPingTotal = 0;
1237            for (int n = 0; n < engines; n++)
1238            {
1239                for (int i = 1; i < max; i++)
1240                {
1241                    engPingTotal++;
1242                    start = System.currentTimeMillis();
1243                    if (engine[n].ping() == 1)
1244                    {
1245                        elapsed = System.currentTimeMillis() - start;
1246                        enginePing += (elapsed - enginePing) / engPingTotal;
1247                    }
1248                }
1249            }
1250            /* Creates the intervals, starts the calculation with initial intervals */
1251            render();
1252        }
1253        else
1254        {
1255            /* Initializes the image of the new-coming consumer */
1256            Interval inter = new Interval(0, width, height, 0, height, 1);
1257            c3duser.setPixels(pixels, inter);
1258        }
1259        return i_lastuser++;
1260    }
1261    
1262    public void registerMigratedUser(int userNumber){
1263        
1264
1265        User user = (User)h_users.get(new Integer JavaDoc(userNumber));
1266        log("User " + user.getName() + "(" + userNumber + ") has migrated ");
1267        
1268        for (Enumeration JavaDoc e = h_users.keys(); e.hasMoreElements();)
1269        {
1270            int i = ((Integer JavaDoc) e.nextElement()).intValue();
1271            User oldUser = ((User) h_users.get(new Integer JavaDoc(i)));
1272            if (i != userNumber)
1273            {
1274                // Inform users
1275
user.getObject().informNewUser(i, oldUser.getName());
1276            }
1277        }
1278        
1279        
1280        /* Initializes the image of the migrated consumer */
1281        Interval inter = new Interval(0, width, height, 0, height, 1);
1282        user.getObject().setPixels(pixels, inter);
1283        
1284        
1285    }
1286
1287    /**
1288     * Reset the scene
1289     */

1290    public void resetScene(Scene s)
1291    {
1292        if (!int_stack.isEmpty())
1293        {
1294            showMessageAll("Cannot reset scene while rendering");
1295            return;
1296        }
1297        else
1298        {
1299            scene = s;
1300            showMessageAll("The scene has been reseted. Rendering...");
1301            render();
1302        }
1303    }
1304
1305    /**
1306     * Removes a consumer from the list of registered consumers
1307     *
1308     * @param number number of the consumer to be removed
1309     */

1310    public void unregisterConsumer(int number)
1311    {
1312        showMessageExcept(number, "User " + nameOfUser(number) + " left");
1313        
1314        for (Enumeration JavaDoc e = h_users.keys(); e.hasMoreElements();)
1315        {
1316            int i = ((Integer JavaDoc) e.nextElement()).intValue();
1317            
1318            if (i != number)
1319            {
1320                User user = ((User) h_users.get(new Integer JavaDoc(i)));
1321                // Inform all user except the user that left
1322
user.getObject().informUserLeft(nameOfUser(number));
1323            }
1324        }
1325
1326
1327        try
1328        {
1329            li_users.remove(nameOfUser(number) + " (" + number + ")");
1330        }
1331        catch (Exception JavaDoc ex)
1332        {
1333            ex.printStackTrace();
1334        }
1335        h_users.remove(new Integer JavaDoc(number));
1336        if (h_users.isEmpty())
1337        {
1338            //h_engines.clear();
1339
//li_enginesUsed.removeAll();
1340
//li_enginesAvailable.removeAll();
1341
int_stack.removeAllElements();
1342            i_lastuser = 0;
1343        }
1344    }
1345
1346    /**
1347     * Return OS of the machine, this C3DDispatcher is running on
1348     *
1349     * @return name and version of the OS
1350     */

1351    public String JavaDoc getOSString()
1352    {
1353        return System.getProperty("os.name")
1354            + " "
1355            + System.getProperty("os.version");
1356    }
1357
1358    public int getIntervals()
1359    {
1360        return intervals;
1361    }
1362
1363    public String JavaDoc getUserList()
1364    {
1365        StringBuffer JavaDoc s_list = new StringBuffer JavaDoc();
1366        for (Enumeration JavaDoc e = h_users.elements(); e.hasMoreElements();)
1367        {
1368            s_list.append(" " + ((User) e.nextElement()).getName() + "\n");
1369        }
1370        return s_list.toString();
1371    }
1372
1373    String JavaDoc nameOfUser(int i_user)
1374    {
1375        return ((User) h_users.get(new Integer JavaDoc(i_user))).getName();
1376    }
1377
1378    private void trace(String JavaDoc s_message)
1379    {
1380        logger.info("C3DDispatcher: " + s_message);
1381    }
1382
1383    public void addSphere(Sphere s)
1384    {
1385        // Can only add sphere if there is no rendering going on
1386
if (!int_stack.isEmpty())
1387        {
1388            showMessageAll("Cannot add spheres while rendering");
1389            return;
1390        }
1391        else
1392        {
1393            scene.addObject((Primitive) s);
1394            showMessageAll(
1395                "A Sphere has been added\nX:"
1396                    + Math.floor(s.getCenter().x)
1397                    + " Y:"
1398                    + Math.floor(s.getCenter().y)
1399                    + " Z:"
1400                    + Math.floor(s.getCenter().y));
1401            render();
1402            log("Scene now contains " + scene.getObjects() + " spheres");
1403        }
1404    }
1405
1406    /**
1407     * @@ experimental benchmark function...
1408     * Should maybe dump the results into a file???
1409     * Ascii / cvs format ???
1410     */

1411    public void doBenchmarks()
1412    {
1413        FileWriter JavaDoc bench;
1414        long start;
1415        long elapsed;
1416
1417        for (int n = 0; n < engines; n++)
1418        {
1419            // Pings each engine
1420
start = System.currentTimeMillis();
1421            if (engine[n].ping() == 0)
1422            {
1423                elapsed = System.currentTimeMillis() - start;
1424                enginePing += (elapsed - enginePing) / (n + 1);
1425                log(
1426                    "Pinging engine "
1427                        + n
1428                        + "in "
1429                        + elapsed
1430                        + " ms. Average: "
1431                        + enginePing);
1432            }
1433        }
1434        try
1435        {
1436            log("Creating file");
1437
1438            bench = new FileWriter JavaDoc("bench" + engines + ".txt");
1439
1440            bench.write("#Test file for bench generation\n");
1441            bench.write(new Date JavaDoc().toString());
1442            bench.write("#Total number of users:\n" + userTotal);
1443            bench.write("\n#Avg. rd-trip time:\n" + userPing);
1444            bench.write("\n#Number of engines:\n" + engine.length);
1445            bench.write("\n#Avg rd-trip time:\n" + enginePing);
1446            bench.write("\n#Number of renderings:\n" + totalRender);
1447            bench.write("\n#Avg rendering time:\n" + avgRender);
1448            bench.write('\n');
1449            bench.close();
1450            log("Closing");
1451        }
1452        catch (IOException JavaDoc e)
1453        {
1454            log(e.getMessage());
1455        }
1456
1457        // Popular demand : plot file
1458
try
1459        {
1460            RandomAccessFile JavaDoc plot = new RandomAccessFile JavaDoc("papdc.plot", "rw");
1461
1462            // Goes to EOF
1463
plot.seek(plot.length());
1464            plot.writeChars("#" + new Date JavaDoc().toString() + "\n");
1465            plot.writeChars("" + engines + "\t" + avgRender + "\n");
1466            plot.close();
1467        }
1468        catch (Exception JavaDoc ex)
1469        {
1470            return;
1471        }
1472    }
1473
1474    class C3DDispatcherFrame extends Frame JavaDoc implements ActionListener JavaDoc
1475    {
1476
1477        private MenuItem JavaDoc mi_exit, mi_clear, mi_benchmark;
1478        private Font JavaDoc f_standard = new Font JavaDoc("SansSerif", Font.PLAIN, 12);
1479        private int i_top;
1480
1481        public C3DDispatcherFrame()
1482        {
1483            super("Collaborative 3D Environment - Dispatcher");
1484
1485            setBackground(Color.lightGray);
1486            addWindowListener(new MyWindowListener());
1487            setFont(f_standard);
1488
1489            MenuBar JavaDoc mb = new MenuBar JavaDoc();
1490            Menu JavaDoc m_file = new Menu JavaDoc("File", false);
1491            m_file.setFont(f_standard);
1492            mi_exit = new MenuItem JavaDoc("Exit");
1493            mi_clear = new MenuItem JavaDoc("Clear log");
1494            mi_benchmark = new MenuItem JavaDoc("Benchmarks results");
1495
1496            // Font
1497
mi_clear.setFont(f_standard);
1498            mi_exit.setFont(f_standard);
1499            mi_benchmark.setFont(f_standard);
1500
1501            // Actions
1502
mi_exit.addActionListener(this);
1503            mi_clear.addActionListener(this);
1504            mi_benchmark.addActionListener(this);
1505
1506            m_file.add(mi_clear);
1507            m_file.addSeparator();
1508            m_file.add(mi_exit);
1509            m_file.addSeparator();
1510            m_file.add(mi_benchmark);
1511            mb.add(m_file);
1512            setMenuBar(mb);
1513
1514            GridBagLayout JavaDoc gridbag = new GridBagLayout JavaDoc();
1515            GridBagConstraints JavaDoc c = new GridBagConstraints JavaDoc();
1516            setLayout(gridbag);
1517
1518            Label JavaDoc l_header = new Label JavaDoc("C3D Dispatcher", Label.CENTER);
1519            l_header.setFont(
1520                new Font JavaDoc("SansSerif", Font.ITALIC + Font.BOLD, 18));
1521            c.insets = new Insets JavaDoc(12, 10, 0, 10);
1522            c.weightx = 1.0;
1523            c.gridx = 0;
1524            c.gridy = 0;
1525            c.weighty = 0.0;
1526            c.gridwidth = GridBagConstraints.REMAINDER;
1527            gridbag.setConstraints(l_header, c);
1528            add(l_header);
1529
1530            String JavaDoc s_localhost = "";
1531            try
1532            {
1533                s_localhost = InetAddress.getLocalHost().getCanonicalHostName();
1534            }
1535            catch (UnknownHostException JavaDoc e)
1536            {
1537                s_localhost = "unknown!";
1538            }
1539            Label JavaDoc l_machine =
1540                new Label JavaDoc(
1541                    "on machine: "
1542                        + s_localhost
1543                        + " ("
1544                        + System.getProperty("os.name")
1545                        + " "
1546                        + System.getProperty("os.version")
1547                        + ")");
1548            c.insets = new Insets JavaDoc(0, 10, 5, 10);
1549            c.gridy = 1;
1550            gridbag.setConstraints(l_machine, c);
1551            add(l_machine);
1552
1553            ta_log = new TextArea JavaDoc(10, 35);
1554            ta_log.setEditable(false);
1555
1556            c.anchor = GridBagConstraints.CENTER;
1557            c.weighty = 1.0;
1558            c.gridy++;
1559            c.fill = GridBagConstraints.BOTH;
1560            gridbag.setConstraints(ta_log, c);
1561            add(ta_log);
1562
1563            Label JavaDoc l_users = new Label JavaDoc("List of current users:", Label.LEFT);
1564            c.gridy++;
1565            c.insets = new Insets JavaDoc(5, 10, 0, 10);
1566            c.anchor = GridBagConstraints.WEST;
1567            gridbag.setConstraints(l_users, c);
1568            add(l_users);
1569
1570            li_users = new List JavaDoc(5);
1571            c.gridy++;
1572            gridbag.setConstraints(li_users, c);
1573            add(li_users);
1574
1575            //-----------------------------
1576
// Panel for engines
1577

1578            Panel JavaDoc p_eng = new Panel JavaDoc();
1579            GridBagLayout JavaDoc p_gl = new GridBagLayout JavaDoc();
1580            GridBagConstraints JavaDoc pc = new GridBagConstraints JavaDoc();
1581
1582            p_eng.setLayout(p_gl);
1583            c.gridy++;
1584            c.fill = GridBagConstraints.BOTH;
1585            c.gridwidth = GridBagConstraints.REMAINDER;
1586            //c.weightx=1.0;
1587
// p_eng.setBackground(Color.blue);
1588
gridbag.setConstraints(p_eng, c);
1589            add(p_eng);
1590
1591            Label JavaDoc l_engines = new Label JavaDoc("Available engines:", Label.CENTER);
1592            // pc.anchor=pc.CENTER;
1593
// pc.anchor=pc.center;
1594
pc.weightx = 1.0;
1595            pc.weighty = 1.0;
1596            pc.gridx = 0;
1597            pc.gridy = 0;
1598            pc.insets = new Insets JavaDoc(5, 5, 5, 5);
1599            pc.gridwidth = GridBagConstraints.RELATIVE;
1600            p_gl.setConstraints(l_engines, pc);
1601            p_eng.add(l_engines);
1602
1603            Label JavaDoc l_used = new Label JavaDoc("Engines used:", Label.CENTER);
1604            pc.gridx = 1;
1605            pc.gridwidth = GridBagConstraints.REMAINDER;
1606            p_gl.setConstraints(l_used, pc);
1607            p_eng.add(l_used);
1608
1609            li_enginesAvailable = new List JavaDoc(5);
1610            li_enginesAvailable.setMultipleMode(true);
1611            pc.fill = GridBagConstraints.BOTH;
1612            pc.gridy = 1;
1613            pc.gridx = 0;
1614            pc.gridwidth = GridBagConstraints.RELATIVE;
1615            p_gl.setConstraints(li_enginesAvailable, pc);
1616            p_eng.add(li_enginesAvailable);
1617
1618            li_enginesUsed = new List JavaDoc(5);
1619            li_enginesUsed.setMultipleMode(true);
1620            pc.gridx = 1;
1621            pc.gridwidth = GridBagConstraints.REMAINDER;
1622            p_gl.setConstraints(li_enginesUsed, pc);
1623            p_eng.add(li_enginesUsed);
1624
1625            b_addEng.addActionListener(this);
1626            pc.fill = GridBagConstraints.NONE;
1627            pc.gridx = 0;
1628            pc.gridy = 2;
1629            pc.gridwidth = GridBagConstraints.RELATIVE;
1630            p_gl.setConstraints(b_addEng, pc);
1631            p_eng.add(b_addEng);
1632
1633            b_rmEng.addActionListener(this);
1634            pc.gridwidth = GridBagConstraints.REMAINDER;
1635            pc.gridx = 1;
1636            p_gl.setConstraints(b_rmEng, pc);
1637            p_eng.add(b_rmEng);
1638
1639            pack();
1640            setVisible(true);
1641            toFront();
1642        }
1643
1644        private void exit()
1645        {
1646            try
1647            {
1648// org.objectweb.proactive.ProActive.unregisterVirtualNode(
1649
// vn);
1650
proActiveDescriptor.killall(false);
1651                
1652            }
1653            catch (Exception JavaDoc e)
1654            {
1655                trace("WARNING occurs when killing the application!");
1656                //e.printStackTrace();
1657
}
1658            try
1659            {
1660                setVisible(false);
1661                dispose();
1662                System.exit(0);
1663            }
1664            catch (Exception JavaDoc e)
1665            {
1666                e.printStackTrace();
1667            }
1668        }
1669
1670        public void paint(Graphics JavaDoc g)
1671        {
1672            update(g);
1673        }
1674
1675        public void update(Graphics JavaDoc g)
1676        {
1677            i_top = this.getInsets().top;
1678            g.setColor(Color.gray);
1679            g.drawLine(0, i_top - 1, 2000, i_top - 1);
1680            g.setColor(Color.white);
1681            g.drawLine(0, i_top, 2000, i_top);
1682        }
1683
1684        public void actionPerformed(ActionEvent JavaDoc e)
1685        {
1686            Object JavaDoc source = e.getSource();
1687            if (source == mi_exit)
1688                exit();
1689            else if (source == mi_clear)
1690                ta_log.setText("");
1691            else if (source == mi_benchmark)
1692                doBenchmarks();
1693            else if (source == b_addEng)
1694            {
1695                String JavaDoc sel[] = li_enginesAvailable.getSelectedItems();
1696                if (sel != null)
1697                {
1698                    for (int i = 0; i < sel.length; i++)
1699                    {
1700                        li_enginesUsed.add(sel[i]);
1701                        try
1702                        {
1703                            li_enginesAvailable.remove(sel[i]);
1704                        }
1705                        catch (Exception JavaDoc l_ex)
1706                        {
1707                            l_ex.printStackTrace();
1708                        }
1709                    }
1710                }
1711            }
1712            else if (source == b_rmEng)
1713            {
1714                String JavaDoc sel[] = li_enginesUsed.getSelectedItems();
1715                if (sel != null)
1716                {
1717                    for (int i = 0; i < sel.length; i++)
1718                    {
1719                        li_enginesAvailable.add(sel[i]);
1720                        try
1721                        {
1722                            li_enginesUsed.remove(sel[i]);
1723                        }
1724                        catch (Exception JavaDoc l_ex)
1725                        {
1726                            l_ex.printStackTrace();
1727                        }
1728                    }
1729                }
1730            }
1731        }
1732
1733        /**
1734         * AWT 1.1 event handling for window events
1735         */

1736        class MyWindowListener extends WindowAdapter JavaDoc
1737        {
1738
1739            public void windowClosing(WindowEvent JavaDoc e)
1740            {
1741                exit();
1742            }
1743        }
1744    }
1745
1746}
1747
1748class Election extends Thread JavaDoc
1749{
1750
1751    public static final int UP = 0;
1752    public static final int DOWN = 1;
1753    public static final int LEFT = 2;
1754    public static final int RIGHT = 3;
1755    public static final int CLOCKWISE = 4;
1756    public static final int UNCLOCKWISE = 5;
1757    /**
1758     * Duration of one election round in seconds
1759     */

1760    private static final int WAITSECS = 4;
1761    private static boolean running = false;
1762    private static Hashtable JavaDoc wishes;
1763    private static C3DDispatcher c3ddispatcher;
1764
1765    public Election(int i_user, Integer JavaDoc wish, C3DDispatcher c3ddispatcher)
1766    {
1767        Election.c3ddispatcher = c3ddispatcher;
1768        Election.running = true;
1769        wishes = new Hashtable JavaDoc();
1770        vote(i_user, wish);
1771        c3ddispatcher.showMessage(
1772            i_user,
1773            "Request 'rotate "
1774                + voteString(wish)
1775                + "' submitted, \nnew "
1776                + WAITSECS
1777                + " second election started ...");
1778        c3ddispatcher.showMessageExcept(
1779            i_user,
1780            "New " + WAITSECS + " second election started:");
1781        c3ddispatcher.showMessageExcept(
1782            i_user,
1783            " User "
1784                + c3ddispatcher.nameOfUser(i_user)
1785                + " wants to rotate "
1786                + voteString(wish));
1787
1788        //c3ddispatcher.showDialogExcept(i_user,"Election","An election has been started !");
1789

1790        // Launches the Election thread
1791
this.start();
1792
1793    }
1794
1795    public synchronized void run()
1796    {
1797        try
1798        {
1799            wait(WAITSECS * 1000);
1800        }
1801        catch (InterruptedException JavaDoc e)
1802        {
1803            e.printStackTrace();
1804        }
1805
1806        int score[] = { 0, 0, 0, 0, 0, 0 };
1807
1808        int i_user;
1809
1810        c3ddispatcher.showMessageAll("Election finished");
1811        for (Enumeration JavaDoc e = wishes.keys(); e.hasMoreElements();)
1812        {
1813            i_user = ((Integer JavaDoc) e.nextElement()).intValue();
1814            Integer JavaDoc wish = (Integer JavaDoc) wishes.get(new Integer JavaDoc(i_user));
1815            c3ddispatcher.showMessageAll(
1816                " User "
1817                    + c3ddispatcher.nameOfUser(i_user)
1818                    + " voted '"
1819                    + voteString(wish)
1820                    + "'");
1821
1822            // update the scores
1823
score[wish.intValue()]++;
1824        }
1825        c3ddispatcher.showMessageAll(
1826            " Result:\n "
1827                + score[RIGHT]
1828                + " right, "
1829                + score[LEFT]
1830                + " left [rotate]\n "
1831                + score[UP]
1832                + " up ,"
1833                + score[DOWN]
1834                + " down [vertical]\n "
1835                + score[CLOCKWISE]
1836                + " right,"
1837                + score[UNCLOCKWISE]
1838                + " left [spin]");
1839
1840        // Computes the winner
1841
int winner = -1;
1842        for (int i = 0; i < score.length; i++)
1843        {
1844            // If a candidate has got all the votes
1845
if (score[i] == wishes.size())
1846                winner = i;
1847        }
1848
1849        switch (winner)
1850        {
1851            case UP :
1852                c3ddispatcher.showMessageAll(
1853                    " The scene will be rotated up.");
1854                Election.running = false;
1855                Election.wishes.clear();
1856                c3ddispatcher.rotateUp(0);
1857                break;
1858            case DOWN :
1859                c3ddispatcher.showMessageAll(
1860                    " The scene will be rotated down.");
1861                Election.running = false;
1862                Election.wishes.clear();
1863                c3ddispatcher.rotateDown(0);
1864                break;
1865            case LEFT :
1866                c3ddispatcher.showMessageAll(
1867                    " The scene will be rotated left.");
1868                Election.running = false;
1869                Election.wishes.clear();
1870                c3ddispatcher.rotateLeft(0);
1871                break;
1872            case RIGHT :
1873                c3ddispatcher.showMessageAll(
1874                    " The scene will be rotated right.");
1875                Election.running = false;
1876                Election.wishes.clear();
1877                c3ddispatcher.rotateRight(0);
1878                break;
1879            case CLOCKWISE :
1880                c3ddispatcher.showMessageAll(
1881                    " The scene will be spinned right");
1882                Election.running = false;
1883                Election.wishes.clear();
1884                c3ddispatcher.spinClock(0);
1885                break;
1886            case UNCLOCKWISE :
1887                c3ddispatcher.showMessageAll(
1888                    " The scene will be spinned left");
1889                Election.running = false;
1890                Election.wishes.clear();
1891                c3ddispatcher.spinUnclock(0);
1892                break;
1893            default :
1894                c3ddispatcher.showMessageAll(
1895                    " No consensus found, vote again please!");
1896        }
1897
1898        Election.running = false;
1899        Election.wishes.clear();
1900    }
1901
1902    public synchronized static int vote(int i_user, Integer JavaDoc wish)
1903    {
1904        if (wishes.containsKey(new Integer JavaDoc(i_user)))
1905            c3ddispatcher.showMessage(
1906                i_user,
1907                "You have already voted in this round");
1908        else
1909            wishes.put(new Integer JavaDoc(i_user), wish);
1910        return wishes.size();
1911    }
1912
1913    public synchronized static boolean isRunning()
1914    {
1915        return running;
1916    }
1917
1918    public String JavaDoc voteString(Integer JavaDoc wish)
1919    {
1920        String JavaDoc ret;
1921        switch (wish.intValue())
1922        {
1923            case UP :
1924                ret = "up";
1925                break;
1926            case DOWN :
1927                ret = "down";
1928                break;
1929            case LEFT :
1930                ret = "left";
1931                break;
1932            case RIGHT :
1933                ret = "right";
1934                break;
1935            case CLOCKWISE :
1936                ret = "clockwise";
1937                break;
1938            case UNCLOCKWISE :
1939                ret = "unclockwise";
1940                break;
1941            default :
1942                ret = "error";
1943                break;
1944        }
1945        return ret;
1946    }
1947
1948    public synchronized void finish()
1949    {
1950        c3ddispatcher.showMessageAll("Everybody voted");
1951        this.notify();
1952    }
1953}
1954
1955class User
1956{
1957
1958    private String JavaDoc name;
1959    private C3DUser c3duser;
1960
1961    User(String JavaDoc name, C3DUser c3duser)
1962    {
1963        this.name = name;
1964        this.c3duser = c3duser;
1965    }
1966
1967    String JavaDoc getName()
1968    {
1969        return name;
1970    }
1971
1972    C3DUser getObject()
1973    {
1974        return c3duser;
1975    }
1976}
1977
Popular Tags