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 }
// 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; } ); }