1
0
mirror of https://github.com/danog/loop.git synced 2024-12-11 08:50:23 +01:00
loop/lib/Traits/SignalLoop.php
2020-07-21 21:45:22 +02:00

82 lines
2.0 KiB
PHP

<?php
/**
* Loop helper trait.
*
* @author Daniil Gentili <daniil@daniil.it>
* @copyright 2016-2020 Daniil Gentili <daniil@daniil.it>
* @license https://opensource.org/licenses/MIT MIT
*/
namespace danog\Loop\Traits;
use Amp\Coroutine;
use Amp\Deferred;
use Amp\Promise;
/**
* Signal loop helper trait.
*
* @author Daniil Gentili <daniil@daniil.it>
*/
trait SignalLoop
{
/**
* Signal deferred.
*
* @var ?Deferred
*/
private $signalDeferred;
/**
* Send signal to loop.
*
* @param mixed|\Throwable $what Data to signal
*
* @return void
*/
public function signal($what): void
{
if ($this->signalDeferred) {
$deferred = $this->signalDeferred;
$this->signalDeferred = null;
if ($what instanceof \Throwable) {
$deferred->fail($what);
} else {
$deferred->resolve($what);
}
}
}
/**
* Resolve the promise or return|throw the signal.
*
* @param Promise|\Generator $promise The original promise or generator
*
* @return Promise
*
* @template T
*
* @psalm-param Promise<T>|\Generator<mixed,Promise|array<array-key,
* Promise>,mixed,Promise<T>|T> $promise The original promise or generator
*
* @psalm-return Promise<T|mixed>
*/
public function waitSignal($promise): Promise
{
if ($promise instanceof \Generator) {
$promise = new Coroutine($promise);
}
$this->signalDeferred = new Deferred();
$combinedPromise = $this->signalDeferred->promise();
$promise->onResolve(
function () use ($promise) {
if ($this->signalDeferred !== null) {
$deferred = $this->signalDeferred;
$this->signalDeferred = null;
$deferred->resolve($promise);
}
}
);
return $combinedPromise;
}
}