001         package com.croftsoft.apps.tag3d;
002    
003         import java.rmi.*;
004         import java.util.HashMap;
005         import java.util.Map;
006    
007         import javax.media.j3d.*;
008    
009         import com.croftsoft.core.media.j3d.Transform3DState;
010         import com.croftsoft.core.util.state.*;
011    
012         /*********************************************************************
013         * Bidirectional routing of Transform3DState updates.
014         *
015         * @author
016         *   <A HREF="http://www.alumni.caltech.edu/~croft/">David W. Croft</A>
017         * @version
018         *   1999-02-07
019         *********************************************************************/
020    
021         public class  Tag3DStateManager
022           implements StateListener, StateMulticaster
023         //////////////////////////////////////////////////////////////////////
024         //////////////////////////////////////////////////////////////////////
025         {
026    
027         protected Map               stateMap = new HashMap ( );
028    
029         protected StateMulticaster  stateMulticaster;
030         protected Tag3DWorld        tag3DWorld;
031         protected String            id;
032    
033         //////////////////////////////////////////////////////////////////////
034         //////////////////////////////////////////////////////////////////////
035    
036         /*********************************************************************
037         * Establishes the objects for bidirectional communication.
038         *
039         * @param  stateMulticaster
040         *   All of Tag3DStateManager StateMulticaster interface method calls
041         *   are relayed to the StateMulticaster implementation provided by
042         *   this argument.
043         * @param  tag3DWorld
044         *   Updated when the State events are received via the StateListener
045         *   method.
046         * @param  id
047         *   The unique identifier for this particular client.
048         *********************************************************************/
049         public  Tag3DStateManager (
050           StateMulticaster  stateMulticaster,
051           Tag3DWorld        tag3DWorld,
052           String            id )
053         //////////////////////////////////////////////////////////////////////
054         {
055           this.stateMulticaster = stateMulticaster;
056           this.tag3DWorld       = tag3DWorld;
057           this.id               = id;
058    
059           stateMap.put ( id, tag3DWorld.viewTransformGroup );
060    
061           addStateListener ( this );
062         }
063    
064         /*********************************************************************
065         * this ( new QueuedStateMulticaster ( ), tag3DWorld, id );
066         *********************************************************************/
067         public  Tag3DStateManager (
068           Tag3DWorld        tag3DWorld,
069           String            id )
070         //////////////////////////////////////////////////////////////////////
071         {
072           this ( new QueuedStateMulticaster ( ), tag3DWorld, id );
073         }
074    
075         //////////////////////////////////////////////////////////////////////
076         // StateListener interface method
077         //////////////////////////////////////////////////////////////////////
078    
079         /*********************************************************************
080         * Handles Transform3DState update events from the StateMulticaster.
081         * Updates the appropriate transformGroup in the stateMap as keyed by
082         * the State key.  If the key does not exist in the stateMap, updates
083         * the tag3DWorld with a newly created transformGroup and adds it to
084         * the stateMap.
085         *********************************************************************/
086         public void  stateListen ( State  state )
087         //////////////////////////////////////////////////////////////////////
088         {
089           if ( !( state instanceof Transform3DState ) ) return;
090    
091           String  key = ( String ) state.getKey ( );
092           Transform3D  transform3D = new Transform3D ( );
093           ( ( Transform3DState ) state ).getTransform3D ( transform3D );
094    
095           TransformGroup  transformGroup = null;
096    
097           synchronized ( stateMap )
098           {
099             transformGroup = ( TransformGroup ) stateMap.get ( key );
100    
101             // If no transformGroup currently exists for this I.D. key,
102             // create one; otherwise, update it.
103    
104             if ( transformGroup == null )
105             {
106               transformGroup = tag3DWorld.addHead ( key, transform3D );
107               stateMap.put ( key, transformGroup );
108             }
109             else
110             {
111               transformGroup.setTransform ( transform3D );
112             }
113           }
114         }
115    
116         //////////////////////////////////////////////////////////////////////
117         // StateMulticaster interface methods
118         //////////////////////////////////////////////////////////////////////
119    
120         public void  update ( State  state )
121         //////////////////////////////////////////////////////////////////////
122         {
123           stateMulticaster.update ( state );
124         }
125    
126         public boolean  addStateListener ( StateListener  stateListener )
127         //////////////////////////////////////////////////////////////////////
128         {
129           return stateMulticaster.addStateListener ( stateListener );
130         }
131    
132         public boolean  removeStateListener ( StateListener  stateListener )
133         //////////////////////////////////////////////////////////////////////
134         {
135           return stateMulticaster.removeStateListener ( stateListener );
136         }
137    
138         //////////////////////////////////////////////////////////////////////
139         //////////////////////////////////////////////////////////////////////
140    
141         /*********************************************************************
142         * Sets up this Tag3DStateManager object to use a remote
143         * StateMulticaster and subscribes itself as a remote StateListener.
144         *
145         * <P>
146         *
147         * If the remote StateMulticaster cannot be contacted, an attempt will
148         * be made to establish this Tag3DStateManager object as the remote
149         * StateMulticaster.
150         *
151         * @param  remoteName
152         *   The RMI URL of the remote StateMulticaster.
153         *********************************************************************/
154         public void  setupRemote ( String  remoteName )
155         //////////////////////////////////////////////////////////////////////
156         {
157           try
158           {
159             StateMulticasterRemote  stateMulticasterRemote = null;
160    
161             try
162             {
163               stateMulticasterRemote
164                 = ( StateMulticasterRemote ) Naming.lookup ( remoteName );
165               stateMulticaster
166                 = new StateMulticasterAmbassador ( stateMulticasterRemote );
167               StateListenerRemote  stateListenerRemote
168                 = new StateListenerProxy ( this );
169               Naming.rebind ( id, stateListenerRemote );
170               addStateListener ( new StateListenerAmbassador (
171                 stateListenerRemote ) );
172             }
173             catch ( Exception  ex )
174             {
175             }
176    
177             if ( stateMulticasterRemote == null )
178             {
179               stateMulticasterRemote = new StateMulticasterProxy ( this );
180               Naming.rebind ( remoteName, stateMulticasterRemote );
181             }
182           }
183           catch ( Exception  ex )
184           {
185             ex.printStackTrace ( );
186           }
187         }
188    
189         //////////////////////////////////////////////////////////////////////
190         //////////////////////////////////////////////////////////////////////
191         }