001    package org.bukkit.scheduler;
002    
003    import org.bukkit.Bukkit;
004    import org.bukkit.plugin.Plugin;
005    
006    /**
007     * This class is provided as an easy way to handle scheduling tasks.
008     */
009    public abstract class BukkitRunnable implements Runnable {
010        private int taskId = -1;
011    
012        /**
013         * Attempts to cancel this task.
014         *
015         * @throws IllegalStateException if task was not scheduled yet
016         */
017        public synchronized void cancel() throws IllegalStateException {
018            Bukkit.getScheduler().cancelTask(getTaskId());
019        }
020    
021        /**
022         * Schedules this in the Bukkit scheduler to run on next tick.
023         *
024         * @param plugin the reference to the plugin scheduling task
025         * @return a BukkitTask that contains the id number
026         * @throws IllegalArgumentException if plugin is null
027         * @throws IllegalStateException if this was already scheduled
028         * @see BukkitScheduler#runTask(Plugin, Runnable)
029         */
030        public synchronized BukkitTask runTask(Plugin plugin) throws IllegalArgumentException, IllegalStateException {
031            checkState();
032            return setupId(Bukkit.getScheduler().runTask(plugin, (Runnable) this));
033        }
034    
035        /**
036         * <b>Asynchronous tasks should never access any API in Bukkit. Great care
037         * should be taken to assure the thread-safety of asynchronous tasks.</b>
038         * <p>
039         * Schedules this in the Bukkit scheduler to run asynchronously.
040         *
041         * @param plugin the reference to the plugin scheduling task
042         * @return a BukkitTask that contains the id number
043         * @throws IllegalArgumentException if plugin is null
044         * @throws IllegalStateException if this was already scheduled
045         * @see BukkitScheduler#runTaskAsynchronously(Plugin, Runnable)
046         */
047        public synchronized BukkitTask runTaskAsynchronously(Plugin plugin) throws IllegalArgumentException, IllegalStateException  {
048            checkState();
049            return setupId(Bukkit.getScheduler().runTaskAsynchronously(plugin, (Runnable) this));
050        }
051    
052        /**
053         * Schedules this to run after the specified number of server ticks.
054         *
055         * @param plugin the reference to the plugin scheduling task
056         * @param delay the ticks to wait before running the task
057         * @return a BukkitTask that contains the id number
058         * @throws IllegalArgumentException if plugin is null
059         * @throws IllegalStateException if this was already scheduled
060         * @see BukkitScheduler#runTaskLater(Plugin, Runnable, long)
061         */
062        public synchronized BukkitTask runTaskLater(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException  {
063            checkState();
064            return setupId(Bukkit.getScheduler().runTaskLater(plugin, (Runnable) this, delay));
065        }
066    
067        /**
068         * <b>Asynchronous tasks should never access any API in Bukkit. Great care
069         * should be taken to assure the thread-safety of asynchronous tasks.</b>
070         * <p>
071         * Schedules this to run asynchronously after the specified number of
072         * server ticks.
073         *
074         * @param plugin the reference to the plugin scheduling task
075         * @param delay the ticks to wait before running the task
076         * @return a BukkitTask that contains the id number
077         * @throws IllegalArgumentException if plugin is null
078         * @throws IllegalStateException if this was already scheduled
079         * @see BukkitScheduler#runTaskLaterAsynchronously(Plugin, Runnable, long)
080         */
081        public synchronized BukkitTask runTaskLaterAsynchronously(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException  {
082            checkState();
083            return setupId(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, (Runnable) this, delay));
084        }
085    
086        /**
087         * Schedules this to repeatedly run until cancelled, starting after the
088         * specified number of server ticks.
089         *
090         * @param plugin the reference to the plugin scheduling task
091         * @param delay the ticks to wait before running the task
092         * @param period the ticks to wait between runs
093         * @return a BukkitTask that contains the id number
094         * @throws IllegalArgumentException if plugin is null
095         * @throws IllegalStateException if this was already scheduled
096         * @see BukkitScheduler#runTaskTimer(Plugin, Runnable, long, long)
097         */
098        public synchronized BukkitTask runTaskTimer(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException  {
099            checkState();
100            return setupId(Bukkit.getScheduler().runTaskTimer(plugin, (Runnable) this, delay, period));
101        }
102    
103        /**
104         * <b>Asynchronous tasks should never access any API in Bukkit. Great care
105         * should be taken to assure the thread-safety of asynchronous tasks.</b>
106         * <p>
107         * Schedules this to repeatedly run asynchronously until cancelled,
108         * starting after the specified number of server ticks.
109         *
110         * @param plugin the reference to the plugin scheduling task
111         * @param delay the ticks to wait before running the task for the first
112         *     time
113         * @param period the ticks to wait between runs
114         * @return a BukkitTask that contains the id number
115         * @throws IllegalArgumentException if plugin is null
116         * @throws IllegalStateException if this was already scheduled
117         * @see BukkitScheduler#runTaskTimerAsynchronously(Plugin, Runnable, long,
118         *     long)
119         */
120        public synchronized BukkitTask runTaskTimerAsynchronously(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException  {
121            checkState();
122            return setupId(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, (Runnable) this, delay, period));
123        }
124    
125        /**
126         * Gets the task id for this runnable.
127         *
128         * @return the task id that this runnable was scheduled as
129         * @throws IllegalStateException if task was not scheduled yet
130         */
131        public synchronized int getTaskId() throws IllegalStateException {
132            final int id = taskId;
133            if (id == -1) {
134                throw new IllegalStateException("Not scheduled yet");
135            }
136            return id;
137        }
138    
139        private void checkState() {
140            if (taskId != -1) {
141                throw new IllegalStateException("Already scheduled as " + taskId);
142            }
143        }
144    
145        private BukkitTask setupId(final BukkitTask task) {
146            this.taskId = task.getTaskId();
147            return task;
148        }
149    }