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 }