diff options
author | Raphfrk <raphfrk@gmail.com> | 2011-02-12 00:29:23 +0000 |
---|---|---|
committer | EvilSeph <evilseph@unaligned.org> | 2011-02-13 22:12:26 -0500 |
commit | 973d61c41897b2312699c4ba13c2b93d13858311 (patch) | |
tree | dd0c5f63aecc9b16b944a130db13d16d90608a26 /src/main | |
parent | 4a4b67cc425861f377d9575fe52c2053085fac40 (diff) | |
download | craftbukkit-973d61c41897b2312699c4ba13c2b93d13858311.tar craftbukkit-973d61c41897b2312699c4ba13c2b93d13858311.tar.gz craftbukkit-973d61c41897b2312699c4ba13c2b93d13858311.tar.lz craftbukkit-973d61c41897b2312699c4ba13c2b93d13858311.tar.xz craftbukkit-973d61c41897b2312699c4ba13c2b93d13858311.zip |
Allows calling of functions in the main thread
Diffstat (limited to 'src/main')
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; + } + +} |