Skip to content

Instantly share code, notes, and snippets.

@SOF3
Last active May 17, 2023 23:30
Show Gist options
  • Save SOF3/0398e81f568d72b29888c42ba969ac62 to your computer and use it in GitHub Desktop.
Save SOF3/0398e81f568d72b29888c42ba969ac62 to your computer and use it in GitHub Desktop.
Proof of concept for abusing yield as sleep
<?php
namespace SOFe\YieldTask;
use pocketmine\plugin\Plugin;
use pocketmine\scheduler\PluginTask;
class YieldTask extends PluginTask{
const UNIT_TICKS = 1;
const UNIT_SECONDS = 20;
const UNIT_MINUTES = 1200;
private $generator;
private $factor;
public function __construct(Plugin $owner, $generator, int $unit = self::UNIT_SECONDS){
if(is_callable($generator)) $generator = $generator();
if(!($generator instanceof \Generator)) throw new \InvalidArgumentException;
parent::__construct($owner);
$this->generator = $generator;
$this->factor = $unit;
$this->owner->getServer()->getScheduler()->scheduleDelayedTask($this, $this->generator->current() * $this->factor);
}
public function onRun(int $tick){
$this->generator->next();
$this->owner->getServer()->getScheduler()->scheduleDelayedTask($this, $this->generator->current() * $this->factor);
}
}
<?php
namespace SOFe\YieldTaskTest;
use pocketmine\plugin\PluginBase;
use SOFe\YieldTask\YieldTask;
class YieldTaskTest extends PluginBase{
public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool{
new YieldTask($this, function() use($sender){
$sender->sendMessage("10 seconds left");
yield 1;
$sender->sendMessage("9 seconds left");
yield 4;
$sender->sendMessage("5 seconds left");
yield 5;
$sender->sendMessage("Time's up!");
}, YieldTask::UNIT_SECONDS);
return true;
}
}
@0x15f
Copy link

0x15f commented Jan 10, 2018

Really neat, this could be used in countless ways.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment