summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java106
-rw-r--r--src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java12
-rw-r--r--src/main/java/org/bukkit/craftbukkit/scheduler/ObjectContainer.java15
3 files changed, 132 insertions, 1 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java
new file mode 100644
index 00000000..0952a2ca
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java
@@ -0,0 +1,106 @@
+package org.bukkit.craftbukkit.scheduler;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.CancellationException;
+
+public class CraftFuture<T> implements Runnable, Future<T> {
+
+ private final CraftScheduler craftScheduler;
+ private final Callable<T> callable;
+ private final ObjectContainer<T> returnStore = new ObjectContainer<T>();
+ private boolean done = false;
+ private boolean running = false;
+ private boolean cancelled = false;
+ private Exception e = null;
+ private int taskId = -1;
+
+ CraftFuture(CraftScheduler craftScheduler, Callable callable) {
+ this.callable = callable;
+ this.craftScheduler = craftScheduler;
+ }
+
+ public void run() {
+ synchronized(this) {
+ if(cancelled) {
+ return;
+ }
+ running = true;
+ }
+ try {
+ returnStore.setObject(callable.call());
+ } catch (Exception e) {
+ this.e = e;
+ }
+ synchronized(this) {
+ running = false;
+ done = true;
+ this.notify();
+ }
+ }
+
+ public T get() throws InterruptedException, ExecutionException {
+ try {
+ return get(0L, TimeUnit.MILLISECONDS);
+ } catch (TimeoutException te) {}
+ return null;
+ }
+
+ public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ synchronized(this) {
+ if(isDone()) {
+ return getResult();
+ }
+ this.wait(TimeUnit.MILLISECONDS.convert(timeout, unit));
+ return getResult();
+ }
+ }
+
+ public T getResult() throws ExecutionException {
+ if(cancelled) {
+ throw new CancellationException();
+ }
+ if(e!=null) {
+ throw new ExecutionException(e);
+ }
+ return returnStore.getObject();
+ }
+
+ public boolean isDone() {
+ synchronized(this) {
+ return done;
+ }
+ }
+
+ public boolean isCancelled() {
+ synchronized(this) {
+ return cancelled;
+ }
+ }
+
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ synchronized(this) {
+ if(cancelled) {
+ return false;
+ }
+ cancelled = true;
+ if(taskId!=-1) {
+ craftScheduler.cancelTask(taskId);
+ }
+ if(!running && !done) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public void setTaskId(int taskId) {
+ synchronized(this) {
+ this.taskId = taskId;
+ }
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index edf5bae8..46e095bc 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -6,6 +6,8 @@ import java.util.Iterator;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.plugin.Plugin;
@@ -105,7 +107,6 @@ public class CraftScheduler implements BukkitScheduler, Runnable {
}
-
// If the main thread cannot obtain the lock, it doesn't wait
public void mainThreadHeartbeat(long currentTick) {
if (mainThreadLock.tryLock()) {
@@ -177,6 +178,15 @@ public class CraftScheduler implements BukkitScheduler, Runnable {
return newTask.getIdNumber();
}
+ public <T> Future<T> callSyncMethod(Plugin plugin, Callable<T> task) {
+ CraftFuture<T> craftFuture = new CraftFuture<T>(this, task);
+ synchronized(craftFuture) {
+ int taskId = scheduleSyncDelayedTask(plugin, craftFuture);
+ craftFuture.setTaskId(taskId);
+ }
+ return craftFuture;
+ }
+
public void cancelTask(int taskId) {
synchronized (schedulerQueue) {
Iterator<CraftTask> itr = schedulerQueue.keySet().iterator();
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/ObjectContainer.java b/src/main/java/org/bukkit/craftbukkit/scheduler/ObjectContainer.java
new file mode 100644
index 00000000..c0fa37cb
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/ObjectContainer.java
@@ -0,0 +1,15 @@
+package org.bukkit.craftbukkit.scheduler;
+
+public class ObjectContainer<T> {
+
+ T object;
+
+ public void setObject(T object) {
+ this.object = object;
+ }
+
+ public T getObject() {
+ return object;
+ }
+
+}