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;
 | 
						|
  }
 | 
						|
}
 |