PocketMine-MP 5.23.3 git-f7687af337d001ddbcc47b8e773f014a33faa662
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 }
97
101 public function isCrashed() : bool{
102 return $this->isTerminated();
103 }
104
109 public function isFinished() : bool{
110 return $this->finished || $this->isTerminated();
111 }
112
113 public function hasResult() : bool{
114 return $this->result !== null;
115 }
116
120 public function getResult(){
121 if($this->result instanceof NonThreadSafeValue){
122 return $this->result->deserialize();
123 }
124 return $this->result;
125 }
126
127 public function setResult(mixed $result) : void{
128 $this->result = is_scalar($result) || is_null($result) || $result instanceof ThreadSafe ? $result : new NonThreadSafeValue($result);
129 }
130
134 public function cancelRun() : void{
135 //NOOP
136 }
137
141 public function hasCancelledRun() : bool{
142 return false;
143 }
144
145 public function setSubmitted() : void{
146 $this->submitted = true;
147 }
148
149 public function isSubmitted() : bool{
150 return $this->submitted;
151 }
152
156 abstract public function onRun() : void;
157
162 public function onCompletion() : void{
163
164 }
165
174 public function publishProgress(mixed $progress) : void{
175 $progressUpdates = $this->progressUpdates;
176 if($progressUpdates === null){
177 $progressUpdates = $this->progressUpdates = new ThreadSafeArray();
178 }
179 $progressUpdates[] = igbinary_serialize($progress) ?? throw new \InvalidArgumentException("Progress must be serializable");
180 }
181
186 public function checkProgressUpdates() : void{
187 $progressUpdates = $this->progressUpdates;
188 if($progressUpdates !== null){
189 while(($progress = $progressUpdates->shift()) !== null){
190 $this->onProgressUpdate(igbinary_unserialize($progress));
191 }
192 }
193 }
194
205 public function onProgressUpdate($progress) : void{
206
207 }
208
212 public function onError() : void{
213
214 }
215
230 protected function storeLocal(string $key, mixed $complexData) : void{
231 self::$threadLocalStorage[spl_object_id($this)][$key] = $complexData;
232 }
233
244 protected function fetchLocal(string $key){
245 $id = spl_object_id($this);
246 if(!isset(self::$threadLocalStorage[$id]) || !array_key_exists($key, self::$threadLocalStorage[$id])){
247 throw new \InvalidArgumentException("No matching thread-local data found on this thread");
248 }
249
250 return self::$threadLocalStorage[$id][$key];
251 }
252
253 final public function __destruct(){
254 $this->reallyDestruct();
255 unset(self::$threadLocalStorage[spl_object_id($this)]);
256 }
257
261 protected function reallyDestruct() : void{
262
263 }
264}