sdl3/examples/threaded_two_windows.php
2025-10-25 22:04:24 +02:00

171 lines
4.8 KiB
PHP

<?php
/**
* Simple example with 2 windows running in parallel threads
* Requires: parallel extension
*/
require_once __DIR__ . '/../vendor/autoload.php';
use parallel\Runtime;
use parallel\Channel;
// Check if parallel extension is loaded
if (!extension_loaded('parallel')) {
die("Error: parallel extension is not loaded. Install with: pecl install parallel\n");
}
echo "Starting 2 windows in parallel threads...\n";
echo "Each window runs independently in its own thread\n";
echo "Press ESC or close button to exit each window\n\n";
/**
* Window function that runs in a thread
*/
$windowFunction = function(string $title, int $x, int $y, int $width, int $height, array $bgColor) {
// Enable event queue mode
rgfw_setQueueEvents(true);
// Create window
$window = rgfw_createWindow($title, $x, $y, $width, $height, 0);
if (!$window) {
throw new \Exception("Failed to create window: $title");
}
// Initialize RSGL renderer
if (!rsgl_init($window)) {
throw new \Exception("Failed to initialize RSGL for: $title");
}
[$r, $g, $b] = $bgColor;
$running = true;
$frameCount = 0;
$mouseX = 0;
$mouseY = 0;
$isHovering = false;
while ($running) {
// Poll events for this window
rgfw_pollEvents();
// Process queued events
while ($event = rgfw_window_checkQueuedEvent($window)) {
switch ($event['type']) {
case RGFW_quit:
$running = false;
break;
case RGFW_keyPressed:
$keyCode = $event['keyCode'] ?? 0;
if ($keyCode == RGFW_Escape) {
$running = false;
}
break;
case RGFW_mousePosChanged:
$mouseX = $event[0] ?? 0;
$mouseY = $event[1] ?? 0;
// Check if hovering over center rectangle
$rectSize = 100;
$rectX = ($width / 2) - ($rectSize / 2);
$rectY = ($height / 2) - ($rectSize / 2);
$isHovering = $mouseX >= $rectX && $mouseX <= ($rectX + $rectSize) &&
$mouseY >= $rectY && $mouseY <= ($rectY + $rectSize);
break;
case RGFW_mouseButtonPressed:
if ($isHovering) {
echo "$title - Rectangle clicked!\n";
}
break;
}
}
// Check if window should close
if (rgfw_window_shouldClose($window)) {
$running = false;
}
// Clear with background color
rsgl_clear($window, $r, $g, $b, 255);
// Draw center rectangle
$rectSize = 100;
$rectX = ($width / 2) - ($rectSize / 2);
$rectY = ($height / 2) - ($rectSize / 2);
// White or yellow depending on hover state
if ($isHovering) {
rsgl_setColor($window, 255, 255, 100, 255); // Yellow on hover
} else {
rsgl_setColor($window, 255, 255, 255, 255); // White
}
rsgl_drawRectF($window, (int) $rectX, (int) $rectY, $rectSize, $rectSize);
// Draw text showing frame count (if possible)
$frameCount++;
// Render and swap buffers
rsgl_render($window);
rgfw_window_swapBuffers($window);
// ~60 FPS
usleep(16666);
}
// Cleanup
rsgl_close($window);
rgfw_window_close($window);
return "$title closed after $frameCount frames";
};
try {
// Create first window in a thread (Red background)
echo "Launching Window 1 (Red) in thread...\n";
$runtime1 = new Runtime();
$future1 = $runtime1->run($windowFunction, [
'Window 1 - Red',
100,
100,
400,
300,
[255, 100, 100]
]);
// Create second window in a thread (Blue background)
echo "Launching Window 2 (Blue) in thread...\n";
$runtime2 = new Runtime();
$future2 = $runtime2->run($windowFunction, [
'Window 2 - Blue',
550,
100,
400,
300,
[100, 100, 255]
]);
echo "\nBoth windows launched!\n";
echo "Hover over the center rectangles to see them change color\n";
echo "Click on them to see messages in the console\n";
echo "Main thread waiting for windows to close...\n\n";
// Wait for first window
echo "Waiting for Window 1...\n";
$result1 = $future1->value();
echo $result1 . "\n";
// Wait for second window
echo "Waiting for Window 2...\n";
$result2 = $future2->value();
echo $result2 . "\n";
echo "\nAll windows closed. Application exiting.\n";
} catch (\Throwable $e) {
echo "Error: " . $e->getMessage() . "\n";
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
}