Example #1
0
        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();
            }
        }
Example #2
0
        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";
                }
            );
        }