package com.aelitis.azureus.ui.common.table.impl;
import java.util.ArrayList;
import java.util.List;
import org.gudy.azureus2.core3.util.*;
import com.aelitis.azureus.ui.common.table.impl.TableViewImpl;
public class DataSourceCallBackUtil
{
public static final long IMMEDIATE_ADDREMOVE_DELAY = 150;
private static final long IMMEDIATE_ADDREMOVE_MAXDELAY = 2000;
private static Timer timerProcessDataSources = new Timer("Process Data Sources");
private static TimerEvent timerEventProcessDS;
private static List processDataSourcesOutstanding = new ArrayList();
public static boolean
addDataSourceAggregated(
addDataSourceCallback callback )
{
if ( callback == null ){
return( true );
}
boolean processQueueImmediately = false;
List to_do_now = null;
synchronized( timerProcessDataSources ){
if ( timerEventProcessDS != null && !timerEventProcessDS.hasRun()){
// Push timer forward, unless we've pushed it forward for over x seconds
long now = SystemTime.getCurrentTime();
if (now - timerEventProcessDS.getCreatedTime() < IMMEDIATE_ADDREMOVE_MAXDELAY) {
long lNextTime = now + IMMEDIATE_ADDREMOVE_DELAY;
timerProcessDataSources.adjustAllBy( lNextTime - timerEventProcessDS.getWhen());
if ( !processDataSourcesOutstanding.contains( callback )){
processDataSourcesOutstanding.add( callback );
}
}else{
timerEventProcessDS.cancel();
timerEventProcessDS = null;
processQueueImmediately = true;
to_do_now = processDataSourcesOutstanding;
processDataSourcesOutstanding = new ArrayList();
}
}else{
if ( !processDataSourcesOutstanding.contains( callback )){
processDataSourcesOutstanding.add( callback );
}
timerEventProcessDS =
timerProcessDataSources.addEvent(
SystemTime.getCurrentTime() + IMMEDIATE_ADDREMOVE_DELAY,
new TimerEventPerformer()
{
public void
perform(
TimerEvent event )
{
List to_do;
synchronized( timerProcessDataSources ){
timerEventProcessDS = null;
to_do = processDataSourcesOutstanding;
processDataSourcesOutstanding = new ArrayList();
}
for (int i=0;i<to_do.size();i++){
try{
addDataSourceCallback this_callback = (addDataSourceCallback)to_do.get(i);
if (TableViewImpl.DEBUGADDREMOVE ) {
this_callback.debug("processDataSourceQueue after "
+ (SystemTime.getCurrentTime() - event.getCreatedTime())
+ "ms");
}
this_callback.process();
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
});
}
if ( to_do_now != null ){
// process outside the synchronized block, otherwise we'll end up with deadlocks
to_do_now.remove( callback );
for (int i=0;i<to_do_now.size();i++){
try{
addDataSourceCallback this_callback = (addDataSourceCallback)to_do_now.get(i);
if ( TableViewImpl.DEBUGADDREMOVE ){
this_callback.debug("Over immediate delay limit, processing queue now");
}
this_callback.process();
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
}
return( processQueueImmediately );
}
public interface
addDataSourceCallback
{
public void
process();
public void
debug(
String str );
}
}