Scheduling a player check?

Discussion in 'Plugin Development' started by sli, Mar 6, 2011.

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

    sli

    I'm still getting over the initial learning curve. Would anyone mind giving me an explanation on how I'd schedule a check of all online players? I get the gist of it, but I know this (starting) code of mine is wrong:

    Code:
    plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
                public void run() {
                    // check players
                    Player[] onlinePlayers = plugin.getServer().getOnlinePlayers();
                    // loop through players, perform check
                }
            }, 1200L, 24000L);
    The "plugin" variable isn't correct. I know it's supposed to be a reference to my plugin, but I'm not clear on what I need to do to hand it over in that way. Java isn't my realm.

    Also, is onEnable a suitable place for scheduling tasks, or is there a better place for it?
     
  2. Offline

    andret

    as I see it onEnable only run once, and thats at server start.
     
  3. Offline

    Cheesier

    onEnable is a fine starting place in my ears, just keep the Id of the timer so you can stop it.

    If you are calling the scheduler from onEnable() then you can use
    Code:
    this.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
     
  4. Offline

    xZise

    Not only once! Everytime you reload your server (with the reload command) it will trigger this method. And there are also plugins which allows you to dynamically enable plugins.

    But I have no idea of schedulers in bukkit, so I couldn't help you much at this point. But if I'm understand this right, you could do this, but you have to stop the task in the onDisable() method. So save the taskid and call cancelTask(int) in onDisable().

    Fabian
    --- merged: Mar 6, 2011 10:39 PM ---
    @Cheesier: If you replace plugin with this you should replace all occurrences of plugin (the first parameter) and in the Runnable:
    Code:
    Player[] onlinePlayers = <Pluginclass>.this.getServer().…
    Fabian
     
  5. Offline

    Sammy

    Let me borrow this thread to ask something about scheduling too.
    How can I cancel a Schedule in a way that the runnable will not trigger not even once ?

    I have this this:
    Code:
     VoteEndTime = serv.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {}, 1400L, 1200L);
    And this Method closes the Schedule:
    Code:
    public void VoteCancel() {
    serv.getScheduler().cancelTask(VoteEndTime);
    }
    The problem is that the Runnable still trigger once.
     
  6. Offline

    sli

    Using my Pluginclass (in this case RandomGiant) is throwing an error there. Obviously I can't use "this," because the context is different inside the Runnable. But this code isn't working, either:

    Code:
    rgTask = this.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
    
                public void run() {
                    // check players and spawn a giant near one on the surface
                	Player[] onlinePlayers = RandomGiant.getServer().getOnlinePlayers();
                }
            }, 1200L, 24000L);
    It's complaining about a static reference to getServer(), so I'm assuming there's a step I'm missing.

    Pardon my ignorance. This plugin is my excuse to learn Java once and for all. :p
     
  7. Offline

    xZise

    This works:
    Code:
    package de.xzise.usa;
    
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class UniveralStandardAdapter extends JavaPlugin {
    
    	@Override
    	public void onEnable() {
    		this.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
    			@Override
    			public void run() {
    				UniveralStandardAdapter.this.getServer().getOnlinePlayers();
    			}
    		}, 0, 120*1000);
    	}
    }
    
    Fabian
    --- merged: Mar 6, 2011 11:36 PM ---
    I think a new thread would be best, because you asking something different. And as I could see in the code the task won't get executed. Only if you are too slow and missed the 1400 ms. cancelTask simply removes the task from the tasks list. The problem also is, that I doesn't find your method signature (with 4 parameters)?! Am I blind?

    Fabian
     
  8. Offline

    sli

    Thanks, xZise, that works great!

    So, to verify. scheduleAsyncRepeatingTask returns an integer, which I defined class-wide here:

    Code:
    public class RandomGiant extends JavaPlugin {
        // ...snip...
        private final HashMap<Player, Boolean> debugees = new HashMap<Player, Boolean>();
        private int rgTask;
    
        public RandomGiant(PluginLoader pluginLoader, Server instance,
                PluginDescriptionFile desc, File folder, File plugin, // ...snip...
    I create the task in onEnable, handing the return value to rgTask. Then, in onDisable, I want:

    Code:
    this.getServer().getScheduler().cancelTask(rgTask);
    Correct?
     
  9. Offline

    Raphfrk

    That cancel operation should remove the task from the queue. Is the task running when you call cancel?
    --- merged: Mar 6, 2011 11:57 PM ---
    Right.

    One point to note, if you use the Async version of the method calls, it will create another thread for executing your task. This means that you can't call the bukkit API methods from your runnable, as they aren't thread safe.
     
  10. Offline

    xZise

    But the CraftScheduler tells the CraftThreadManager to interrupt the worker which handles the task. But I'm not sure how the JVM handles this (as the worker simply interrupt the corresponding thread).

    @sli: That should work.

    Fabian
     
  11. Offline

    Raphfrk

    If the task is running in another thread, the thread is interrupted.

    This won't have any effect unless the other thread supports it. For example, if you have a .wait() call, it will throw an exception if the thread is interrupted while the wait is on going.

    You can also manually test it by calling Thread.interrupted().

    Some of the socket methods can't actually be interrupted. If you thread is waiting on network traffic, then it won't exit from the wait.
     
Thread Status:
Not open for further replies.

Share This Page