@@ -6,11 +6,36 @@ final class Loop
6
6
{
7
7
use Registry;
8
8
9
+ /**
10
+ * @var LoopDriverFactory
11
+ */
12
+ private static $ factory = null ;
13
+
9
14
/**
10
15
* @var LoopDriver
11
16
*/
12
17
private static $ driver = null ;
13
18
19
+ /**
20
+ * @var bool
21
+ */
22
+ private static $ running = false ;
23
+
24
+ /**
25
+ * Set the factory to be used to create a driver if none is passed to
26
+ * self::execute. A default driver will be created if none is running
27
+ * to support synchronous waits in traditional applications.
28
+ */
29
+ public static function setFactory (LoopDriverFactory $ factory = null )
30
+ {
31
+ self ::$ factory = $ factory ;
32
+
33
+ if (!self ::$ running ) {
34
+ self ::$ driver = self ::createDriver ();
35
+ self ::$ registry = [];
36
+ }
37
+ }
38
+
14
39
/**
15
40
* Execute a callback within the scope of an event loop driver.
16
41
*
@@ -19,13 +44,16 @@ final class Loop
19
44
*
20
45
* @return void
21
46
*/
22
- public static function execute (callable $ callback , LoopDriver $ driver )
47
+ public static function execute (callable $ callback , LoopDriver $ driver = null )
23
48
{
24
- $ previousDriver = self ::$ driver ;
25
49
$ previousRegistry = self ::$ registry ;
50
+ $ previousDriver = self ::$ driver ;
51
+
52
+ $ driver = $ driver ?: self ::createDriver ();
26
53
27
54
self ::$ driver = $ driver ;
28
55
self ::$ registry = [];
56
+ self ::$ running = true ;
29
57
30
58
try {
31
59
$ callback ();
@@ -34,9 +62,31 @@ public static function execute(callable $callback, LoopDriver $driver)
34
62
} finally {
35
63
self ::$ driver = $ previousDriver ;
36
64
self ::$ registry = $ previousRegistry ;
65
+ self ::$ running = false ;
37
66
}
38
67
}
39
68
69
+ /**
70
+ * Create a new driver if a factory is present, otherwise throw.
71
+ *
72
+ * @throws \LogicException if no factory is set or no driver returned from factory
73
+ */
74
+ private static function createDriver ()
75
+ {
76
+ if (self ::$ factory === null ) {
77
+ throw new \LogicException ("No loop driver factory set; Either pass a driver to Loop::execute or set a factory. " );
78
+ }
79
+
80
+ $ driver = self ::$ factory ->create ();
81
+
82
+ if (!$ driver instanceof LoopDriver) {
83
+ $ type = is_object ($ driver ) ? "an instance of " . get_class ($ driver ) : gettype ($ driver );
84
+ throw new \LogicException ("Loop driver factory returned {$ type }, but must return an instance of LoopDriver. " );
85
+ }
86
+
87
+ return $ driver ;
88
+ }
89
+
40
90
/**
41
91
* Retrieve the event loop driver that is in scope.
42
92
*
@@ -45,7 +95,7 @@ public static function execute(callable $callback, LoopDriver $driver)
45
95
public static function get ()
46
96
{
47
97
if (null === self ::$ driver ) {
48
- throw new \RuntimeException ('Not within the scope of an event loop driver ' );
98
+ throw new \RuntimeException ('Missing driver; Neither in Loop::execute nor factory set. ' );
49
99
}
50
100
51
101
return self ::$ driver ;
@@ -232,12 +282,16 @@ public static function setErrorHandler(callable $callback = null)
232
282
*
233
283
* @return bool
234
284
*/
235
- public static function supports ($ feature ) {
285
+ public static function supports ($ feature )
286
+ {
236
287
return self ::get ()->supports ($ feature );
237
288
}
238
289
239
290
/**
240
291
* Disable construction as this is a static class.
241
292
*/
242
- private function __construct () {}
293
+ private function __construct ()
294
+ {
295
+ // intentionally left blank
296
+ }
243
297
}
0 commit comments