sdl3/src/Async/AsyncTask.php
2025-11-11 11:39:33 +01:00

126 lines
2.8 KiB
PHP

<?php
namespace PHPNative\Async;
use parallel\Runtime;
use parallel\Future;
class AsyncTask
{
private ?Future $future = null;
private mixed $result = null;
private bool $completed = false;
private bool $failed = false;
private mixed $error = null;
private mixed $onComplete = null;
private mixed $onError = null;
private mixed $task = null;
public function __construct(
callable $task
) {
$this->task = $task;
}
/**
* Start the async task execution
*/
public function start(): void
{
if ($this->future !== null) {
return; // Already started
}
try {
// Create runtime with bootstrap file to load autoloader
$bootstrapPath = __DIR__ . '/bootstrap.php';
$runtime = new Runtime($bootstrapPath);
$this->future = $runtime->run($this->task);
} catch (\Throwable $e) {
$this->failed = true;
$this->error = $e;
$this->completed = true;
}
}
/**
* Check if task is completed and process result
*/
public function update(): void
{
if ($this->completed || $this->future === null) {
return;
}
// Check if future is done without blocking
if ($this->future->done()) {
try {
$this->result = $this->future->value();
$this->completed = true;
if ($this->onComplete !== null) {
($this->onComplete)($this->result);
}
} catch (\Throwable $e) {
$this->failed = true;
$this->error = $e;
$this->completed = true;
if ($this->onError !== null) {
($this->onError)($this->error);
}
}
}
}
/**
* Set callback for successful completion
*/
public function onComplete(callable $callback): self
{
$this->onComplete = $callback;
return $this;
}
/**
* Set callback for errors
*/
public function onError(callable $callback): self
{
$this->onError = $callback;
return $this;
}
/**
* Check if task is completed
*/
public function isCompleted(): bool
{
return $this->completed;
}
/**
* Check if task failed
*/
public function isFailed(): bool
{
return $this->failed;
}
/**
* Get the result (only available after completion)
*/
public function getResult(): mixed
{
return $this->result;
}
/**
* Get the error (only available after failure)
*/
public function getError(): mixed
{
return $this->error;
}
}