-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfunctions.php
More file actions
142 lines (125 loc) · 3.97 KB
/
Copy pathfunctions.php
File metadata and controls
142 lines (125 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
declare(strict_types=1);
namespace WyriHaximus\React;
use React\EventLoop\Loop;
use React\EventLoop\TimerInterface;
use React\Promise\Deferred;
use React\Promise\PromiseInterface;
/**
* @param T $value Value to return on resolve.
*
* @return PromiseInterface<T>
*
* @template T
* Promise that resolves once future tick is called.
*
* @phpstan-ignore ergebnis.noParameterWithNullDefaultValue
*/
function futurePromise(mixed $value = null): PromiseInterface
{
/** @var Deferred<T> $deferred */
$deferred = new Deferred();
Loop::futureTick(static function () use ($deferred, $value): void {
$deferred->resolve($value);
});
return $deferred->promise();
}
/**
* Promise that resolves after $interval has passed.
*
* @param float $interval The number of seconds to wait before execution.
* @param T $value Value to return on resolve.
*
* @return PromiseInterface<T>
*
* @template T
*
* @phpstan-ignore ergebnis.noParameterWithNullDefaultValue
*/
function timedPromise(float $interval, mixed $value = null): PromiseInterface
{
/** @var Deferred<T> $deferred */
$deferred = new Deferred();
Loop::addTimer($interval, static function () use ($deferred, $value): void {
$deferred->resolve($value);
});
return $deferred->promise();
}
/**
* Promise that resolves once $check returns something other then false. Runs at periodic $interval.
*
* @param float $interval The number of seconds between each interval to run $check.
* @param callable(mixed): (false|mixed) $check Callable to run at the specified $interval.
* @param T $value Value to pass into $check on tick.
*
* @return PromiseInterface<T>
*
* @template T
*
* @phpstan-ignore ergebnis.noParameterWithNullDefaultValue
*/
function tickingPromise(float $interval, callable $check, mixed $value = null): PromiseInterface
{
/** @var Deferred<T> $deferred */
$deferred = new Deferred();
Loop::addPeriodicTimer($interval, static function (TimerInterface $timer) use ($deferred, $check, $value): void {
$result = $check($value);
if ($result === false) {
return;
}
Loop::cancelTimer($timer);
$deferred->resolve($result);
});
return $deferred->promise();
}
/**
* Promise that resolves once $check returns something other then false. Runs at future tick interval.
*
* @param (callable(?mixed): (T|false)) $check Callable to run at tick.
* @param mixed $value Value to pass into $check on tick.
* @param int $iterations Number of iterations to call $check in one tick.
*
* @return PromiseInterface<(T is void ? null : T)>
*
* @template T
*
* @phpstan-ignore ergebnis.noParameterWithNullDefaultValue
*/
function tickingFuturePromise(callable $check, mixed $value = null, int $iterations = 1): PromiseInterface
{
/** @var Deferred<T> $deferred */
$deferred = new Deferred();
$runCheck = static function () use ($check, &$runCheck, $deferred, $iterations, $value): void {
for ($i = 0; $i <= $iterations; $i++) {
$result = $check($value);
if ($result !== false) {
$runCheck = null;
$deferred->resolve($result);
return;
}
}
futurePromise()->then($runCheck);
};
futurePromise()->then($runCheck);
return $deferred->promise();
}
/**
* Sandwich a $function call within two futureTicks.
*
* @param T $value Value to pass into $function.
* @param (callable(T): T) $function Function to wrap.
*
* @return PromiseInterface<T>
*
* @template T
*/
function futureFunctionPromise(mixed $value, callable $function): PromiseInterface
{
/**
* @param T $value
*
* @return PromiseInterface<T>
*/
$handler = static fn (mixed $value): PromiseInterface => futurePromise($function($value));
return futurePromise($value)->then($handler);
}