Countdown issues

Discussion in 'Plugin Development' started by 1928i, Jan 18, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    1928i

    Currently having some issues creating a countdown of sorts. Here is my code so far:

    Code:
    public void startTime() {
            Countdown.time = 0;
            this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Countdown(this), 20l, 20l)
        }
    Here is the referenced "countdown" class.

    Code:
    Core plugin;
       
        public Countdown(Core pl){
            plugin = pl;
        }
       
        public static int time;
       
        public void run() {
            if(time % 1200 == 0){
               
            }
        time-=1;
        }
    On the first bit, when I put in schedualSyncRepeatingTack, it says that it is depreciated. I know what this means but I can't figure out how to fix it. Can anyone help me?
     
    GrandmaJam likes this.
  2. Offline

    1Rogue

    Use runTaskTimer instead. Also, make "time" private, not public static.
     
    GrandmaJam likes this.
  3. Offline

    1928i

    @1Rogue
    I tried using runTaskTimer instead and it didn't help anything, it gives me the same error. Here is the code:

    Code:
    public void startTime() {
            Countdown.time = 0;
            this.getServer().getScheduler().runTaskTimer(this, new Countdown(this), 20l, 20l);
        }
    Also, if I make "time" private then I can't reference it in my main class.
     
  4. Offline

    1Rogue

    Make an accessor method, or better yet do whatever logic with the variable you need in your run() method. Fields should never be publicly mutable.

    What is your "error"? So far all you've said was the method was deprecated, for which I told you to use the newer method (which is definitely not deprecated).
     
  5. Offline

    1928i

    @1Rogue
    I used the newer method you gave me and it says that it is also depreciated. I don't understand why though.
     
  6. Offline

    1Rogue

    Then that's only happening because your Runnable is a BukkitRunnable (doesn't need to be, but it doesn't really make any difference).
     
    GrandmaJam likes this.
  7. Offline

    1928i

    @1Rogue
    It seems as if this is working fine now, but I have a new issue. I can't figure out how to stop the countdown. Can you help me?
     
  8. Offline

    1Rogue

    Just cancel the task when you reach 0.
     
  9. Offline

    UaVxChallenge

    To cancel it get its id to do this just make a method like
    Code:
    public static int CountdownID;
    
    //In the method where you start the countdown add this
    
    CountdownID = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, runnable, //,//);
    
    //Then to stop it make a method that has
    
    Bukkit.getServer().getScheduler().cancelTask(CountdownID);
    That should work obviously the // will need to be changed in a scheduler but I am out of town and don't have my computer with eclipse or anything to code it and test. This should work though.
     
  10. Offline

    1Rogue

    scheduleSyncRepeatingTask is deprecated. You would use the returned BukkitTask object from runTaskTimer.
     
  11. Offline

    UaVxChallenge

    Yea I am trying to go off of memory of my code and no API to look off of so it's hard. It also depends on how he is using his countdown I make a whole new class and extend Runnable on mine. However if his is running like he says then my way will get the id of the Task and cancel the task it does work.
     
  12. Offline

    1928i

    @1Rogue
    Whenever I try to cancel it it doesn't work properly. For some reason I just can't figure out how to cancel a runnable. How would one do this?
     
  13. Offline

    UaVxChallenge

    Did you try the way that I put?

    In the place you use to start countdown have
    Code:
    public static int CountdownID;
    
    public static void startCountdown(){
    Countdownid = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin etc..);
    }
    In the method to shut down the time just put

    Code:
    public static void stopCountdown(){
    Bukkit.getServer().getScheduler().cancelTask(CountdownID);
    //Like in earlier post
    }
    Then in your countdown method put

    Code:
    if(time == 0){
    class.stopcountdown();
    //class referring to where you put the stop countdown method obviously
    }
    I know Rogue said because its deprecated it won't return the id but since you are extending Runnable in the other class it will work. It returns the ID from the runnable extending class. Tasks almost always will return an id.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 13, 2016
  14. Offline

    1Rogue

    ...It doesn't matter at all how he calls the runnable, you would still get the returned BukkitTask regardless of whether you call a method on BukkitRunnable or pass a Runnable yourself to the scheduler. You should not be using the integer id, you should use the returned BukkitTask object.

    Edit: Forgot to mention that BukkitRunnable even has an internal "cancel" method you can call.

    I didn't say this at all. Nor does it make sense.

    How are you trying?
     
    Last edited: Jan 18, 2015
  15. Offline

    UaVxChallenge

    Well here if this isn't finished by tomorrow I will post my countdown method (If this still isn't fixed) maybe I left something out or missed a little thing like I said I am on my laptop , out of town, and don't have anyway to check what I am typing just by memory with no code in front of me.
     
  16. Offline

    mythbusterma

    @UaVxChallenge

    Even typing from memory is no excuse for your flagrant abuse of the static keyword. That code is absolutely atrocious and will only allow one countdown to be created.



    @1928i

    I can't believe I have to do this, but here, before anyone else posts something stupid:

    Code:
    public class Countdown extends BukkitRunnable {
    
          private int time;
    
          public Countdown (int time) {
                this.time = time;
          }
    
          public int getTimeRemaning() {
                return time;
          }
       
          @Override
          public void run () {
             if (time % 1200 == 0) {
                   // do something
              }
              time --;
              if (time == 0) {
                  this.cancel();
          }
       }
    }

    And then just instantiate and schedule this when you need, it really isn't that hard, and doesn't require abusing the static keyword.
     
    GrandmaJam likes this.
  17. Offline

    1928i

    @UaVxChallenge
    Setting up an idea only throws me an error saying that I can't have an int equal a task like that.
    @mythbusterma
    You are currently using a Bukkit Runnable which causes it to be depreciated which means your code will not work.
    @1Rogue
    Currently I have tried using this.cancel but it said it is not right for the given field. This.cancel was the only thing I could find when I tried to figure out ways to cancel a runnable.

    Can anyone else help me with this issue?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 13, 2016
  18. Offline

    xize

    @1928i

    do you have new code what you have so far?

    also maybe its a good idea to print/log the countdown in case its goes into negative numbers which means it never stops.
     
  19. Offline

    1928i

    @xise
    Here is the code:

    Code:
    public void startTime() {
            Countdown.time = 0;
            this.getServer().getScheduler().runTaskTimer(this, new Countdown(this), 20l, 20l);
        }

    Code:
    package me.i1928i.UHC;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    
    public class Countdown implements Runnable{
    
        Core plugin;
       
        public Countdown(Core pl){
            plugin = pl;
        }
       
        public static int time;
       
        public void run() {
            Bukkit.broadcastMessage("" + time);
            if(time % 1200 == 0){
                if(plugin.getConfig().isSet("EpisodeNumber")){
                    int hi = plugin.getConfig().getInt("EpisodeNumber")+1;
                    Bukkit.broadcastMessage(ChatColor.GOLD + "[Episode End] " + ChatColor.GREEN + "We are " + time/60 + " minutes in.");
                    plugin.getConfig().set("EpisodeNumber", hi);
                }else{
                    plugin.getConfig().set("EpisodeNumber", 2);
                    Bukkit.broadcastMessage(ChatColor.GOLD + "[Episode End] " + ChatColor.GREEN + "We are " + time/60 + " minutes in.");
                }
            }
        time+=1;
        }
    }
    
     
  20. Offline

    xize

    @1928i

    like others already said change:
    Code:
    public static int time;
    
    into:
    Code:
    private int time = 0;
    
    then as follows I dont know what your plans are for the time variable in the runnable but:

    use either time++; or time--;

    the problem with your code was that the int time wasnt instanced and actually null while an int cannot be null, an Integer can because thats a wrap around a int and counts as a object while a int doesnt count as a object but as a primitive such like a string for example.

    see more info here:

    http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

    edit1:
    maybe Im not saying it fully correctly since a Integer can be cast to a int but Im still seeing it as a object rather than a primitive since it can be null while a int cannot, makes it easier for me to understand.

    edit2:
    also I forgot to mentoin since its a primitive the chance is that it becomes 0 or -1 rather than I said it cant be null as default, so if you do:
    Code:
    private int time = 10;
    
    @Override
    public void run() {
         if(time == 0) {
               this.cancel();
               this.time = 10; //reset the time
         }
          time--;
    }
    
    it should work because it counts down form 10 to 0 with time++ it counts up.
     
    Last edited: Jan 19, 2015
  21. Offline

    1928i

    @xize
    Well, I already have time+=time so I don't need that. But, if time is private, I can't reference it in my other class. So it needs to be public. Finally, you didn't answer my question of how do I get the countdown to stop.

    Anyone else wanna help?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 13, 2016
  22. Offline

    xize

    @1928i

    if Im correct aslong your field is outside the runnable its possible to reference the field inside the runnable, whenever its private or public.

    if you for some reason want that number you could make a getter to it like so:
    Code:
    public int getTime() {
         return time;
    }
    
    and then obtain the time through the object you instanced with the new keyword like:

    Code:
    Countdown count = new Countdown(plugin); //for usage for later
    Bukkit.getScheduler().runTaskTimer(yourplugin, count);
    //you can now do in a other method something like:
    int time = count.getTime();
    
    you should use either this.time or just the time variable it self in the runnable.

    to awnser your question:

    your time variable has to be atleast higher than 0, then if you use this check time == 0 it works fine while decrementing the number.

    however in the code you have:

    Code:
    private int time;
    
    @Override
    public void run() {
         //snip
           time+=time;
    }
    
    you are actually doing time+time which isn't counting down and if the time field is 0 because it hasnt been instanced it means you are doing 0+0 or -1 + -1 I geuss it would be 0+0 though.

    this is why you should put debug lines to see what the time variable is at every tick.

    in your case I think I see what you want, you want the time being instanced from the constructor?, then you can do this:
    Code:
    private Yourplugin plugin;
    private int time;
    
    public Cooldown(Yourplugin aplugin, int atime) {
          this.plugin = aplugin;
          this.time = atime;
    }
    
    this means you enforce to set a time when doing this: Countdown countdown = new Countdown(yourplug, 30);

    you could also make a setter very smiliar as how I did with my first snippet about the getter.

    I hope this gives you some ideas though.
     
  23. Offline

    1928i

    Ok, but can anyone explain to me how to make the countdown end?
     
  24. Offline

    1Rogue

    Code:java
    1. this.cancel();
     
  25. Offline

    1928i

    @1Rogue
    That doesn't work. It never has. I just says that it is unidentified for the type.

    Anyone else?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 13, 2016
  26. Offline

    mythbusterma

    @1928i

    Yes it does. You just don't know enough Java to actually attempt to write a Bukkit plugin. If you actually read the documentation for the class instead of being lazy and telling other people to write code for you and blindly dismissing things as "hurr durr deprecated" when in fact they are not only not deprecated, but the method that you were talking about is only deprecated because of the ambiguity of it's name, not "hurr durr deprecated means no workie."

    The method to schedule a BukkitRunnable using the instance of that runnable is VERY CLEARLY NOT DEPRECATED, so try actually doing so research next time.
     
  27. Offline

    1928i

    @mythbusterma
    Ok, I have taken an entire class on java. I have been coding java for multiple years now. I know a lot about java. I just don't know about the Bukkit API very well. Also, maybe you should actually read the other comments where people are actually helping me. Maybe they can set an example for you. So, you know what, why don't you either try to help or just stop commenting. Your code may work sometimes, but it seemingly isn't as reliable as the code I have now. If you read the other comments you would see that I was actually got help and they told me to use a different method, not yours! And it was a retired staff. Also, everyone else with different comments then you, actually has plugins made, while you sit there with a big fat "0". So, think before you type.

    Can anyone else help me with this issue I'm having, where I can't cancel the countdown.
     
  28. Offline

    1Rogue

    Ah I see, you're not using BukkitRunnable anymore. In that case, when you schedule the runnable, you should note the returned BukkitTask in a Box<T>:

    Code:java
    1. /**
    2. * Used for enclosing a single return value, such as a returned task from a
    3. * scheduler. Should not be exposed beyond being a local member, as the only
    4. * field of the class is both public and mutable.
    5. *
    6. * @since 0.1.0
    7. * @author 1Rogue
    8. * @version 0.1.0
    9. *
    10. * @param <T> The type of the boxed item
    11. */
    12. public class Box<T> {
    13.  
    14. /**
    15.   * The value of the {@code Box<T>}
    16.   *
    17.   * @since 0.1.0
    18.   * @version 0.1.0
    19.   */
    20. public volatile T value;
    21.  
    22. }


    In semi-pseudo code:
    Code:java
    1. Box<BukkitTask> taskBox = new Box<>();
    2. taskBox.value = Scheduler.runTaskTimer(/* ... */ {
    3. taskBox.value.cancel();
    4. }, /* ... */);



    runTaskTimer is deprecated when scheduling a BukkitRunnable instead of a Runnable. Though now OP is using a runnable so I'm not sure.
     
  29. Offline

    mythbusterma

    @1928i

    Actually I did help. You just think you know everything because "I've taken a class," I have a degree, and I do know what I'm talking about. These other "methods" that you describe are poor programming practice and there are very legitimate reasons not to use them, as pointed out by 1Rogue.

    The code I wrote works 100% of the time, I don't understand why you're going on about "reliability" when you haven't even bother to test my code, or even look up why those methods were deprecated in the first place.

    Simply do this:

    Code:
    Countdown countdown1;
    
    Countdown countdown2;
    
    @Override
    public void onEnable() {
         countdown1 = new Countdown(*some number*);
         countdown2 = new Countdown(*some number*);
        
         countdown1.runTaskTimer(this, 20);
         countdown2.runTaskTimer(this, 20);
    }
    Then, at any point afterwards you may do this:

    Code:
    int i = countdown1.getTimeRemaining();
    
    Just because he used to be on staff, doesn't mean he's good at programming, and just because I don't have any plugins, doesn't mean I don't know what I'm talking about.

    So come down off your high horse and actually take some advice from someone who knows what they're talking about.

    @1Rogue

    I don't think I could've made that link any bigger, but BukkitRunnable#runTaskTimer(...) is not deprecated, as you can see.
     
  30. Offline

    1Rogue

    Nonono, scheduling a BukkitRunnable through the BukkitScheduler manually is deprecated. Java matches methods on most-specific, so you would get a deprecation warning if the Runnable you're scheduling is a BukkitRunnable.

    javadocs
     
Thread Status:
Not open for further replies.

Share This Page