Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Tutorial How to use schedules in a plugin

Comments in 'Resources' started by Orycterope, Aug 25, 2014.

  1. Orycterope
    Offline

    Orycterope New Member

    Joined:
    Jan 7, 2014
    Posts:
    9
    Minecraft User:
    Orycterope
    When i was learning how to use the new API, I wish I had a tutorial on how to use schedules, cause they are great, but i couldn't find one so I had to figure it out by myself... So now i decided to share it ;)

    Let's pretend we are writing a new plugin called ExamplePlugin, and we have already coded the ExamplePlugin.php exept the schedule part.

    Here we go !

    First, you need to create a new class and extend PluginTask (pocketmine\scheduler\PluginTask)
    We will do it in ExampleTask.php :

    PHP:
    <?php

    namespace exampleauthor\exampleplugin;

    use 
    pocketmine\scheduler\PluginTask;

    class 
    ExampleTask extends PluginTask{

        public function 
    onRun($currentTick) {
      
            
    //The code that will be executed when the Task is called

            
    $this->getOwner()->getServer()->broadcastMessage("Executing the task");
            
    //You can also call a function of ExamplePlugin.php with $getOwner() :
            
    $this->getOwner()->dummyFunction("parameter 1""parameter 2""etc.");
        }
    }
    This is the most basic task you can write, but you get the idea :p

    The task is what will be given to the server, and when it will be the time, the server will call the onRun() function so make sure to override it ;)

    You can also hand on variables to the task (such as a Player object, for instance) by overriding the __construct() method :
    PHP:
    use pocketmine\plugin\Plugin;

    use 
    pocketmine\Player;
    PHP:
    public function __construct(Plugin $owner,  Player $player) {

            
    parent::__construct($owner);
            
    $this->player $player;
        }
    And a way to cancel the task easily is convenient, so you can write a cancel() methode :
    PHP:
    public function cancel() {

            
    $this->getHandler()->cancel();
        }
    So the full ExampleTask.php might be like that :
    PHP:
    namespace exampleauthor\exampleplugin;

    use 
    pocketmine\scheduler\PluginTask;
    use 
    pocketmine\plugin\Plugin;
    use 
    pocketmine\Player;

    class 
    ExampleTask extends PluginTask{

        public function 
    __construct(Plugin $ownerPlayer $player) {
            
    parent::__construct($owner);
            
    $this->player $player;
        }

        public function 
    onRun($currentTick) {
            
    $this->getOwner()->getServer()->broadcastMessage("Executing the task");
            
    $this->getOwner()->dummyFunction("parameter 1""parameter 2""etc.");
            if(
    $this->player instanceof Player){ //verifying if the player is still connect to avoid errors
                 
    $player->sendMessage("Hello");
            }
        }

        public function 
    cancel() {
            
    $this->getHandler()->cancel();
        }
    }
    Here we are ! The task class is complete, now it is time to instantiate it. Go back tou you main file ExamplePlugin.php and write that :
    PHP:
    [........]

         public function 
    onCommand(CommandSender $senderCommand $command$label, array $args){

           
    $task = new ExampleTask($this$randomPlayer);
           
    //if you did not override the __construct methode, the code is
           //$task = new ExampleTask($this);

    Now you need to know the differents way for the server to register a task (the differents schedule types) :
    • scheduleTask(Task $task) : a basic schedule that won't work if you don't modify anything (let's ignore it for now)
    • scheduleDelayedTask(Task $task, $delay) : this task will be called in "now + $delay" (the delay is in ticks, *remember : 1 tick = 1/20 sec, so 1 sec = 20 ticks*)
    • scheduleRepeatingTask(Task $task, $period) : a task that will executed every $period ticks, starting right now.
    • scheduleDelayedRepeatingTask(Task $task, $delay, $period) : a task that will be executed every $period ticks, sarting in $delay ticks (same as scheduleRepeatingTask but delayed)
    • scheduleAsyncTask(AsyncTask $task) : a task that is not synchronized with the main thread (you can execute infinite loops for instance and it won't block the serv) For this one you must extend AsyncTask instead of PluginTask. Attention, AsyncTasks are really particular tu use, so use them only if you know what you're doing !
    When you have choosed the one that you want for your plugin, you call it with
    PHP:
    [..........]

    public function 
    onCommand(CommandSender $senderCommand $command$label, array $args){

           
    $task = new ExampleTask($this$randomPlayer);
           
    $this->getServer()->getScheduler()->scheduleDelayedTask($task600);
           
    // ! remeber that the delay/period is in ticks
           // you can replace "scheduleDelayTask" with the other functions above

    [..........]

    Keeping a list of your tasks in an array is also a good habit, so you can cancel some or execute some functions while waiting for the schedule to be over :
    PHP:
    $this->tasks[] = $task
    Your final ExamplPlugin.php might be like that :

    PHP:
    [..........]
    public 
    tasks = array();

    public function 
    onCommand(CommandSender $senderCommand $command$label, array $args){

           
    $randomPlayer $sender // let's make it simple ;)

           
    $task = new ExampleTask($this$randomPlayer);
           
    $this->getServer()->getScheduler()->scheduleDelayedTask($task600);

    public function 
    dummyFunction($string1$string2$string3){

          
    $this->getServer()->broadcastMessage("I'm dummy ! :D");
    }

    [............]

    And that's it ! Now you know how to use schedules !
    I hope i helped you :D
    Last edited: Aug 25, 2014
  2. GlaciercreepsMC
    Offline

    GlaciercreepsMC Active Member Plugin Developer

    Joined:
    Jan 21, 2014
    Posts:
    91
    Plugins:
    1
    Minecraft User:
    GlaciercreepsMC
    Very nice tutorial, good job! :)
    Also you may want to add that one tick = 1/20 sec, so twenty ticks is one sec, in other words.
    Orycterope likes this.
  3. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    You forgot some parentheses.

    The $this->player instanceof Player line is pointless. If it was a Player object when it was passed in, since it is a strong reference, it will not be garbaged.

    Meanwhile, since it is a strong reference, it is a bad practice to store a player object since some strange things may happen if you work on a Player object whose client is in fact offline. As a good practice, you should either:
    • Save $player->getID() and then loop through all online players to see if $player->getID() equals the stored value. This, however, is only suitable when the player is still online. Once the player quits, even if he reconnects, the ID would no longer work. Nevertheless, this is most memory-efficient.
    • Save the player's name. You are recommended to save the lowercase name since you are advised to only use getID() if you expect the player is in the same session, otherwise, you should check case-insensitively.
    • Use WeakRef. After getting the player object, if you save it for later use, store it as $this->wr = new \WeakRef($player). Then every time you want to get the player, use this:
      PHP:
      if($this->wr->valid()){
          
      $player $this->wr->get();
          
      // do something with $player, where $player should be instance of Player.
      }
      else{
          
      // the player is offline. Do something if you want.
      }
      Note that if you didn't add the valid() check, a RuntimeException will be thrown. Details at my debugging cheat sheet thread.
    Also, consider saving TaskHandler instead of the PluginTask instance.

    And you forgot to tell them the danger of AsyncTask and that AsyncTask is not am instance if Task and should be declared in other ways.
    Last edited: Aug 25, 2014
  4. Orycterope
    Offline

    Orycterope New Member

    Joined:
    Jan 7, 2014
    Posts:
    9
    Minecraft User:
    Orycterope
    Thanks for all this informations ! :D I didn't know about half you said :p

    What do you mean by
    I didn't get it :/

    Ok I add informations and a warning for thr AsyncTask.
  5. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    schedule***() returns a TaskHandler instance.

    And you didn't say how to cancel the task.
  6. CavinMiana
    Offline

    CavinMiana Active Member

    Joined:
    Aug 26, 2015
    Posts:
    101
    Minecraft User:
    CavinMiana
    Don't you do
    Code:
    return {
    }
  7. CavinMiana
    Offline

    CavinMiana Active Member

    Joined:
    Aug 26, 2015
    Posts:
    101
    Minecraft User:
    CavinMiana
    Wait do if you schedulerepeattask its it like Time kind of like a timer? Because you were talking about how 1 tick = 20 secs
    and nice tutorial
  8. Blaneplooster2
    Offline

    Blaneplooster2 New Member

    Joined:
    May 26, 2015
    Posts:
    7
    Minecraft User:
    Blaneplooster2
    Lol
  9. CavinMiana
    Offline

    CavinMiana Active Member

    Joined:
    Aug 26, 2015
    Posts:
    101
    Minecraft User:
    CavinMiana
    Umm ok
  10. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    Please do not bump old threads. There are some pretty outdated things here, like WeakRef.
  11. CavinMiana
    Offline

    CavinMiana Active Member

    Joined:
    Aug 26, 2015
    Posts:
    101
    Minecraft User:
    CavinMiana
    Ok sorry

Share This Page

Advertisement