package miscperipherals.core;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import net.minecraft.world.World;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
public class TickHandler implements ITickHandler {
private static Map<Integer, LinkedBlockingQueue<FutureTask>> callbacks = Collections.synchronizedMap(new HashMap<Integer, LinkedBlockingQueue<FutureTask>>());
@Override
public void tickStart(EnumSet<TickType> type, Object... tickData) {
if (type.contains(TickType.WORLD)) {
World world = (World)tickData[0];
if (callbacks.containsKey(world.provider.dimensionId)) {
Queue<FutureTask> callbackList = callbacks.get(world.provider.dimensionId);
FutureTask callback = callbackList.poll();
while (callback != null) {
callback.run();
callback = callbackList.poll();
}
}
}
}
@Override
public void tickEnd(EnumSet<TickType> type, Object... tickData) {
}
@Override
public EnumSet<TickType> ticks() {
return EnumSet.of(TickType.WORLD);
}
@Override
public String getLabel() {
return "MiscPeripherals";
}
public static <T> Future<T> addTickCallback(World world, Callable<T> callback) throws InterruptedException {
if (!callbacks.containsKey(world.provider.dimensionId)) callbacks.put(world.provider.dimensionId, new LinkedBlockingQueue<FutureTask>());
FutureTask task = new FutureTask<T>(callback) {
@Override
protected void done() {
try {
if (!isCancelled()) get();
} catch (Throwable e) {
MiscPeripherals.log.warning("Exception while executing tick callback! " + this);
e.printStackTrace();
}
}
};
callbacks.get(world.provider.dimensionId).put(task);
return task;
}
}