2020-08-18 23:13:36 +02:00
package it.tdlight.tdlight ;
2020-08-20 01:59:56 +02:00
import it.tdlight.tdlib.TdApi.Object ;
import it.tdlight.tdlib.NativeClient ;
2020-08-18 23:13:36 +02:00
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.List ;
import java.util.concurrent.locks.ReentrantLock ;
import java.util.concurrent.locks.StampedLock ;
/ * *
* Interface for interaction with TDLib .
* /
public class Client extends NativeClient implements TelegramClient {
private long clientId ;
private final ReentrantLock receiveLock = new ReentrantLock ( ) ;
private final StampedLock executionLock = new StampedLock ( ) ;
2020-09-02 16:01:58 +02:00
private volatile Long stampedLockValue ;
2020-08-18 23:13:36 +02:00
/ * *
* Creates a new TDLib client .
* /
2020-09-02 16:01:58 +02:00
public Client ( ) {
try {
Init . start ( ) ;
} catch ( Throwable throwable ) {
throwable . printStackTrace ( ) ;
System . exit ( 1 ) ;
}
this . clientId = createNativeClient ( ) ;
}
2020-08-18 23:13:36 +02:00
@Override
public void send ( Request request ) {
if ( this . executionLock . isWriteLocked ( ) ) {
throw new IllegalStateException ( " ClientActor is destroyed " ) ;
}
nativeClientSend ( this . clientId , request . getId ( ) , request . getFunction ( ) ) ;
}
private long [ ] eventIds ;
private Object [ ] events ;
@Override
2020-09-02 14:56:46 +02:00
public List < Response > receive ( double timeout , int eventSize , boolean receiveResponses , boolean receiveUpdates ) {
2020-08-18 23:13:36 +02:00
if ( this . executionLock . isWriteLocked ( ) ) {
throw new IllegalStateException ( " ClientActor is destroyed " ) ;
}
2020-08-20 13:59:38 +02:00
ArrayList < Response > responseList = new ArrayList < > ( ) ;
2020-08-18 23:13:36 +02:00
if ( eventIds = = null ) {
eventIds = new long [ eventSize ] ;
events = new Object [ eventSize ] ;
} else if ( eventIds . length ! = eventSize ) {
throw new IllegalArgumentException ( " EventSize can't change! Previous value = " + eventIds . length + " New value = " + eventSize ) ;
} else {
Arrays . fill ( eventIds , 0 ) ;
Arrays . fill ( events , null ) ;
}
if ( this . receiveLock . isLocked ( ) ) {
throw new IllegalThreadStateException ( " Thread: " + Thread . currentThread ( ) . getName ( ) + " trying receive incoming updates but shouldn't be called simultaneously from two different threads! " ) ;
}
int resultSize ;
this . receiveLock . lock ( ) ;
try {
2020-09-02 14:56:46 +02:00
resultSize = nativeClientReceive ( this . clientId , eventIds , events , timeout , receiveResponses , receiveUpdates ) ;
2020-08-18 23:13:36 +02:00
} finally {
this . receiveLock . unlock ( ) ;
}
for ( int i = 0 ; i < resultSize ; i + + ) {
responseList . add ( new Response ( eventIds [ i ] , events [ i ] ) ) ;
}
return responseList ;
}
@Override
2020-09-02 14:56:46 +02:00
public Response receive ( double timeout , boolean receiveResponses , boolean receiveUpdates ) {
2020-08-18 23:13:36 +02:00
if ( this . executionLock . isWriteLocked ( ) ) {
throw new IllegalStateException ( " ClientActor is destroyed " ) ;
}
2020-09-02 14:56:46 +02:00
List < Response > responseList = receive ( timeout , 1 , receiveResponses , receiveUpdates ) ;
2020-08-18 23:13:36 +02:00
if ( responseList . size ( ) < 1 ) {
return null ;
}
return responseList . get ( 0 ) ;
}
@Override
public Response execute ( Request request ) {
if ( this . executionLock . isWriteLocked ( ) ) {
throw new IllegalStateException ( " ClientActor is destroyed " ) ;
}
Object object = nativeClientExecute ( request . getFunction ( ) ) ;
return new Response ( 0 , object ) ;
}
@Override
public void destroyClient ( ) {
stampedLockValue = this . executionLock . tryWriteLock ( ) ;
destroyNativeClient ( this . clientId ) ;
}
@Override
public void initializeClient ( ) {
this . executionLock . tryUnlockWrite ( ) ;
stampedLockValue = null ;
this . clientId = createNativeClient ( ) ;
}
}