34 private bool $enabled =
true;
45 protected int $currentTick = 0;
47 public function __construct(
48 private ?
string $owner =
null
61 return $this->addTask($task, -1, -1);
71 return $this->addTask($task, $delay, -1);
81 return $this->addTask($task, -1, $period);
91 return $this->addTask($task, $delay, $period);
94 public function cancelAllTasks() : void{
95 foreach($this->tasks as $id => $task){
98 $this->tasks->clear();
99 while(!$this->queue->isEmpty()){
100 $this->queue->extract();
108 return $this->tasks->contains($task);
117 private function addTask(
Task $task,
int $delay,
int $period) :
TaskHandler{
119 throw new \LogicException(
"Tried to schedule task to disabled scheduler");
128 }elseif($period < 1){
132 return $this->handle(
new TaskHandler($task, $delay, $period, $this->owner));
140 private function handle(TaskHandler $handler) : TaskHandler{
141 if($handler->isDelayed()){
142 $nextRun = $this->currentTick + $handler->getDelay();
144 $nextRun = $this->currentTick;
147 $handler->setNextRun($nextRun);
148 $this->tasks->add($handler);
149 $this->queue->insert($handler, $nextRun);
154 public function shutdown() : void{
155 $this->enabled = false;
156 $this->cancelAllTasks();
159 public function setEnabled(
bool $enabled) : void{
160 $this->enabled = $enabled;
163 public function mainThreadHeartbeat(
int $currentTick) : void{
165 throw new \LogicException(
"Cannot run heartbeat on a disabled scheduler");
167 $this->currentTick = $currentTick;
168 while($this->isReady($this->currentTick)){
170 $task = $this->queue->extract();
171 if($task->isCancelled()){
172 $this->tasks->remove($task);
176 if(!$task->isCancelled() && $task->isRepeating()){
177 $task->setNextRun($this->currentTick + $task->getPeriod());
178 $this->queue->insert($task, $this->currentTick + $task->getPeriod());
181 $this->tasks->remove($task);
186 private function isReady(
int $currentTick) : bool{
187 return !$this->queue->isEmpty() && $this->queue->current()->getNextRun() <= $currentTick;