package net.md_5.bungee.scheduler;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import gnu.trove.TCollections;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import net.md_5.bungee.api.scheduler.TaskScheduler;
public class BungeeScheduler implements TaskScheduler
{
private final Object lock = new Object();
private final AtomicInteger taskCounter = new AtomicInteger();
private final TIntObjectMap<BungeeTask> tasks = TCollections.synchronizedMap( new TIntObjectHashMap<BungeeTask>() );
private final Multimap<Plugin, BungeeTask> tasksByPlugin = Multimaps.synchronizedMultimap( HashMultimap.<Plugin, BungeeTask>create() );
//
private final Unsafe unsafe = new Unsafe()
{
@Override
public ExecutorService getExecutorService(Plugin plugin)
{
return plugin.getExecutorService();
}
};
@Override
public void cancel(int id)
{
BungeeTask task = tasks.get( id );
Preconditions.checkArgument( task != null, "No task with id %s", id );
task.cancel();
}
void cancel0(BungeeTask task)
{
synchronized ( lock )
{
tasks.remove( task.getId() );
tasksByPlugin.values().remove( task );
}
}
@Override
public void cancel(ScheduledTask task)
{
task.cancel();
}
@Override
public int cancel(Plugin plugin)
{
Set<ScheduledTask> toRemove = new HashSet<>();
for ( ScheduledTask task : tasksByPlugin.get( plugin ) )
{
toRemove.add( task );
}
for ( ScheduledTask task : toRemove )
{
cancel( task );
}
return toRemove.size();
}
@Override
public ScheduledTask runAsync(Plugin owner, Runnable task)
{
return schedule( owner, task, 0, TimeUnit.MILLISECONDS );
}
@Override
public ScheduledTask schedule(Plugin owner, Runnable task, long delay, TimeUnit unit)
{
return schedule( owner, task, delay, 0, unit );
}
@Override
public ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit)
{
Preconditions.checkNotNull( owner, "owner" );
Preconditions.checkNotNull( task, "task" );
BungeeTask prepared = new BungeeTask( this, taskCounter.getAndIncrement(), owner, task, delay, period, unit );
synchronized ( lock )
{
tasks.put( prepared.getId(), prepared );
tasksByPlugin.put( owner, prepared );
}
owner.getExecutorService().execute( prepared );
return prepared;
}
@Override
public Unsafe unsafe()
{
return unsafe;
}
}