- Timestamp:
- 02/09/09 09:54:45 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
chess/src/chess/remote/impl/BTNode.java
r30 r31 21 21 */ 22 22 public class BTNode implements IRemoteNode, Runnable { 23 /** 24 * êàíàë BT, èñïîëüçóåìûé íàøèì ïðèëîæåíèåì 25 * todo ïîíÿòü, êàêèå êàíàëû ñóùåñòâóþò 26 */ 27 private static final String BT_STREAM = "1"; 28 29 private String name; 30 31 private RemoteDevice device; 32 private IConnectionListener listener = null; 33 private StreamConnection connection = null; 34 35 private transient InputStream in; 36 private transient OutputStream out; 37 private transient Thread pump; 38 39 /** ìîíèòîð îæèäàíèÿ îòêðûòèÿ ñîåäèíåíèÿ */ 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 */ 40 42 // private final Object connectLock = new Object(); 41 43 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 } 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*/false ); 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 while ( true ) { 108 //áëîêèðóåì this ÷òîáû íàñ íå çàêðûëè íåâîâðåìÿ 109 synchronized ( this ) { 110 checkConnected(); 111 try { 112 synchronized ( postQueue ) { 113 //áëîêèðóåì î÷åðåäü, ÷òîáû ïðåäóïðåäèòü åå èçìåíåíèÿ 114 for ( int i = 0; i < postQueue.length; i++ ) { 115 if ( postQueue[i] == null ) { 116 postQueue[i] = data; 117 return; 118 } 119 } 120 } 121 } finally { 122 notifyAll();//push pump to run 123 } 124 } 125 //åñëè î÷åðåäü ïåðåïîëíåíà -- âûíóæäåíû æäàòü 126 synchronized ( queueOverloadedLock ) { 127 try { 128 queueOverloadedLock.wait( 250 ); 129 } catch ( InterruptedException e ) { 130 e.printStackTrace(); 131 } 132 } 133 } 134 } 135 136 public void run() { 137 try { 138 synchronized ( this ) { 139 if ( isClosed() ) { 140 return; 141 } 142 openPipeline(); 143 } 144 if ( listener != null ) { 145 listener.connected(); 146 } 154 147 // synchronized( connectLock ) { 155 148 // connectLock.notifyAll(); 156 149 // } 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 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 } 150 final GenericDatagram data = new GenericDatagram(); 151 while ( !isClosed() ) { 152 synchronized ( this ) { 153 final int timeout; 154 //îòïðàâëÿåì íåîòïðàâëåííîå 155 synchronized ( postQueue ) { 156 for ( int i = 0; i < postQueue.length; i++ ) { 157 final IDatagram packet = postQueue[i]; 158 if ( packet != null ) { 159 data.setWrapped( packet ); 160 data.write( out ); 161 postQueue[i] = null; 162 if ( listener != null ) { 163 listener.wasSent( packet ); 164 } 165 } 166 } 167 } 168 synchronized ( queueOverloadedLock ) { 169 //îïîâåùàåì, ÷òî î÷åðåäü îñâîáîäèëàñü 170 queueOverloadedLock.notifyAll(); 171 } 172 //÷èòàåì íåäî÷èòàííîå 173 if ( in.available() > 0 ) { 174 data.read( in ); 175 if ( listener != null ) { 176 listener.received( data.wrapped() ); 177 } 178 timeout = 50; 179 } else { 180 timeout = 250; 181 } 182 try { 183 wait( timeout ); 184 } catch ( InterruptedException e ) { 185 } 186 } 187 } 188 } catch ( Throwable e ) { 189 e.printStackTrace(); 190 } finally { 191 pump = null; 192 close(); 193 } 194 } 195 196 public void close() { 197 if ( isClosed() ) { 198 return; 199 } 200 try { 201 if ( in != null ) { 202 try { 203 in.close(); 204 } catch ( IOException e ) { 205 e.printStackTrace(); 206 } finally { 207 in = null; 208 } 209 } 210 if ( out != null ) { 211 try { 212 out.close(); 213 } catch ( IOException e ) { 214 e.printStackTrace(); 215 } finally { 216 out = null; 217 } 218 } 219 if ( connection != null ) { 220 try { 221 connection.close(); 222 } catch ( IOException e ) { 223 e.printStackTrace(); 224 } finally { 225 connection = null; 226 } 227 } 228 229 if ( pump != null && pump.isAlive() ) { 230 pump.interrupt(); 231 if ( pump != Thread.currentThread() ) { 232 try { 233 pump.join(); 234 } catch ( InterruptedException e ) { 235 e.printStackTrace(); 236 } 237 } 238 } 239 for ( int i = 0; i < postQueue.length; i++ ) { 240 postQueue[i] = null; 241 } 242 } finally { 243 pump = null; 244 device = null; 245 if ( listener != null ) { 246 listener.closed(); 247 } 248 } 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 } 315 315 }
Note: See TracChangeset
for help on using the changeset viewer.