161 lines
4.1 KiB
PHP
161 lines
4.1 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Multi-Process Window Example
|
|
*
|
|
* Each window runs in a separate process (not thread!)
|
|
* This works because each process has its own main thread for OpenGL
|
|
*/
|
|
|
|
require_once __DIR__ . '/../vendor/autoload.php';
|
|
|
|
use PHPNative\Framework\Application;
|
|
use PHPNative\Ui\Widget\Button;
|
|
use PHPNative\Ui\Widget\Container;
|
|
use PHPNative\Ui\Widget\Label;
|
|
|
|
// Check if we're the main process or a child
|
|
$windowId = $argv[1] ?? null;
|
|
|
|
if ($windowId === null) {
|
|
// MAIN PROCESS - Launch child processes
|
|
echo "Main Process: Launching 2 window processes...\n\n";
|
|
|
|
$pids = [];
|
|
|
|
// Launch Window 1 process
|
|
$pid1 = pcntl_fork();
|
|
if ($pid1 == -1) {
|
|
die("Could not fork for Window 1\n");
|
|
} elseif ($pid1 == 0) {
|
|
// Child process 1
|
|
runWindow('1', 'Window 1 - Blue', 100, 100, 'blue');
|
|
exit(0);
|
|
} else {
|
|
$pids[] = $pid1;
|
|
echo "Main Process: Window 1 started with PID $pid1\n";
|
|
}
|
|
|
|
// Small delay to avoid race conditions
|
|
usleep(100000);
|
|
|
|
// Launch Window 2 process
|
|
$pid2 = pcntl_fork();
|
|
if ($pid2 == -1) {
|
|
die("Could not fork for Window 2\n");
|
|
} elseif ($pid2 == 0) {
|
|
// Child process 2
|
|
runWindow('2', 'Window 2 - Green', 550, 100, 'green');
|
|
exit(0);
|
|
} else {
|
|
$pids[] = $pid2;
|
|
echo "Main Process: Window 2 started with PID $pid2\n";
|
|
}
|
|
|
|
echo "\nMain Process: Both windows launched!\n";
|
|
echo "Main Process: Waiting for child processes to exit...\n\n";
|
|
|
|
// Wait for all child processes
|
|
foreach ($pids as $pid) {
|
|
$status = 0;
|
|
pcntl_waitpid($pid, $status);
|
|
echo "Main Process: Child process $pid exited\n";
|
|
}
|
|
|
|
echo "\nMain Process: All windows closed. Exiting.\n";
|
|
} else {
|
|
// This shouldn't happen in fork mode
|
|
die("Error: Unexpected command line argument\n");
|
|
}
|
|
|
|
/**
|
|
* Run a single window in this process
|
|
*/
|
|
function runWindow(string $id, string $title, int $x, int $y, string $bgColor): void
|
|
{
|
|
echo "Process $id: Creating window '$title'\n";
|
|
|
|
// Create application
|
|
$app = new Application();
|
|
|
|
// Create window
|
|
$window = $app->createWindow($title, 400, 350, $x, $y);
|
|
|
|
// Create UI
|
|
$container = new Container("flex flex-col p-6 gap-4 bg-$bgColor-100");
|
|
|
|
$titleLabel = new Label(
|
|
text: $title,
|
|
style: "text-2xl text-$bgColor-900"
|
|
);
|
|
|
|
$processLabel = new Label(
|
|
text: 'Process ID: ' . getmypid(),
|
|
style: "text-sm text-$bgColor-700"
|
|
);
|
|
|
|
$frameLabel = new Label(
|
|
text: 'Frame: 0',
|
|
style: "text-base text-$bgColor-600"
|
|
);
|
|
|
|
$button = new Button(
|
|
text: 'Click Me!',
|
|
style: "bg-$bgColor-500 hover:bg-$bgColor-700 text-white p-4 rounded-lg"
|
|
);
|
|
|
|
$clickCount = 0;
|
|
$button->setOnClick(function() use (&$clickCount, $button, $title) {
|
|
$clickCount++;
|
|
$button->setText("Clicked $clickCount times");
|
|
echo "$title - Button clicked! Count: $clickCount\n";
|
|
});
|
|
|
|
$closeButton = new Button(
|
|
text: 'Close Window',
|
|
style: "bg-red-500 hover:bg-red-700 text-white p-3 rounded"
|
|
);
|
|
|
|
$closeButton->setOnClick(function() use ($window) {
|
|
echo "Close button clicked!\n";
|
|
$window->close();
|
|
});
|
|
|
|
$container->addComponent($titleLabel);
|
|
$container->addComponent($processLabel);
|
|
$container->addComponent($frameLabel);
|
|
$container->addComponent($button);
|
|
$container->addComponent($closeButton);
|
|
|
|
$window->setRoot($container);
|
|
|
|
echo "Process $id: Starting event loop\n";
|
|
|
|
// Run the window
|
|
$frameCount = 0;
|
|
while (!$window->shouldClose()) {
|
|
$frameCount++;
|
|
$frameLabel->setText("Frame: $frameCount");
|
|
|
|
$window->layout();
|
|
|
|
// Poll events
|
|
rgfw_pollEvents();
|
|
$window->handleEvents();
|
|
|
|
// Update
|
|
\PHPNative\Async\TaskManager::getInstance()->update();
|
|
$window->update();
|
|
|
|
// Render
|
|
$window->render();
|
|
|
|
// ~60 FPS
|
|
usleep(16666);
|
|
}
|
|
|
|
// Cleanup
|
|
echo "Process $id: Window closed after $frameCount frames\n";
|
|
$window->cleanup();
|
|
}
|