Changeset 38 for chess


Ignore:
Timestamp:
02/11/09 08:57:33 (13 years ago)
Author:
BegemoT
Message:

=services search

Location:
chess/src/chess
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • chess/src/chess/MSG.properties

    r36 r38  
    5151alert.error = \u041e\u0448\u0438\u0431\u043a\u0430 
    5252alert.warning = \u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435 
     53 
     54device.unknown=<<\u0418\u043c\u044f \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e>> 
  • chess/src/chess/control/BaseController.java

    r37 r38  
    118118    } 
    119119 
     120    private final IUnit[] kings = new IUnit[1]; 
    120121    protected void processAction( final Action a ) { 
    121122        game.doAction( a ); 
     123        final int cnt = game.units( player, IUnit.KING, kings ); 
     124        if ( cnt == 0 ) { 
     125            //todo show alert for user 
     126            surrender( app.getMidlet() ); 
     127        } 
    122128    } 
    123129 
     
    169175    } 
    170176 
    171         public void post( final IDatagram data ) { 
     177    public void post( final IDatagram data ) { 
    172178        setStatus( WAITING_FOR_NETWORK ); 
    173179        node.send( data ); 
     
    338344                ui.clearHighlightedCells(); 
    339345            } else if ( c == ui.surrenderCommand ) { 
    340                 postSurrender(); 
    341                 node.close( true ); 
    342                 midlet.showStartScreen(); 
     346                surrender( midlet ); 
    343347            } else if ( c == ui.askForDrawCommand ) { 
    344                 postAskForDraw();                 
    345             } 
    346         } 
     348                postAskForDraw(); 
     349            } 
     350        } 
     351    } 
     352 
     353    private void surrender( final ChessMIDlet midlet ) { 
     354        postSurrender(); 
     355        node.close( true ); 
     356        midlet.showStartScreen(); 
    347357    } 
    348358 
  • chess/src/chess/remote/impl/BTNode.java

    r37 r38  
    1111import chess.remote.IDatagram; 
    1212import chess.remote.IRemoteNode; 
     13import chess.MSG; 
    1314 
    1415 
     
    2122 */ 
    2223public 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 volatile boolean quitPump = false; 
    36  
    37         private transient InputStream in; 
    38         private transient OutputStream out; 
    39         private transient Thread pump; 
    40  
    41         private Throwable lastError = null; 
    42  
    43         /** ìîíèòîð îæèäàíèÿ îòêðûòèÿ ñîåäèíåíèÿ */ 
     24    /** 
     25     * êàíàë BT, èñïîëüçóåìûé íàøèì ïðèëîæåíèåì 
     26     * todo ïîíÿòü, êàêèå êàíàëû ñóùåñòâóþò 
     27     */ 
     28    private static final String BT_STREAM = "1"; 
     29 
     30    private final String name; 
     31 
     32    private RemoteDevice device; 
     33    private IConnectionListener listener = null; 
     34    private StreamConnection connection = null; 
     35 
     36    private volatile boolean pumpShouldQuit = false; 
     37 
     38    private transient InputStream in; 
     39    private transient OutputStream out; 
     40    private transient Thread pump; 
     41 
     42    private Throwable lastError = null; 
     43 
     44    /** 
     45     * ìîíèòîð îæèäàíèÿ îòêðûòèÿ ñîåäèíåíèÿ 
     46     */ 
    4447//      private final Object connectLock = new Object(); 
    4548 
    46         private final Object queueOverloadedLock = new Object(); 
    47         private final IDatagram[] postQueue = new IDatagram[2]; 
    48  
    49  
    50         public BTNode( final RemoteDevice device ) throws IOException { 
    51                 this( device, null ); 
    52         } 
    53  
    54         public BTNode( final StreamConnection conn ) throws IOException { 
    55                 this( null, null, conn ); 
    56         } 
    57  
    58         public BTNode( final RemoteDevice device, 
    59                        final StreamConnection conn ) throws IOException { 
    60                 this( null, device, conn ); 
    61         } 
    62  
    63         public BTNode( final String name, 
    64                        final RemoteDevice device, 
    65                        final StreamConnection conn ) throws IOException { 
    66                 if( device == null && conn == null ) { 
    67                         throw new IllegalArgumentException( "No-no-no, David Blain! device=null && conn=null" ); 
    68                 } 
    69  
    70                 if( device == null ) { 
    71                         this.device = RemoteDevice.getRemoteDevice( conn ); 
    72                 } else { 
    73                         this.device = device; 
    74                 } 
    75                 if( name == null ) { 
    76                         try { 
    77                                 this.name = this.device.getFriendlyName( true ); 
    78                         } catch( IOException e ) { 
    79                                 e.printStackTrace(); 
    80                                 this.name = "unknown"; 
    81                         } 
    82                 } else { 
    83                         this.name = name; 
    84                 } 
    85                 connection = conn; 
    86         } 
    87  
    88         public BTNode( final String name, 
    89                        final StreamConnection conn ) throws IOException { 
    90                 this( name, null, conn ); 
    91         } 
    92  
    93         public String getName() { 
    94                 return name; 
    95         } 
    96  
    97         public synchronized void start() { 
    98                 checkNotClosed(); 
    99                 if( !isStartCalled() ) { 
    100                         pump = new Thread( this, "network pump" ); 
    101                         pump.start(); 
    102                 } 
    103         } 
    104  
    105         public synchronized void setListener( final IConnectionListener l ) { 
    106                 if( l != null && isClosed() ) { 
    107                         throw new IllegalStateException( "Node is closed - lsitener is useless" ); 
    108                 } 
    109                 this.listener = l; 
    110         } 
    111  
    112         public void send( final IDatagram data ) { 
    113                 checkPumpActive(); 
    114                 while( true ) { 
    115                         //áëîêèðóåì this ÷òîáû íàñ íå çàêðûëè íåâîâðåìÿ 
    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                         final GenericDatagram data = new GenericDatagram(); 
    155                         while( !isClosed() && !quitPump ) { 
    156                                 synchronized( this ) { 
    157                                         final int timeout; 
    158                                         //îòïðàâëÿåì íåîòïðàâëåííîå 
    159                                         synchronized( postQueue ) { 
    160                                                 for( int i = 0; i < postQueue.length; i++ ) { 
    161                                                         final IDatagram packet = postQueue[i]; 
    162                                                         if( packet != null ) { 
    163                                                                 data.setWrapped( packet ); 
    164                                                                 data.write( out ); 
    165                                                                 postQueue[i] = null; 
    166                                                                 if( listener != null ) { 
    167                                                                         listener.wasSent( packet ); 
    168                                                                 } 
    169                                                         } 
    170                                                 } 
    171                                         } 
    172                                         synchronized( queueOverloadedLock ) { 
    173                                                 //îïîâåùàåì, ÷òî î÷åðåäü îñâîáîäèëàñü 
    174                                                 queueOverloadedLock.notifyAll(); 
    175                                         } 
    176                                         //÷èòàåì íåäî÷èòàííîå 
    177                                         if( in.available() > 0 ) { 
    178                                                 data.read( in ); 
    179                                                 if( listener != null ) { 
    180                                                         listener.received( data.wrapped() ); 
    181                                                 } 
    182                                                 timeout = 50; 
    183                                         } else { 
    184                                                 timeout = 250; 
    185                                         } 
    186                                         try { 
    187                                                 wait( timeout ); 
    188                                         } catch( InterruptedException e ) { 
    189                                         } 
    190                                 } 
    191                         } 
    192                 } catch( Throwable e ) { 
    193                         e.printStackTrace(); 
    194                         lastError = e; 
    195                 } finally { 
    196                         pump = null; 
    197                         closeImpl(); 
    198                 } 
    199         } 
    200  
    201         public void close( final boolean safe ) { 
    202                 if( isClosed() ) { 
    203                         return; 
    204                 } 
    205                 if( safe ) { 
    206                         askPumpToQuit(); 
    207                 } else { 
    208                         closeImpl(); 
    209                 } 
    210         } 
    211  
    212         public Throwable getError() { 
    213                 return null; 
    214         } 
    215  
    216         private void closeImpl() { 
    217                 try { 
    218                         if( in != null ) { 
    219                                 try { 
    220                                         in.close(); 
    221                                 } catch( IOException e ) { 
    222                                         e.printStackTrace(); 
    223                                 } finally { 
    224                                         in = null; 
    225                                 } 
    226                         } 
    227                         if( out != null ) { 
    228                                 try { 
    229                                         out.close(); 
    230                                 } catch( IOException e ) { 
    231                                         e.printStackTrace(); 
    232                                 } finally { 
    233                                         out = null; 
    234                                 } 
    235                         } 
    236                         if( connection != null ) { 
    237                                 try { 
    238                                         connection.close(); 
    239                                 } catch( IOException e ) { 
    240                                         e.printStackTrace(); 
    241                                 } finally { 
    242                                         connection = null; 
    243                                 } 
    244                         } 
    245  
    246                         if( pump != null && pump.isAlive() ) { 
    247                                 pump.interrupt(); 
    248                                 if( pump != Thread.currentThread() ) { 
    249                                         try { 
    250                                                 pump.join(); 
    251                                         } catch( InterruptedException e ) { 
    252                                                 e.printStackTrace(); 
    253                                         } 
    254                                 } 
    255                         } 
    256                         for( int i = 0; i < postQueue.length; i++ ) { 
    257                                 postQueue[i] = null; 
    258                         } 
    259                 } finally { 
    260                         pump = null; 
    261                         device = null; 
    262                         if( listener != null ) { 
    263                                 listener.closed(); 
    264                         } 
    265                 } 
    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 ex; 
    279                                 //throw new IOException( "Can't open input stream:" + ex.getMessage() ); 
    280                         } 
    281                 } 
    282                 if( out == null ) { 
    283                         try { 
    284                                 out = connection.openOutputStream(); 
    285                         } catch( IOException ex ) { 
    286                                 ex.printStackTrace(); 
    287                                 throw ex; 
    288                                 //throw new IOException( "Can't open output stream:" + ex.getMessage() ); 
    289                         } 
    290                 } 
    291         } 
    292  
    293         public String toString() { 
    294                 return getName(); 
    295         } 
    296  
    297         private void checkNotClosed() { 
    298                 if( isClosed() ) { 
    299                         throw new IllegalStateException( "Node already closed" ); 
    300                 } 
    301         } 
    302  
    303         private void checkPumpActive() { 
    304                 checkNotClosed(); 
    305                 if( !isStartCalled() ) { 
    306                         throw new IllegalStateException( ".start() not called" ); 
    307                 } 
    308         } 
    309  
    310         private void checkConnected() { 
    311                 checkNotClosed(); 
    312                 checkPumpActive(); 
    313                 if( !isConnected() ) { 
    314                         throw new IllegalStateException( "Node not connected" ); 
    315                 } 
    316         } 
    317  
    318         private boolean isClosed() { 
    319                 return device == null; 
    320         } 
    321  
    322         private void askPumpToQuit() { 
    323                 synchronized( this ) { 
    324                         quitPump = true; 
    325                         notifyAll(); 
    326                 } 
    327                 //device = null; 
    328         } 
    329  
    330         private boolean isStartCalled() { 
    331                 return pump != null; 
    332         } 
    333  
    334         private boolean isConnected() { 
    335                 return connection != null && in != null && out != null; 
    336         } 
    337  
    338  
    339         private static String getBluetoothURL( final RemoteDevice device ) { 
    340                 return BTRemote.BTSPP_SCHEME + device.getBluetoothAddress() + ":" + BT_STREAM; 
    341         } 
     49    private final Object queueOverloadedLock = new Object(); 
     50    private final IDatagram[] postQueue = new IDatagram[2]; 
     51 
     52 
     53    public BTNode( final RemoteDevice device ) throws IOException { 
     54        this( device, null ); 
     55    } 
     56 
     57    public BTNode( final StreamConnection conn ) throws IOException { 
     58        this( null, null, conn ); 
     59    } 
     60 
     61    public BTNode( final RemoteDevice device, 
     62                   final StreamConnection conn ) throws IOException { 
     63        this( null, device, conn ); 
     64    } 
     65 
     66    public BTNode( final String name, 
     67                   final RemoteDevice device, 
     68                   final StreamConnection conn ) throws IOException { 
     69        if ( device == null && conn == null ) { 
     70            throw new IllegalArgumentException( "No-no-no, David Blain! device=null && conn=null" ); 
     71        } 
     72 
     73        if ( device == null ) { 
     74            this.device = RemoteDevice.getRemoteDevice( conn ); 
     75        } else { 
     76            this.device = device; 
     77        } 
     78        if ( name == null ) { 
     79            String _name = MSG.getMessage( "device.unknown" ); 
     80            try { 
     81                _name = this.device.getFriendlyName( true ); 
     82            } catch ( IOException e ) { 
     83                e.printStackTrace(); 
     84            } 
     85            this.name = _name; 
     86        } else { 
     87            this.name = name; 
     88        } 
     89        connection = conn; 
     90    } 
     91 
     92    public BTNode( final String name, 
     93                   final StreamConnection conn ) throws IOException { 
     94        this( name, null, conn ); 
     95    } 
     96 
     97    public String getName() { 
     98        return name; 
     99    } 
     100 
     101    public synchronized void start() { 
     102        checkNotClosed(); 
     103        if ( !isStartCalled() ) { 
     104            pump = new Thread( this, "network pump" ); 
     105            pump.start(); 
     106        } 
     107    } 
     108 
     109    public synchronized void setListener( final IConnectionListener l ) { 
     110        if ( l != null && isClosed() ) { 
     111            throw new IllegalStateException( "Node is closed - lsitener is useless" ); 
     112        } 
     113        this.listener = l; 
     114    } 
     115 
     116    public void send( final IDatagram data ) { 
     117        checkPumpActive(); 
     118        while ( true ) { 
     119            //áëîêèðóåì this ÷òîáû íàñ íå çàêðûëè íåâîâðåìÿ 
     120            synchronized ( this ) { 
     121                checkConnected(); 
     122                try { 
     123                    synchronized ( postQueue ) { 
     124                        //áëîêèðóåì î÷åðåäü, ÷òîáû ïðåäóïðåäèòü åå èçìåíåíèÿ 
     125                        for ( int i = 0; i < postQueue.length; i++ ) { 
     126                            if ( postQueue[i] == null ) { 
     127                                postQueue[i] = data; 
     128                                return; 
     129                            } 
     130                        } 
     131                    } 
     132                } finally { 
     133                    notifyAll();//push pump to run 
     134                } 
     135            } 
     136            //åñëè î÷åðåäü ïåðåïîëíåíà -- âûíóæäåíû æäàòü 
     137            synchronized ( queueOverloadedLock ) { 
     138                try { 
     139                    queueOverloadedLock.wait( 250 ); 
     140                } catch ( InterruptedException e ) { 
     141                } 
     142            } 
     143        } 
     144    } 
     145 
     146    public void run() { 
     147        try { 
     148            synchronized ( this ) { 
     149                if ( isClosed() ) { 
     150                    return; 
     151                } 
     152                openPipeline(); 
     153            } 
     154            if ( listener != null ) { 
     155                listener.connected(); 
     156            } 
     157            final GenericDatagram data = new GenericDatagram(); 
     158            while ( !isClosed() && !pumpShouldQuit ) { 
     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            lastError = e; 
     198        } finally { 
     199            pump = null; 
     200            closeImpl(); 
     201        } 
     202    } 
     203 
     204    private void openPipeline() throws IOException { 
     205        if ( connection == null ) { 
     206            final String addr = getBluetoothURL( device ); 
     207            connection = ( StreamConnection )Connector.open( addr, Connector.READ_WRITE, true ); 
     208        } 
     209        if ( in == null ) { 
     210            try { 
     211                in = connection.openInputStream(); 
     212            } catch ( IOException ex ) { 
     213                ex.printStackTrace(); 
     214                throw ex; 
     215                //throw new IOException( "Can't open input stream:" + ex.getMessage() ); 
     216            } 
     217        } 
     218        if ( out == null ) { 
     219            try { 
     220                out = connection.openOutputStream(); 
     221            } catch ( IOException ex ) { 
     222                ex.printStackTrace(); 
     223                throw ex; 
     224                //throw new IOException( "Can't open output stream:" + ex.getMessage() ); 
     225            } 
     226        } 
     227    } 
     228 
     229    public void close( final boolean safe ) { 
     230        if ( isClosed() ) { 
     231            return; 
     232        } 
     233        if ( safe ) { 
     234            askPumpToQuit(); 
     235        } else { 
     236            closeImpl(); 
     237        } 
     238    } 
     239 
     240    private void closeImpl() { 
     241        try { 
     242            if ( in != null ) { 
     243                try { 
     244                    in.close(); 
     245                } catch ( IOException e ) { 
     246                    e.printStackTrace(); 
     247                } finally { 
     248                    in = null; 
     249                } 
     250            } 
     251            if ( out != null ) { 
     252                try { 
     253                    out.close(); 
     254                } catch ( IOException e ) { 
     255                    e.printStackTrace(); 
     256                } finally { 
     257                    out = null; 
     258                } 
     259            } 
     260            if ( connection != null ) { 
     261                try { 
     262                    connection.close(); 
     263                } catch ( IOException e ) { 
     264                    e.printStackTrace(); 
     265                } finally { 
     266                    connection = null; 
     267                } 
     268            } 
     269 
     270            if ( pump != null && pump.isAlive() ) { 
     271                pump.interrupt(); 
     272                if ( pump != Thread.currentThread() ) { 
     273                    try { 
     274                        pump.join(); 
     275                    } catch ( InterruptedException e ) { 
     276                        e.printStackTrace(); 
     277                    } 
     278                } 
     279            } 
     280            for ( int i = 0; i < postQueue.length; i++ ) { 
     281                postQueue[i] = null; 
     282            } 
     283        } finally { 
     284            pump = null; 
     285            device = null; 
     286            if ( listener != null ) { 
     287                listener.closed(); 
     288            } 
     289        } 
     290    } 
     291 
     292    private void askPumpToQuit() { 
     293        synchronized ( this ) { 
     294            pumpShouldQuit = true; 
     295            notifyAll(); 
     296        } 
     297        //device = null; 
     298    } 
     299 
     300    public Throwable getError() { 
     301        return lastError; 
     302    } 
     303 
     304    private void checkNotClosed() { 
     305        if ( isClosed() ) { 
     306            throw new IllegalStateException( "Node already closed" ); 
     307        } 
     308    } 
     309 
     310    private void checkPumpActive() { 
     311        checkNotClosed(); 
     312        if ( !isStartCalled() ) { 
     313            throw new IllegalStateException( ".start() not called" ); 
     314        } 
     315    } 
     316 
     317    private void checkConnected() { 
     318        checkNotClosed(); 
     319        checkPumpActive(); 
     320        if ( !isConnected() ) { 
     321            throw new IllegalStateException( "Node not connected" ); 
     322        } 
     323    } 
     324 
     325    private boolean isClosed() { 
     326        return device == null; 
     327    } 
     328 
     329    private boolean isStartCalled() { 
     330        return pump != null; 
     331    } 
     332 
     333    private boolean isConnected() { 
     334        return connection != null && in != null && out != null; 
     335    } 
     336 
     337    public String toString() { 
     338        return getName(); 
     339    } 
     340 
     341 
     342    public static String getBluetoothURL( final RemoteDevice device ) { 
     343        return BTRemote.SCHEME + device.getBluetoothAddress() + ":" + BT_STREAM; 
     344    } 
    342345} 
  • chess/src/chess/remote/impl/BTRemote.java

    r37 r38  
    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 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[devices.size()]; 
    86                 boolean wasFailed = false; 
    87                 for( int i = 0; i < length; i++ ) { 
    88                         try { 
    89                                 final RemoteDevice device = ( RemoteDevice ) devices.elementAt( i ); 
    90                                 final BTNode node = new BTNode( device ); 
    91                                 nodes[i] = node; 
    92                         } catch( IOException e ) { 
    93                                 wasFailed = true; 
    94                                 e.printStackTrace(); 
    95                         } 
    96                 } 
    97                 if( wasFailed ) { 
    98                         //óäàëÿåì ïóñòûå ÿ÷åéêè 
    99                         final Vector res = new Vector( nodes.length ); 
    100                         for( int i = 0; i < nodes.length; i++ ) { 
    101                                 final IRemoteNode node = nodes[i]; 
    102                                 if( node != null ) { 
    103                                         res.addElement( node ); 
    104                                 } 
    105                         } 
    106  
    107                         final IRemoteNode[] _nodes = new IRemoteNode[res.size()]; 
    108                         res.copyInto( _nodes ); 
    109                         return _nodes; 
    110                 } else { 
    111                         return nodes; 
    112                 } 
    113         } 
    114  
    115         private static class WaitForIncomingThread extends BaseAsyncProcess { 
    116                 private final LocalDevice localDevice; 
    117                 private StreamConnectionNotifier server; 
    118  
    119                 public WaitForIncomingThread( final LocalDevice local, 
    120                                               final IServerListener listener ) { 
    121                         super( listener, "wait-for-incoming" ); 
    122                         this.localDevice = local; 
    123                         start(); 
    124                 } 
    125  
    126                 public void run() { 
    127                         try { 
    128                                 localDevice.setDiscoverable( DiscoveryAgent.GIAC ); 
    129                                 setStatus( IN_PROCESS ); 
    130                                 while( true ) { 
    131                                         server = ( StreamConnectionNotifier ) Connector.open( 
    132                                                         BTSPP_SCHEME + "localhost:" + MY_SERVICE_NUMBER, 
    133                                                         Connector.READ_WRITE, 
    134                                                         true 
    135                                         ); 
    136                                         Util.log.println( "creating server and waiting for incoming" ); 
    137                                         try { 
    138                                                 final IServerListener _listener = ( IServerListener ) listener; 
    139                                                 while( server != null ) { 
    140                                                         // Îæèäàåì âõîäÿùåå ïîòîêîâîå ñîåäèíåíèå 
    141                                                         final StreamConnection conn = server.acceptAndOpen(); 
    142                                                         Util.log.println( "accepted incoming: " + conn ); 
    143                                                         final BTNode client = new BTNode( conn ); 
    144                                                         if( _listener.incoming( client ) ) { 
    145                                                                 //åñëè êëèåíò ïðèíÿò -- âûõîäèì (èãðà äîïóñêàåò òîëüêî îäíîãî ñîïåðíèêà) 
    146                                                                 Util.log.println( "client accepted -> close server" ); 
    147                                                                 setStatus( SUCCEEDED ); 
    148                                                                 return; 
    149                                                         } 
    150                                                         client.close( true ); 
    151                                                 } 
    152                                         } catch( InterruptedIOException ex ) { 
    153                                                 //setStatus( INTERRUPTED ); 
    154                                                 //return; 
    155                                                 throw ex; 
    156                                         } catch( IOException ex ) { 
    157                                                 Util.log.println( "server got error -- trying to recreate server connection" ); 
    158                                                 ex.printStackTrace(); 
    159                                         } finally { 
    160                                                 if( server != null ) { 
    161                                                         try { 
    162                                                                 server.close(); 
    163                                                                 server = null; 
    164                                                         } catch( IOException e ) { 
    165                                                                 e.printStackTrace(); 
    166                                                         } 
    167                                                 } 
    168                                         } 
    169                                 } 
    170                         } catch( Throwable ex ) { 
    171                                 //åñëè íå óäàëîñü îòêðûòü ñîåäèíåíèå -- ýòî ïèçäåö. óõîäèì 
    172                                 //...íå óäàëîñü îïóáëèêîâàòü óñòðîéñòâî -- ïèçäåö, óõîäèì 
    173                                 if( isQueryInterrupt() ) { 
    174                                         Util.log.println( "server was closed: " + ex.getMessage() ); 
    175                                         setStatus( INTERRUPTED ); 
    176                                 } else { 
    177                                         setStatus( FAILED, ex ); 
    178                                 } 
    179                         } finally { 
    180                                 listener.finished( null ); 
    181                                 Util.log.println( "server stopped" ); 
    182                         } 
    183                 } 
    184  
    185                 public void stop( final int waitMillis ) { 
    186                         setQueryInterrupt(); 
    187                         if( isAlive() ) { 
    188                                 if( server != null ) { 
    189                                         try { 
    190                                                 server.close(); 
    191                                                 server = null; 
    192                                         } catch( IOException e ) { 
    193                                                 e.printStackTrace(); 
    194                                         } 
    195                                 } 
    196                                 waitForThread( waitMillis ); 
    197                         } 
    198                 } 
    199  
    200         } 
    201  
    202         private static class QueryDeviceProcess extends BaseAsyncProcess implements DiscoveryListener { 
    203                 private final BTRemote remote; 
    204                 private final boolean realQuery; 
    205                 private final DiscoveryAgent agent; 
    206  
    207                 private boolean finishedEventWasPost = false; 
    208  
    209                 public QueryDeviceProcess( final BTRemote remote, 
    210                                            final boolean realQuery, 
    211                                            final DiscoveryAgent agent, 
    212                                            final IClientListener listener ) { 
    213                         super( listener, "query-device-list" ); 
    214                         this.remote = remote; 
    215                         this.agent = agent; 
    216                         this.realQuery = realQuery; 
    217                         start(); 
    218                 } 
    219  
    220                 public void run() { 
    221                         setStatus( IN_PROCESS ); 
    222  
    223                         Util.log.println( "starting query device list" ); 
    224                         try { 
    225                                 /** 
    226                                  * Íåïîíÿòíî, ÿâëÿåòñÿ ëè ýòîò çàïðîñ ñèíõðîííûì, èëè àñèíõðîííûì -- 
    227                                  * äîêóìåíòàöèÿ íà ýòîò ñ÷åò ìîë÷èò, à ïðàêòèêà ïîêàçûâàåò, ÷òî 
    228                                  * áûâàåò è òàê è ýäàê. Ïîýòîìó ñòðàõóåìñÿ îò íåâåäîìîé õóéíè è 
    229                                  * äåëàåì ýòî â îòäåëüíîì ïîòîêå 
    230                                  */ 
    231                                 if( realQuery ) { 
    232                                         agent.startInquiry( DiscoveryAgent.GIAC, this ); 
    233                                 } else { 
    234                                         final IRemoteNode[] nodes = remote.getNodes(); 
    235                                         setStatus( SUCCEEDED ); 
    236                                         ensureListenerInformed( nodes ); 
    237                                 } 
    238                         } catch( Throwable e ) { 
    239                                 if( isQueryInterrupt() ) { 
    240                                         setStatus( INTERRUPTED ); 
    241                                 } else { 
    242                                         setStatus( FAILED, e ); 
    243                                 } 
    244                                 ensureListenerInformed( null ); 
    245                         } finally { 
    246 //                              synchronized( this ) { 
    247 //                                      notifyAll(); 
    248 //                              } 
    249                         } 
    250                 } 
    251  
    252                 private synchronized void ensureListenerInformed( final IRemoteNode[] nodes ) { 
    253                         if( !finishedEventWasPost ) { 
    254                                 listener.finished( nodes ); 
    255                                 finishedEventWasPost = true; 
    256                         } 
    257                 } 
    258  
    259  
    260                 public void stop( final int waitMillis ) { 
    261                         setQueryInterrupt(); 
    262                         if( status() == IN_PROCESS ) { 
    263                                 if( realQuery ) { 
    264                                         agent.cancelInquiry( this ); 
    265                                 } else { 
    266                                         interrupt(); 
    267                                 } 
    268                                 waitForThread( waitMillis ); 
    269                         } 
    270                         if( status() == IN_PROCESS ) { 
    271                                 setStatus( INTERRUPTED ); 
    272                         } 
    273                         ensureListenerInformed( null ); 
    274                 } 
    275  
    276                 public void deviceDiscovered( final RemoteDevice btDevice, 
    277                                               final DeviceClass cod ) { 
    278                         Util.log.println( "device found:" + btDevice.getBluetoothAddress() ); 
    279                 } 
    280  
    281                 public void servicesDiscovered( final int transID, 
    282                                                 final ServiceRecord[] servRecord ) { 
    283                         //Util.log.println( "service found:" + transID ); 
    284                 } 
    285  
    286                 public void serviceSearchCompleted( final int transID, 
    287                                                     final int respCode ) { 
    288  
    289                 } 
    290  
    291                 public void inquiryCompleted( final int discType ) { 
    292                         remote.refreshCache(); 
    293                         switch( discType ) { 
    294                                 case INQUIRY_COMPLETED: 
    295                                         Util.log.println( "device list query finished" ); 
    296                                         setStatus( SUCCEEDED ); 
    297                                         ensureListenerInformed( remote.getNodes() ); 
    298                                         break; 
    299                                 case INQUIRY_TERMINATED: 
    300                                         Util.log.println( "device list query interrupted" ); 
    301                                         setStatus( INTERRUPTED ); 
    302                                         ensureListenerInformed( null ); 
    303                                         break; 
    304                                 case INQUIRY_ERROR: 
    305                                         Util.log.println( "device list query failed" ); 
    306                                         setStatus( FAILED ); 
    307                                         ensureListenerInformed( null ); 
    308                                         break; 
    309                                 default: 
    310                                         setStatus( FAILED ); 
    311                                         ensureListenerInformed( null ); 
    312                                         throw new IllegalStateException( "Unknown type:" + discType ); 
    313                         } 
    314                 } 
    315         } 
     22    public static final String SCHEME = "btspp://"; 
     23    public static final String SERVER_SUUID = "3B9FA89520078C303355AAA694238FF9"; 
     24    public static final UUID SERVER_UUID = new UUID( SERVER_SUUID, false ); 
     25    public static final String SERVER_NAME = "ChessGameServer"; 
     26 
     27    public static final IRemoteNode[] EMPTY = new IRemoteNode[0]; 
     28 
     29    private final LocalDevice localDevice; 
     30    private final Vector devices = new Vector(); 
     31 
     32    public BTRemote() throws Exception { 
     33        localDevice = LocalDevice.getLocalDevice(); 
     34        fillupCache(); 
     35    } 
     36 
     37    private synchronized void fillupCache() { 
     38        final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 
     39        final RemoteDevice[] preknownDevices = agent.retrieveDevices( DiscoveryAgent.PREKNOWN ); 
     40        if ( preknownDevices != null ) { 
     41            for ( int i = 0; i < preknownDevices.length; i++ ) { 
     42                final RemoteDevice device = preknownDevices[i]; 
     43                devices.addElement( device ); 
     44            } 
     45        } 
     46        final RemoteDevice[] cachedDevices = agent.retrieveDevices( DiscoveryAgent.CACHED ); 
     47        if ( cachedDevices != null ) { 
     48            for ( int i = 0; i < cachedDevices.length; i++ ) { 
     49                final RemoteDevice device = cachedDevices[i]; 
     50                devices.addElement( device ); 
     51            } 
     52        } 
     53    } 
     54 
     55    private synchronized void refreshCache() { 
     56        devices.removeAllElements(); 
     57        fillupCache(); 
     58    } 
     59 
     60    public IAsyncProcess waitForIncoming( final IServerListener l ) { 
     61        return new WaitForIncomingThread( localDevice, l ); 
     62    } 
     63 
     64    public IAsyncProcess getAvailable( final boolean refresh, 
     65                                       final IClientListener listener ) { 
     66        final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 
     67        return new QueryDeviceProcess( this, refresh, agent, listener ); 
     68    } 
     69 
     70    private synchronized IRemoteNode[] getNodes() { 
     71        if ( devices.isEmpty() ) { 
     72            return EMPTY; 
     73        } 
     74        final int length = devices.size(); 
     75        final IRemoteNode[] nodes = new IRemoteNode[devices.size()]; 
     76        boolean wasFailed = false; 
     77        for ( int i = 0; i < length; i++ ) { 
     78            try { 
     79                final RemoteDevice device = ( RemoteDevice )devices.elementAt( i ); 
     80                final BTNode node = new BTNode( device ); 
     81                nodes[i] = node; 
     82            } catch ( IOException e ) { 
     83                wasFailed = true; 
     84                e.printStackTrace(); 
     85            } 
     86        } 
     87        if ( wasFailed ) { 
     88            //óäàëÿåì ïóñòûå ÿ÷åéêè 
     89            final Vector res = new Vector( nodes.length ); 
     90            for ( int i = 0; i < nodes.length; i++ ) { 
     91                final IRemoteNode node = nodes[i]; 
     92                if ( node != null ) { 
     93                    res.addElement( node ); 
     94                } 
     95            } 
     96 
     97            final IRemoteNode[] _nodes = new IRemoteNode[res.size()]; 
     98            res.copyInto( _nodes ); 
     99            return _nodes; 
     100        } else { 
     101            return nodes; 
     102        } 
     103    } 
     104 
     105    private static class WaitForIncomingThread extends BaseAsyncProcess { 
     106        private final LocalDevice localDevice; 
     107        private StreamConnectionNotifier server; 
     108 
     109        public WaitForIncomingThread( final LocalDevice local, 
     110                                      final IServerListener listener ) { 
     111            super( listener, "wait-for-incoming" ); 
     112            this.localDevice = local; 
     113            start(); 
     114        } 
     115 
     116        protected void runImpl() { 
     117            try { 
     118                localDevice.setDiscoverable( DiscoveryAgent.GIAC ); 
     119                while ( !isInterruptQueried() ) { 
     120                    server = ( StreamConnectionNotifier )Connector.open( 
     121                            SCHEME + "localhost:" + SERVER_SUUID + ";name=" + SERVER_NAME, 
     122                            Connector.READ_WRITE, 
     123                            true 
     124                    ); 
     125                    Util.log.println( "creating server and waiting for incoming" ); 
     126                    try { 
     127                        final IServerListener _listener = ( IServerListener )listener; 
     128                        while ( !isInterruptQueried() && server != null ) { 
     129                            // Îæèäàåì âõîäÿùåå ïîòîêîâîå ñîåäèíåíèå 
     130                            final StreamConnection conn = server.acceptAndOpen(); 
     131                            Util.log.println( "accepted incoming: " + conn ); 
     132                            final BTNode client = new BTNode( conn ); 
     133                            if ( _listener.incoming( client ) ) { 
     134                                //åñëè êëèåíò ïðèíÿò -- âûõîäèì (èãðà äîïóñêàåò òîëüêî îäíîãî ñîïåðíèêà) 
     135                                Util.log.println( "client accepted -> close server" ); 
     136                                setStatus( SUCCEEDED ); 
     137                                return; 
     138                            } else { 
     139                                client.close( true ); 
     140                            } 
     141                        } 
     142                    } catch ( InterruptedIOException ex ) { 
     143                        throw ex; 
     144                    } catch ( IOException ex ) { 
     145                        Util.log.println( "server got error -- trying to recreate server connection" ); 
     146                        ex.printStackTrace(); 
     147                    } finally { 
     148                        if ( server != null ) { 
     149                            try { 
     150                                server.close(); 
     151                                server = null; 
     152                            } catch ( IOException e ) { 
     153                                e.printStackTrace(); 
     154                            } 
     155                        } 
     156                    } 
     157                } 
     158            } catch ( Throwable ex ) { 
     159                //åñëè íå óäàëîñü îòêðûòü ñîåäèíåíèå -- ýòî ïèçäåö. óõîäèì 
     160                //...íå óäàëîñü îïóáëèêîâàòü óñòðîéñòâî -- ïèçäåö, óõîäèì 
     161                if ( isInterruptQueried() ) { 
     162                    Util.log.println( "server was closed: " + ex.getMessage() ); 
     163                    setStatus( INTERRUPTED ); 
     164                } else { 
     165                    setStatus( FAILED, ex ); 
     166                } 
     167            } finally { 
     168                postFinishedEvent( null ); 
     169                Util.log.println( "server stopped" ); 
     170            } 
     171        } 
     172 
     173        public void stop( final int waitMillis ) { 
     174            queryForInterrupt(); 
     175            if ( isAlive() ) { 
     176                if ( server != null ) { 
     177                    try { 
     178                        server.close(); 
     179                        server = null; 
     180                    } catch ( IOException e ) { 
     181                        e.printStackTrace(); 
     182                    } 
     183                } 
     184                waitForThread( waitMillis ); 
     185            } 
     186        } 
     187    } 
     188 
     189    private static class QueryDeviceProcess extends BaseAsyncProcess implements DiscoveryListener { 
     190        private final BTRemote remote; 
     191        private final boolean realQuery; 
     192        private final DiscoveryAgent agent; 
     193 
     194        public QueryDeviceProcess( final BTRemote remote, 
     195                                   final boolean realQuery, 
     196                                   final DiscoveryAgent agent, 
     197                                   final IClientListener listener ) { 
     198            super( listener, "query-device-list" ); 
     199            this.remote = remote; 
     200            this.agent = agent; 
     201            this.realQuery = realQuery; 
     202            start(); 
     203        } 
     204 
     205        protected void runImpl() { 
     206            Util.log.println( "starting query device list" ); 
     207            try { 
     208                /** 
     209                 * Íåïîíÿòíî, ÿâëÿåòñÿ ëè ýòîò çàïðîñ ñèíõðîííûì, èëè àñèíõðîííûì -- 
     210                 * äîêóìåíòàöèÿ íà ýòîò ñ÷åò ìîë÷èò, à ïðàêòèêà ïîêàçûâàåò, ÷òî 
     211                 * áûâàåò è òàê è ýäàê. Ïîýòîìó ñòðàõóåìñÿ îò íåâåäîìîé õóéíè è 
     212                 * äåëàåì ýòî â îòäåëüíîì ïîòîêå 
     213                 */ 
     214                if ( realQuery ) { 
     215                    final boolean res = agent.startInquiry( DiscoveryAgent.GIAC, this ); 
     216                    if ( !res ) { 
     217                        if ( isInterruptQueried() ) { 
     218                            setStatus( INTERRUPTED ); 
     219                        } else { 
     220                            setStatus( FAILED ); 
     221                        } 
     222                        postFinishedEvent( null ); 
     223                    } 
     224                } else { 
     225                    final IRemoteNode[] nodes = remote.getNodes(); 
     226                    setStatus( SUCCEEDED ); 
     227                    postFinishedEvent( nodes ); 
     228                } 
     229            } catch ( Throwable e ) { 
     230                if ( isInterruptQueried() ) { 
     231                    setStatus( INTERRUPTED ); 
     232                } else { 
     233                    setStatus( FAILED, e ); 
     234                } 
     235                postFinishedEvent( null ); 
     236            } 
     237        } 
     238 
     239        public void stop( final int waitMillis ) { 
     240            queryForInterrupt(); 
     241            if ( status() == IN_PROCESS ) { 
     242                if ( realQuery ) { 
     243                    final boolean res = agent.cancelInquiry( this ); 
     244                    if ( !res ) { 
     245                        interrupt(); 
     246                    } 
     247                } else { 
     248                    interrupt(); 
     249                } 
     250                waitForThread( waitMillis ); 
     251            } 
     252            /** Äåëàåì ýòî íà âñÿêèé ñëó÷àé -- èíîãäà ïî÷åìó-òî 
     253             * ïðè îòìåíå çàïðîñà inquiryCompleted íå âûçûâàåòñÿ 
     254             */ 
     255            if ( status() == IN_PROCESS ) { 
     256                setStatus( INTERRUPTED ); 
     257            } 
     258            postFinishedEvent( null ); 
     259        } 
     260 
     261        private static final int SERVICE_NAME_ATTR_ID = 0x0100; 
     262        private static final int[] attrSet = new int[]{ SERVICE_NAME_ATTR_ID }; 
     263        private static final UUID[] uuids = new UUID[]{ SERVER_UUID }; 
     264 
     265        public void deviceDiscovered( final RemoteDevice btDevice, 
     266                                      final DeviceClass cod ) { 
     267            Util.log.println( "device found:" + btDevice.getBluetoothAddress() ); 
     268            try { 
     269                final int transID = agent.searchServices( attrSet, uuids, btDevice, this ); 
     270            } catch ( BluetoothStateException e ) { 
     271                e.printStackTrace(); 
     272            } 
     273        } 
     274 
     275        public void servicesDiscovered( final int transID, 
     276                                        final ServiceRecord[] servRecord ) { 
     277            Util.log.println( "services found, transID=" + transID ); 
     278            for ( int i = 0; i < servRecord.length; i++ ) { 
     279                final ServiceRecord record = servRecord[i]; 
     280                final String cUrl = record.getConnectionURL( ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false ); 
     281                final DataElement value = record.getAttributeValue( SERVICE_NAME_ATTR_ID ); 
     282                Util.log.println( "\tservice:" + cUrl + ", name=" + value.getValue() ); 
     283            } 
     284        } 
     285 
     286        public void serviceSearchCompleted( final int transID, 
     287                                            final int respCode ) { 
     288            Util.log.println( "service search completed:" + transID ); 
     289        } 
     290 
     291        public void inquiryCompleted( final int discType ) { 
     292            remote.refreshCache(); 
     293            switch ( discType ) { 
     294                case INQUIRY_COMPLETED: 
     295                    Util.log.println( "device list query finished" ); 
     296                    setStatus( SUCCEEDED ); 
     297                    postFinishedEvent( remote.getNodes() ); 
     298                    break; 
     299                case INQUIRY_TERMINATED: 
     300                    Util.log.println( "device list query interrupted" ); 
     301                    setStatus( INTERRUPTED ); 
     302                    postFinishedEvent( null ); 
     303                    break; 
     304                case INQUIRY_ERROR: 
     305                    Util.log.println( "device list query failed" ); 
     306                    setStatus( FAILED ); 
     307                    postFinishedEvent( null ); 
     308                    break; 
     309                default: 
     310                    setStatus( FAILED ); 
     311                    postFinishedEvent( null ); 
     312                    throw new IllegalStateException( "Unknown type:" + discType ); 
     313            } 
     314        } 
     315    } 
    316316} 
  • chess/src/chess/remote/impl/BaseAsyncProcess.java

    r37 r38  
    44import chess.remote.IAsyncProcess; 
    55import chess.remote.IAsyncProcessListener; 
     6import chess.remote.IRemoteNode; 
    67 
    78/** 
     
    1112 * Time: 18:31:21<br/> 
    1213 */ 
    13 public class BaseAsyncProcess extends Thread implements IAsyncProcess { 
     14public abstract class BaseAsyncProcess extends Thread implements IAsyncProcess { 
    1415    protected final IAsyncProcessListener listener; 
    1516 
    1617    private int status = NOT_STARTED; 
    1718    private Throwable lastError = null; 
    18     private volatile boolean queryInterrupt = false; 
     19    /** 
     20     * "çàïðîñ íà ïðåêðàùåíèå": ôëàã, ñèãíàëèçèðóþùèé ïîòîêó, ÷òî åìó áû ïîðà 
     21     * çàâåðøàòüñÿ. Óñòàíàâëèâàåòñÿ â ìåòîäå {@link BaseAsyncProcess#stop(int);} 
     22     */ 
     23    private boolean interruptQueried = false; 
     24 
     25    private final Object threadFinishedLock = new Object(); 
     26    private boolean finishedEventWasPost = false; 
    1927 
    2028    public BaseAsyncProcess( final IAsyncProcessListener listener ) { 
     
    2230    } 
    2331 
    24         public BaseAsyncProcess( final IAsyncProcessListener listener, 
    25                                  final String name ) { 
     32    public BaseAsyncProcess( final IAsyncProcessListener listener, 
     33                             final String name ) { 
     34        super( name ); 
    2635        this.listener = listener; 
    2736    } 
    2837 
    29     public final int status() { 
     38    public final synchronized int status() { 
    3039        return status; 
    3140    } 
    3241 
    33     protected synchronized final boolean isQueryInterrupt() { 
    34         return queryInterrupt; 
     42    protected final synchronized boolean isInterruptQueried() { 
     43        return interruptQueried; 
    3544    } 
    3645 
    37     protected synchronized void setQueryInterrupt() { 
    38         this.queryInterrupt = true; 
     46    protected final synchronized void queryForInterrupt() { 
     47        this.interruptQueried = true; 
    3948    } 
    4049 
     
    6170    } 
    6271 
     72    public final void run() { 
     73        setStatus( IN_PROCESS ); 
     74        try { 
     75            runImpl(); 
     76        } catch ( Throwable t ) { 
     77            t.printStackTrace(); 
     78        } finally { 
     79            synchronized ( threadFinishedLock ) { 
     80                threadFinishedLock.notifyAll(); 
     81            } 
     82        } 
     83    } 
     84 
     85    protected abstract void runImpl(); 
     86 
    6387    public void stop( final int waitMillis ) { 
    64         setQueryInterrupt(); 
     88        queryForInterrupt(); 
    6589        if ( isAlive() ) { 
    6690            interrupt(); 
     
    6993    } 
    7094 
     95    /** 
     96     * @param waitMillis if 0, then wait until thread really finished (via join()), 
     97     *                   if >0 then no more then waitMillis milliseconds (via wait(waitMIllis)), 
     98     *                   if <0 then no wait at all 
     99     */ 
    71100    protected void waitForThread( final int waitMillis ) { 
    72         if ( waitMillis > 0 
     101        if ( waitMillis >= 0 
    73102                && isAlive() 
    74103                && Thread.currentThread() != this ) { 
    75104            Util.log.println( "waiting for thread to finish" ); 
    76             synchronized ( this ) { 
    77                 try { 
    78                     wait( waitMillis ); 
    79                 } catch ( InterruptedException e ) { 
     105            try { 
     106                if ( waitMillis > 0 ) { 
     107                    synchronized ( threadFinishedLock ) { 
     108                        threadFinishedLock.wait( waitMillis ); 
     109                    } 
     110                } else { 
     111                    //synchronized ( this ) { 
     112                    join(); 
     113                    //} 
    80114                } 
     115            } catch ( InterruptedException e ) { 
    81116            } 
     117 
    82118        } 
    83119    } 
     
    87123    } 
    88124 
    89     public Throwable getError() { 
     125    public final Throwable getError() { 
    90126        return lastError; 
    91127    } 
     128 
     129    protected synchronized void postFinishedEvent( final Object res ) { 
     130        if ( !finishedEventWasPost ) { 
     131            listener.finished( res ); 
     132            finishedEventWasPost = true; 
     133        } else { 
     134            Util.log.println( "WARN:dublicate 'finished' event post!" ); 
     135            new Exception().printStackTrace(); 
     136        } 
     137    } 
    92138} 
  • chess/src/chess/remote/impl/debug/DebugRemote.java

    r34 r38  
    105105        } 
    106106 
    107         public void run() { 
     107        protected void runImpl() { 
     108            //setStatus( IN_PROCESS ); 
    108109            try { 
    109                 setStatus( IN_PROCESS ); 
    110110                final IServerListener _listener = ( IServerListener )listener; 
    111111                while ( true ) { 
     
    124124                setStatus( FAILED ); 
    125125            } finally { 
    126                 listener.finished( null ); 
     126                postFinishedEvent( null ); 
    127127            } 
    128128        } 
  • chess/src/chess/ui/GameCanvas.java

    r37 r38  
    505505        return getStatus() == ACTIVE; 
    506506    } 
    507  
    508     //public void repaint(){ 
    509     //    this.repaint(); 
    510     //} 
    511507} 
  • chess/src/chess/ui/JoinGameScreen.java

    r37 r38  
    1616 */ 
    1717public class JoinGameScreen extends BaseListScreen 
    18                 implements IChoiceListener, IClientListener { 
    19         //private final ChessMIDlet midlet; 
     18        implements IChoiceListener, IClientListener { 
     19    //private final ChessMIDlet midlet; 
    2020 
    21         private IRemoteNode[] nodes; 
    22         private boolean force; 
     21    private IRemoteNode[] nodes; 
     22    private boolean force; 
    2323 
    24         private final Alert nothingFoundAlert = new Alert( 
    25                         MSG.getMessage( "join-game.no-server-found.title" ), 
    26                         MSG.getMessage( "join-game.no-server-found.message" ), 
    27                         null, 
    28                         AlertType.INFO 
    29         ); 
     24    private final Alert nothingFoundAlert = new Alert( 
     25            MSG.getMessage( "join-game.no-server-found.title" ), 
     26            MSG.getMessage( "join-game.no-server-found.message" ), 
     27            null, 
     28            AlertType.INFO 
     29    ); 
    3030 
    31         private final Alert scanningNetworkAlert = new Alert( 
    32                         MSG.getMessage( "join-game.scanning-network.title" ), 
    33                         MSG.getMessage( "join-game.scanning-network.message" ), 
    34                         null, 
    35                         AlertType.INFO 
    36         ); 
     31    private final Alert scanningNetworkAlert = new Alert( 
     32            MSG.getMessage( "join-game.scanning-network.title" ), 
     33            MSG.getMessage( "join-game.scanning-network.message" ), 
     34            null, 
     35            AlertType.INFO 
     36    ); 
    3737 
    38         private IAsyncProcess asyncProcess; 
     38    private IAsyncProcess asyncProcess; 
    3939 
    40         public JoinGameScreen( final ChessMIDlet midlet ) { 
    41                 super( midlet, MSG.getMessage( "join-game.title" ) ); 
     40    public JoinGameScreen( final ChessMIDlet midlet ) { 
     41        super( midlet, MSG.getMessage( "join-game.title" ) ); 
    4242 
    43                 scanningNetworkAlert.setTimeout( Alert.FOREVER ); 
    44                 scanningNetworkAlert.addCommand( midlet.cancelCommand ); 
    45                 scanningNetworkAlert.setCommandListener( this ); 
     43        scanningNetworkAlert.setTimeout( Alert.FOREVER ); 
     44        scanningNetworkAlert.addCommand( midlet.cancelCommand ); 
     45        scanningNetworkAlert.setCommandListener( this ); 
    4646 
    47                 addCommand( midlet.refreshCommand ); 
    48                 addCommand( midlet.backCommand ); 
     47        addCommand( midlet.refreshCommand ); 
     48        addCommand( midlet.backCommand ); 
    4949 
    50                 setChoiceListener( this ); 
    51         } 
     50        setChoiceListener( this ); 
     51    } 
    5252 
    5353//      public void run() { 
     
    5555//      } 
    5656 
    57         public void refresh( final boolean force ) { 
    58                 this.force = force; 
    59                 ensureSearcherClosed(); 
    60                 midlet.display.setCurrent( scanningNetworkAlert ); 
    61                 asyncProcess = midlet.getRemoteManager().getAvailable( this.force, this ); 
    62         } 
     57    public void refresh( final boolean force ) { 
     58        this.force = force; 
     59        ensureSearcherClosed(); 
     60        midlet.display.setCurrent( scanningNetworkAlert ); 
     61        synchronized ( this ) { 
     62            asyncProcess = midlet.getRemoteManager().getAvailable( this.force, this ); 
     63        } 
     64    } 
    6365 
    64         public void finished( final Object res ) { 
    65                 final IRemoteNode[] servers = ( IRemoteNode[] ) res; 
    66                 removeAllItems(); 
    67                 nodes = servers; 
     66    public synchronized void finished( final Object res ) { 
     67        final IRemoteNode[] servers = ( IRemoteNode[] )res; 
     68        removeAllItems(); 
     69        nodes = servers; 
    6870 
    69                 final boolean nothingFound = ( servers == null || servers.length == 0 ); 
    70                 if( nothingFound ) { 
    71                         final int status = asyncProcess.status(); 
    72                         if( status == IAsyncProcess.FAILED ) { 
    73                                 final Throwable e = asyncProcess.getError(); 
    74                                 if( e != null ) { 
    75                                         final Alert alert = Util.createErrorDialog( e ); 
    76                                         midlet.display.setCurrent( alert, this ); 
    77                                 } 
    78                         } else if( status == IAsyncProcess.INTERRUPTED ) { 
    79                                 final Alert alert = new Alert( 
    80                                                 MSG.getMessage( "alert.warning" ), 
    81                                                 MSG.getMessage( "join-game.search-interrupted.message" ), 
    82                                                 null, 
    83                                                 AlertType.WARNING 
    84                                 ); 
    85                                 midlet.display.setCurrent( alert, this ); 
    86                         } else if( force ) { 
    87                                 //åñëè èñêàëè â ñåòè è íè÷åãî íå íàøëè -- íå ñóäüáà 
    88                                 midlet.display.setCurrent( nothingFoundAlert, this ); 
    89                         } else { 
    90                                 //åñëè èñêàëè â êýøå... 
    91                                 //...è íèõåðà íå íàøëè -- ïðèäåòñÿ îïðîñèòü ñåòü è îáíîâèòü êýø 
    92                                 refresh( true ); 
    93                         } 
    94                 } else { 
    95                         for( int i = 0; i < nodes.length; i++ ) { 
    96                                 final IRemoteNode node = nodes[i]; 
    97                                 addItem( node.getName() ); 
    98                         } 
    99                         midlet.display.setCurrent( this ); 
    100                 } 
    101         } 
     71        final boolean nothingFound = ( servers == null || servers.length == 0 ); 
     72        if ( nothingFound ) { 
     73            final int status = asyncProcess.status(); 
     74            if ( status == IAsyncProcess.FAILED ) { 
     75                final Throwable e = asyncProcess.getError(); 
     76                if ( e != null ) { 
     77                    final Alert alert = Util.createErrorDialog( e ); 
     78                    midlet.display.setCurrent( alert, this ); 
     79                } 
     80            } else if ( status == IAsyncProcess.INTERRUPTED ) { 
     81                final Alert alert = new Alert( 
     82                        MSG.getMessage( "alert.warning" ), 
     83                        MSG.getMessage( "join-game.search-interrupted.message" ), 
     84                        null, 
     85                        AlertType.WARNING 
     86                ); 
     87                midlet.display.setCurrent( alert, this ); 
     88            } else if ( force ) { 
     89                //åñëè èñêàëè â ñåòè è íè÷åãî íå íàøëè -- íå ñóäüáà 
     90                midlet.display.setCurrent( nothingFoundAlert, this ); 
     91            } else { 
     92                //åñëè èñêàëè â êýøå... 
     93                //...è íèõåðà íå íàøëè -- ïðèäåòñÿ îïðîñèòü ñåòü è îáíîâèòü êýø 
     94                refresh( true ); 
     95            } 
     96        } else { 
     97            for ( int i = 0; i < nodes.length; i++ ) { 
     98                final IRemoteNode node = nodes[i]; 
     99                addItem( node.getName() ); 
     100            } 
     101            midlet.display.setCurrent( this ); 
     102        } 
     103    } 
    102104 
    103         public void commandAction( final Command command, 
    104                                    final Displayable displayable ) { 
    105                 if( displayable == scanningNetworkAlert ) { 
    106                         if( command == midlet.cancelCommand ) { 
    107                                 ensureSearcherClosed(); 
     105    public void commandAction( final Command command, 
     106                               final Displayable displayable ) { 
     107        if ( displayable == scanningNetworkAlert ) { 
     108            if ( command == midlet.cancelCommand ) { 
     109                ensureSearcherClosed(); 
    108110//                              scanningNetworkAlert.setString( "Cancelled" ); 
    109                         } 
    110                 } 
    111                 super.commandAction( command, displayable ); 
    112         } 
     111            } 
     112        } 
     113        super.commandAction( command, displayable ); 
     114    } 
    113115 
    114         public void choosed( final Command c, 
    115                              final int selectedIndex ) { 
    116                 if( c == getDefaultCommand() ) { 
    117                         if( selectedIndex >= 0 && selectedIndex < nodes.length ) { 
    118                                 final IRemoteNode server = nodes[selectedIndex]; 
    119                                 midlet.connectToServer( server ); 
    120                         } 
    121                 } else if( c == midlet.backCommand ) { 
    122                         ensureSearcherClosed(); 
    123                         midlet.showStartScreen(); 
    124                 } else if( c == midlet.refreshCommand ) { 
    125                         refresh( true ); 
    126                 } 
    127         } 
     116    public void choosed( final Command c, 
     117                         final int selectedIndex ) { 
     118        if ( c == getDefaultCommand() ) { 
     119            if ( selectedIndex >= 0 && selectedIndex < nodes.length ) { 
     120                final IRemoteNode server = nodes[selectedIndex]; 
     121                midlet.connectToServer( server ); 
     122            } 
     123        } else if ( c == midlet.backCommand ) { 
     124            ensureSearcherClosed(); 
     125            midlet.showStartScreen(); 
     126        } else if ( c == midlet.refreshCommand ) { 
     127            refresh( true ); 
     128        } 
     129    } 
    128130 
    129         private void ensureSearcherClosed() { 
    130                 if( asyncProcess != null ) { 
    131                         asyncProcess.stop( 1000 ); 
    132                         //asyncProcess = null; 
    133                 } 
    134         } 
     131    private void ensureSearcherClosed() { 
     132        if ( asyncProcess != null ) { 
     133            asyncProcess.stop( 1000 ); 
     134            //asyncProcess = null; 
     135        } 
     136    } 
    135137} 
Note: See TracChangeset for help on using the changeset viewer.