From 8ab55eae3811dcf2842dad5e4430fe2a9aeb2012 Mon Sep 17 00:00:00 2001 From: Simon Frings Date: Tue, 3 Aug 2021 12:37:16 +0200 Subject: [PATCH] Simplify usage by supporting new default loop --- README.md | 39 ++++++++------------------------ composer.json | 4 ++-- examples/01-dialog.php | 7 +----- examples/02-file.php | 7 +----- examples/03-progress-pulsate.php | 10 +++----- examples/04-progress-random.php | 10 +++----- examples/05-form.php | 6 +---- examples/06-menu.php | 7 +----- examples/10-notification.php | 10 +++----- examples/20-blocking.php | 5 +--- src/Launcher.php | 11 +++++++-- tests/LauncherTest.php | 19 ++++++++++++++++ tests/Zen/BaseZenTest.php | 2 -- 13 files changed, 54 insertions(+), 83 deletions(-) create mode 100644 tests/LauncherTest.php diff --git a/README.md b/README.md index 698ca76..c640942 100644 --- a/README.md +++ b/README.md @@ -62,8 +62,7 @@ Once [installed](#install), you can use the following code to open a prompt asking the user for his name and presenting it in another info dialog. ```php -$loop = Factory::create(); -$launcher = new Launcher($loop); +$launcher = new Clue\React\Zenity\Launcher(); $entry = new EntryDialog(); $entry->setText('What\'s your name?'); @@ -72,8 +71,6 @@ $entry->setEntryText(getenv('USER')); // prefill with current user $launcher->launch($entry)->then(function ($name) use ($launcher) { $launcher->launch(new InfoDialog('Welcome to zenity-react, ' . $name .'!')); }); - -$loop->run(); ``` Looking for more examples? Take a look at the [examples](examples) folder. @@ -91,9 +88,14 @@ to enable an async workflow where you can launch multiple dialogs while simultan doing more I/O work. This library exposes both a simple blocking API and a more advanced async API. +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. + ```php -$loop = React\EventLoop\Factory::create(); -$launcher = new Launcher($loop); +$launcher = new Clue\React\Zenity\Launcher(); ``` #### setBin() @@ -145,7 +147,7 @@ Some dialog types also support modifying the information presented to the user. ```php $zen = $launcher->launchZen($dialog); -$loop->addTimer(3.0, function () use ($zen) { +Loop::addTimer(3.0, function () use ($zen) { $zen->close(); }); @@ -154,27 +156,6 @@ $zen->promise()->then(function ($result) { }); ``` -#### Mixing synchronous and asynchronous PHP #### -ReactPHP expects all PHP to be non-blocking. Therefore it's not easily possible to use launch or launchZen followed by regular blocking events in PHP. Currently there is a simple but dirty workaround. It's possible to manually tick the loop to have changes on zen-objects take effect. - -```php -$progress = new ProgressDialog('Step 1'); -$progress->setPulsate(TRUE); -$progress->setAutoClose(TRUE); -$progress_zen = $launcher->launchZen($progress); - -// This regular command is blocking and breaks the asynchronous workflow -$hostname = gethostname(); - -$progress_zen->setText('Step 2'); -$loop->tick(); - -// SQL is also regular blocking PHP -$get_sync = $db_serv->prepare('SELECT last_sync FROM tbl_sync WHERE hostname=?'); -$get_sync->execute(array($hostname)); -$result_sync = $get_sync->fetch(); -``` - ### Builder Additionally, the `Builder` implements an even simpler interface for commonly @@ -345,7 +326,7 @@ Zenity it not officially supported on other platforms, however several non-offic This library assumes Zenity is installed in your PATH. If it is not, you can explicitly set its path like this: ```php -$launcher = new Launcher($loop); +$launcher = new Clue\React\Zenity\Launcher(); $launcher->setBin('/path/to/zenity'); ``` diff --git a/composer.json b/composer.json index 2655f00..bb99145 100644 --- a/composer.json +++ b/composer.json @@ -12,8 +12,8 @@ ], "require": { "php": ">=5.3", - "react/child-process": "^0.6 || ^0.5 || ^0.4 || ^0.3", - "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3", + "react/child-process": "^0.6.3", + "react/event-loop": "^1.2", "react/promise": "~2.0|~1.0" }, "require-dev": { diff --git a/examples/01-dialog.php b/examples/01-dialog.php index 8e11b56..8d1bd69 100644 --- a/examples/01-dialog.php +++ b/examples/01-dialog.php @@ -1,6 +1,5 @@ setEntryText(getenv('USER')); @@ -29,5 +26,3 @@ }, function () use ($launcher) { $launcher->launch(new WarningDialog('No name given')); }); - -$loop->run(); diff --git a/examples/02-file.php b/examples/02-file.php index a7db782..23d2f4d 100644 --- a/examples/02-file.php +++ b/examples/02-file.php @@ -1,6 +1,5 @@ launch($builder->fileSelection())->then(function (SplFileInfo $file) use ($launcher) { @@ -26,5 +23,3 @@ $launcher->launch($selection); }); }); - -$loop->run(); diff --git a/examples/03-progress-pulsate.php b/examples/03-progress-pulsate.php index 6522540..9096f22 100644 --- a/examples/03-progress-pulsate.php +++ b/examples/03-progress-pulsate.php @@ -1,14 +1,12 @@ launchZen($builder->pulsate('Pseudo-processing...')); @@ -24,7 +22,7 @@ 'Finishing' ); -$timer = $loop->addPeriodicTimer(2.0, function ($timer) use ($progress, $texts) { +$timer = Loop::addPeriodicTimer(2.0, function ($timer) use ($progress, $texts) { static $i = 0; if (isset($texts[$i])) { @@ -48,5 +46,3 @@ $launcher->launch($builder->error('Canceled')); }); - -$loop->run(); diff --git a/examples/04-progress-random.php b/examples/04-progress-random.php index 9320f4f..c48fa2b 100644 --- a/examples/04-progress-random.php +++ b/examples/04-progress-random.php @@ -1,21 +1,19 @@ launchZen($builder->progress('Pseudo-processing...')); $progress->setPercentage(50); -$timer = $loop->addPeriodicTimer(0.2, function () use ($progress) { +$timer = Loop::addPeriodicTimer(0.2, function () use ($progress) { $progress->advance(mt_rand(-1, 3)); }); @@ -29,5 +27,3 @@ function() use ($timer) { $timer->cancel(); } ); - -$loop->run(); diff --git a/examples/05-form.php b/examples/05-form.php index a284a3e..058cea5 100644 --- a/examples/05-form.php +++ b/examples/05-form.php @@ -1,13 +1,11 @@ setWindowIcon('info'); @@ -25,5 +23,3 @@ }, function() { var_dump('form canceled'); }); - -$loop->run(); diff --git a/examples/06-menu.php b/examples/06-menu.php index cacd310..430692a 100644 --- a/examples/06-menu.php +++ b/examples/06-menu.php @@ -1,15 +1,12 @@ run(); diff --git a/examples/10-notification.php b/examples/10-notification.php index cfd0080..1ea288c 100644 --- a/examples/10-notification.php +++ b/examples/10-notification.php @@ -1,14 +1,12 @@ notifier(); @@ -17,11 +15,9 @@ $zen->setMessage('Hello world'); $n = 0; -$loop->addPeriodicTimer(10.0, function ($timer) use ($zen, &$n) { +Loop::addPeriodicTimer(10.0, function ($timer) use ($zen, &$n) { static $icons = array('error', 'warning', 'info', ''); $zen->setIcon($icons[array_rand($icons)]); $zen->setMessage('Hi' . ++$n); }); - -$loop->run(); diff --git a/examples/20-blocking.php b/examples/20-blocking.php index f43dd10..d4a3b83 100644 --- a/examples/20-blocking.php +++ b/examples/20-blocking.php @@ -1,15 +1,12 @@ waitFor(new EntryDialog('Search package')); diff --git a/src/Launcher.php b/src/Launcher.php index 5faf46e..563e7d6 100644 --- a/src/Launcher.php +++ b/src/Launcher.php @@ -2,6 +2,7 @@ namespace Clue\React\Zenity; +use React\EventLoop\Loop; use React\EventLoop\LoopInterface; use Clue\React\Zenity\Dialog\AbstractDialog; use React\Promise\Deferred; @@ -14,11 +15,17 @@ */ class Launcher { + /** @var LoopInterface */ private $loop; + private $processLauncher; private $bin = 'zenity'; - public function __construct(LoopInterface $loop, $processLauncher = null) + /** + * @param ?LoopInterface $loop + * @param ?Callable $processLauncher + */ + public function __construct(LoopInterface $loop = null, $processLauncher = null) { if ($processLauncher === null) { $processLauncher = function ($cmd) { @@ -26,8 +33,8 @@ public function __construct(LoopInterface $loop, $processLauncher = null) }; } + $this->loop = $loop ?: Loop::get(); $this->processLauncher = $processLauncher; - $this->loop = $loop; } public function setBin($bin) diff --git a/tests/LauncherTest.php b/tests/LauncherTest.php new file mode 100644 index 0000000..65e48e3 --- /dev/null +++ b/tests/LauncherTest.php @@ -0,0 +1,19 @@ +setAccessible(true); + $loop = $ref->getValue($launcher); + + $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + } +} diff --git a/tests/Zen/BaseZenTest.php b/tests/Zen/BaseZenTest.php index 24ed184..eb3ce96 100644 --- a/tests/Zen/BaseZenTest.php +++ b/tests/Zen/BaseZenTest.php @@ -1,8 +1,6 @@