Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package sander;
- import java.util.ArrayList;
- import static java.util.Collections.addAll;
- import java.util.List;
- import static org.bukkit.Bukkit.getScheduler;
- import org.bukkit.plugin.Plugin;
- public class MainThreadPlanner<T> {
- private AccumulativeRunnable<T> doProcess;
- private final AccumulativeRunnable<Runnable> doSubmit;
- protected final Plugin plugin;
- private final Processor<T> processor;
- public MainThreadPlanner(Plugin plugin,Processor<T> processor) {
- this.doSubmit = new DoSubmitAccumulativeRunnable(plugin);
- this.plugin = plugin;
- this.processor = processor;
- }
- private void process(List<T> chunks) {
- this.processor.process(chunks);
- }
- /**
- * Sends data chunks to the {@link #process} method. This method is to be
- * used from inside the {@code doInBackground} method to deliver
- * intermediate results for processing on the <i>Bukkit Main Server
- * Thread</i> inside the {@code process} method.
- *
- * <p>
- * Because the {@code process} method is invoked asynchronously on the
- * <i>Bukkit Main Server Thread</i>
- * multiple invocations to the {@code publish} method might occur before the
- * {@code process} method is executed. For performance purposes all these
- * invocations are coalesced into one invocation with concatenated
- * arguments.
- *
- * <p>
- * For example:
- *
- * <pre>
- * publish("1");
- * publish("2", "3");
- * publish("4", "5", "6");
- * </pre>
- *
- * might result in:
- *
- * <pre>
- * process("1", "2", "3", "4", "5", "6")
- * </pre>
- *
- *
- * @param chunks intermediate results to process
- *
- * @see #process
- *
- */
- public final void publish(T... chunks) {
- synchronized (this) {
- if (this.doProcess == null) {
- this.doProcess = new AccumulativeRunnable<T>() {
- @Override
- public void run(List<T> args) {
- MainThreadPlanner.this.process(args);
- }
- @Override
- protected void submit() {
- MainThreadPlanner.this.doSubmit.add(this);
- }
- };
- }
- }
- this.doProcess.add(chunks);
- }
- private static abstract class AccumulativeRunnable<T extends Object> implements Runnable {
- private List<T> arguments = null;
- protected abstract void run(List<T> paramList);
- @Override
- public final void run() {
- this.run(this.flush());
- }
- public final synchronized void add(T... toAdd) {
- boolean mustSubmit = false;
- if (this.arguments == null) {
- mustSubmit = true;
- this.arguments = new ArrayList<>();
- }
- addAll(this.arguments, toAdd);
- if (mustSubmit) {
- this.submit();
- }
- }
- abstract protected void submit();
- private synchronized List<T> flush() {
- List<T> localList = this.arguments;
- this.arguments = null;
- return localList;
- }
- }
- public interface Processor<T> {
- public void process(List<T> process);
- }
- private class DoSubmitAccumulativeRunnable extends AccumulativeRunnable<Runnable> implements Runnable {
- /**
- * Time in ticks between 2 invokings of the schedular
- */
- private final static int DELAY = 1;
- /**
- * The plugin, used to schedule tasks
- */
- private final Plugin plugin;
- public DoSubmitAccumulativeRunnable(Plugin plugin) {
- this.plugin = plugin;
- }
- @Override
- protected void run(List<Runnable> args) {
- for (Runnable runnable : args) {
- runnable.run();
- }
- }
- @Override
- protected void submit() {
- if (this.plugin.isEnabled()) {
- getScheduler().scheduleSyncDelayedTask(this.plugin, this, DELAY);
- } else {
- // What do do, scheduling an task would throw an IllegalArgumentException, and enablking this plugin for a little time may cause bugs inside the plugin?
- // Mayby use reflection to access the enabled field of JavaPlugin, but this wont work whit plugins that dont exend that class
- throw new IllegalStateException("Plugin not enabled, unable to schadule task");
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment