using System; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; using Blacklight.Core; using Blacklight.Core.Cameras; using Blacklight.WebGL2; // [JSImport]/[JSExport] require the assembly to be marked browser-targeted, or they won't compile. [assembly: SupportedOSPlatform("browser")] namespace Glass.Testbed { internal static class Program { // A backgrounded tab stops getting frames and delivers the whole gap on the first one after, so the same // cap the desktop needs for a window drag applies here. private static readonly TimeSpan LongestTick = TimeSpan.FromMilliseconds(100); private static World world = null!; private static double? lastTimestampInMilliseconds = null; private static void OnFrame(double timestampInMilliseconds) { TimeSpan elapsed = TimeSpan.FromMilliseconds( timestampInMilliseconds - (lastTimestampInMilliseconds ?? timestampInMilliseconds)); lastTimestampInMilliseconds = timestampInMilliseconds; world.Tick(elapsed < LongestTick ? elapsed : LongestTick); } private static async Task Main() { await GL.EnsureLoadedAsync(); WindowHandle window = WebGL2Backend.CreateWindowHandle(); var inputRouter = new InputRouter(); inputRouter.AddLowestPriority(new MicroscopeController { Handle = window }); world = new World( window, inputRouter, new MicroscopeCamera(window), cursorSurface: new WebGL2CursorSurface(), pointerSource: new WebGL2Input(WebGL2Backend.DefaultCanvasElementId, inputRouter), // requestAnimationFrame is paced off the display and the driver decides when, which is what // Driver means; the browser offers nothing to turn it off with. verticalSync: VerticalSyncMode.Driver); GL.StartRenderLoop(OnFrame); // Don't let Main return. The browser drives frames, but the runtime must stay resident. await Task.Delay(Timeout.Infinite); } } }