Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package org.bukkit.craftbukkit.scheduler;
2
3import java.util.concurrent.*;
4
5public class CraftFuture<T> implements Runnable, Future<T> {
6
7 private final CraftScheduler craftScheduler;
8 private final Callable<T> callable;
9 private final ObjectContainer<T> returnStore = new ObjectContainer<T>();
10 private boolean done = false;
11 private boolean running = false;
12 private boolean cancelled = false;
13 private Exception e = null;
14 private int taskId = -1;
15
16 CraftFuture(CraftScheduler craftScheduler, Callable callable) {
17 this.callable = callable;
18 this.craftScheduler = craftScheduler;
19 }
20
21 public void run() {
22 synchronized (this) {
23 if (cancelled) {
24 return;
25 }
26 running = true;
27 }
28 try {
29 returnStore.setObject(callable.call());
30 } catch (Exception e) {
31 this.e = e;
32 }
33 synchronized (this) {
34 running = false;
35 done = true;
36 this.notify();
37 }
38 }
39
40 public T get() throws InterruptedException, ExecutionException {
41 try {
42 return get(0L, TimeUnit.MILLISECONDS);
43 } catch (TimeoutException te) {
44 }
45 return null;
46 }
47
48 public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
49 synchronized (this) {
50 if (isDone()) {
51 return getResult();
52 }
53 this.wait(TimeUnit.MILLISECONDS.convert(timeout, unit));
54 return getResult();
55 }
56 }
57
58 public T getResult() throws ExecutionException {
59 if (cancelled) {
60 throw new CancellationException();
61 }
62 if (e != null) {
63 throw new ExecutionException(e);
64 }
65 return returnStore.getObject();
66 }
67
68 public boolean isDone() {
69 synchronized (this) {
70 return done;
71 }
72 }
73
74 public boolean isCancelled() {
75 synchronized (this) {
76 return cancelled;
77 }
78 }
79
80 public boolean cancel(boolean mayInterruptIfRunning) {
81 synchronized (this) {
82 if (cancelled) {
83 return false;
84 }
85 cancelled = true;
86 if (taskId != -1) {
87 craftScheduler.cancelTask(taskId);
88 }
89 if (!running && !done) {
90 return true;
91 } else {
92 return false;
93 }
94 }
95 }
96
97 public void setTaskId(int taskId) {
98 synchronized (this) {
99 this.taskId = taskId;
100 }
101 }
102}