Question on timing.

Discussion in 'Plugin Development' started by darknesschaos, Jan 18, 2011.

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

    darknesschaos

    How would I set a particular piece of code to run in a plugin at a certain point in time? or how about something like a timer?

    An example would be like,
    You use a command. The command sends a message to a player and/or does something in say x (mili)seconds.

    Thanks!
     
  2. Offline

    Archelaus

    Bukkit (to my knowledge) doesn't support this in its API. But Java does.

    Code:
    public static void waiting (int n){
    
            long t0, t1;
    
            t0 =  System.currentTimeMillis();
    
            do{
                 //what to do here
                t1 = System.currentTimeMillis();
            }
            while ((t1 - t0) < (n * 1000));
        }
     
  3. Offline

    darknesschaos

    Thanks for the fast reply, I shall try it out.
     
  4. Offline

    Raphfrk

    That isn't a good way to do it, your code will freeze the main thread for that period of time and so the server will not be able to issue new commands until your delay has timed out.

    What you need is a thread to sleep for n seconds and then issue the command. However, as you say the API doesn't support it. There is no way for other threads to communicate back to the main thread.
     
  5. Offline

    darknesschaos

    so, there is no way to do this yet?
     
  6. Offline

    Archelaus

    Yeah. Sorry Dark, I probably should've mentioned what Raph just said. It is the only way to do it right now, sorry.
     
  7. Offline

    darknesschaos

    heh, its ok. I just gotta program a little smarter then.
     
  8. Offline

    Archelaus

    If a event "onTimeChange(interval)" is ever released then I'd recommended hooking it to that.
     
  9. Offline

    Raphfrk

    One option is to piggyback on some other hook and have that check if there is anything in the queue (you could used a "LinkedBlockQueue<Runnable> queue" to create a queue, or a Block).

    For example, every time a player moves you could check if the timer has expired. The more hooks you check from the quicker it will detect the change. However, the more checks, the more server load.

    Code:
    LinkedBlockingQueue queue = new LinkedBlockingQueue();
    
    void addToQueue(Runnable r) {
        queue.offer(r);
    }
    
    void pollQueue() {
        Runnable r;
        do {
            r = queue.poll();
            if( r != null ) {
                r.run();
            }
        } while ( r != null );
    }
    
    You need to call pollQueue() from some hook.

    To add code to the queue use

    Code:
    final SomeClass finalVariableName = variableName;
    
    addToQueue( new Runnable {
        public run() {
            <do something>;
        }
    
    } );
    
    You need to use the final keyword and make copies/clones of any variables you want to pass to the Runnable.
     
  10. Offline

    Kr1sc

    Use the java.util.Timer class:

    Code:
    // Setup a timer so that the update method gets called (and call it)
    updateTimer = new Timer();
    updateTimer.schedule(new KikkitUpdater(this), 0, UPDATE_INTERVAL);
    Taken from: https://github.com/jsedlak/Kikkit/blob/master/src/core/Kikkit.java
    And the updater class: https://github.com/jsedlak/Kikkit/blob/master/src/core/KikkitUpdater.java

    More info: http://download.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html
    More: http://www.java2s.com/Code/Java/Dev...eduleatasktoexecuteonce5secondshavepassed.htm
     
  11. Offline

    Raphfrk

    I'm 90% sure that is also risky. He is calling the API functions from the timer thread.
     
  12. Offline

    Kr1sc

    Good point. I'll have to change it.

    Is there a mechanism in Java similar to the lock keyword in C# for thread safe access?
     
  13. Offline

    Raphfrk

    You can use synchronized blocks.

    Code:
    int x;
    Object xSync = new Object[]
    
    To update the x from another thread:

    Code:
    synchronized(xSync) {
        x++;
    }
    
    Effectively, xSync acts as a mutex.
     
  14. Offline

    Kr1sc

    Works just like lock! Nice.
     
  15. Offline

    Raphfrk

    Also, for non-primative types, you can use the variable itself as the sync object.

    However, be careful.

    Code:
    Integer x = 7;
    
    <do stuff>
    
    synchronized(x) {
      x=y;
    }
    
    is not allowed.

    x = y causes variable x to change reference so that it points at the same object as y. This means that x is no longer synchronized properly.
     
Thread Status:
Not open for further replies.

Share This Page