diff --git a/README.md b/README.md index 0fb1400..d0719c6 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,7 @@ Let's take these projects to the next level together! 🚀 Once [installed](#install), you can use the following code to present a prompt in a CLI program: ```php -$loop = React\EventLoop\Factory::create(); -$stdio = new Stdio($loop); +$stdio = new Stdio(); $stdio->setPrompt('Input > '); @@ -64,8 +63,6 @@ $stdio->on('data', function ($line) use ($stdio) { $stdio->end(); } }); - -$loop->run(); ``` See also the [examples](examples). @@ -77,13 +74,17 @@ See also the [examples](examples). The `Stdio` is the main interface to this library. It is responsible for orchestrating the input and output streams by registering and forwarding the corresponding events. -It also registers everything with the main [EventLoop](https://github.com/reactphp/event-loop#usage). ```php -$loop = React\EventLoop\Factory::create(); -$stdio = new Stdio($loop); +$stdio = new Stdio(); ``` +This class takes an optional `LoopInterface|null $loop` parameter that can be used to +pass the event loop instance to use for this object. You can use a `null` value +here in order to use the [default loop](https://github.com/reactphp/event-loop#loop). +This value SHOULD NOT be given unless you're sure you want to explicitly use a +given event loop instance. + See below for waiting for user input and writing output. The `Stdio` class is a well-behaving duplex stream (implementing ReactPHP's `DuplexStreamInterface`) that emits each complete diff --git a/composer.json b/composer.json index 09eb64b..0e86dcb 100644 --- a/composer.json +++ b/composer.json @@ -14,24 +14,24 @@ "php": ">=5.3", "clue/term-react": "^1.0 || ^0.1.1", "clue/utf8-react": "^1.0 || ^0.1", - "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3", - "react/stream": "^1.0 || ^0.7 || ^0.6" + "react/event-loop": "^1.2", + "react/stream": "^1.2" + }, + "require-dev": { + "clue/arguments": "^2.0", + "clue/commander": "^1.2", + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" }, "suggest": { "ext-mbstring": "Using ext-mbstring should provide slightly better performance for handling I/O" }, + "config": { + "sort-packages": true + }, "autoload": { "psr-4": { "Clue\\React\\Stdio\\": "src/" } }, "autoload-dev": { "psr-4": { "Clue\\Tests\\React\\Stdio\\": "tests/" } - }, - "require-dev": { - "clue/arguments": "^2.0", - "clue/commander": "^1.2", - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" - }, - "config": { - "sort-packages": true } } diff --git a/examples/01-periodic.php b/examples/01-periodic.php index 9b74ad3..cbf8a58 100644 --- a/examples/01-periodic.php +++ b/examples/01-periodic.php @@ -1,38 +1,35 @@ write('Will print periodic messages until you submit anything' . PHP_EOL); // add some periodic noise -$timer = $loop->addPeriodicTimer(0.5, function () use ($stdio) { +$timer = Loop::addPeriodicTimer(0.5, function () use ($stdio) { $stdio->write(date('Y-m-d H:i:s') . ' hello' . PHP_EOL); }); // react to commands the user entered -$stdio->on('data', function ($line) use ($stdio, $loop, $timer) { +$stdio->on('data', function ($line) use ($stdio, $timer) { $stdio->write('you just said: ' . addcslashes($line, "\0..\37") . ' (' . strlen($line) . ')' . PHP_EOL); - $loop->cancelTimer($timer); + Loop::cancelTimer($timer); $stdio->end(); }); // cancel periodic timer if STDIN closed -$stdio->on('end', function () use ($stdio, $loop, $timer) { - $loop->cancelTimer($timer); +$stdio->on('end', function () use ($stdio, $timer) { + Loop::cancelTimer($timer); $stdio->end(); }); // input already closed on program start, exit immediately if (!$stdio->isReadable()) { - $loop->cancelTimer($timer); + Loop::cancelTimer($timer); $stdio->end(); } - -$loop->run(); diff --git a/examples/02-interactive.php b/examples/02-interactive.php index b0ca923..2e55093 100644 --- a/examples/02-interactive.php +++ b/examples/02-interactive.php @@ -4,9 +4,7 @@ require __DIR__ . '/../vendor/autoload.php'; -$loop = React\EventLoop\Factory::create(); - -$stdio = new Stdio($loop); +$stdio = new Stdio(); $stdio->setPrompt('> '); @@ -44,5 +42,3 @@ $stdio->end(); } }); - -$loop->run(); diff --git a/examples/03-commander.php b/examples/03-commander.php index 33a9f8c..427f512 100644 --- a/examples/03-commander.php +++ b/examples/03-commander.php @@ -7,9 +7,7 @@ require __DIR__ . '/../vendor/autoload.php'; -$loop = React\EventLoop\Factory::create(); - -$stdio = new Stdio($loop); +$stdio = new Stdio(); $stdio->setPrompt('> '); // limit history to HISTSIZE env @@ -73,5 +71,3 @@ $stdio->write('Error: Invalid command usage' . PHP_EOL); } }); - -$loop->run(); diff --git a/examples/04-bindings.php b/examples/04-bindings.php index 3b1bd53..0dbd0ce 100644 --- a/examples/04-bindings.php +++ b/examples/04-bindings.php @@ -4,9 +4,7 @@ require __DIR__ . '/../vendor/autoload.php'; -$loop = React\EventLoop\Factory::create(); - -$stdio = new Stdio($loop); +$stdio = new Stdio(); $stdio->setPrompt('> '); // add some special key bindings @@ -40,5 +38,3 @@ $line = rtrim($line, "\r\n"); $stdio->end('you just said: ' . $line . ' (' . strlen($line) . ')' . PHP_EOL); }); - -$loop->run(); diff --git a/examples/05-cursor.php b/examples/05-cursor.php index 5362b8b..22fd9b8 100644 --- a/examples/05-cursor.php +++ b/examples/05-cursor.php @@ -4,9 +4,7 @@ require __DIR__ . '/../vendor/autoload.php'; -$loop = React\EventLoop\Factory::create(); - -$stdio = new Stdio($loop); +$stdio = new Stdio(); $value = 10; $stdio->on("\033[A", function () use (&$value, $stdio) { @@ -40,5 +38,3 @@ Use "q" to quit '); - -$loop->run(); diff --git a/examples/11-login.php b/examples/11-login.php index 88bced8..b1a14f1 100644 --- a/examples/11-login.php +++ b/examples/11-login.php @@ -4,9 +4,7 @@ require __DIR__ . '/../vendor/autoload.php'; -$loop = React\EventLoop\Factory::create(); - -$stdio = new Stdio($loop); +$stdio = new Stdio(); $stdio->setPrompt('Username: '); $first = true; @@ -33,5 +31,3 @@ ); } }); - -$loop->run(); diff --git a/src/Stdio.php b/src/Stdio.php index 4ef8cc9..aff2959 100644 --- a/src/Stdio.php +++ b/src/Stdio.php @@ -22,7 +22,20 @@ class Stdio extends EventEmitter implements DuplexStreamInterface private $incompleteLine = ''; private $originalTtyMode = null; - public function __construct(LoopInterface $loop, ReadableStreamInterface $input = null, WritableStreamInterface $output = null, Readline $readline = null) + /** + * + * This class takes an optional `LoopInterface|null $loop` parameter that can be used to + * pass the event loop instance to use for this object. You can use a `null` value + * here in order to use the [default loop](https://github.com/reactphp/event-loop#loop). + * This value SHOULD NOT be given unless you're sure you want to explicitly use a + * given event loop instance. + * + * @param ?LoopInterface $loop + * @param ?ReadableStreamInterface $input + * @param ?WritableStreamInterface $output + * @param ?Readline $readline + */ + public function __construct(LoopInterface $loop = null, ReadableStreamInterface $input = null, WritableStreamInterface $output = null, Readline $readline = null) { if ($input === null) { $input = $this->createStdin($loop); // @codeCoverageIgnore @@ -529,11 +542,11 @@ private function restoreTtyMode() } /** - * @param LoopInterface $loop + * @param ?LoopInterface $loop * @return ReadableStreamInterface * @codeCoverageIgnore this is covered by functional tests with/without ext-readline */ - private function createStdin(LoopInterface $loop) + private function createStdin(LoopInterface $loop = null) { // STDIN not defined ("php -a") or already closed (`fclose(STDIN)`) // also support starting program with closed STDIN ("example.php 0<&-") @@ -569,11 +582,11 @@ private function createStdin(LoopInterface $loop) } /** - * @param LoopInterface $loop + * @param ?LoopInterface $loop * @return WritableStreamInterface * @codeCoverageIgnore this is covered by functional tests */ - private function createStdout(LoopInterface $loop) + private function createStdout(LoopInterface $loop = null) { // STDOUT not defined ("php -a") or already closed (`fclose(STDOUT)`) // also support starting program with closed STDOUT ("example.php >&-") diff --git a/tests/StdioTest.php b/tests/StdioTest.php index 81ab37f..88d9480 100644 --- a/tests/StdioTest.php +++ b/tests/StdioTest.php @@ -24,7 +24,7 @@ public function setUpLoop() */ public function testCtorDefaultArgs() { - $stdio = new Stdio($this->loop); + $stdio = new Stdio(); // Closing STDIN/STDOUT is not a good idea for reproducible tests // $stdio->close();