public void WorkerThread_Basic() { WorkerThread worker = new WorkerThread(); int thisThreadID = Thread.CurrentThread.ManagedThreadId; object result; try { result = worker.Invoke(new WorkerThreadMethod(Method1), "Hello World!"); Assert.AreEqual("Hello World!", methodArg); Assert.AreEqual("Hello World!", result); Assert.AreNotEqual(thisThreadID, methodThreadID); } finally { worker.Close(); } }
public void WorkerThread_Exception() { WorkerThread worker = new WorkerThread(); try { worker.Invoke(new WorkerThreadMethod(Method2), null); Assert.Fail("Expected an AssertException"); } catch (Exception e) { Assert.AreEqual(typeof(ArgumentException).Name, e.GetType().Name); Assert.AreEqual("Hello", e.Message); } finally { worker.Close(); } }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IApp page) { #region += Launched chrome.app.window dynamic self = Native.self; dynamic self_chrome = self.chrome; object self_chrome_socket = self_chrome.socket; if (self_chrome_socket != null) { if (!(Native.window.opener == null && Native.window.parent == Native.window.self)) { Console.WriteLine("chrome.app.window.create, is that you?"); // pass thru } else { // should jsc send a copresence udp message? chrome.runtime.UpdateAvailable += delegate { new chrome.Notification(title: "UpdateAvailable"); }; chrome.app.runtime.Launched += async delegate { // 0:12094ms chrome.app.window.create {{ href = chrome-extension://aemlnmcokphbneegoefdckonejmknohh/_generated_background_page.html }} Console.WriteLine("chrome.app.window.create " + new { Native.document.location.href }); new chrome.Notification(title: "Launched2"); var xappwindow = await chrome.app.window.create( Native.document.location.pathname, options: null ); //xappwindow.setAlwaysOnTop xappwindow.show(); await xappwindow.contentWindow.async.onload; Console.WriteLine("chrome.app.window loaded!"); }; return; } } #endregion // // http://stackoverflow.com/questions/13076272/how-do-i-give-webkitgetusermedia-permission-in-a-chrome-extension-popup-window // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150712 new { }.With( async delegate { Native.body.Clear(); Native.document.documentElement.style.overflow = IStyle.OverflowEnum.auto; new IHTMLPre { "GearVR should send analog and digital signal to start parallax tracking only if near zero rotation." }.AttachToDocument(); // would it be easy to do head tracking via webcam for VR? // the app would run on android, yet // two sattelites could spawn on two laptops to track the head. // would we be able to thread hop between camera devices and android? // http://shopap.lenovo.com/hk/en/laptops/lenovo/u-series/u330p/ // The U330p's integrated 720p HD webcam // HD wont work for chrome app? var v = await Native.window.navigator.async.onvideo; v.AttachToDocument(); v.play(); new IHTMLButton { "stop" }.AttachToDocument().onclick += delegate { //v.src = null; v.src = ""; //v.pause(); //v.stop(); }; var sw = Stopwatch.StartNew(); while (v.videoWidth == 0) await Native.window.async.onframe; const int zoomx = 2; //const int zoomy = 4; //var ow = v.videoWidth / zoomx; var ow = 512; //var oh = v.videoHeight / zoomy; //var oh = 256; //var oh = 96; //var oh = 256; var oh = 128; // 40 with udp //var oh = 0xA0; //var oh = 0xb0; // 58 //var oh = 196; // 35 //var oh = 256; var aloop = new IHTMLInput { title = "loop it", type = ScriptCoreLib.Shared.HTMLInputTypeEnum.checkbox, @checked = true }.AttachToDocument(); var slider = new IHTMLInput { title = "stabilizer?", type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, //max = 255, //max = 128, max = 64, // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150712-1 valueAsNumber = 48 }.AttachToDocument(); var z = 0; var x = 0; var y = 0; var frame0in = new CanvasRenderingContext2D(ow, oh); Action frame0in_drawImage = delegate { var clip = v.videoHeight / 6; // 6000 zoom out // 8000 zoom in // haha. this wont work. //var zz = (2000 - (z - 6000).Min(2000)) / 2000f; //clip = (int)(clip * zz); frame0in.drawImage(v, 0, clip, v.videoWidth, v.videoHeight - clip * 2, 0, 0, ow, oh); }; //frame0in.canvas.AttachToDocument(); //var frame0out = new CanvasRenderingContext2D(ow, oh); ////frame0out.canvas.AttachToDocument(); //var frame1out = new CanvasRenderingContext2D(ow, oh); ////frame1out.canvas.AttachToDocument(); //var frame2out = new CanvasRenderingContext2D(ow, oh); //frame2out.canvas.AttachToDocument(); var frame3out = new CanvasRenderingContext2D(ow, oh); frame3out.canvas.AttachToDocument(); var frame0sw = Stopwatch.StartNew(); var frameID = 0; var frame0sw0 = Stopwatch.StartNew(); var fps3 = 0; // avg per sec x3 var fps3avg = new byte[20 * 3]; var sent = new IHTMLPre { }.AttachToDocument(); // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150701 // what about 255.255.255.255 ? chrome.socket.getNetworkList().ContinueWithResult(async n => { // which networks should we notify of our data? //new IHTMLPre { new { n.Length } }.AttachToDocument(); foreach (var item in n) { // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704 // skip ipv6 if (item.address.Contains(":")) continue; #region send new IHTMLButton { "send onframe " + item.address }.AttachToDocument().With( async refresh => { refresh.style.color = "blue"; refresh.style.display = IStyle.DisplayEnum.block; // experimental until ref count 33? await refresh.async.onmousedown; refresh.disabled = true; var port = new Random().Next(16000, 40000); //new IHTMLPre { "about to bind... " + new { port } }.AttachToDocument(); // where is bind async? var socket = new UdpClient(); socket.Client.Bind( //new IPEndPoint(IPAddress.Any, port: 40000) new IPEndPoint(IPAddress.Parse(item.address), port) ); // this will eat too much memory? //div.ownerDocument.defaultView.onframe += Native.window.onframe += e => { //var px = (float)(__yscan64max_ix - v.videoWidth / 2) / (float)v.videoWidth; var px0 = (float)(x - ow / 2) / (float)ow; var py0 = (float)(y - oh / 2) / (float)oh; // 4000 zoom out // 7000 zoom in // haha. this wont work. //var pz = ((z - 4500) / 2000f).Max(0f).Min(1.5f); // in a dark room? var pz = ((z - 6000) / 1000f).Max(0f).Min(1.5f); // allow py only if pz is negative. // 0 means py stays // 1 means py is zero var pzz = (1.0f - pz).Max(0.0f).Min(1.0f); var py = py0 * pzz; var px = px0 * pzz; pz -= 0.3f; // !! leaning in kills parallax left and up. // rotating on gear vr will cancel all parallax. // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704 var nmessage = e.counter + ":" + px + ":" + py + ":" + pz; //sent.innerText = nmessage.Replace(":", ":\n") + new { py0, pzz, py }; sent.innerText = nmessage.Replace(":", ":\n"); var data = Encoding.UTF8.GetBytes(nmessage); //creates a variable b of type byte //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument(); // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs socket.Send( data, data.Length, hostname: "239.1.2.3", port: 43834 ); }; } ); #endregion } } ); var status = new IHTMLPre { () => new { frameID, frame0sw.ElapsedMilliseconds, fps = 1000 / frame0sw.ElapsedMilliseconds , fps3avg = (byte)fps3avg.Average(k => k), x,y,z, fps3, // script: error JSC1000: No implementation found for this native method, please implement [System.String.Replace(System.Char, System.Char)] }.ToString().Replace(",", ",\t") }.AttachToDocument(); var fdiv = new IHTMLDiv { }.AttachToDocument(); new { }.With( async delegate { var vw = ow; var vh = oh; #region 3 workers // what about sending bytes[2,3] over? byte[] rgba_bytes0in = null; var rgba_bytes0in_set = new System.Threading.SemaphoreSlim(1); byte[] rgba_bytes0out = null; var rgba_bytes0out_set = new System.Threading.SemaphoreSlim(1); //SemaphoreSlim rgba_bytes0out_set = new __SemaphoreSlim(1) { Name = "rgba_bytes0out_set" }; byte[] rgba_bytes1in = null; var rgba_bytes1in_set = new System.Threading.SemaphoreSlim(1); byte[] rgba_bytes1out = null; var rgba_bytes1out_set = new System.Threading.SemaphoreSlim(1); byte[] rgba_bytes2in = null; var rgba_bytes2in_set = new System.Threading.SemaphoreSlim(1); byte[] rgba_bytes2out = null; var rgba_bytes2out_set = new System.Threading.SemaphoreSlim(1); Task.Run( async delegate { var w = new WorkerThread(0, vw, vh); next: await rgba_bytes0in_set.WaitAsync(); rgba_bytes0out = w.Invoke(rgba_bytes0in); rgba_bytes1out = null; rgba_bytes2out = null; rgba_bytes0in = null; rgba_bytes1in = null; rgba_bytes2in = null; // we should not sync back data we did not put there. nor should it be there anyway? rgba_bytes0out_set.Release(); goto next; } ); Task.Run( async delegate { var w = new WorkerThread(1, vw, vh); next: await rgba_bytes1in_set.WaitAsync(); rgba_bytes0out = null; rgba_bytes1out = w.Invoke(rgba_bytes1in); rgba_bytes2out = null; rgba_bytes0in = null; rgba_bytes1in = null; rgba_bytes2in = null; rgba_bytes1out_set.Release(); goto next; } ); Task.Run( async delegate { var w = new WorkerThread(2, vw, vh); next: await rgba_bytes2in_set.WaitAsync(); rgba_bytes0out = null; rgba_bytes1out = null; rgba_bytes2out = w.Invoke(rgba_bytes2in); rgba_bytes0in = null; rgba_bytes1in = null; rgba_bytes2in = null; rgba_bytes2out_set.Release(); goto next; } ); #endregion Console.WriteLine("worker0 spinning already..."); //do await v.async.onclick; { frame0sw0 = Stopwatch.StartNew(); //Console.WriteLine(frame0sw0.ElapsedMilliseconds + " fetch frame0"); frame0in.drawImage(v, 0, v.videoHeight / 4, v.videoWidth, v.videoHeight / 2, 0, 0, vw, vh); rgba_bytes0in = frame0in.bytes; rgba_bytes0in_set.Release(); new IHTMLPre { frame0sw0.ElapsedMilliseconds + " frame0 posted" }.AttachTo(fdiv); // await Task.Delay(1000 / 60); // 300? // Console.WriteLine(frame0sw0.ElapsedMilliseconds + " send frame2"); frame0in.drawImage(v, 0, v.videoHeight / 4, v.videoWidth, v.videoHeight / 2, 0, 0, vw, vh); rgba_bytes1in = frame0in.bytes; rgba_bytes1in_set.Release(); new IHTMLPre { frame0sw0.ElapsedMilliseconds + " frame1 posted" }.AttachTo(fdiv); loop: // 60fps!! frameID += 3; frame0in_drawImage(); rgba_bytes2in = frame0in.bytes; rgba_bytes2in[0] = (byte)(frameID & 0xff); rgba_bytes2in[1] = (byte)((frameID >> 8) & 0xff); rgba_bytes2in[4] = slider; rgba_bytes2in_set.Release(); //await Task.WhenAll(Native.window.async.onframe, rgba_bytes0out_set.WaitAsync()); await rgba_bytes0out_set.WaitAsync(); if (!aloop.@checked) new IHTMLPre { frame0sw0.ElapsedMilliseconds + " collected frame0" }.AttachTo(fdiv); //frame0out.bytes = rgba_bytes0out; //frame3out.drawImage(frame0out.canvas, 0, 0, vw, vh); frame3out.bytes = rgba_bytes0out; rgba_bytes2in = null; rgba_bytes0out = null; frame0in_drawImage(); rgba_bytes0in = frame0in.bytes; rgba_bytes0in[0] = (byte)(frameID & 0xff); rgba_bytes0in[1] = (byte)((frameID >> 8) & 0xff); rgba_bytes0in[4] = slider; rgba_bytes0in_set.Release(); //await Task.WhenAll(Native.window.async.onframe, rgba_bytes1out_set.WaitAsync()); await rgba_bytes1out_set.WaitAsync(); if (!aloop.@checked) new IHTMLPre { frame0sw0.ElapsedMilliseconds + " collected frame1" }.AttachTo(fdiv); //frame1out.bytes = rgba_bytes1out; //frame3out.drawImage(frame1out.canvas, 0, 0, vw, vh); frame3out.bytes = rgba_bytes1out; rgba_bytes0in = null; rgba_bytes1out = null; frame0in_drawImage(); rgba_bytes1in = frame0in.bytes; rgba_bytes1in[0] = (byte)(frameID & 0xff); rgba_bytes1in[1] = (byte)((frameID >> 8) & 0xff); rgba_bytes1in[4] = slider; rgba_bytes1in_set.Release(); await Task.WhenAll(Native.window.async.onframe, rgba_bytes2out_set.WaitAsync()); if (!aloop.@checked) new IHTMLPre { frame0sw0.ElapsedMilliseconds + " collected frame2, next? " + new { aloop.@checked } }.AttachTo(fdiv); // z = rgba_bytes2out[0] + (rgba_bytes2out[1] << 8); x = rgba_bytes2out[4] + (rgba_bytes2out[5] << 8); y = rgba_bytes2out[8]; //frame2out.bytes = rgba_bytes2out; //frame3out.drawImage(frame2out.canvas, 0, 0, vw, vh); frame3out.bytes = rgba_bytes2out; rgba_bytes1in = null; rgba_bytes2out = null; frame0sw0.Stop(); frame0sw = frame0sw0; //if (v.src == null) //{ // Native.body.style.backgroundColor = "red"; // return; //} //if (aloop) if (!aloop.@checked) { //await Task.WhenAny(aloop.async.@checked, v.async.onclick); await v.async.onclick; fdiv.Clear(); } frame0sw0 = Stopwatch.StartNew(); fps3 = (int)(3000 / frame0sw.ElapsedMilliseconds); fps3avg[(frameID / 3) % fps3avg.Length] = (byte)fps3; if (fps3 > 55) { status.style.color = "blue"; } else { status.style.color = "red"; } goto loop; // 10000ms? // 400ms? } //} while (await v.async.onclick); //} while (await Native.window.async.onframe); } ); await Native.window.async.onblur; Native.body.style.backgroundColor = "yellow"; } ); }