/* catcrafts.net Copyright (C) 2026 Catcrafts The source code of this website is made available for viewing purposes only. No permission is granted to copy, modify, distribute, or create derivative works. */ import Catcrafts; import Crafter.Graphics; import std; using namespace Catcrafts; using namespace Crafter; int main() { Device::Initialize(); // Window in CRAFTER_GRAPHICS_WINDOW_DOM mode is a page-level event hub // plus the rAF driver; even without subscribing to its events we need // it so StartSync() can keep the wasm module alive past main() (the // bridge stashes a raw pointer, so the storage has to outlive main). // The dimensions are a hint only — the JS bridge sizes the render // surface to the canvas (full viewport, or the mount element). static Window window(1280, 720, "Catcrafts"); // document.title is only reachable through Window::SetTitle, so give the // router a way to set a per-route title without threading a Window // through every render call. SetActiveWindow(&window); // Build the ray-tracing pipeline + scene now (runs StartInit/FinishInit). // The render canvas starts hidden; it only traces once the /demo route // mounts it into #webgpu-demo (see Catcrafts:Demo). SetupDemo(window); InitializePage(); // Back/forward. The Router V1 callback carries no payload, so the route is // re-read from window.location — which is the right thing regardless, // since the location is the single source of truth for what should be on // screen. Router::AddPopStateListener([]{ RenderCurrentRoute(); }); RenderCurrentRoute(); window.Render(); window.StartUpdate(); // StartSync rather than StayAlive: /demo drives the ray tracer from the // animation-frame loop, so the loop has to exist before that route is // visited. A build of this site without the demo could call StayAlive // instead and skip the permanent rAF tick entirely. window.StartSync(); return 0; }