Cancelling bukkitrunnable does not cancel nested bukkitrunnable

Discussion in 'Plugin Development' started by easterex, May 27, 2020.

  1. Offline

    easterex

    Hello!
    I have a problem with trying to cancel a bukkitrunnable, which I store in a hashmap, as I have another bucketrunnable that runs inside it.

    Code:java
    1. public static HashMap<String, BukkitTask> taskIDMap = new HashMap<String, BukkitTask>();
    2. public void countdown(final Player sender, final Player target, int playerDuration) {
    3. taskIDMap.put(sender.getName(), new BukkitRunnable() {
    4.  
    5. @Override
    6. public void run() {
    7. new BukkitRunnable() {
    8. int timer = 10;
    9.  
    10. @Override
    11. public void run() {
    12.  
    13. if (timer < 1) {
    14. swapPlayers(sender, target);
    15. timer = 10;
    16. this.cancel();
    17. } else {
    18.  
    19. sender.sendMessage("Time remaining: " + timer);
    20. target.sendMessage("Time remaining: " + timer);
    21. --timer;
    22. }
    23.  
    24. }
    25. }.runTaskTimer(plugin, 0L, 20L);
    26.  
    27. }
    28.  
    29. }.runTaskTimer(plugin, playerDuration, playerDuration));
    30. }
    31.  


    I cancel the runnable in, among other places, using something like this:

    Code:java
    1. if (taskIDMap.get(sender.getName()) != null) {
    2. taskIDMap.get(sender.getName()).cancel();
    3. taskIDMap.remove(sender.getName());
    4. }


    The only solution I could come up with is storing the nested bukkitrunnable separately, cancelling it whenever I cancel the outer one (as long as it isn't null) and cleaning it up. This would, however, require a lot of cluttering of my code, by adding something like
    Code:java
    1. if (taskIDMap2.get(sender.getName()) != null) {
    2. taskIDMap2.get(sender.getName()).cancel();
    3. taskIDMap2.remove(sender.getName());
    4. }

    in if-cases and events.

    Does anyone know of a smoother way to do this? Thanks :)
     
    Last edited: May 28, 2020
  2. Offline

    BrittleMind

    Could you not have something like this...?
    Code:java
    1. new BukkitRunnable() {
    2. BukkitRunnable subRunnable;
    3.  
    4. @Override
    5. public void run() {
    6. subRunnable = new BukkitRunnable() {
    7. int timer = 10;
    8.  
    9. @Override
    10. public void run() {
    11. ...Your Code...
    12. }
    13. }.runTaskTimer(plugin, 0L, 20L);
    14. }
    15.  
    16. @Override
    17. public void cancel(){
    18. subRunnable.cancel();
    19. super.cancel();
    20. }
    21. }.runTaskTimer(plugin, delay, period);

    Not sure how advisable it is though
     
    Last edited by a moderator: May 28, 2020
  3. Offline

    easterex

    Thank you for the reply!
    I tried implementing exactly this, with no other changes except:
    Code:java
    1. BukkitTask subRunnable;

    instead of BukkitRunnable due to type mismatch, but the inner runnable still doesn't seem to cancel while counting down for some reason.
    The cancel() seems to work exactly the same as before.
     

Share This Page