Skip to content

Instantly share code, notes, and snippets.

@TigerHix
Last active November 27, 2016 19:54
Show Gist options
  • Save TigerHix/e989f3f7d9e691fc52b5 to your computer and use it in GitHub Desktop.
Save TigerHix/e989f3f7d9e691fc52b5 to your computer and use it in GitHub Desktop.
PocketMine Task
<?php
namespace hawkpe\common\runnable\task;
use pocketmine\plugin\Plugin;
use pocketmine\scheduler\PluginTask;
class Task extends PluginTask {
const CANCEL = "CANCEL";
const SUCCESS = "SUCCESS";
protected $plugin;
protected $runCallable;
protected $runArgs;
protected $cancelCallable;
protected $cancelArgs;
protected $executionTimestamp;
protected $counter;
private $id = -1;
private $executionDelay = -1;
private $repeatInterval = -1;
private $numberOfExecutions = -1;
private $willRunOnCancel = false;
public function __construct(Plugin $plugin, callable $runCallable = null, array $runArgs = [], callable $cancelCallable = null, array $cancelArgs = []) {
parent::__construct($plugin);
$this->plugin = $plugin;
$this->runCallable = $runCallable;
$this->runArgs = $runArgs;
$this->cancelCallable = $cancelCallable;
$this->cancelArgs = $cancelArgs;
$this->instant();
}
public function schedule() {
if ($this->plugin->isDisabled()) return $this;
if ($this->id != -1) $this->cancel();
$this->executionTimestamp = microtime(true);
if ($this->executionDelay != -1) {
if ($this->repeatInterval != -1) {
$this->id = $this->plugin->getServer()->getScheduler()->scheduleDelayedRepeatingTask($this, $this->executionDelay, $this->repeatInterval)->getTaskId();
} else {
$this->id = $this->plugin->getServer()->getScheduler()->scheduleDelayedTask($this, $this->executionDelay)->getTaskId();
}
$this->executionTimestamp += $this->executionDelay * 50 / 1000;
} else {
$this->id = $this->plugin->getServer()->getScheduler()->scheduleTask($this)->getTaskId();
}
return $this;
}
public final function cancel() {
if ($this->id == -1) return false;
$this->plugin->getServer()->getScheduler()->cancelTask($this->id);
return true;
}
public function onRun($currentTick) {
if (isset($this->runCallable) && $this->invoke($this->runCallable, $this->runArgs) == Task::CANCEL) {
$this->cancel();
}
if ($this->willCount()) {
$this->counter++;
if ($this->counter == $this->numberOfExecutions) {
$this->cancel();
}
}
}
public function onCancel() {
if ($this->willRunOnCancel) $this->invoke($this->runCallable, $this->runArgs);
if (isset($this->cancelCallable)) $this->invoke($this->cancelCallable, $this->cancelArgs);
}
protected function invoke($callable, array $args) {
return call_user_func_array($callable, $args);
}
public function instant() {
return $this->after(0);
}
public function after($executionDelay) {
if ($executionDelay < 0) throw new \InvalidArgumentException();
$this->executionDelay = $executionDelay;
return $this;
}
public function repeat($repeatInterval) {
if ($repeatInterval < 0) throw new \InvalidArgumentException();
$this->repeatInterval = $repeatInterval;
if ($this->executionDelay == -1) $this->executionDelay = 0;
return $this;
}
public function times($numberOfExecutions) {
if ($numberOfExecutions < 1) throw new \InvalidArgumentException();
$this->numberOfExecutions = $numberOfExecutions;
if ($this->executionDelay == -1) $this->executionDelay = 0;
return $this;
}
private function willCount() {
return $this->numberOfExecutions > 0;
}
public function willRunOnCancel() {
return $this->willRunOnCancel;
}
public function setWillRunOnCancel($willRunOnCancel) {
$this->willRunOnCancel = $willRunOnCancel;
return $this;
}
}
$task = new Task($plugin, function() {
foreach ($plugin->getServer()->getOnlinePlayers() as $player) {
$player->sendMessage("This is an delayed message");
}
});
$task->after(10)->schedule(); // The task will be run after 10 ticks
$task = new Task($plugin, function() {
foreach ($plugin->getServer()->getOnlinePlayers() as $player) {
$player->sendMessage("This is a repeating message");
}
});
$task->repeat(5)->schedule(); // The task will be run for the first time after 5 ticks, and run repeatedly on an interval of 5 ticks afterwards
$task = new Task($plugin, function() {
foreach ($plugin->getServer()->getOnlinePlayers() as $player) {
$player->sendMessage("This is a repeating and delayed message");
}
});
$task->after(60)->repeat(5)->schedule(); // The task will be run for the first time after 60 ticks, and run repeatedly on an interval of 5 ticks afterwards
$task = new Task($plugin, function() {
foreach ($plugin->getServer()->getOnlinePlayers() as $player) {
$player->sendMessage("This message will be sent for 10 times");
}
});
$task->repeat(5)->times(10)->schedule(); // The task will be run on an interval of 5 ticks, and automatically get cancelled after executing 10 times
$task = new Task($plugin, function(Player $player, Item $item) {
$player->sendMessage("This task give an item to a player");
$player->getInventory()->addItem($item);
}, [$plugin->getServer()->getPlayer("TigerHix"), Item::get(Item::APPLE)]); // You can supply parameters to the function as long as you provide them as the second parameter
$task->cancel(); // You can cancel a task at anytime by simply calling the cancel() method
// Or, you can cancel the task within the function, by returning Task::CANCEL
$task = (new Task($plugin, function() {
if (mt_rand(0, 1)) {
print("Cool"); // If number one generated, this task will still be scheduled for the next tick
} else {
print("Boom");
return Task::CANCEL; // If number zero generated, this task will be cancelled and will not be run afterwards
}
}))->repeat(1)->schedule();
// You can even specify what function to run when the task is cancelled by passing the 3rd and 4th paramater
$task = new Task($plugin, function() {
return Task::CANCEL; // This task will be cancelled immediately on run
}, [], function() {
print("This task is cancelled :("); // On cancel, this message will be printed
}, []); // In case you haven't realized yet, you can set parameters of the cancel function as well
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment