package fr.lteconsulting.hexa.client.ui.uploadjs;
import java.util.ArrayList;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import fr.lteconsulting.hexa.client.tools.Action;
public class Tasker
{
private interface Task
{
}
public interface SynchroneTask extends Task
{
void execute();
}
public interface AsynchroneTask extends Task
{
void execute( Action taskFinishedCallback );
}
private class TaskInfo
{
Task task;
Action taskAsyncCallback;
Action taskFinishedCallback;
public TaskInfo( Task task, Action taskFinishedCallback )
{
this.task = task;
this.taskFinishedCallback = taskFinishedCallback;
}
public TaskInfo( Action task, Action taskFinishedCallback )
{
this.taskAsyncCallback = task;
this.taskFinishedCallback = taskFinishedCallback;
}
}
private final ArrayList<TaskInfo> tasks = new ArrayList<TaskInfo>();
private TaskInfo busyOn;
public Tasker()
{
}
public void enqueueTask( Action task )
{
tasks.add( new TaskInfo( task, null ) );
if( tasks.size() == 1 && busyOn == null ) // first task and not busy
Scheduler.get().scheduleDeferred( doSomething );
}
public void enqueueTask( Task task )
{
enqueueTask( task, null );
}
public void enqueueTask( Task task, Action taskFinishedCallback )
{
tasks.add( new TaskInfo( task, taskFinishedCallback ) );
if( tasks.size() == 1 && busyOn == null ) // first task and not busy
Scheduler.get().scheduleDeferred( doSomething );
}
private void taskEnded()
{
assert busyOn != null;
if( busyOn.taskFinishedCallback != null )
busyOn.taskFinishedCallback.exec();
busyOn = null;
if( !tasks.isEmpty() )
Scheduler.get().scheduleDeferred( doSomething );
}
private final ScheduledCommand doSomething = new ScheduledCommand()
{
@Override
public void execute()
{
assert busyOn == null;
if( tasks.isEmpty() )
return;
busyOn = tasks.remove( 0 );
if( busyOn.taskAsyncCallback != null )
{
busyOn.taskAsyncCallback.exec();
taskEnded();
}
else if( busyOn.task instanceof SynchroneTask )
{
SynchroneTask t = (SynchroneTask) busyOn.task;
t.execute();
taskEnded();
}
else if( busyOn.task instanceof AsynchroneTask )
{
((AsynchroneTask) busyOn.task).execute( taskFinishedCallback );
}
}
};
private final Action taskFinishedCallback = new Action()
{
@Override
public void exec()
{
taskEnded();
}
};
}