Signatur
Beschreibung
UI\Executor ist eine Klasse aus der UI-Extension (php-ui / libui) und ermöglicht es, einen Callback-Aufruf in einem definierten Intervall wiederholt auszuführen, während die UI-Hauptschleife läuft. Sie wird typischerweise eingesetzt, um Animationen zu steuern, Fortschrittsbalken zu aktualisieren oder andere zeitabhängige Aktionen in grafischen PHP-Anwendungen periodisch anzustoßen.
Ein UI\Executor-Objekt wird instanziiert und mit einem Millisekunden-Intervall versehen. Innerhalb der onTick()-Methode – die in einer Unterklasse überschrieben werden muss – wird die gewünschte Logik implementiert. Gibt onTick() false zurück, wird der Executor gestoppt; andernfalls läuft er weiter.
Der Executor ist eng an die laufende UI-Hauptschleife (UI\run()) gekoppelt. Er wird erst aktiv, wenn die Hauptschleife gestartet ist, und hört automatisch auf, wenn die Hauptschleife beendet wird. Das Intervall wird beim Konstruktoraufruf gesetzt und kann danach nicht mehr geändert werden.
- Geeignet für einfache zeitgesteuerte Animationen in
UI\Draw\Area. - Nicht für hochpräzises Timing geeignet – die tatsächliche Genauigkeit hängt von der Systemlast und dem Ereignis-Loop ab.
- Nur innerhalb der UI-Extension (PECL ui) verfügbar.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $interval Pflicht | int | Das Ausführungsintervall in Millisekunden. Gibt an, wie oft onTick() aufgerufen wird. |
Rückgabewert
Beispiele
Einfacher Executor für eine periodische Konsolenausgabe (Demo-Struktur)
<?php
use UI\Executor;
use UI\Window;
// Unterklasse von UI\Executor mit überschriebener onTick()-Methode
class MyExecutor extends Executor {
private int $count = 0;
public function onTick(): bool {
$this->count++;
echo "Tick #{$this->count}\n";
// Nach 5 Ticks stoppen
if ($this->count >= 5) {
return false;
}
return true;
}
}
$window = new Window('Executor Demo', 400, 300, true);
$window->show();
// Executor mit 500 ms Intervall starten
$executor = new MyExecutor(500);
// UI-Hauptschleife starten (blockierend)
UI\run();
Animation mit UI\Draw\Area über Executor
<?php
use UI\Executor;
use UI\Window;
use UI\Box;
use UI\Draw\Area;
use UI\Draw\Pen;
use UI\Draw\Brush;
use UI\Draw\Path;
use UI\Draw\Color;
use UI\Size;
use UI\Point;
class AnimationArea extends Area {
public float $angle = 0.0;
protected function onDraw(Pen $pen, Size $areaSize, Point $clipPoint, Size $clipSize): void {
// Hintergrund
$bg = new Brush(Brush::Solid, new Color(0.1, 0.1, 0.1));
$path = new Path(Path::Winding);
$path->addRectangle(new Point(0, 0), $areaSize);
$path->end();
$pen->fill($path, $bg);
// Rotierender Punkt
$cx = $areaSize->width / 2;
$cy = $areaSize->height / 2;
$r = 80;
$x = $cx + $r * cos($this->angle);
$y = $cy + $r * sin($this->angle);
$dot = new Brush(Brush::Solid, new Color(1.0, 0.3, 0.1));
$circle = new Path(Path::Winding);
$circle->newFigureWithArc(new Point($x, $y), 10, 0, 6.2832);
$circle->end();
$pen->fill($circle, $dot);
}
}
class AnimationExecutor extends Executor {
public function __construct(
private AnimationArea $area,
int $interval
) {
parent::__construct($interval);
}
protected function onTick(): bool {
$this->area->angle += 0.05;
$this->area->queue(); // Neuzeichnen anfordern
return true; // Endlos weiterlaufen
}
}
$window = new Window('Animation Demo', 400, 400, false);
$box = new Box(Box::Vertical);
$area = new AnimationArea();
$box->append($area, true);
$window->add($box);
$window->show();
$executor = new AnimationExecutor($area, 16); // ~60 FPS
UI\run();
// Wichtig · Fallstricke
Nur in der PECL-Extension ui verfügbar. Die Extension befindet sich seit Jahren im experimentellen Zustand und ist nicht Teil von PHP-Core. Vor dem Einsatz in Produktivprojekten sollte die Stabilität der jeweiligen Version geprüft werden.
Timing-Genauigkeit: Das angegebene Intervall ist ein Mindestwert. Durch Systemlast oder Ereignisverarbeitung kann der tatsächliche Abstand zwischen zwei onTick()-Aufrufen größer sein. Für präzises Timing (z. B. Musik, Messungen) ist diese Klasse ungeeignet.
Stopp-Mechanismus: Um den Executor gezielt zu beenden, muss onTick() false zurückgeben. Ein externes Stoppen über ein Flag in der Unterklasse ist die empfohlene Praxis.