package jk_5.nailed.server.scheduler;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.DefaultPromise;
import jk_5.eventbus.EventHandler;
import jk_5.nailed.api.event.server.ServerPostTickEvent;
import jk_5.nailed.api.scheduler.Scheduler;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.concurrent.*;
public class NailedScheduler implements Scheduler {
private static final NailedScheduler INSTANCE = new NailedScheduler();
private final DefaultEventExecutorGroup executor = new DefaultEventExecutorGroup(Runtime.getRuntime().availableProcessors() * 2);
private final Queue<Runnable> executionQueue = new LinkedList<Runnable>();
@Nonnull
@Override
public Future<?> submit(@Nonnull Runnable task) {
return executor.submit(task);
}
@Nonnull
@Override
public <T> Future<T> submit(@Nonnull Runnable task, T result) {
return executor.submit(task, result);
}
@Nonnull
@Override
public <T> Future<T> submit(@Nonnull Callable<T> task) {
return executor.submit(task);
}
@Nonnull
@Override
public ScheduledFuture<?> schedule(@Nonnull Runnable command, long delay, @Nonnull TimeUnit unit) {
return executor.schedule(command, delay, unit);
}
@Nonnull
@Override
public <V> ScheduledFuture<V> schedule(@Nonnull Callable<V> callable, long delay, @Nonnull TimeUnit unit) {
return executor.schedule(callable, delay, unit);
}
@Nonnull
@Override
public ScheduledFuture<?> scheduleAtFixedRate(@Nonnull Runnable command, long initialDelay, long period, @Nonnull TimeUnit unit) {
return executor.scheduleAtFixedRate(command, initialDelay, period, unit);
}
@Nonnull
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(@Nonnull Runnable command, long initialDelay, long delay, @Nonnull TimeUnit unit) {
return executor.scheduleWithFixedDelay(command, initialDelay, delay, unit);
}
@Nonnull
@Override
public <T> List<Future<T>> invokeAll(@Nonnull Collection<? extends Callable<T>> tasks) throws InterruptedException {
return executor.invokeAll(tasks);
}
@Nonnull
@Override
public <T> List<Future<T>> invokeAll(@Nonnull Collection<? extends Callable<T>> tasks, long timeout, @Nonnull TimeUnit unit) throws InterruptedException {
return executor.invokeAll(tasks, timeout, unit);
}
@Nonnull
@Override
public <T> T invokeAny(@Nonnull Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
return executor.invokeAny(tasks);
}
@Override
public <T> T invokeAny(@Nonnull Collection<? extends Callable<T>> tasks, long timeout, @Nonnull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return executor.invokeAny(tasks, timeout, unit);
}
@Override
public void execute(@Nonnull Runnable command) {
executor.execute(command);
}
@Nonnull
@Override
public Future<?> submitSync(@Nonnull Runnable task) {
return this.submitSync(task, null);
}
@Nonnull
@Override
public <T> Future<T> submitSync(@Nonnull final Runnable task, final T result) {
final DefaultPromise<T> future = new DefaultPromise<T>(this.executor.next());
this.executionQueue.add(new Runnable() {
@Override
public void run() {
try{
task.run();
future.setSuccess(result);
}catch(Exception e){
future.setFailure(e);
}
}
});
return future;
}
@Nonnull
@Override
public <T> Future<T> submitSync(@Nonnull final Callable<T> task) {
final DefaultPromise<T> future = new DefaultPromise<T>(this.executor.next());
this.executionQueue.add(new Runnable() {
@Override
public void run() {
try{
future.setSuccess(task.call());
}catch(Exception e){
future.setFailure(e);
}
}
});
return future;
}
@Override
public <T> T invokeAnySync(@Nonnull Collection<? extends Callable<T>> tasks, long timeout, @Nonnull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
throw new UnsupportedOperationException();
}
@Nonnull
@Override
public ScheduledFuture<?> scheduleSync(@Nonnull Runnable command, long delay, @Nonnull TimeUnit unit) {
throw new UnsupportedOperationException();
}
@Nonnull
@Override
public <V> ScheduledFuture<V> scheduleSync(@Nonnull Callable<V> callable, long delay, @Nonnull TimeUnit unit) {
throw new UnsupportedOperationException();
}
@Nonnull
@Override
public ScheduledFuture<?> scheduleAtFixedRateSync(@Nonnull Runnable command, long initialDelay, long period, @Nonnull TimeUnit unit) {
throw new UnsupportedOperationException();
}
@Nonnull
@Override
public ScheduledFuture<?> scheduleWithFixedDelaySync(@Nonnull Runnable command, long initialDelay, long delay, @Nonnull TimeUnit unit) {
throw new UnsupportedOperationException();
}
@Nonnull
@Override
public <T> List<Future<T>> invokeAllSync(@Nonnull Collection<? extends Callable<T>> tasks) throws InterruptedException {
throw new UnsupportedOperationException();
}
@Nonnull
@Override
public <T> List<Future<T>> invokeAllSync(@Nonnull Collection<? extends Callable<T>> tasks, long timeout, @Nonnull TimeUnit unit) throws InterruptedException {
throw new UnsupportedOperationException();
}
@Nonnull
@Override
public <T> T invokeAnySync(@Nonnull Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
throw new UnsupportedOperationException();
}
@Override
public void executeSync(@Nonnull Runnable command) {
this.executionQueue.add(command);
}
@Override
public void shutdown() {
}
@Override
public List<Runnable> shutdownNow() {
return Collections.emptyList();
}
@Override
public boolean isShutdown() {
return false;
}
@Override
public boolean isTerminated() {
return false;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return false;
}
@EventHandler
public void onTick(ServerPostTickEvent event){
if(executionQueue.size() > 0){
for (Runnable e : executionQueue) {
e.run();
}
executionQueue.clear();
}
}
public DefaultEventExecutorGroup getExecutor() {
return executor;
}
public static NailedScheduler instance(){
return INSTANCE;
}
}