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: <?phpnamespace 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 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 $owner, Player $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 $sender, Command $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 $sender, Command $command, $label, array $args){ $task = new ExampleTask($this, $randomPlayer); $this->getServer()->getScheduler()->scheduleDelayedTask($task, 600); // ! 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 $sender, Command $command, $label, array $args){ $randomPlayer = $sender // let's make it simple ;) $task = new ExampleTask($this, $randomPlayer); $this->getServer()->getScheduler()->scheduleDelayedTask($task, 600);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
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.
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.
Thanks for all this informations ! I didn't know about half you said What do you mean by I didn't get it :/ Ok I add informations and a warning for thr AsyncTask.
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