PocketMine-MP 5.28.3 git-94fb5d95b92604840dabb719f04327efa559cf94
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;
31use function array_key_exists;
32use function igbinary_serialize;
33use function igbinary_unserialize;
34use function is_null;
35use function is_scalar;
36use function spl_object_id;
37
62abstract class AsyncTask extends Runnable{
69 private static array $threadLocalStorage = [];
70
75 private ?ThreadSafeArray $progressUpdates = null;
76
77 private ThreadSafe|string|int|bool|null|float $result = null;
78
79 private bool $submitted = false;
80 private bool $finished = false;
81
82 public function run() : void{
83 $this->result = null;
84
85 $timings = Timings::getAsyncTaskRunTimings($this);
86 $timings->startTiming();
87
88 try{
89 $this->onRun();
90 }finally{
91 $timings->stopTiming();
92 }
93
94 $this->finished = true;
95 AsyncWorker::getNotifier()->wakeupSleeper();
96 AsyncWorker::maybeCollectCycles();
97 }
98
102 public function isCrashed() : bool{
103 return $this->isTerminated();
104 }
105
110 public function isFinished() : bool{
111 return $this->finished || $this->isTerminated();
112 }
113
114 public function hasResult() : bool{
115 return $this->result !== null;
116 }
117
121 public function getResult(){
122 if($this->result instanceof NonThreadSafeValue){
123 return $this->result->deserialize();
124 }
125 return $this->result;
126 }
127
128 public function setResult(mixed $result) : void{
129 $this->result = is_scalar($result) || is_null($result) || $result instanceof ThreadSafe ? $result : new NonThreadSafeValue($result);
130 }
131
135 public function cancelRun() : void{
136 //NOOP
137 }
138
142 public function hasCancelledRun() : bool{
143 return false;
144 }
145
146 public function setSubmitted() : void{
147 $this->submitted = true;
148 }
149
150 public function isSubmitted() : bool{
151 return $this->submitted;
152 }
153
157 abstract public function onRun() : void;
158
163 public function onCompletion() : void{
164
165 }
166
175 public function publishProgress(mixed $progress) : void{
176 $progressUpdates = $this->progressUpdates;
177 if($progressUpdates === null){
178 $progressUpdates = $this->progressUpdates = new ThreadSafeArray();
179 }
180 $progressUpdates[] = igbinary_serialize($progress) ?? throw new \InvalidArgumentException("Progress must be serializable");
181 }
182
187 public function checkProgressUpdates() : void{
188 $progressUpdates = $this->progressUpdates;
189 if($progressUpdates !== null){
190 while(($progress = $progressUpdates->shift()) !== null){
191 $this->onProgressUpdate(igbinary_unserialize($progress));
192 }
193 }
194 }
195
206 public function onProgressUpdate($progress) : void{
207
208 }
209
213 public function onError() : void{
214
215 }
216
231 protected function storeLocal(string $key, mixed $complexData) : void{
232 self::$threadLocalStorage[spl_object_id($this)][$key] = $complexData;
233 }
234
245 protected function fetchLocal(string $key){
246 $id = spl_object_id($this);
247 if(!isset(self::$threadLocalStorage[$id]) || !array_key_exists($key, self::$threadLocalStorage[$id])){
248 throw new \InvalidArgumentException("No matching thread-local data found on this thread");
249 }
250
251 return self::$threadLocalStorage[$id][$key];
252 }
253
254 final public function __destruct(){
255 $this->reallyDestruct();
256 unset(self::$threadLocalStorage[spl_object_id($this)]);
257 }
258
262 protected function reallyDestruct() : void{
263
264 }
265}