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