Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify usage by supporting new default loop #61

Merged
merged 1 commit into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 10 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ with PHP.
* [waitFor()](#waitfor)
* [launch()](#launch)
* [launchZen()](#launchzen)
* [Mixing synchronous and asynchronous PHP](#mixing-synchronous-and-asynchronous-php)
* [Builder](#builder)
* [Dialog](#dialog)
* [AbstractDialog](#abstractdialog)
Expand Down Expand Up @@ -62,8 +61,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?');
Expand All @@ -72,8 +70,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.
Expand All @@ -91,9 +87,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()
Expand Down Expand Up @@ -145,7 +146,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();
});

Expand All @@ -154,27 +155,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();
```

clue marked this conversation as resolved.
Show resolved Hide resolved
### Builder

Additionally, the `Builder` implements an even simpler interface for commonly
Expand Down Expand Up @@ -345,7 +325,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');
```

Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
7 changes: 1 addition & 6 deletions examples/01-dialog.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php

use React\EventLoop\Factory;
use Clue\React\Zenity\Launcher;
use Clue\React\Zenity\Dialog\InfoDialog;
use Clue\React\Zenity\Dialog\QuestionDialog;
Expand All @@ -10,9 +9,7 @@

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

$launcher = new Launcher($loop);
$launcher = new Launcher();

$q = new EntryDialog('What\'s your name?');
$q->setEntryText(getenv('USER'));
Expand All @@ -29,5 +26,3 @@
}, function () use ($launcher) {
$launcher->launch(new WarningDialog('No name given'));
});

$loop->run();
7 changes: 1 addition & 6 deletions examples/02-file.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
<?php

use React\EventLoop\Factory;
use Clue\React\Zenity\Launcher;
use Clue\React\Zenity\Dialog\FileSelectionDialog;
use Clue\React\Zenity\Builder;
use Clue\React\Zenity\Dialog\InfoDialog;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

$launcher = new Launcher($loop);
$launcher = new Launcher();
$builder = new Builder();

$launcher->launch($builder->fileSelection())->then(function (SplFileInfo $file) use ($launcher) {
Expand All @@ -26,5 +23,3 @@
$launcher->launch($selection);
});
});

$loop->run();
10 changes: 3 additions & 7 deletions examples/03-progress-pulsate.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<?php

use React\EventLoop\Factory;
use Clue\React\Zenity\Launcher;
use Clue\React\Zenity\Builder;
use React\EventLoop\Loop;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

$launcher = new Launcher($loop);
$launcher = new Launcher();
$builder = new Builder();

$progress = $launcher->launchZen($builder->pulsate('Pseudo-processing...'));
Expand All @@ -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])) {
Expand All @@ -48,5 +46,3 @@

$launcher->launch($builder->error('Canceled'));
});

$loop->run();
10 changes: 3 additions & 7 deletions examples/04-progress-random.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
<?php

use React\EventLoop\Factory;
use Clue\React\Zenity\Launcher;
use Clue\React\Zenity\Builder;
use React\EventLoop\Loop;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

$launcher = new Launcher($loop);
$launcher = new Launcher();
$builder = new Builder();

$progress = $launcher->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));
});

Expand All @@ -29,5 +27,3 @@ function() use ($timer) {
$timer->cancel();
}
);

$loop->run();
6 changes: 1 addition & 5 deletions examples/05-form.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<?php

use React\EventLoop\Factory;
use Clue\React\Zenity\Launcher;
use Clue\React\Zenity\Dialog\FormsDialog;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();
$launcher = new Launcher($loop);
$launcher = new Launcher();

$form = new FormsDialog();
$form->setWindowIcon('info');
Expand All @@ -25,5 +23,3 @@
}, function() {
var_dump('form canceled');
});

$loop->run();
7 changes: 1 addition & 6 deletions examples/06-menu.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<?php

use React\EventLoop\Factory;
use Clue\React\Zenity\Launcher;
use Clue\React\Zenity\Builder;
use Clue\React\Zenity\Dialog\InfoDialog;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

$launcher = new Launcher($loop);
$launcher = new Launcher();
$builder = new Builder();

$main = function() use (&$main, $builder, $launcher) {
Expand Down Expand Up @@ -53,5 +50,3 @@
};

$main();

$loop->run();
10 changes: 3 additions & 7 deletions examples/10-notification.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<?php

use React\EventLoop\Factory;
use Clue\React\Zenity\Launcher;
use Clue\React\Zenity\Builder;
use React\EventLoop\Loop;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

$launcher = new Launcher($loop);
$launcher = new Launcher();
$builder = new Builder();

$notification = $builder->notifier();
Expand All @@ -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();
5 changes: 1 addition & 4 deletions examples/20-blocking.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<?php

use React\EventLoop\Factory;
use Clue\React\Zenity\Launcher;
use Clue\React\Zenity\Builder;
use Clue\React\Zenity\Dialog\EntryDialog;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

$launcher = new Launcher($loop);
$launcher = new Launcher();
$builder = new Builder();

$name = $launcher->waitFor(new EntryDialog('Search package'));
Expand Down
11 changes: 9 additions & 2 deletions src/Launcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -14,20 +15,26 @@
*/
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) {
return new Process($cmd);
};
}

$this->loop = $loop ?: Loop::get();
$this->processLauncher = $processLauncher;
$this->loop = $loop;
}

public function setBin($bin)
Expand Down
19 changes: 19 additions & 0 deletions tests/LauncherTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Clue\Tests\React\Zenity;

use Clue\React\Zenity\Launcher;

class LauncherTest extends TestCase
{
public function testConstructWithoutLoopAssignsLoopAutomatically()
{
$launcher = new Launcher();

$ref = new \ReflectionProperty($launcher, 'loop');
$ref->setAccessible(true);
$loop = $ref->getValue($launcher);

$this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
}
}
2 changes: 0 additions & 2 deletions tests/Zen/BaseZenTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?php

use Clue\React\Zenity\Zen\BaseZen;
use React\EventLoop\Factory;
use React\ChildProcess\Process;
use Clue\Tests\React\Zenity\TestCase;

abstract class BaseZenTest extends TestCase
Expand Down