public GIFEncoderAsync(
        int width,
        int height,
        int delay = 1000 / 15,
        int repeat = 0
        )
    {
        var xscope = new { width, height, repeat, delay };

        Console.WriteLine("will share scope data: " + xscope);

        var w = new Worker(
            scope =>
            {
                var encoder = default(GIFEncoder);
                Console.WriteLine("waiting for scope data");

                scope.onmessage +=
                    ze =>
                    {
                        #region once
                        if (encoder != null)
                            return;
                        #endregion


                        Console.WriteLine("new encoder");

                        dynamic zscope = ze.data;

                        int zwidth = zscope.width;
                        int zheight = zscope.height;
                        int zrepeat = zscope.repeat;
                        int zdelay = zscope.delay;

                        Console.WriteLine("got scope data: " + new { zwidth, zheight, zrepeat, zdelay });

                        encoder = new GIFEncoder();
                        encoder.setSize(zwidth, zheight);
                        encoder.setRepeat(zrepeat); //auto-loop
                        encoder.setDelay(zdelay);
                        encoder.start();

                        scope.onmessage +=
                            ee =>
                            {
                                dynamic xdata = ee.data;
                                string message = xdata.message;

                                //Console.WriteLine(new { message });


                                #region addFrame
                                if (message == "addFrame")
                                {
                                    //Console.WriteLinke("addFrame");

                                    // http://stackoverflow.com/questions/8776751/web-worker-dealing-with-imagedata-working-with-firefox-but-not-chrome
                                    //byte[] data = xdata.data;
                                    Uint8ClampedArray data = xdata.data;
                                    //data[
                                    // { data = [object Uint8ClampedArray] } 
                                    //Console.WriteLine(new { data });

                                    encoder.addFrame(data, true);

                                    ee.ports.WithEach(port => port.postMessage("ok"));
                                }
                                #endregion

                                #region finish
                                if (message == "finish")
                                {
                                    Console.WriteLine("finish");

                                    encoder.finish();

                                    var bytes = Encoding.ASCII.GetBytes(encoder.stream().getData());
                                    var src = "data:image/gif;base64," + Convert.ToBase64String(bytes);

                                    ee.ports.WithEach(port => port.postMessage(src));

                                }
                                #endregion

                            };
                    };

            }
        );

        w.postMessage(xscope);

        #region addFrame
        this.addFrame =
            (data, yield) =>
            {

                dynamic xdata = new object();

                xdata.message = "addFrame";
                xdata.data = data;

                // Error	4	Cannot convert lambda expression to type 'ScriptCoreLib.JavaScript.DOM.MessagePort[]' because it is not a delegate type	X:\jsc.svn\examples\javascript\synergy\jsgif\jsgif\Application.cs	171	38	jsgif


                w.postMessage(
                    (object)xdata,
                    (MessageEvent ee) =>
                    {
                        //Console.WriteLine("addFrame done");

                        if (yield != null)
                            yield();
                    }
                );

            };
        #endregion

        #region finish
        this.finish =
            yield_src =>
            {
                w.postMessage(
                      new { message = "finish" },
                      (MessageEvent ee) =>
                      {
                          //Console.WriteLine("finish done");

                          var src = (string)ee.data;

                          //Console.WriteLine(e.Elapsed);
                          //new IHTMLImage { src = src }.AttachToDocument();

                          w.terminate();

                          yield_src(src);
                      }
                   );
            };
        #endregion

    }
