How to call a method every time the time changes

Discussion in 'Plugin Development' started by Crash, Feb 25, 2011.

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

    Crash

    I need a way to call a method every time the server time changes. I tried the scheduler set to 1 for the delay but it is kinda off by a bit, sometimes it skips a time and sometimes it does one twice :\

    Any help?
     
  2. Offline

    Edward Hand

    Make sure you are using the synchronised delay. Then it should do it perfectly.
     
  3. Offline

    Raphfrk

    The scheduler doesn't guarantee that it hits the period exactly.

    Why do you need every tick? Would an API method that gives the current clock tick count work instead?
     
  4. Offline

    Crash

    Do you mean scheduleSyncRepeatingTask instead of async ? If so, I'm already doing that.

    @Raphfrk : I basically need to call a method when it is a certain time.
     
  5. Offline

    Raphfrk

    The problem is that the main thread doesn't wait for the scheduler. It uses tryLock(). This means that if the scheduler is updating at that exact moment, then the main thread will won't check the queue.

    Is it to detect night fall or something?
     
  6. Offline

    Crash

    It's an event that happens at a certain time of day.
     
  7. Offline

    Raphfrk

    Why does it matter if you are out by 1-2 ticks? That is around 100ms.
     
  8. Offline

    Crash

    The time needs to be exact and if I miss a time then it might be the event.

    I was thinking of ways around this by checking if the time last tick was less than the time and the time now is greater but the wrapping around of the time from 24000 -> 0 is annoying if they want the event to happen at 24000 or 0
     
  9. Offline

    Afforess

    There's no reason that you HAVE to use the bukkit scheduler. god did not come down from Mt. Sinai and decree that as the 11th commandment.

    PumpkinDiver just uses the Java thread class and works fine.

    My source, cut and paste word for word:

    Code:
    new Thread() {
                public void run() {
                    try {
                       sleep(150);
                        Player player = PumpkinDiver.server.getPlayer(name);
                        if (currentAir != player.getRemainingAir()) {
                            onRemainingAirChange(player, currentAir);
                        }
                        if (wearingDivingHelmet && player.getInventory().getHelmet().getTypeId() != Material.PUMPKIN.getId()) {
                            player.setMaximumAir(300);
                        }
                        else if (!wearingDivingHelmet && player.getInventory().getHelmet().getTypeId() == Material.PUMPKIN.getId()) {
                            player.setMaximumAir(3000);
                        }
                        doPumpkinDiver(name);
                    }
                    catch (InterruptedException e) {
                        doPumpkinDiver(name);
                    }
                    catch (NullPointerException e) {
                        players.remove(name);
                    }
                }
            }.start();
    Note the sleep line makes the thread wait for 150ms before executing.

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

    Edward Hand

    How about rounding the time to the nearest 10 ticks or something and doing a check like:
    if(roundedCurrentTime == roundedTargetTime && roundedPreviousTime != roundedTargetTime)
    Just the same as you suggested but it'll work with wrapping too.
     
  11. Offline

    Raphfrk

    So, it would be acceptable for it to fire a few ticks off then.

    You could work it by chaining single shot tasks.

    -> if(!firstRun)
    --> execute task
    -> T = time until next event
    -> if (T<100)
    --> T += 20000 (or whatever 1 day is)
    -> schedule the task to occur in T ticks

    This is better than having the scheduler fire every clock tick.

    Also, you could use the same Runnable every time.

    If you plan to use Afforess' suggestion, you need to check that any API call is thread safe. This requires checking the CraftBukkit source for the method is thread-safe and assuming that the underlying minecraft classes are thread safe.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 10, 2016
  12. Offline

    retsrif

    Give the event a specific area maybe? Like:
    Code:
    if(x<maxTime && x>minTime) {
    //do whatever
    //minTime and maxTime would be a few ticks apart, and x is the current time
    } 
     
Thread Status:
Not open for further replies.

Share This Page