Inheritance: implements AsyncPHP\Doorman\Manager
 /**
  * @test
  */
 public function basicRulesAndTasksWork()
 {
     $task1 = new ProcessCallbackTask(function () {
         touch(__DIR__ . "/task1.temp");
         for ($i = 0; $i < 10; $i++) {
             usleep(50000);
         }
         unlink(__DIR__ . "/task1.temp");
     });
     $task2 = new ProcessCallbackTask(function () {
         touch(__DIR__ . "/task2.temp");
         for ($i = 0; $i < 10; $i++) {
             usleep(50000);
         }
         unlink(__DIR__ . "/task2.temp");
     });
     $rule = new InMemoryRule();
     $rule->setProcesses(1);
     $rule->setMinimumProcessorUsage(0);
     $rule->setMaximumProcessorUsage(100);
     $added = false;
     $this->manager->addRule($rule);
     $this->manager->addTask($task1);
     while ($this->manager->tick()) {
         usleep(50000);
         if (!$added) {
             $this->manager->addTask($task2);
             $added = true;
         }
         if (file_exists(__DIR__ . "/task1.temp") && file_exists(__DIR__ . "/task2.temp")) {
             $this->fail("Tasks should not be run concurrently");
         }
     }
     $this->manager->removeRule($rule);
     $this->manager->addTask($task1);
     $this->manager->addTask($task2);
     if ($this->manager->tick()) {
         usleep(50000);
         if (!file_exists(__DIR__ . "/task1.temp") || !file_exists(__DIR__ . "/task2.temp")) {
             $this->fail("Tasks should be run concurrently");
         }
     }
 }
 /**
  * @return string
  */
 public function Export()
 {
     $assetPath = ASSETS_PATH;
     $reflowPath = REFLOW_DIR;
     $deckSegment = $this->URLSegment;
     $manager = new ProcessManager();
     $manager->setLogPath(ASSETS_PATH);
     $rule = new InMemoryRule();
     $rule->setProcesses(5);
     $rule->setMinimumProcessorUsage(0);
     $rule->setMaximumProcessorUsage(100);
     $manager->addRule($rule);
     $manager->addTask(new ProcessCallbackTask(function () use($assetPath, $deckSegment) {
         exec("mkdir {$assetPath}/{$deckSegment}/export");
     }));
     /** @var Slide $slide */
     foreach ($this->Slides() as $slide) {
         $slideLink = $slide->AbsoluteLink("Capture");
         $slideSegment = $slide->URLSegment;
         $link = rtrim($this->AbsoluteLink(), "/") . "#" . $slide->URLSegment;
         $manager->addTask(new ProcessCallbackTask(function () use($link, $assetPath, $reflowPath, $slideLink, $slideSegment, $deckSegment) {
             $client = Client::getInstance();
             $client->setBinDir($reflowPath . "/../vendor/bin");
             /**
              * @see JonnyW\PhantomJs\Message\CaptureRequest
              **/
             $request = $client->getMessageFactory()->createCaptureRequest($link, "GET");
             $request->setViewportSize(1440, 900);
             // TODO
             $request->setDelay(3);
             // TODO
             $request->setCaptureFile("{$assetPath}/{$deckSegment}/{$slideSegment}.png");
             /**
              * @see JonnyW\PhantomJs\Message\Response
              **/
             $response = $client->getMessageFactory()->createResponse();
             // Send the request
             $client->send($request, $response);
         }));
         print "Exporting: " . $slide->Title . "<br>";
     }
     $slides = [];
     /** @var Slide $slide */
     foreach ($this->Slides() as $slide) {
         $slideSegment = $slide->URLSegment;
         $slides[] = "{$assetPath}/{$deckSegment}/export/{$slideSegment}.png";
     }
     while ($manager->tick()) {
         usleep(10);
     }
     $manager->addTask(new ProcessCallbackTask(function () use($assetPath, $deckSegment, $slides) {
         $pdf = new FPDF();
         /** @var Slide $slide */
         foreach ($slides as $slide) {
             $pdf->AddPage("L", array(15 * 72, 9.380000000000001 * 72));
             $pdf->Image($slide, 0, 0, 15 * 72, 9.380000000000001 * 72);
         }
         $pdf->Output("{$assetPath}/{$deckSegment}/export.pdf", "F");
     }));
     while ($manager->tick()) {
         usleep(10);
     }
 }