- Timestamp:
- 02/07/09 14:47:49 (13 years ago)
- Location:
- chess
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
chess/chess.jad
r28 r29 1 1 MIDlet-1: Chess Game, , chess.ui.ChessMIDlet 2 MIDlet-Jar-Size: 3112142 MIDlet-Jar-Size: 85700 3 3 MIDlet-Jar-URL: chess.jar 4 4 MIDlet-Name: Chess 5 5 MIDlet-Vendor: I am 6 MIDlet-Version: 1.1. 36 MIDlet-Version: 1.1.5 7 7 MicroEdition-Configuration: CLDC-1.0 8 8 MicroEdition-Profile: MIDP-2.0 -
chess/src/chess/Util.java
r28 r29 1 1 package chess; 2 2 3 import java.io.PrintStream; 4 import java.io.OutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 3 import java.io.*; 8 4 import javax.microedition.rms.RecordStore; 9 5 10 6 import chess.remote.IRemote; 11 7 import chess.remote.impl.BTRemote; 12 import chess.remote.impl.debug.DebugRemote;13 8 14 9 … … 31 26 32 27 public static IRemote create() throws Exception { 33 //return new BTRemote();34 return new DebugRemote( 500, 500 );28 return new BTRemote(); 29 // return new DebugRemote( 500, 500 ); 35 30 } 36 31 -
chess/src/chess/control/BaseController.java
r28 r29 168 168 169 169 public synchronized void setStatus( final int status ) { 170 //todo171 170 this.status = status; 172 171 switch ( status ) { -
chess/src/chess/game/units/Bishop.java
r19 r29 7 7 /** 8 8 * Ñëîí 9 * todo implement10 9 * User: BegemoT<br/> 11 10 * Date: 29.01.2009<br/> -
chess/src/chess/game/units/King.java
r19 r29 8 8 /** 9 9 * Êîðîëü 10 * todo implement11 10 * User: BegemoT<br/> 12 11 * Date: 29.01.2009<br/> -
chess/src/chess/remote/IAsyncProcess.java
r27 r29 6 6 */ 7 7 public interface IAsyncProcess { 8 public static final int NOT_STARTED = -1; 8 9 public static final int IN_PROCESS = 0; 9 10 public static final int SUCCEEDED = 1; … … 13 14 public int status(); 14 15 15 public void interrupt( final boolean waitFor);16 public void stop( final int waitMillis ); 16 17 17 18 public IAsyncProcessListener getListener(); -
chess/src/chess/remote/impl/BTNode.java
r25 r29 21 21 */ 22 22 public class BTNode implements IRemoteNode, Runnable { 23 /** 24 * êàíàë BT, èñïîëüçóåìûé íàøèì ïðèëîæåíèåì 25 * todo ïîíÿòü, êàêèå êàíàëû ñóùåñòâóþò 26 */ 27 private static final String BT_STREAM = "1"; 28 29 private String name; 30 31 private RemoteDevice device; 32 private IConnectionListener listener = null; 33 private StreamConnection connection = null; 34 35 private transient InputStream in; 36 private transient OutputStream out; 37 private transient Thread pump; 38 39 /** 40 * ìîíèòîð îæèäàíèÿ îòêðûòèÿ ñîåäèíåíèÿ 41 */ 42 private final Object connectLock = new Object(); 43 44 private final Object queueOverloadedLock = new Object(); 45 private final IDatagram[] postQueue = new IDatagram[2]; 46 47 48 public BTNode( final RemoteDevice device ) throws IOException { 49 this( device, null ); 50 } 51 52 public BTNode( final StreamConnection conn ) throws IOException { 53 this( null, null, conn ); 54 } 55 56 public BTNode( final RemoteDevice device, 57 final StreamConnection conn ) throws IOException { 58 this( null, device, conn ); 59 } 60 61 public BTNode( final String name, 62 final RemoteDevice device, 63 final StreamConnection conn ) throws IOException { 64 if ( device == null && conn == null ) { 65 throw new IllegalArgumentException( "No-no-no, David Blain! device=null && conn=null" ); 66 } 67 68 if ( device == null ) { 69 this.device = RemoteDevice.getRemoteDevice( conn ); 70 } else { 71 this.device = device; 72 } 73 if ( name == null ) { 74 this.name = this.device.getFriendlyName( true ); 75 } else { 76 this.name = name; 77 } 78 connection = conn; 79 } 80 81 public BTNode( final String name, 82 final StreamConnection conn ) throws IOException { 83 this( name, null, conn ); 84 } 85 86 public String getName() { 87 return name; 88 } 89 90 public synchronized void start() { 91 checkNotClosed(); 92 if ( !isStartCalled() ) { 93 pump = new Thread( this, "network pump" ); 94 pump.start(); 95 } 96 } 97 98 public synchronized void setListener( final IConnectionListener l ) { 99 if ( l != null && isClosed() ) { 100 throw new IllegalStateException( "Node is closed - lsitener is useless" ); 101 } 102 this.listener = l; 103 } 104 105 public void send( final IDatagram data ) { 106 checkPumpActive(); 107 synchronized ( connectLock ) { 108 while ( !isConnected() && !isClosed() ) { 109 try { 110 connectLock.wait( 250 ); 111 } catch ( InterruptedException e ) { 112 e.printStackTrace(); 113 } 114 } 115 } 116 //áëîêèðóåì this ÷òîáû íàñ íå çàêðûëè íåâîâðåìÿ 117 while ( true ) { 118 synchronized ( this ) { 119 checkConnected(); 120 try { 121 synchronized ( postQueue ) { 122 //áëîêèðóåì î÷åðåäü, ÷òîáû ïðåäóïðåäèòü åå èçìåíåíèÿ 123 for ( int i = 0; i < postQueue.length; i++ ) { 124 if ( postQueue[i] == null ) { 125 postQueue[i] = data; 126 return; 127 } 128 } 129 } 130 } finally { 131 notifyAll();//push pump to run/ïèíàåì íàøåãî ïî÷òàëüîíà 132 } 133 } 134 //åñëè î÷åðåäü ïåðåïîëíåíà -- âûíóæäåíû æäàòü 135 synchronized ( queueOverloadedLock ) { 136 try { 137 queueOverloadedLock.wait( 250 ); 138 } catch ( InterruptedException e ) { 139 e.printStackTrace(); 140 } 141 } 142 } 143 //todo ýòî áû òîæå íåïëîõî áû âíåñòè â run() -- à òî áóäåò áëîêèðîâàòüñÿ EDT 144 //try { 145 // final GenericDatagram gdata = new GenericDatagram( data ); 146 // gdata.write( out ); 147 //} catch ( IOException ex ) { 148 // ex.printStackTrace(); 149 // throw new RuntimeException( ex.getMessage() ); 150 //} 151 //if ( listener != null ) { 152 // listener.wasSent( data ); 153 //} 154 } 155 156 public void run() { 157 try { 158 synchronized ( this ) { 159 if ( isClosed() ) { 160 return; 161 } 162 openPipeline(); 163 } 164 if ( listener != null ) { 165 listener.connected(); 166 } 167 synchronized ( connectLock ) { 168 connectLock.notifyAll(); 169 } 170 final GenericDatagram data = new GenericDatagram(); 171 while ( !isClosed() ) { 172 synchronized ( this ) { 173 final int timeout; 174 //îòïðàâëÿåì íåîòïðàâëåííîå 175 synchronized ( postQueue ) { 176 for ( int i = 0; i < postQueue.length; i++ ) { 177 final IDatagram packet = postQueue[i]; 178 if ( packet != null ) { 179 data.setWrapped( packet ); 180 data.write( out ); 181 postQueue[i] = null; 182 if ( listener != null ) { 183 listener.wasSent( packet ); 184 } 185 } 186 } 187 } 188 synchronized ( queueOverloadedLock ) { 189 //îïîâåùàåì, ÷òî î÷åðåäü îñâîáîäèëàñü 190 queueOverloadedLock.notifyAll(); 191 } 192 //÷èòàåì íåäî÷èòàííîå 193 if ( in.available() > 0 ) { 194 data.read( in ); 195 if ( listener != null ) { 196 listener.received( data.wrapped() ); 197 } 198 timeout = 50; 199 } else { 200 timeout = 250; 201 } 202 try { 203 wait( timeout ); 204 } catch ( InterruptedException e ) { 205 } 206 } 207 } 208 } catch ( Throwable e ) { 209 e.printStackTrace(); 210 } finally { 211 pump = null; 212 close(); 213 } 214 } 215 216 public synchronized void close() { 217 if ( isClosed() ) { 218 return; 219 } 220 if ( pump != null && pump.isAlive() ) { 221 pump.interrupt(); 222 if ( pump != Thread.currentThread() ) { 223 try { 224 pump.join(); 225 } catch ( InterruptedException e ) { 226 e.printStackTrace(); 227 } 228 } 229 } 230 if ( in != null ) { 231 synchronized ( in ) { 232 try { 233 in.close(); 234 } catch ( IOException e ) { 235 e.printStackTrace(); 236 } finally { 237 in = null; 238 } 239 } 240 } 241 if ( out != null ) { 242 synchronized ( out ) { 243 try { 244 out.close(); 245 } catch ( IOException e ) { 246 e.printStackTrace(); 247 } finally { 248 out = null; 249 } 250 } 251 } 252 if ( connection != null ) { 253 try { 254 connection.close(); 255 } catch ( IOException e ) { 256 e.printStackTrace(); 257 } finally { 258 connection = null; 259 } 260 } 261 if ( listener != null ) { 262 listener.closed(); 263 } 264 pump = null; 265 device = null; 266 } 267 268 private void openPipeline() throws IOException { 269 if ( connection == null ) { 270 final String addr = getBluetoothURL( device ); 271 connection = ( StreamConnection )Connector.open( addr, Connector.READ_WRITE, true ); 272 } 273 if ( in == null ) { 274 try { 275 in = connection.openInputStream(); 276 } catch ( IOException ex ) { 277 ex.printStackTrace(); 278 throw new RuntimeException( "Can't open input stream:" + ex.getMessage() ); 279 } 280 } 281 if ( out == null ) { 282 try { 283 out = connection.openOutputStream(); 284 } catch ( IOException ex ) { 285 ex.printStackTrace(); 286 throw new RuntimeException( "Can't open output stream:" + ex.getMessage() ); 287 } 288 } 289 } 290 291 public String toString() { 292 return getName(); 293 } 294 295 private void checkNotClosed() { 296 if ( isClosed() ) { 297 throw new IllegalStateException( "Node already closed" ); 298 } 299 } 300 301 private void checkPumpActive() { 302 checkNotClosed(); 303 if ( !isStartCalled() ) { 304 throw new IllegalStateException( ".start() not called" ); 305 } 306 } 307 308 private void checkConnected() { 309 checkNotClosed(); 310 checkPumpActive(); 311 if ( !isConnected() ) { 312 throw new IllegalStateException( "Node not connected" ); 313 } 314 } 315 316 private boolean isClosed() { 317 return device == null; 318 } 319 320 private boolean isStartCalled() { 321 return pump != null; 322 } 323 324 private boolean isConnected() { 325 return connection != null && in != null && out != null; 326 } 327 328 329 private static String getBluetoothURL( final RemoteDevice device ) { 330 return BTRemote.BTSPP_SCHEME + device.getBluetoothAddress() + ":" + BT_STREAM; 331 } 23 /** 24 * êàíàë BT, èñïîëüçóåìûé íàøèì ïðèëîæåíèåì 25 * todo ïîíÿòü, êàêèå êàíàëû ñóùåñòâóþò 26 */ 27 private static final String BT_STREAM = "1"; 28 29 private String name; 30 31 private RemoteDevice device; 32 private IConnectionListener listener = null; 33 private StreamConnection connection = null; 34 35 private transient InputStream in; 36 private transient OutputStream out; 37 private transient Thread pump; 38 39 /** ìîíèòîð îæèäàíèÿ îòêðûòèÿ ñîåäèíåíèÿ */ 40 private final Object connectLock = new Object(); 41 42 private final Object queueOverloadedLock = new Object(); 43 private final IDatagram[] postQueue = new IDatagram[2]; 44 45 46 public BTNode( final RemoteDevice device ) throws IOException { 47 this( device, null ); 48 } 49 50 public BTNode( final StreamConnection conn ) throws IOException { 51 this( null, null, conn ); 52 } 53 54 public BTNode( final RemoteDevice device, 55 final StreamConnection conn ) throws IOException { 56 this( null, device, conn ); 57 } 58 59 public BTNode( final String name, 60 final RemoteDevice device, 61 final StreamConnection conn ) throws IOException { 62 if( device == null && conn == null ) { 63 throw new IllegalArgumentException( "No-no-no, David Blain! device=null && conn=null" ); 64 } 65 66 if( device == null ) { 67 this.device = RemoteDevice.getRemoteDevice( conn ); 68 } else { 69 this.device = device; 70 } 71 if( name == null ) { 72 this.name = this.device.getFriendlyName( true ); 73 } else { 74 this.name = name; 75 } 76 connection = conn; 77 } 78 79 public BTNode( final String name, 80 final StreamConnection conn ) throws IOException { 81 this( name, null, conn ); 82 } 83 84 public String getName() { 85 return name; 86 } 87 88 public synchronized void start() { 89 checkNotClosed(); 90 if( !isStartCalled() ) { 91 pump = new Thread( this, "network pump" ); 92 pump.start(); 93 } 94 } 95 96 public synchronized void setListener( final IConnectionListener l ) { 97 if( l != null && isClosed() ) { 98 throw new IllegalStateException( "Node is closed - lsitener is useless" ); 99 } 100 this.listener = l; 101 } 102 103 public void send( final IDatagram data ) { 104 checkPumpActive(); 105 synchronized( connectLock ) { 106 while( !isConnected() && !isClosed() ) { 107 try { 108 connectLock.wait( 250 ); 109 } catch( InterruptedException e ) { 110 e.printStackTrace(); 111 } 112 } 113 } 114 //áëîêèðóåì this ÷òîáû íàñ íå çàêðûëè íåâîâðåìÿ 115 while( true ) { 116 synchronized( this ) { 117 checkConnected(); 118 try { 119 synchronized( postQueue ) { 120 //áëîêèðóåì î÷åðåäü, ÷òîáû ïðåäóïðåäèòü åå èçìåíåíèÿ 121 for( int i = 0; i < postQueue.length; i++ ) { 122 if( postQueue[i] == null ) { 123 postQueue[i] = data; 124 return; 125 } 126 } 127 } 128 } finally { 129 notifyAll();//push pump to run/ïèíàåì íàøåãî ïî÷òàëüîíà 130 } 131 } 132 //åñëè î÷åðåäü ïåðåïîëíåíà -- âûíóæäåíû æäàòü 133 synchronized( queueOverloadedLock ) { 134 try { 135 queueOverloadedLock.wait( 250 ); 136 } catch( InterruptedException e ) { 137 e.printStackTrace(); 138 } 139 } 140 } 141 } 142 143 public void run() { 144 try { 145 synchronized( this ) { 146 if( isClosed() ) { 147 return; 148 } 149 openPipeline(); 150 } 151 if( listener != null ) { 152 listener.connected(); 153 } 154 synchronized( connectLock ) { 155 connectLock.notifyAll(); 156 } 157 final GenericDatagram data = new GenericDatagram(); 158 while( !isClosed() ) { 159 synchronized( this ) { 160 final int timeout; 161 //îòïðàâëÿåì íåîòïðàâëåííîå 162 synchronized( postQueue ) { 163 for( int i = 0; i < postQueue.length; i++ ) { 164 final IDatagram packet = postQueue[i]; 165 if( packet != null ) { 166 data.setWrapped( packet ); 167 data.write( out ); 168 postQueue[i] = null; 169 if( listener != null ) { 170 listener.wasSent( packet ); 171 } 172 } 173 } 174 } 175 synchronized( queueOverloadedLock ) { 176 //îïîâåùàåì, ÷òî î÷åðåäü îñâîáîäèëàñü 177 queueOverloadedLock.notifyAll(); 178 } 179 //÷èòàåì íåäî÷èòàííîå 180 if( in.available() > 0 ) { 181 data.read( in ); 182 if( listener != null ) { 183 listener.received( data.wrapped() ); 184 } 185 timeout = 50; 186 } else { 187 timeout = 250; 188 } 189 try { 190 wait( timeout ); 191 } catch( InterruptedException e ) { 192 } 193 } 194 } 195 } catch( Throwable e ) { 196 e.printStackTrace(); 197 } finally { 198 pump = null; 199 close(); 200 } 201 } 202 203 public synchronized void close() { 204 if( isClosed() ) { 205 return; 206 } 207 if( pump != null && pump.isAlive() ) { 208 pump.interrupt(); 209 if( pump != Thread.currentThread() ) { 210 try { 211 pump.join(); 212 } catch( InterruptedException e ) { 213 e.printStackTrace(); 214 } 215 } 216 } 217 if( in != null ) { 218 try { 219 in.close(); 220 } catch( IOException e ) { 221 e.printStackTrace(); 222 } finally { 223 in = null; 224 } 225 } 226 if( out != null ) { 227 try { 228 out.close(); 229 } catch( IOException e ) { 230 e.printStackTrace(); 231 } finally { 232 out = null; 233 } 234 } 235 if( connection != null ) { 236 try { 237 connection.close(); 238 } catch( IOException e ) { 239 e.printStackTrace(); 240 } finally { 241 connection = null; 242 } 243 } 244 if( listener != null ) { 245 listener.closed(); 246 } 247 pump = null; 248 device = null; 249 } 250 251 private void openPipeline() throws IOException { 252 if( connection == null ) { 253 final String addr = getBluetoothURL( device ); 254 connection = ( StreamConnection ) Connector.open( addr, Connector.READ_WRITE, true ); 255 } 256 if( in == null ) { 257 try { 258 in = connection.openInputStream(); 259 } catch( IOException ex ) { 260 ex.printStackTrace(); 261 throw new RuntimeException( "Can't open input stream:" + ex.getMessage() ); 262 } 263 } 264 if( out == null ) { 265 try { 266 out = connection.openOutputStream(); 267 } catch( IOException ex ) { 268 ex.printStackTrace(); 269 throw new RuntimeException( "Can't open output stream:" + ex.getMessage() ); 270 } 271 } 272 } 273 274 public String toString() { 275 return getName(); 276 } 277 278 private void checkNotClosed() { 279 if( isClosed() ) { 280 throw new IllegalStateException( "Node already closed" ); 281 } 282 } 283 284 private void checkPumpActive() { 285 checkNotClosed(); 286 if( !isStartCalled() ) { 287 throw new IllegalStateException( ".start() not called" ); 288 } 289 } 290 291 private void checkConnected() { 292 checkNotClosed(); 293 checkPumpActive(); 294 if( !isConnected() ) { 295 throw new IllegalStateException( "Node not connected" ); 296 } 297 } 298 299 private boolean isClosed() { 300 return device == null; 301 } 302 303 private boolean isStartCalled() { 304 return pump != null; 305 } 306 307 private boolean isConnected() { 308 return connection != null && in != null && out != null; 309 } 310 311 312 private static String getBluetoothURL( final RemoteDevice device ) { 313 return BTRemote.BTSPP_SCHEME + device.getBluetoothAddress() + ":" + BT_STREAM; 314 } 332 315 } -
chess/src/chess/remote/impl/BTRemote.java
r27 r29 20 20 */ 21 21 public class BTRemote implements IRemote { 22 public static final String BTSPP_SCHEME = "btspp://"; 23 public static final String MY_SERVICE_NUMBER = "3B9FA89520078C303355AAA694238F08;name=ChessGameServer"; 24 25 public static final IRemoteNode[] EMPTY = new IRemoteNode[0]; 26 27 private final LocalDevice localDevice; 28 private final Vector devices = new Vector(); 29 30 public BTRemote() throws Exception { 31 localDevice = LocalDevice.getLocalDevice(); 32 fillupCache(); 33 } 34 35 private synchronized void fillupCache() { 36 final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 37 final RemoteDevice[] preknownDevices = agent.retrieveDevices( DiscoveryAgent.PREKNOWN ); 38 if ( preknownDevices != null ) { 39 for ( int i = 0; i < preknownDevices.length; i++ ) { 40 final RemoteDevice device = preknownDevices[i]; 41 devices.addElement( device ); 42 } 43 } 44 final RemoteDevice[] cachedDevices = agent.retrieveDevices( DiscoveryAgent.CACHED ); 45 if ( cachedDevices != null ) { 46 for ( int i = 0; i < cachedDevices.length; i++ ) { 47 final RemoteDevice device = cachedDevices[i]; 48 devices.addElement( device ); 49 } 50 } 51 } 52 53 private synchronized void refreshCache() { 54 devices.removeAllElements(); 55 fillupCache(); 56 } 57 58 public IAsyncProcess waitForIncoming( final IServerListener l ) { 59 return new WaitForIncomingThread( localDevice, l ); 60 } 61 62 public IAsyncProcess getAvailable( final boolean refresh, 63 final IClientListener l ) { 64 if ( refresh ) { 65 try { 66 final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 67 return new QueryDeviceProcess( this, agent, l ); 68 } catch ( Exception e ) { 69 e.printStackTrace(); 70 l.finished( null ); 71 return null; 72 } 73 } else { 74 final IRemoteNode[] nodes = getNodes(); 75 l.finished( nodes ); 76 return null; 77 } 78 } 79 80 private synchronized IRemoteNode[] getNodes() { 81 if ( devices.isEmpty() ) { 82 return EMPTY; 83 } 84 final int length = devices.size(); 85 final IRemoteNode[] nodes = new IRemoteNode[length]; 86 for ( int i = 0; i < length; i++ ) { 87 try { 88 final RemoteDevice device = ( RemoteDevice )devices.elementAt( i ); 89 final BTNode node = new BTNode( device ); 90 nodes[i] = node; 91 } catch ( IOException e ) { 92 e.printStackTrace(); 93 } 94 } 95 return nodes; 96 } 97 98 private static class WaitForIncomingThread extends BaseAsyncProcess { 99 private final LocalDevice localDevice; 100 private StreamConnectionNotifier server; 101 102 public WaitForIncomingThread( final LocalDevice local, 103 final IServerListener listener ) { 104 super( listener ); 105 this.localDevice = local; 106 start(); 107 } 108 109 public void run() { 110 try { 111 localDevice.setDiscoverable( DiscoveryAgent.GIAC ); 112 setStatus( IN_PROCESS ); 113 while ( true ) { 114 server = ( StreamConnectionNotifier )Connector.open( 115 BTSPP_SCHEME + "localhost:" + MY_SERVICE_NUMBER, 116 Connector.READ_WRITE, 117 true 118 ); 119 Util.log.println( "creating server and waiting for incoming" ); 120 try { 121 final IServerListener _listener = ( IServerListener )listener; 122 while ( true ) { 123 // Îæèäàåì âõîäÿùåå ïîòîêîâîå ñîåäèíåíèå 124 final StreamConnection conn = server.acceptAndOpen(); 125 Util.log.println( "accepted incoming: " + conn ); 126 final BTNode client = new BTNode( conn ); 127 if ( _listener.incoming( client ) ) { 128 //åñëè êëèåíò ïðèíÿò -- âûõîäèì (èãðà äîïóñêàåò òîëüêî îäíîãî ñîïåðíèêà) 129 Util.log.println( "client accepted -> close server" ); 130 setStatus( SUCCEEDED ); 131 return; 132 } 133 client.close(); 134 } 135 } catch ( InterruptedIOException ex ) { 136 setStatus( INTERRUPTED ); 137 Util.log.println( "server was closed: " + ex.getMessage() ); 138 return; 139 } catch ( IOException ex ) { 140 Util.log.println( "server got error -- trying to recreate server connection" ); 141 ex.printStackTrace(); 142 } finally { 143 if ( server != null ) { 144 try { 145 server.close(); 146 server = null; 147 } catch ( IOException e ) { 148 e.printStackTrace(); 149 } 150 } 151 } 152 } 153 } catch ( IOException ex ) { 154 //åñëè íå óäàëîñü îòêðûòü ñîåäèíåíèå -- ýòî ïèçäåö. óõîäèì 155 //...íå óäàëîñü îïóáëèêîâàòü óñòðîéñòâî -- ïèçäåö, óõîäèì 156 ex.printStackTrace(); 157 setStatus( FAILED ); 158 } finally { 159 listener.finished( null ); 160 Util.log.println( "server stopped" ); 161 } 162 } 163 164 public void interrupt( final boolean waitFor ) { 165 if ( isAlive() ) { 166 if ( server != null ) { 167 try { 168 server.close(); 169 server = null; 170 } catch ( IOException e ) { 171 e.printStackTrace(); 172 } 173 } 174 waitForThread( waitFor ); 175 } 176 } 177 178 } 179 180 private static class QueryDeviceProcess extends BaseAsyncProcess implements DiscoveryListener { 181 private final DiscoveryAgent agent; 182 private final BTRemote remote; 183 184 public QueryDeviceProcess( final BTRemote remote, 185 final DiscoveryAgent agent, 186 final IClientListener listener ) { 187 super( listener ); 188 this.remote = remote; 189 this.agent = agent; 190 start(); 191 } 192 193 public void run() { 194 /* Íåïîíÿòíî, ÿâëÿåòñÿ ëè ýòîò çàïðîñ ñèíõðîííûì, èëè àñèíõðîííûì -- 195 * äîêóìåíòàöèÿ íà ýòîò ñ÷åò ìîë÷èò, à ïðàêòèêà ïîêàçûâàåò, ÷òî 196 * áûâàåò è òàê è ýäàê. Ïîýòîìó ñòðàõóåìñÿ íà âñÿêèé ñëó÷àé îò 197 * íåâåäîìîé õóéíè è äåëàåì ýòî â îòäåëüíîì ïîòîêå 198 */ 199 setStatus( IN_PROCESS ); 200 Util.log.println( "starting query device list" ); 201 try { 202 agent.startInquiry( DiscoveryAgent.GIAC, this ); 203 } catch ( BluetoothStateException e ) { 204 e.printStackTrace(); 205 setStatus( FAILED ); 206 listener.finished( null ); 207 } 208 } 209 210 211 public void interrupt( final boolean waitFor ) { 212 if ( status() == IN_PROCESS ) { 213 agent.cancelInquiry( this ); 214 waitForThread( waitFor ); 215 } 216 } 217 218 public void deviceDiscovered( final RemoteDevice btDevice, 219 final DeviceClass cod ) { 220 Util.log.println( "device found:" + btDevice.getBluetoothAddress() ); 221 } 222 223 public void servicesDiscovered( final int transID, 224 final ServiceRecord[] servRecord ) { 225 Util.log.println( "service found:" + transID ); 226 } 227 228 public void serviceSearchCompleted( final int transID, 229 final int respCode ) { 230 231 } 232 233 public void inquiryCompleted( final int discType ) { 234 switch ( discType ) { 235 case INQUIRY_COMPLETED: 236 Util.log.println( "device list query finished" ); 237 remote.refreshCache(); 238 setStatus( SUCCEEDED ); 239 listener.finished( remote.getNodes() ); 240 break; 241 case INQUIRY_TERMINATED: 242 Util.log.println( "device list query interrupted" ); 243 setStatus( INTERRUPTED ); 244 listener.finished( null ); 245 break; 246 case INQUIRY_ERROR: 247 Util.log.println( "device list query failed" ); 248 setStatus( FAILED ); 249 listener.finished( null ); 250 break; 251 } 252 } 253 } 22 public static final String BTSPP_SCHEME = "btspp://"; 23 public static final String MY_SERVICE_NUMBER = "3B9FA89520078C303355AAA694238F08;name=ChessGameServer"; 24 25 public static final IRemoteNode[] EMPTY = new IRemoteNode[0]; 26 27 private final LocalDevice localDevice; 28 private final Vector devices = new Vector(); 29 30 public BTRemote() throws Exception { 31 localDevice = LocalDevice.getLocalDevice(); 32 fillupCache(); 33 } 34 35 private synchronized void fillupCache() { 36 final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 37 final RemoteDevice[] preknownDevices = agent.retrieveDevices( DiscoveryAgent.PREKNOWN ); 38 if( preknownDevices != null ) { 39 for( int i = 0; i < preknownDevices.length; i++ ) { 40 final RemoteDevice device = preknownDevices[i]; 41 devices.addElement( device ); 42 } 43 } 44 final RemoteDevice[] cachedDevices = agent.retrieveDevices( DiscoveryAgent.CACHED ); 45 if( cachedDevices != null ) { 46 for( int i = 0; i < cachedDevices.length; i++ ) { 47 final RemoteDevice device = cachedDevices[i]; 48 devices.addElement( device ); 49 } 50 } 51 } 52 53 private synchronized void refreshCache() { 54 devices.removeAllElements(); 55 fillupCache(); 56 } 57 58 public IAsyncProcess waitForIncoming( final IServerListener l ) { 59 return new WaitForIncomingThread( localDevice, l ); 60 } 61 62 public IAsyncProcess getAvailable( final boolean refresh, 63 final IClientListener listener ) { 64 final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 65 return new QueryDeviceProcess( this, refresh, agent, listener ); 66 // try { 67 // } catch( Exception e ) { 68 // e.printStackTrace(); 69 // listener.finished( null ); 70 // return null; 71 // } 72 // if( refresh ) { 73 // } else { 74 // final IRemoteNode[] nodes = getNodes(); 75 // listener.finished( nodes ); 76 // return null; 77 // } 78 } 79 80 private synchronized IRemoteNode[] getNodes() { 81 if( devices.isEmpty() ) { 82 return EMPTY; 83 } 84 final int length = devices.size(); 85 final IRemoteNode[] nodes = new IRemoteNode[length]; 86 for( int i = 0; i < length; i++ ) { 87 try { 88 final RemoteDevice device = ( RemoteDevice ) devices.elementAt( i ); 89 final BTNode node = new BTNode( device ); 90 nodes[i] = node; 91 } catch( IOException e ) { 92 //todo remove node from list, or causing NPE 93 e.printStackTrace(); 94 } 95 } 96 return nodes; 97 } 98 99 private static class WaitForIncomingThread extends BaseAsyncProcess { 100 private final LocalDevice localDevice; 101 private StreamConnectionNotifier server; 102 103 public WaitForIncomingThread( final LocalDevice local, 104 final IServerListener listener ) { 105 super( listener ); 106 this.localDevice = local; 107 start(); 108 } 109 110 public void run() { 111 try { 112 localDevice.setDiscoverable( DiscoveryAgent.GIAC ); 113 setStatus( IN_PROCESS ); 114 while( true ) { 115 server = ( StreamConnectionNotifier ) Connector.open( 116 BTSPP_SCHEME + "localhost:" + MY_SERVICE_NUMBER, 117 Connector.READ_WRITE, 118 true 119 ); 120 Util.log.println( "creating server and waiting for incoming" ); 121 try { 122 final IServerListener _listener = ( IServerListener ) listener; 123 while( true ) { 124 // Îæèäàåì âõîäÿùåå ïîòîêîâîå ñîåäèíåíèå 125 final StreamConnection conn = server.acceptAndOpen(); 126 Util.log.println( "accepted incoming: " + conn ); 127 final BTNode client = new BTNode( conn ); 128 if( _listener.incoming( client ) ) { 129 //åñëè êëèåíò ïðèíÿò -- âûõîäèì (èãðà äîïóñêàåò òîëüêî îäíîãî ñîïåðíèêà) 130 Util.log.println( "client accepted -> close server" ); 131 setStatus( SUCCEEDED ); 132 return; 133 } 134 client.close(); 135 } 136 } catch( InterruptedIOException ex ) { 137 setStatus( INTERRUPTED ); 138 Util.log.println( "server was closed: " + ex.getMessage() ); 139 return; 140 } catch( IOException ex ) { 141 Util.log.println( "server got error -- trying to recreate server connection" ); 142 ex.printStackTrace(); 143 } finally { 144 if( server != null ) { 145 try { 146 server.close(); 147 server = null; 148 } catch( IOException e ) { 149 e.printStackTrace(); 150 } 151 } 152 } 153 } 154 } catch( IOException ex ) { 155 //åñëè íå óäàëîñü îòêðûòü ñîåäèíåíèå -- ýòî ïèçäåö. óõîäèì 156 //...íå óäàëîñü îïóáëèêîâàòü óñòðîéñòâî -- ïèçäåö, óõîäèì 157 ex.printStackTrace(); 158 setStatus( FAILED ); 159 } finally { 160 listener.finished( null ); 161 Util.log.println( "server stopped" ); 162 } 163 } 164 165 public void stop( final int waitMillis ) { 166 if( isAlive() ) { 167 if( server != null ) { 168 try { 169 server.close(); 170 server = null; 171 } catch( IOException e ) { 172 e.printStackTrace(); 173 } 174 } 175 waitForThread( waitMillis ); 176 } 177 } 178 179 } 180 181 private static class QueryDeviceProcess extends BaseAsyncProcess implements DiscoveryListener { 182 private final BTRemote remote; 183 private final boolean realQuery; 184 private final DiscoveryAgent agent; 185 186 public QueryDeviceProcess( final BTRemote remote, 187 final boolean realQuery, 188 final DiscoveryAgent agent, 189 final IClientListener listener ) { 190 super( listener ); 191 this.remote = remote; 192 this.agent = agent; 193 this.realQuery = realQuery; 194 start(); 195 } 196 197 public void run() { 198 199 setStatus( IN_PROCESS ); 200 Util.log.println( "starting query device list" ); 201 try { 202 /** 203 * Íåïîíÿòíî, ÿâëÿåòñÿ ëè ýòîò çàïðîñ ñèíõðîííûì, èëè àñèíõðîííûì -- 204 * äîêóìåíòàöèÿ íà ýòîò ñ÷åò ìîë÷èò, à ïðàêòèêà ïîêàçûâàåò, ÷òî 205 * áûâàåò è òàê è ýäàê. Ïîýòîìó ñòðàõóåìñÿ íà âñÿêèé ñëó÷àé îò 206 * íåâåäîìîé õóéíè è äåëàåì ýòî â îòäåëüíîì ïîòîêå 207 */ 208 if( realQuery ) { 209 agent.startInquiry( DiscoveryAgent.GIAC, this ); 210 } else { 211 listener.finished( remote.getNodes() ); 212 } 213 } catch( BluetoothStateException e ) { 214 e.printStackTrace(); 215 setStatus( FAILED ); 216 listener.finished( null ); 217 } 218 } 219 220 221 public void stop( final int waitMillis ) { 222 if( status() == IN_PROCESS ) { 223 if( realQuery ) { 224 agent.cancelInquiry( this ); 225 } else { 226 interrupt(); 227 } 228 waitForThread( waitMillis ); 229 } 230 } 231 232 public void deviceDiscovered( final RemoteDevice btDevice, 233 final DeviceClass cod ) { 234 Util.log.println( "device found:" + btDevice.getBluetoothAddress() ); 235 } 236 237 public void servicesDiscovered( final int transID, 238 final ServiceRecord[] servRecord ) { 239 Util.log.println( "service found:" + transID ); 240 } 241 242 public void serviceSearchCompleted( final int transID, 243 final int respCode ) { 244 245 } 246 247 public void inquiryCompleted( final int discType ) { 248 switch( discType ) { 249 case INQUIRY_COMPLETED: 250 Util.log.println( "device list query finished" ); 251 remote.refreshCache(); 252 setStatus( SUCCEEDED ); 253 listener.finished( remote.getNodes() ); 254 break; 255 case INQUIRY_TERMINATED: 256 Util.log.println( "device list query interrupted" ); 257 setStatus( INTERRUPTED ); 258 listener.finished( null ); 259 break; 260 case INQUIRY_ERROR: 261 Util.log.println( "device list query failed" ); 262 setStatus( FAILED ); 263 listener.finished( null ); 264 break; 265 } 266 } 267 } 254 268 } -
chess/src/chess/remote/impl/BaseAsyncProcess.java
r27 r29 1 1 package chess.remote.impl; 2 2 3 import chess.Util; 3 4 import chess.remote.IAsyncProcess; 4 5 import chess.remote.IAsyncProcessListener; 5 import chess.Util;6 6 7 7 /** … … 12 12 */ 13 13 public class BaseAsyncProcess extends Thread implements IAsyncProcess { 14 14 protected final IAsyncProcessListener listener; 15 15 16 private int status = IN_PROCESS;16 private int status = NOT_STARTED; 17 17 18 19 20 18 public BaseAsyncProcess( final IAsyncProcessListener listener ) { 19 this.listener = listener; 20 } 21 21 22 23 24 22 public final int status() { 23 return status; 24 } 25 25 26 27 switch( status ) {28 29 30 31 32 33 34 35 36 37 26 protected final synchronized void setStatus( final int status ) { 27 switch( status ) { 28 case IN_PROCESS: 29 case SUCCEEDED: 30 case FAILED: 31 case INTERRUPTED: 32 this.status = status; 33 break; 34 default: 35 throw new IllegalArgumentException( "Status " + status + " is unknown" ); 36 } 37 } 38 38 39 public void interrupt( final boolean waitFor) {40 if( isAlive() ) {41 42 waitForThread( waitFor);43 44 39 public void stop( final int waitMillis ) { 40 if( isAlive() ) { 41 interrupt(); 42 waitForThread( waitMillis ); 43 } 44 } 45 45 46 protected void waitForThread( final boolean waitFor ) { 47 if ( waitFor 48 && isAlive() 49 && Thread.currentThread() != this ) { 50 Util.log.println( "waiting for thread to finish" ); 51 try { 52 join(); 53 } catch ( InterruptedException e ) { 54 e.printStackTrace(); 55 } 56 } 57 } 46 protected void waitForThread( final int waitMillis ) { 47 if( waitMillis > 0 48 && isAlive() 49 && Thread.currentThread() != this ) { 50 Util.log.println( "waiting for thread to finish" ); 51 synchronized( this ) { 52 try { 53 wait( waitMillis ); 54 } catch( InterruptedException e ) { 55 } 56 } 57 } 58 } 58 59 59 60 61 60 public final IAsyncProcessListener getListener() { 61 return listener; 62 } 62 63 } -
chess/src/chess/remote/impl/debug/DebugRemote.java
r28 r29 2 2 3 3 import java.io.*; 4 import java.util.Timer; 5 import java.util.TimerTask; 6 import java.util.Random; 7 4 import java.util.*; 5 6 import chess.Util; 7 import chess.control.SystemAction; 8 import chess.game.Action; 9 import chess.game.Player; 8 10 import chess.remote.*; 11 import chess.remote.impl.BTRemote; 9 12 import chess.remote.impl.BaseAsyncProcess; 10 13 import chess.remote.impl.GenericDatagram; 11 import chess.remote.impl.BTRemote;12 import chess.game.Action;13 import chess.game.Player;14 import chess.control.SystemAction;15 import chess.Util;16 14 17 15 … … 23 21 */ 24 22 public class DebugRemote implements IRemote { 25 private static final Timer TIMER = new Timer(); 26 27 private static final Random random = new Random(); 28 29 private final int networkLatency; 30 private final int userLatency; 31 32 public DebugRemote( final int networkLatency, 33 final int userLatency ) { 34 this.networkLatency = networkLatency; 35 this.userLatency = userLatency; 36 } 37 38 private InputStream prepareLog( final Player player ) { 39 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 40 try { 41 final int yPawnLine = ( player == Player.WHITE ) ? ( 1 ) : ( 6 ); 42 final int dir = player.getDirection(); 43 putAction( player, out, 2 * userLatency, 0, yPawnLine, 0, yPawnLine + 2 * dir ); 44 45 putAction( player, out, 12 * userLatency, 3, yPawnLine, 3, yPawnLine + 2 * dir ); 46 47 putAction( player, out, 10 * userLatency, 4, yPawnLine, 4, yPawnLine + dir ); 48 49 putAction( player, out, 20 * userLatency, 4, yPawnLine + dir, 4, yPawnLine + 2 * dir ); 50 51 //new GenericDatagram( 52 // new SystemAction( 53 // SystemAction.SURRENDER, 54 // player 55 // ) 56 //).write( out ); 57 } catch ( IOException e ) { 58 e.printStackTrace(); 59 } 60 61 return new ByteArrayInputStream( out.toByteArray() ); 62 } 63 64 private static void putAction( final Player player, 65 final OutputStream out, 66 final int duration, 67 final int xFrom, 68 final int yFrom, 69 final int xTo, 70 final int yTo ) throws IOException { 71 final Action a = new Action( 72 player, 73 duration, 74 xFrom, yFrom, 75 xTo, yTo 76 ); 77 new GenericDatagram( a ).write( out ); 78 final SystemAction yourTurnAction = SystemAction.yourTurn( player.opponent() ); 79 new GenericDatagram( yourTurnAction ).write( out ); 80 } 81 82 public IAsyncProcess waitForIncoming( final IServerListener l ) { 83 return new ServerAsyncProcess( l ); 84 } 85 86 public IAsyncProcess getAvailable( final boolean force, 87 final IClientListener l ) { 88 if ( !force ) { 89 try { 90 Thread.sleep( networkLatency ); 91 } catch ( InterruptedException e ) { 92 e.printStackTrace(); 93 } 94 l.finished( BTRemote.EMPTY ); 95 return null; 96 } else { 97 final QueryDeviceProcess process = new QueryDeviceProcess( this, l ); 98 TIMER.schedule( process, networkLatency ); 99 return process; 100 } 101 } 102 103 private class ServerAsyncProcess extends BaseAsyncProcess { 104 public ServerAsyncProcess( final IServerListener listener ) { 105 super( listener ); 106 start(); 107 } 108 109 public void run() { 110 try { 111 setStatus( IN_PROCESS ); 112 final IServerListener _listener = ( IServerListener )listener; 113 while ( true ) { 114 synchronized ( this ) { 115 wait( 4 * networkLatency ); 116 } 117 if ( _listener.incoming( new ClientRemoteNode() ) ) { 118 Util.log.println( "emulate incoming connection: OK" ); 119 setStatus( SUCCEEDED ); 120 return; 121 } 122 } 123 } catch ( InterruptedException ex ) { 124 setStatus( INTERRUPTED ); 125 } catch ( Exception ex ) { 126 setStatus( FAILED ); 127 } finally { 128 listener.finished( null ); 129 } 130 } 131 132 } 133 134 private class ClientRemoteNode implements IRemoteNode { 135 private InputStream is; 136 private IConnectionListener listener; 137 private Player player; 138 139 public String getName() { 140 return "debug client"; 141 } 142 143 public void setListener( final IConnectionListener l ) { 144 this.listener = l; 145 } 146 147 public void start() { 148 TIMER.schedule( 149 new TimerTask() { 150 public void run() { 151 listener.connected(); 152 } 153 }, 154 networkLatency 155 ); 156 } 157 158 public void send( final IDatagram data ) { 159 if ( listener != null ) { 160 Util.log.println( "emulate data send: " + data ); 161 TIMER.schedule( 162 new TimerTask() { 163 public void run() { 164 Util.log.println( "emulate wasSent: " + data ); 165 listener.wasSent( data ); 166 if ( data instanceof SystemAction ) { 167 final SystemAction sa = ( SystemAction )data; 168 if ( sa.type() == SystemAction.SET_PLAYER ) { 169 player = sa.getPlayer(); 170 is = prepareLog( player ); 171 } else if ( sa.type() == SystemAction.YOUR_TURN ) { 172 try { 173 if ( is.available() > 0 ) { 174 final GenericDatagram aPacket = new GenericDatagram( ClientRemoteNode.this.is ); 175 final GenericDatagram saPacket = new GenericDatagram( ClientRemoteNode.this.is ); 176 Thread.sleep( 5 * networkLatency ); 177 TIMER.schedule( 178 new TimerTask() { 179 public void run() { 180 Util.log.println( "recv: emulate" ); 181 182 Util.log.println( "recv: " + aPacket.wrapped() ); 183 listener.received( aPacket.wrapped() ); 184 185 Util.log.println( "recv: " + saPacket.wrapped() ); 186 listener.received( saPacket.wrapped() ); 187 } 188 }, 189 ( ( Action )aPacket.wrapped() ).duration() 190 ); 191 } else { 192 listener.received( SystemAction.surrender( player ) ); 193 } 194 } catch ( Exception e ) { 195 e.printStackTrace(); 196 } 197 } 198 } 199 } 200 }, 201 2 * networkLatency 202 ); 203 } 204 } 205 206 public void close() { 207 listener.closed(); 208 } 209 } 210 211 private class ServerRemoteNode implements IRemoteNode { 212 private InputStream is; 213 private IConnectionListener listener; 214 private final Player player; 215 private final String name; 216 217 private ServerRemoteNode( final int n ) { 218 player = Player.byType( n % 2 ); 219 name = "debug server #" + n + "[" + player + "]"; 220 } 221 222 public String getName() { 223 return name; 224 } 225 226 public void setListener( final IConnectionListener l ) { 227 this.listener = l; 228 } 229 230 public void start() { 231 if ( listener == null ) { 232 throw new IllegalStateException( "listener can't be null in start!" ); 233 } 234 //ïîñûëàåì íà÷àëüíóþ ïîñëåäîâàòåëüíîñòü -- 235 //restore logged actions, SET_PLAYER, YOUR_TURN 236 Util.log.println( "server emulation started: " + name ); 237 is = prepareLog( player ); 238 final TimerTask handshakeTask = new TimerTask() { 239 public void run() { 240 Util.log.println( name + ": sending SET_PLAYER" ); 241 listener.received( 242 SystemAction.setPlayer( player.opponent() ) 243 ); 244 if ( player == Player.WHITE ) { 245 packet(); 246 } else { 247 listener.received( 248 SystemAction.yourTurn( player.opponent() ) 249 ); 250 //èíà÷å æäåì YOUR_TURN îò áåëûõ 251 } 252 } 253 }; 254 255 TIMER.schedule( 256 new TimerTask() { 257 public void run() { 258 Util.log.println( name + ":sending connect" ); 259 listener.connected(); 260 TIMER.schedule( handshakeTask, networkLatency ); 261 } 262 }, 263 networkLatency 264 ); 265 } 266 267 public void send( final IDatagram data ) { 268 if ( listener != null ) { 269 Util.log.println( name + ": send data " + data ); 270 TIMER.schedule( 271 new TimerTask() { 272 public void run() { 273 Util.log.println( name + ": wasSent " + data ); 274 listener.wasSent( data ); 275 if ( data instanceof SystemAction ) { 276 final SystemAction sa = ( SystemAction )data; 277 if ( sa.type() == SystemAction.SET_PLAYER ) { 278 throw new IllegalStateException( "Can't be SET_PLAYER to server" ); 279 } 280 if ( sa.type() == SystemAction.YOUR_TURN ) { 281 packet(); 282 } 283 } 284 } 285 }, 286 2 * networkLatency 287 ); 288 } 289 } 290 291 private void packet() { 292 try { 293 if ( is.available() > 0 ) { 294 final GenericDatagram aPacket = new GenericDatagram( is ); 295 final GenericDatagram saPacket = new GenericDatagram( is ); 296 Thread.sleep( 5 * networkLatency ); 297 TIMER.schedule( 298 new TimerTask() { 299 public void run() { 300 Util.log.println( name + ":recv emulation..." ); 301 302 Util.log.println( name + ":recv " + aPacket.wrapped() ); 303 listener.received( aPacket.wrapped() ); 304 305 Util.log.println( name + ":recv " + saPacket.wrapped() ); 306 listener.received( saPacket.wrapped() ); 307 } 308 }, 309 ( ( Action )aPacket.wrapped() ).duration() 310 ); 311 } else { 312 listener.received( SystemAction.surrender( player ) ); 313 } 314 } catch ( Exception e ) { 315 e.printStackTrace(); 316 } 317 } 318 319 public void close() { 320 listener.closed(); 321 } 322 } 323 324 private static class QueryDeviceProcess extends TimerTask implements IAsyncProcess { 325 private final IClientListener l; 326 private final DebugRemote remote; 327 328 public QueryDeviceProcess( final DebugRemote remote, 329 final IClientListener l ) { 330 this.remote = remote; 331 this.l = l; 332 } 333 334 public void run() { 335 final int rnd = random.nextInt( 5 ); 336 final IRemoteNode[] servers = new IRemoteNode[rnd]; 337 for ( int i = 0; i < servers.length; i++ ) { 338 servers[i] = remote.new ServerRemoteNode( i + 1 ); 339 } 340 l.finished( servers ); 341 } 342 343 public int status() { 344 return 0; 345 } 346 347 public void interrupt( final boolean waitFor ) { 348 cancel(); 349 } 350 351 public IAsyncProcessListener getListener() { 352 return l; 353 } 354 } 23 private static final Timer TIMER = new Timer(); 24 25 private static final Random random = new Random(); 26 27 private final int networkLatency; 28 private final int userLatency; 29 30 public DebugRemote( final int networkLatency, 31 final int userLatency ) { 32 this.networkLatency = networkLatency; 33 this.userLatency = userLatency; 34 } 35 36 private InputStream prepareLog( final Player player ) { 37 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 38 try { 39 final int yPawnLine = ( player == Player.WHITE ) ? ( 1 ) : ( 6 ); 40 final int dir = player.getDirection(); 41 putAction( player, out, 2 * userLatency, 0, yPawnLine, 0, yPawnLine + 2 * dir ); 42 43 putAction( player, out, 12 * userLatency, 3, yPawnLine, 3, yPawnLine + 2 * dir ); 44 45 putAction( player, out, 10 * userLatency, 4, yPawnLine, 4, yPawnLine + dir ); 46 47 putAction( player, out, 20 * userLatency, 4, yPawnLine + dir, 4, yPawnLine + 2 * dir ); 48 49 //new GenericDatagram( 50 // new SystemAction( 51 // SystemAction.SURRENDER, 52 // player 53 // ) 54 //).write( out ); 55 } catch( IOException e ) { 56 e.printStackTrace(); 57 } 58 59 return new ByteArrayInputStream( out.toByteArray() ); 60 } 61 62 private static void putAction( final Player player, 63 final OutputStream out, 64 final int duration, 65 final int xFrom, 66 final int yFrom, 67 final int xTo, 68 final int yTo ) throws IOException { 69 final Action a = new Action( 70 player, 71 duration, 72 xFrom, yFrom, 73 xTo, yTo 74 ); 75 new GenericDatagram( a ).write( out ); 76 final SystemAction yourTurnAction = SystemAction.yourTurn( player.opponent() ); 77 new GenericDatagram( yourTurnAction ).write( out ); 78 } 79 80 public IAsyncProcess waitForIncoming( final IServerListener l ) { 81 return new ServerAsyncProcess( l ); 82 } 83 84 public IAsyncProcess getAvailable( final boolean force, 85 final IClientListener l ) { 86 if( !force ) { 87 try { 88 Thread.sleep( networkLatency ); 89 } catch( InterruptedException e ) { 90 e.printStackTrace(); 91 } 92 l.finished( BTRemote.EMPTY ); 93 return null; 94 } else { 95 final QueryDeviceProcess process = new QueryDeviceProcess( this, l ); 96 TIMER.schedule( process, networkLatency ); 97 return process; 98 } 99 } 100 101 private class ServerAsyncProcess extends BaseAsyncProcess { 102 public ServerAsyncProcess( final IServerListener listener ) { 103 super( listener ); 104 start(); 105 } 106 107 public void run() { 108 try { 109 setStatus( IN_PROCESS ); 110 final IServerListener _listener = ( IServerListener ) listener; 111 while( true ) { 112 synchronized( this ) { 113 wait( 4 * networkLatency ); 114 } 115 if( _listener.incoming( new ClientRemoteNode() ) ) { 116 Util.log.println( "emulate incoming connection: OK" ); 117 setStatus( SUCCEEDED ); 118 return; 119 } 120 } 121 } catch( InterruptedException ex ) { 122 setStatus( INTERRUPTED ); 123 } catch( Exception ex ) { 124 setStatus( FAILED ); 125 } finally { 126 listener.finished( null ); 127 } 128 } 129 130 } 131 132 private class ClientRemoteNode implements IRemoteNode { 133 private InputStream is; 134 private IConnectionListener listener; 135 private Player player; 136 137 public String getName() { 138 return "debug client"; 139 } 140 141 public void setListener( final IConnectionListener l ) { 142 this.listener = l; 143 } 144 145 public void start() { 146 TIMER.schedule( 147 new TimerTask() { 148 public void run() { 149 listener.connected(); 150 } 151 }, 152 networkLatency 153 ); 154 } 155 156 public void send( final IDatagram data ) { 157 if( listener != null ) { 158 Util.log.println( "emulate data send: " + data ); 159 TIMER.schedule( 160 new TimerTask() { 161 public void run() { 162 Util.log.println( "emulate wasSent: " + data ); 163 listener.wasSent( data ); 164 if( data instanceof SystemAction ) { 165 final SystemAction sa = ( SystemAction ) data; 166 if( sa.type() == SystemAction.SET_PLAYER ) { 167 player = sa.getPlayer(); 168 is = prepareLog( player ); 169 } else 170 if( sa.type() == SystemAction.YOUR_TURN ) { 171 try { 172 if( is.available() > 0 ) { 173 final GenericDatagram aPacket = new GenericDatagram( ClientRemoteNode.this.is ); 174 final GenericDatagram saPacket = new GenericDatagram( ClientRemoteNode.this.is ); 175 Thread.sleep( 5 * networkLatency ); 176 TIMER.schedule( 177 new TimerTask() { 178 public void run() { 179 Util.log.println( "recv: emulate" ); 180 181 Util.log.println( "recv: " + aPacket.wrapped() ); 182 listener.received( aPacket.wrapped() ); 183 184 Util.log.println( "recv: " + saPacket.wrapped() ); 185 listener.received( saPacket.wrapped() ); 186 } 187 }, 188 ( ( Action ) aPacket.wrapped() ).duration() 189 ); 190 } else { 191 listener.received( SystemAction.surrender( player ) ); 192 } 193 } catch( Exception e ) { 194 e.printStackTrace(); 195 } 196 } 197 } 198 } 199 }, 200 2 * networkLatency 201 ); 202 } 203 } 204 205 public void close() { 206 listener.closed(); 207 } 208 } 209 210 private class ServerRemoteNode implements IRemoteNode { 211 private InputStream is; 212 private IConnectionListener listener; 213 private final Player player; 214 private final String name; 215 216 private ServerRemoteNode( final int n ) { 217 player = Player.byType( n % 2 ); 218 name = "debug server #" + n + "[" + player + "]"; 219 } 220 221 public String getName() { 222 return name; 223 } 224 225 public void setListener( final IConnectionListener l ) { 226 this.listener = l; 227 } 228 229 public void start() { 230 if( listener == null ) { 231 throw new IllegalStateException( "listener can't be null in start!" ); 232 } 233 //ïîñûëàåì íà÷àëüíóþ ïîñëåäîâàòåëüíîñòü -- 234 //restore logged actions, SET_PLAYER, YOUR_TURN 235 Util.log.println( "server emulation started: " + name ); 236 is = prepareLog( player ); 237 final TimerTask handshakeTask = new TimerTask() { 238 public void run() { 239 Util.log.println( name + ": sending SET_PLAYER" ); 240 listener.received( 241 SystemAction.setPlayer( player.opponent() ) 242 ); 243 if( player == Player.WHITE ) { 244 packet(); 245 } else { 246 listener.received( 247 SystemAction.yourTurn( player.opponent() ) 248 ); 249 //èíà÷å æäåì YOUR_TURN îò áåëûõ 250 } 251 } 252 }; 253 254 TIMER.schedule( 255 new TimerTask() { 256 public void run() { 257 Util.log.println( name + ":sending connect" ); 258 listener.connected(); 259 TIMER.schedule( handshakeTask, networkLatency ); 260 } 261 }, 262 networkLatency 263 ); 264 } 265 266 public void send( final IDatagram data ) { 267 if( listener != null ) { 268 Util.log.println( name + ": send data " + data ); 269 TIMER.schedule( 270 new TimerTask() { 271 public void run() { 272 Util.log.println( name + ": wasSent " + data ); 273 listener.wasSent( data ); 274 if( data instanceof SystemAction ) { 275 final SystemAction sa = ( SystemAction ) data; 276 if( sa.type() == SystemAction.SET_PLAYER ) { 277 throw new IllegalStateException( "Can't be SET_PLAYER to server" ); 278 } 279 if( sa.type() == SystemAction.YOUR_TURN ) { 280 packet(); 281 } 282 } 283 } 284 }, 285 2 * networkLatency 286 ); 287 } 288 } 289 290 private void packet() { 291 try { 292 if( is.available() > 0 ) { 293 final GenericDatagram aPacket = new GenericDatagram( is ); 294 final GenericDatagram saPacket = new GenericDatagram( is ); 295 Thread.sleep( 5 * networkLatency ); 296 TIMER.schedule( 297 new TimerTask() { 298 public void run() { 299 Util.log.println( name + ":recv emulation..." ); 300 301 Util.log.println( name + ":recv " + aPacket.wrapped() ); 302 listener.received( aPacket.wrapped() ); 303 304 Util.log.println( name + ":recv " + saPacket.wrapped() ); 305 listener.received( saPacket.wrapped() ); 306 } 307 }, 308 ( ( Action ) aPacket.wrapped() ).duration() 309 ); 310 } else { 311 listener.received( SystemAction.surrender( player ) ); 312 } 313 } catch( Exception e ) { 314 e.printStackTrace(); 315 } 316 } 317 318 public void close() { 319 listener.closed(); 320 } 321 } 322 323 private static class QueryDeviceProcess extends TimerTask implements IAsyncProcess { 324 private final IClientListener l; 325 private final DebugRemote remote; 326 327 public QueryDeviceProcess( final DebugRemote remote, 328 final IClientListener l ) { 329 this.remote = remote; 330 this.l = l; 331 } 332 333 public void run() { 334 final int rnd = random.nextInt( 5 ); 335 final IRemoteNode[] servers = new IRemoteNode[rnd]; 336 for( int i = 0; i < servers.length; i++ ) { 337 servers[i] = remote.new ServerRemoteNode( i + 1 ); 338 } 339 l.finished( servers ); 340 } 341 342 public int status() { 343 return 0; 344 } 345 346 public void stop( final int waitMillis ) { 347 cancel(); 348 synchronized( this ) { 349 try { 350 wait( waitMillis ); 351 } catch( InterruptedException e ) { 352 } 353 } 354 } 355 356 public IAsyncProcessListener getListener() { 357 return l; 358 } 359 } 355 360 } -
chess/src/chess/ui/ChessMIDlet.java
r28 r29 110 110 private void ensureServerClosed() { 111 111 if ( waitForIncomingProcess != null ) { 112 waitForIncomingProcess. interrupt( true);112 waitForIncomingProcess.stop( 1000 ); 113 113 waitForIncomingProcess = null; 114 114 } -
chess/src/chess/ui/JoinGameScreen.java
r28 r29 50 50 } 51 51 52 53 54 52 public void run() { 55 53 refresh( true ); … … 58 56 public void refresh( final boolean force ) { 59 57 this.force = force; 60 if ( force && midlet.display.getCurrent() == this ) { 61 midlet.display.setCurrent( scanningNetworkAlert ); 62 }58 midlet.display.setCurrent( scanningNetworkAlert ); 59 // if ( force && midlet.display.getCurrent() == this ) { 60 // } 63 61 ensureSearcherClosed(); 64 62 asyncProcess = midlet.getRemoteManager().getAvailable( this.force, this ); … … 122 120 private void ensureSearcherClosed() { 123 121 if ( asyncProcess != null ) { 124 asyncProcess. interrupt( true);122 asyncProcess.stop( 1000 ); 125 123 asyncProcess = null; 126 124 }
Note: See TracChangeset
for help on using the changeset viewer.