PocketMine-MP 5.21.2 git-a6534ecbbbcf369264567d27e5ed70f7f5be9816
Loading...
Searching...
No Matches
AsyncTask.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\scheduler;
25
26use pmmp\thread\Runnable;
27use pmmp\thread\ThreadSafe;
28use pmmp\thread\ThreadSafeArray;
30use function array_key_exists;
31use function igbinary_serialize;
32use function igbinary_unserialize;
33use function is_null;
34use function is_scalar;
35use function spl_object_id;
36
61abstract class AsyncTask extends Runnable{
68 private static array $threadLocalStorage = [];
69
71 private ?ThreadSafeArray $progressUpdates = null;
72
73 private ThreadSafe|string|int|bool|null|float $result = null;
74
75 private bool $submitted = false;
76 private bool $finished = false;
77
78 public function run() : void{
79 $this->result = null;
80
81 $this->onRun();
82
83 $this->finished = true;
84 AsyncWorker::getNotifier()->wakeupSleeper();
85 }
86
91 public function isFinished() : bool{
92 return $this->finished || $this->isTerminated();
93 }
94
95 public function hasResult() : bool{
96 return $this->result !== null;
97 }
98
102 public function getResult(){
103 if($this->result instanceof NonThreadSafeValue){
104 return $this->result->deserialize();
105 }
106 return $this->result;
107 }
108
109 public function setResult(mixed $result) : void{
110 $this->result = is_scalar($result) || is_null($result) || $result instanceof ThreadSafe ? $result : new NonThreadSafeValue($result);
111 }
112
113 public function setSubmitted() : void{
114 $this->submitted = true;
115 }
116
117 public function isSubmitted() : bool{
118 return $this->submitted;
119 }
120
124 abstract public function onRun() : void;
125
130 public function onCompletion() : void{
131
132 }
133
140 public function publishProgress(mixed $progress) : void{
141 $progressUpdates = $this->progressUpdates;
142 if($progressUpdates === null){
143 $progressUpdates = $this->progressUpdates = new ThreadSafeArray();
144 }
145 $progressUpdates[] = igbinary_serialize($progress) ?? throw new \InvalidArgumentException("Progress must be serializable");
146 }
147
151 public function checkProgressUpdates() : void{
152 $progressUpdates = $this->progressUpdates;
153 if($progressUpdates !== null){
154 while(($progress = $progressUpdates->shift()) !== null){
155 $this->onProgressUpdate(igbinary_unserialize($progress));
156 }
157 }
158 }
159
168 public function onProgressUpdate($progress) : void{
169
170 }
171
186 protected function storeLocal(string $key, mixed $complexData) : void{
187 self::$threadLocalStorage[spl_object_id($this)][$key] = $complexData;
188 }
189
200 protected function fetchLocal(string $key){
201 $id = spl_object_id($this);
202 if(!isset(self::$threadLocalStorage[$id]) || !array_key_exists($key, self::$threadLocalStorage[$id])){
203 throw new \InvalidArgumentException("No matching thread-local data found on this thread");
204 }
205
206 return self::$threadLocalStorage[$id][$key];
207 }
208
209 final public function __destruct(){
210 $this->reallyDestruct();
211 unset(self::$threadLocalStorage[spl_object_id($this)]);
212 }
213
217 protected function reallyDestruct() : void{
218
219 }
220}