89 lines
2.2 KiB
PHP
89 lines
2.2 KiB
PHP
|
<?php
|
||
|
namespace nur\mapper\base;
|
||
|
|
||
|
use Generator;
|
||
|
use IteratorAggregate;
|
||
|
use nur\b\ICloseable;
|
||
|
use nur\b\params\IParametrable;
|
||
|
use nur\b\params\Parametrable;
|
||
|
use nur\mapper\base\oobd\IOobdManager;
|
||
|
use nur\mapper\base\oobd\TOobdManager;
|
||
|
|
||
|
/**
|
||
|
* Class Producer: un générateur qu'il est possible de piloter
|
||
|
* - notamment, il est possible de le fermer avant d'arriver à la fin de la
|
||
|
* génération avec la méthode {@link close()}
|
||
|
*
|
||
|
* La méthode {@link close()} doit être appelée à la fin de la génération, ce
|
||
|
* qui est automatique si on utilise des outils qui supportent {@link ICloseable}.
|
||
|
* le cas échéant, il faut le faire manuellement:
|
||
|
* ~~~
|
||
|
* $producer = new MyProducer();
|
||
|
* try {
|
||
|
* foreach ($producer as $value) {
|
||
|
* ...
|
||
|
* }
|
||
|
* } finally {
|
||
|
* $producer->close();
|
||
|
* }
|
||
|
* ~~~
|
||
|
*/
|
||
|
abstract class Producer extends Parametrable implements IteratorAggregate, ICloseable, IParametrable, IOobdManager {
|
||
|
use TOobdManager;
|
||
|
|
||
|
/**
|
||
|
* initialiser le générateur. cette méthode est appelée avant de lancer
|
||
|
* la génération
|
||
|
*/
|
||
|
protected function setup(): void {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* terminer le générateur. cette méthode est appelée à la fin de la génération
|
||
|
*/
|
||
|
protected function teardown(): void {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* retourner un générateur qui produit les données. ce générateur doit être
|
||
|
* préparé à prendre une exception {@link StopException} à chaque occurrence
|
||
|
* de yield
|
||
|
*/
|
||
|
abstract function producer();
|
||
|
|
||
|
/** @var Generator */
|
||
|
private $generator;
|
||
|
|
||
|
function getIterator() {
|
||
|
$this->setup();
|
||
|
$this->return = null;
|
||
|
return $this->generator = $this->producer();
|
||
|
}
|
||
|
|
||
|
function close(): void {
|
||
|
if ($this->generator !== null) {
|
||
|
if ($this->generator instanceof Generator) {
|
||
|
try {
|
||
|
$this->generator->throw(new StopException());
|
||
|
$hasReturned = true;
|
||
|
} catch (StopException $e) {
|
||
|
$hasReturned = false;
|
||
|
}
|
||
|
$this->return = $hasReturned? $this->generator->getReturn(): null;
|
||
|
}
|
||
|
$this->generator = null;
|
||
|
}
|
||
|
$this->teardown();
|
||
|
}
|
||
|
|
||
|
protected $return;
|
||
|
|
||
|
/**
|
||
|
* retourner la valeur de retour du générateur. il faut d'abord appeler la
|
||
|
* méthode {@link close()}
|
||
|
*/
|
||
|
function getReturn() {
|
||
|
return $this->return;
|
||
|
}
|
||
|
}
|