Exemple #2
0
        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108

        // X:\jsc.svn\examples\javascript\android\com.abstractatech.appmanager\com.abstractatech.appmanager\Application.cs

        // tested by
        // X:\jsc.svn\examples\javascript\android\com.abstractatech.adminshell\com.abstractatech.adminshell\Application.cs

        //02000066 ScriptCoreLib.JavaScript.Experimental.X+<>c__DisplayClassc+<<GetAwaiter>b__7>d__11
        //script: error JSC1000: if block not detected correctly, opcode was { Branch = [0x0020] beq        +0 -2{[0x0019] ldfld      +1 -1{[0x0018] ldarg.0    +1 -0} } {[0x001e] ldc.i4.s   +1 -0} , Location =
        // assembly: T:\com.abstractatech.adminshell.Application.exe
        // type: ScriptCoreLib.JavaScript.Experimental.X+<>c__DisplayClassc+<<GetAwaiter>b__7>d__11, com.abstractatech.adminshell.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
        // offset: 0x0020
        //  method:Int32 <>02000019<>06000044<>MoveNext<0000>.try(<>02000019<>06000044<>MoveNext, <<GetAwaiter>b__7>d__11 ByRef, System.Runtime.CompilerServices.TaskAwaiter`1[System.Byte[]] ByRef, System.Runtime.CompilerServices.TaskAwaiter`1[System.Byte[]] ByRef) }

        //public static object 


        // .NET 4.5!!!
        public static TaskAwaiter<InternalScriptApplicationSource> GetAwaiter(this Type __e)
        {
            Console.WriteLine("enter ScriptCoreLib.JavaScript.Experimental " + new { __e.Name });

            // http://stackoverflow.com/questions/9713058/sending-post-data-with-a-xmlhttprequest

            var y = new TaskCompletionSource<InternalScriptApplicationSource>();

            //var ysource = Native.window.sessionStorage[__e.Name];
            //if (ysource != null)
            //{
            //    y.SetResult(ysource);

            //    return y.Task.GetAwaiter();
            //}

            //return 

            //InternalInitializeInlineWorker Report: { __IProgress_Report = { value = [object Object] } }
            // view-source:27346
            //{ Name = a, loaded = 4538818, total = 4538818 } view-source:27346

            // view-source:27346
            //loading secondary app in a moment... { responseType = arraybuffer, ManagedThreadId = 10 }
            // view-source:27346
            //loading secondary app in a moment... { Length = 4538818 } decrypting...
            // view-source:27346
            //loading secondary app in a moment... { Length = 2269409 } done!

            var bar = new IHTMLDiv { }.AttachToDocument();

            bar.style.SetLocation(0, -2);
            bar.style.position = IStyle.PositionEnum.@fixed;
            bar.style.height = "3px";
            bar.style.backgroundColor = "red";
            //bar.style.borderBottom = "1px solid darkred";

            // http://stackoverflow.com/questions/9670075/css-transition-shorthand-with-multiple-properties

            (bar.style as dynamic).webkitTransition = "top 0.5s linear";
            //(bar.style as dynamic).webkitTransitionProperty = "top, width, background-color";
            (bar.style as dynamic).webkitTransitionProperty = "top, width";




            var state = new
                {
                    __e.Name,

                    backgroundColor = "red",

                    loaded = default(long),
                    total = default(long),
                    source = default(string),

                    Native.document.location.href,


                    references = new InternalScriptApplicationReference[0]
                };

            Console.WriteLine("call Task.Factory.StartNewWithProgress");

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108

            Task.Factory.StartNewWithProgress(
                state,

                progress: x =>
                {
                    bar.style.top = "0px";


                    #region bar
                    if (x.loaded > 0)
                        if (x.total > 0)
                        {
                            //if (x.loaded == x.total)
                            //{
                            //}
                            //else
                            //{
                            //    bar.style.SetLocation(0, 0);
                            //}

                            var xx = (int)(100 * x.loaded / x.total);

                            ;
                            // 
                            // 3% is the minimum we want to show
                            var per = Math.Max(3, xx) + "%";

                            //Console.WriteLine(new { per, x.loaded, x.total, x.backgroundColor });

                            bar.style.backgroundColor = x.backgroundColor;
                            bar.style.width = per;

                        }
                    #endregion



                    //Console.WriteLine(
                    //    new { x.Name, x.loaded, x.total }
                    //);

                    #region SetResult
                    x.source.With(
                        async source =>
                        {
                            //        // should we analyze? IFunction

                            //Console.WriteLine("wall save source to localStorage " + new { __e.Name, source.Length });

                            // sessionStorage out of memory?
                            //Native.window.sessionStorage[__e.Name] = source;

                            //Native.window.eval(
                            //    //x.responseText
                            //    source
                            //);


                            bar.style.backgroundColor = "yellow";
                            await Task.Delay(300);
                            bar.style.backgroundColor = "red";
                            await Task.Delay(300);
                            bar.style.backgroundColor = "yellow";
                            await Task.Delay(300);
                            bar.style.backgroundColor = "red";
                            await Task.Delay(300);
                            bar.Orphanize();

                            //                            { index = 0, name =  ScriptCoreLib.dll.js, size = 1330538 } view-source:27530

                            // view-source:27530
                            //{ index = 1, name =  WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js, size = 507500 } view-source:2753


                            y.SetResult(
                                new InternalScriptApplicationSource
                                {
                                    source = source,
                                    references = x.references
                                }

                            );
                        }
                    );
                    #endregion


                },


                function:
                    tuple =>
                    {
                        var progress = tuple.Item1;
                        var scope = tuple.Item2;

                        // http://stackoverflow.com/questions/13870853/how-to-upload-files-in-web-workers-when-formdata-is-not-defined
                        // FormData is not defined
                        //var f = new FormData();

                        //f.append("Application", scope.Name);


                        // can we use WebClient instead now?
                        var x = new IXMLHttpRequest();

                        // { src = /more-source } 

                        // { src = blob:http%3A//192.168.43.252%3A5485/fdec11d3-735f-4165-937a-43f25ef8d8d3#worker/more-source } 
                        // worker location might not help us talk to our server!

                        //var src = Native.worker.location.href + "/more-source";
                        //POST http://public:[email protected]:14356//more-source 400 (Bad Request) 
                        var src = scope.href;

                        Console.WriteLine(new { src });

                        x.open(ScriptCoreLib.Shared.HTTPMethodEnum.POST, src,
                            async: true,
                            user: "******",
                            password: "******"
                        );

                        // Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.
                        x.setRequestHeader(
                            "X-Application", scope.Name
                        );

                        // what about progress?


                        // http://stackoverflow.com/questions/10956574/why-might-xmlhttprequest-progressevent-lengthcomputable-be-false

                        var xprogress = new { scope.loaded, scope.total };

                        // AppEngine will not report progress

                        #region onprogress
                        x.onprogress +=
                            e =>
                            {
                                // make room for decrypt progress
                                var loaded = e.loaded / 2;

                                xprogress = new { loaded, e.total };

                                //Console.WriteLine();

                                progress.Report(
                                    new
                                    {
                                        scope.Name,
                                        scope.backgroundColor,
                                        xprogress.loaded,
                                        xprogress.total,
                                        scope.source,
                                        scope.href,
                                        scope.references
                                    }
                                );

                            };
                        #endregion


                        #region decrypt
                        Action<byte[]> decrypt = response =>
                        {
                            var AllResponseHeaders = x.getAllResponseHeaders();

                            //AllResponseHeaders = Date: Wed, 11 Sep 2013 14:31:43 GMT
                            //X-Reference-0: ScriptCoreLib.dll.js 1330538
                            //Server: ASP.NET Development Server/11.0.0.0
                            //X-AspNet-Version: 4.0.30319
                            //X-Reference-1: WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js 487668
                            //X-DiagnosticsMakeItSlowAndAddSalt: ok
                            //Content-Type: application/octet-stream
                            //Cache-Control: public
                            //Connection: Close
                            //Content-Length: 3636412
                            //Expires: Wed, 11 Sep 2013 14:46:43 GMT

                            var prefix = "X-Reference-";

                            var references = AllResponseHeaders.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Where(k => k.StartsWith(prefix)).Select(
                                k =>
                                {
                                    var text = k.Substring(prefix.Length);

                                    var index = int.Parse(text.TakeUntilIfAny(":"));
                                    var name = text.SkipUntilIfAny(":").TakeUntilLastIfAny(" ");
                                    var size = int.Parse(text.SkipUntilIfAny(":").SkipUntilLastIfAny(" "));

                                    return new InternalScriptApplicationReference
                                    {
                                        index = index,
                                        name = name,
                                        size = size
                                    };
                                }
                            ).ToArray();


                            Console.WriteLine(
                                "loading secondary app in a moment... "
                                + new
                                {
                                    response.Length,
                                    Thread.CurrentThread.ManagedThreadId
                                } + " decrypting...");

                            // loading secondary app in a moment... { Length = 6265416, ManagedThreadId = 10 } decrypting...


                            //                            X-Reference-0:ScriptCoreLib.dll.js 1330538
                            //X-Reference-1:WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js 485234
                            // "X:\jsc.svn\examples\javascript\WorkerInsideSecondaryApplication\WorkerInsideSecondaryApplication.sln"

                            //y.SetResult(new { x.responseText.Length }.ToString());
                            // X:\jsc.svn\core\ScriptCoreLib.Ultra.Library\ScriptCoreLib.Ultra.Library\Ultra\WebService\InternalGlobalExtensions.cs

                            var mstopwatch = Stopwatch.StartNew();
                            var m = new MemoryStream();

                            var lo = default(byte);
                            var lo_set = false;

                            foreach (var item in response)
                            {
                                if (lo_set)
                                {
                                    lo_set = false;

                                    var hi = (byte)(item << 4);

                                    m.WriteByte(
                                        (byte)(lo | hi)
                                    );

                                    if ((m.Length % 1024 * 8) == 0)
                                    {
                                        var loaded = xprogress.total / 2 + m.Length;

                                        xprogress = new { loaded, xprogress.total };

                                        //Console.WriteLine(new
                                        //{
                                        //    Thread.CurrentThread.ManagedThreadId,

                                        //    mstopwatch.ElapsedMilliseconds,
                                        //    xprogress
                                        //});

                                        progress.Report(
                                            new
                                            {
                                                scope.Name,
                                                backgroundColor = "cyan",
                                                xprogress.loaded,
                                                xprogress.total,
                                                scope.source,
                                                scope.href,
                                                scope.references
                                            }
                                        );
                                    }
                                }
                                else
                                {
                                    lo = item;
                                    lo_set = true;
                                }
                            }

                            // decrypted
                            Console.WriteLine("UTF8.GetString " + new { m.Length });

                            var source = Encoding.UTF8.GetString(m.ToArray());


                            Console.WriteLine("loading secondary app in a moment... " + new { source.Length } + " done!");

                            //return new { response.Length, responseText = source };

                            progress.Report(
                                new
                                {
                                    scope.Name,
                                    backgroundColor = "green",
                                    xprogress.loaded,
                                    xprogress.total,
                                    source,
                                    scope.href,
                                    references
                                }
                            );

                        };
                        #endregion


                        Action send = async delegate
                        {


                            var response = await x.bytes;


                            decrypt(response);

                        };


                        send();

                        // no changes yet
                        return scope;
                    }


            );


            return y.Task.GetAwaiter();


        }
    public GIFEncoderWorker(
        int width,
        int height,
        int delay = 1000 / 15,
        int repeat = 0,

        //object transparentColor = null,

        IEnumerable<byte[]> frames = null,

        Action<int> AtFrame = null
        )
    {
        // X:\jsc.svn\examples\javascript\async\test\TestScopeWithDelegate\TestScopeWithDelegate\Application.cs

        //MethodTargetObjectData: Array[2]
        //0: type$Wp_akjqSvXzyEjEqVpOKCvA._8gAABqSvXzyEjEqVpOKCvA
        //AtFrame: $ctor$.f

        Console.WriteLine("enter GIFEncoderWorker");
        var progress = (new Progress<int>(
             x =>
             {
                 Console.WriteLine("DOM Progress: " + new { x, Thread.CurrentThread.ManagedThreadId });

                 if (AtFrame != null)
                     AtFrame(x);
             }
          ) as IProgress<int>);


        this.Task = System.Threading.Tasks.Task.Factory.StartNew(
            //Tuple.Create(progress,
                    new
                    {
                        width,
                        height,
                        delay,
                        repeat,
                        //transparentColor, 
                        frames = frames.ToArray()
                    }
            //)
            ,
            x =>
            {
                Console.WriteLine("in GIFEncoderWorker");

                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201405/20140526/stack

                var src = default(string);

                // is this killing the rewrite?
                //Action<int> yield = xx.Item1.Report;
                Action<int> yield = progress.Report;

                // wtf?

                //0200003f GIFEncoderWorker
                //script: error JSC1000: Method: <.ctor>b__1, Type: GIFEncoderWorker; emmiting failed : System.NullReferenceException: Object reference not set to an instance of an object.
                //   at jsc.IL2ScriptGenerator.OpCode_newobj(IdentWriter w, Prestatement p, ILInstruction i, ILFlowStackItem[] s) in x:\jsc.internal.svn\compiler\jsc\Languages\JavaScript\IL2ScriptGenerator.OpCodes.Newobj.cs:line 151

                yield(0);

                //var x = xx.Item2;
                var state = new
                {
                    x.width,
                    x.height,
                    x.delay,
                    //x.transparentColor, 
                    x.repeat,
                    x.frames.Length
                };

                // { state = { width = 640, height = 480, delay = 100, repeat = 0, Length = 16 } } 
                Console.WriteLine(new { state });

                var encoder = new GIFEncoder();
                encoder.setSize(x.width, x.height);
                encoder.setRepeat(x.repeat); //auto-loop
                encoder.setDelay(x.delay);
                //encoder.setTransparent(x.transparentColor);
                encoder.start();
                //#if OK

                x.frames.WithEachIndex(
                    (frame, index) =>
                    {
                        Console.WriteLine("addFrame " + new { index });


                        encoder.addFrame((Uint8ClampedArray)(object)frame, true);

                        yield(index);
                    }
                );
                //#endif

                Console.WriteLine("finish");

                encoder.finish();

                var bytes = Encoding.ASCII.GetBytes(encoder.stream().getData());

                src = "data:image/gif;base64," + Convert.ToBase64String(bytes);

                return src;
            }
        );
    }