Changeset 29 for chess


Ignore:
Timestamp:
02/07/09 14:47:49 (13 years ago)
Author:
BegemoT
Message:

threading

Location:
chess
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • chess/chess.jad

    r28 r29  
    11MIDlet-1: Chess Game, , chess.ui.ChessMIDlet 
    2 MIDlet-Jar-Size: 311214 
     2MIDlet-Jar-Size: 85700 
    33MIDlet-Jar-URL: chess.jar 
    44MIDlet-Name: Chess 
    55MIDlet-Vendor: I am 
    6 MIDlet-Version: 1.1.3 
     6MIDlet-Version: 1.1.5 
    77MicroEdition-Configuration: CLDC-1.0 
    88MicroEdition-Profile: MIDP-2.0 
  • chess/src/chess/Util.java

    r28 r29  
    11package chess; 
    22 
    3 import java.io.PrintStream; 
    4 import java.io.OutputStream; 
    5 import java.io.IOException; 
    6 import java.io.InputStream; 
    7  
     3import java.io.*; 
    84import javax.microedition.rms.RecordStore; 
    95 
    106import chess.remote.IRemote; 
    117import chess.remote.impl.BTRemote; 
    12 import chess.remote.impl.debug.DebugRemote; 
    138 
    149 
     
    3126 
    3227    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 ); 
    3530    } 
    3631 
  • chess/src/chess/control/BaseController.java

    r28 r29  
    168168 
    169169    public synchronized void setStatus( final int status ) { 
    170         //todo 
    171170        this.status = status; 
    172171        switch ( status ) { 
  • chess/src/chess/game/units/Bishop.java

    r19 r29  
    77/** 
    88 * Ñëîí 
    9  * todo implement 
    109 * User: BegemoT<br/> 
    1110 * Date: 29.01.2009<br/> 
  • chess/src/chess/game/units/King.java

    r19 r29  
    88/** 
    99 * Êîðîëü 
    10  * todo implement 
    1110 * User: BegemoT<br/> 
    1211 * Date: 29.01.2009<br/> 
  • chess/src/chess/remote/IAsyncProcess.java

    r27 r29  
    66 */ 
    77public interface IAsyncProcess { 
     8        public static final int NOT_STARTED = -1; 
    89        public static final int IN_PROCESS = 0; 
    910        public static final int SUCCEEDED = 1; 
     
    1314        public int status(); 
    1415 
    15         public void interrupt( final boolean waitFor ); 
     16        public void stop( final int waitMillis ); 
    1617 
    1718        public IAsyncProcessListener getListener(); 
  • chess/src/chess/remote/impl/BTNode.java

    r25 r29  
    2121 */ 
    2222public 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        } 
    332315} 
  • chess/src/chess/remote/impl/BTRemote.java

    r27 r29  
    2020 */ 
    2121public 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        } 
    254268} 
  • chess/src/chess/remote/impl/BaseAsyncProcess.java

    r27 r29  
    11package chess.remote.impl; 
    22 
     3import chess.Util; 
    34import chess.remote.IAsyncProcess; 
    45import chess.remote.IAsyncProcessListener; 
    5 import chess.Util; 
    66 
    77/** 
     
    1212 */ 
    1313public class BaseAsyncProcess extends Thread implements IAsyncProcess { 
    14     protected final IAsyncProcessListener listener; 
     14        protected final IAsyncProcessListener listener; 
    1515 
    16     private int status = IN_PROCESS; 
     16        private int status = NOT_STARTED; 
    1717 
    18     public BaseAsyncProcess( final IAsyncProcessListener listener ) { 
    19         this.listener = listener; 
    20     } 
     18        public BaseAsyncProcess( final IAsyncProcessListener listener ) { 
     19                this.listener = listener; 
     20        } 
    2121 
    22     public final int status() { 
    23         return status; 
    24     } 
     22        public final int status() { 
     23                return status; 
     24        } 
    2525 
    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     } 
     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        } 
    3838 
    39     public void interrupt( final boolean waitFor ) { 
    40         if ( isAlive() ) { 
    41             interrupt(); 
    42             waitForThread( waitFor ); 
    43         } 
    44     } 
     39        public void stop( final int waitMillis ) { 
     40                if( isAlive() ) { 
     41                        interrupt(); 
     42                        waitForThread( waitMillis ); 
     43                } 
     44        } 
    4545 
    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        } 
    5859 
    59     public final IAsyncProcessListener getListener() { 
    60         return listener; 
    61     } 
     60        public final IAsyncProcessListener getListener() { 
     61                return listener; 
     62        } 
    6263} 
  • chess/src/chess/remote/impl/debug/DebugRemote.java

    r28 r29  
    22 
    33import java.io.*; 
    4 import java.util.Timer; 
    5 import java.util.TimerTask; 
    6 import java.util.Random; 
    7  
     4import java.util.*; 
     5 
     6import chess.Util; 
     7import chess.control.SystemAction; 
     8import chess.game.Action; 
     9import chess.game.Player; 
    810import chess.remote.*; 
     11import chess.remote.impl.BTRemote; 
    912import chess.remote.impl.BaseAsyncProcess; 
    1013import 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; 
    1614 
    1715 
     
    2321 */ 
    2422public 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        } 
    355360} 
  • chess/src/chess/ui/ChessMIDlet.java

    r28 r29  
    110110    private void ensureServerClosed() { 
    111111        if ( waitForIncomingProcess != null ) { 
    112             waitForIncomingProcess.interrupt( true ); 
     112            waitForIncomingProcess.stop( 1000 ); 
    113113            waitForIncomingProcess = null; 
    114114        } 
  • chess/src/chess/ui/JoinGameScreen.java

    r28 r29  
    5050    } 
    5151 
    52          
    53  
    5452    public void run() { 
    5553        refresh( true ); 
     
    5856    public void refresh( final boolean force ) { 
    5957        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//        } 
    6361        ensureSearcherClosed(); 
    6462        asyncProcess = midlet.getRemoteManager().getAvailable( this.force, this ); 
     
    122120    private void ensureSearcherClosed() { 
    123121        if ( asyncProcess != null ) { 
    124             asyncProcess.interrupt( true ); 
     122            asyncProcess.stop( 1000 ); 
    125123            asyncProcess = null; 
    126124        } 
Note: See TracChangeset for help on using the changeset viewer.