Sponge Scheduler for beginners?

While recoding a plugin, I came across shedulers and they work different than in bukkit …

I assume creating them is easy:

Task task = game.getSyncScheduler().runRepeatingTask(instance, new Runnable{
    @Override
        public void run() {
            // Do whatever you want
        }
}, 100L).get();

but how do i cancel an runnig Task?
the javadocs for task.cancel(); Tells me ‘Cancels the task, if it has not already run.’
But how do i cancel it if it was already run, because it is a repeating one?

Oh and maybe someone knows how to cancel the Task from inside the runnable? If not i will probably rebuild a wrapper for the runnable like bukkit did.

TY :wink:

This just means that it can’t cancel a currently running task, or take back previously run actions.

If it’s a repeating task, you will cancel before the next repeat.

4 Likes

It’s possible to cancel the task inside the runnable

@Override
public void run() {
    for(Task task : game.getSyncScheduler().getScheduledTasks(instance)) {
        if (task.getRunnable() == this) {
            task.cancel();
        }
    }
}
4 Likes

But you have to agree that this is messy :worried:.

3 Likes

I’ve posted this issue, to satisfy this topic.

EDIT: Funnily enough, there’s a recent PR that I didn’t notice (I don’t check every day. :p)

2 Likes

Okay i rebuilt a wrapper for sync runnables:

    import java.util.UUID;
    
    import org.spongepowered.api.service.scheduler.Task;
    import org.spongepowered.common.Sponge;
    
    public abstract class SpongeSyncRunnable implements Runnable {
      private UUID taskUuid = null;
    
      public synchronized void cancel() throws IllegalStateException {
          Sponge.getGame().getSyncScheduler().getTaskById(getTaskUuid()).get().cancel();
      }
    
      public synchronized Task runTask(Object plugin) throws IllegalStateException {
          checkState();
          return setupUuid(Sponge.getGame().getSyncScheduler().runTask(plugin, this).get());
      }
    
        public synchronized Task runTaskAfter(Object plugin, long delay) throws IllegalStateException {
          checkState();
            return setupUuid(Sponge.getGame().getSyncScheduler().runTaskAfter(plugin, this, delay).get());
      }
    
        public synchronized Task runRepeatingTask(Object plugin, long interval) throws IllegalStateException {
          checkState();
            return setupUuid(Sponge.getGame().getSyncScheduler().runRepeatingTask(plugin, this, interval).get());
      }
    
        public synchronized Task runRepeatingTaskAfter(Object plugin, long interval, long delay) throws IllegalStateException {
            checkState();
            return setupUuid(Sponge.getGame().getSyncScheduler().runRepeatingTaskAfter(plugin, this, interval, delay).get());
        }
    
      public synchronized UUID getTaskUuid() throws IllegalStateException {
          final UUID uuid = taskUuid;
          if (uuid == null) throw new IllegalStateException("Not scheduled");
          return uuid;
      }
    
      private void checkState() {
          if (taskUuid != null) throw new IllegalStateException("Scheduled as " + taskUuid);
      }
    
      private Task setupUuid(final Task task) {
          this.taskUuid = task.getUniqueId();
          return task;
      }
    }

now you can use it like this to cancel the runnable inside itself:

    SpongeSyncRunnable runnable = new SpongeSyncRunnable() {
        
        @Override
        public void run() {
            // Do whatever you want
            if (condition)
                this.cancel();
        }
    };

    runnable.runRepeatingTask(instance, 100L);

Or cancel wherever you are:

    runnable.cancel();

Everyone feel free to use this code some where :slight_smile:

4 Likes

Looks good. You’ll most likely need to re-write some of that, when the PR is accepted.

Ya i know :slight_smile: but only inside the SpongSyncRunnable.java, so everything in the plugins code should be unaffected :slight_smile:

1 Like