// https://developer.chrome.com/apps/tags/webview // or what if we were to runn as chrome appwindow and webview // would they be in separate gpu procsses, leeping parent responsive while gpu is buzy? public Application(IApp page) { #if FCHROME #region += Launched chrome.app.window // X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServerAppWindow\ChromeTCPServerAppWindow\Application.cs 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)) { // should implement hop here instead tho //new IHTMLPre { "empty window " }.AttachToDocument(); new IHTMLPre { () => "appwindow: " + new { DateTime.Now.Millisecond } }.AttachToDocument(); } else { //ChromeTCPServer.TheServerWithAppWindow.Invoke(AppSource.Text); ChromeTCPServer.TheServer.Invoke(AppSource.Text, // null means we get a new tab, which we could control as an extension? open: async uri => { // app to appwindow var xappwindow = await chrome.app.window.create(Native.document.location.pathname, options: null); // do we have an empty window? await xappwindow.contentWindow.async.onload; var webview = xappwindow.contentWindow.document.createElement("webview"); // You do not have permission to use <webview> tag. Be sure to declare 'webview' permission in your manifest. webview.setAttribute("partition", "p1"); webview.setAttribute("src", uri); webview.style.SetLocation(100, 80); webview.style.width = "400px"; webview.style.height = "400px"; webview.AttachTo(xappwindow.contentWindow.document.body); } ); } return; } #endregion #endif Native.body.Clear(); // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150824/webgliframebuffer // until we have webgl2 up and running, // iframes could work as well. // what we need is a set of iframes that allow // 360deg multishader rendering // to run it as a hybrid chrome app, either we need aawppwindow tcp webview or tabs window // each shader iframe can prep their frames ahead of time in their own pace.. // will three.planegeometry use atlas? #region setup var isroot = Native.window.parent == Native.window; if (isroot) { Native.body.style.backgroundColor = "yellow"; } else { Native.body.style.backgroundColor = "cyan"; } // called by? 619 app:HopToChromeAppWindow #region window: Native.window.onmessage Native.window.onmessage += e => { Console.WriteLine("iframe: Native.window.onmessage"); // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150822/hoptochromeappwindow var message = e.data; if (message is string) { Console.WriteLine("iframe: Native.window.onmessage: " + message); if (e.ports != null) { foreach (var port in e.ports) { Console.WriteLine("iframe: Native.window.onmessage " + new { port }); //appwindow_to_app = port; } } return; } // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150822/hoptochromeapp // casting from anonymous object. var xShadowIAsyncStateMachine = (TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine)message; // or constructor id? Console.WriteLine("iframe: Native.window.onmessage " + new { xShadowIAsyncStateMachine.state, xShadowIAsyncStateMachine.TypeName }); // 12468ms extension port.onMessage {{ message = do HopToChromeExtension {{ TypeName = <Namespace>.___ctor_b__4_9_d, state = 0 }}, expando_isstring = true, is_string = false, equals_typeofstring = false }} //2015-08-22 15:49:45.729 view-source:53670 12471ms extension port.onMessage {{ message = do HopToChromeExtension {{ TypeName = <Namespace>.___ctor_b__4_9_d, state = 0 }} }} //2015-08-22 15:49:45.733 view-source:53670 12475ms extension port.onMessage {{ message = [object Object], expando_isstring = false, is_string = false, equals_typeofstring = false }} //2015-08-22 15:49:45.737 view-source:53670 12479ms extension port.onMessage {{ state = 0, TypeName = <Namespace>.___ctor_b__4_9_d }} #region xAsyncStateMachineType var xAsyncStateMachineType = typeof(Application).Assembly.GetTypes().FirstOrDefault( xAsyncStateMachineTypeCandidate => { // safety check 1 //Console.WriteLine(new { sw.ElapsedMilliseconds, item.FullName }); //var xisIAsyncStateMachine = typeof(mscorlib::System.Runtime.CompilerServices.IAsyncStateMachine).IsAssignableFrom(xAsyncStateMachineTypeCandidate); var xisIAsyncStateMachine = typeof(global::System.Runtime.CompilerServices.IAsyncStateMachine).IsAssignableFrom(xAsyncStateMachineTypeCandidate); if (xisIAsyncStateMachine) { //Console.WriteLine(new { item.FullName, isIAsyncStateMachine }); return(xAsyncStateMachineTypeCandidate.FullName == xShadowIAsyncStateMachine.TypeName); } return(false); } ); #endregion var NewStateMachine = global::System.Runtime.Serialization.FormatterServices.GetUninitializedObject(xAsyncStateMachineType); var isIAsyncStateMachine = NewStateMachine is global::System.Runtime.CompilerServices.IAsyncStateMachine; var NewStateMachineI = (global::System.Runtime.CompilerServices.IAsyncStateMachine)NewStateMachine; #region 1__state xAsyncStateMachineType.GetFields( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ).WithEach( AsyncStateMachineSourceField => { //Console.WriteLine(new { AsyncStateMachineSourceField }); if (AsyncStateMachineSourceField.Name.EndsWith("1__state")) { AsyncStateMachineSourceField.SetValue( NewStateMachineI, xShadowIAsyncStateMachine.state ); } // X:\jsc.svn\examples\javascript\async\Test\TestSwitchToServiceContextAsync\TestSwitchToServiceContextAsync\CLRWebServiceInvoke.cs // field names/ tokens need to be encrypted like typeinfo. // some do manual restore // X:\jsc.svn\examples\javascript\chrome\extensions\ChromeExtensionHopToTabThenIFrame\ChromeExtensionHopToTabThenIFrame\Application.cs // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150822/hoptochromeappwindow // or, are we supposed to initialize a string value here? var xStringField = TestSwitchToServiceContextAsync.ArrayListExtensions.AsEnumerable(xShadowIAsyncStateMachine.StringFields).FirstOrDefault( f => DecoratedString(f.FieldName) == DecoratedString(AsyncStateMachineSourceField.Name) ); if (xStringField != null) { // once we are to go back to client. we need to reverse it? AsyncStateMachineSourceField.SetValue( NewStateMachineI, xStringField.value ); // next xml? // before lets send our strings back with the new state! // what about exceptions? } } ); #endregion NewStateMachineI.MoveNext(); }; #endregion //Action<ScriptCoreLib.JavaScript.DOM.IWindow, Action> invokeWhenReady = (contentWindow, yield) => #region invokeWhenReady, roslyn ctp needs it. rc does not? Action <IHTMLIFrame, Action> invokeWhenReady = (that, yield) => { that.onload += delegate { if (yield == null) { Console.WriteLine("window: HopToIFrame that.that.contentWindow.onload dismissed"); return; } Console.WriteLine("window: HopToIFrame IHTMLIFrame.onload"); if (yield != null) { yield(); yield = null; } }; }; #endregion #region window:HopToChromeAppWindow // bugcheck: roslyn RC generates byref struct statemachine? //HopToIFrame.VirtualOnCompleted = async (that, continuation) => HopToIFrame.VirtualOnCompleted = (that, continuation) => { // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150824/webgliframebuffer // state 0 ? or state -1 ? Console.WriteLine("window: HopToIFrame VirtualOnCompleted enter "); #region yield Action yield = delegate { // z:\jsc.svn\examples\javascript\async\Test\TestSwitchToServiceContextAsync\TestSwitchToServiceContextAsync\CLRWebServiceInvoke.cs // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150822/hoptochromeappwindow // async dont like ref? TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine.ResumeableContinuation r = TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine.ResumeableFromContinuation(continuation); // 29035ms extension port.onMessage {{ message = do HopToChromeExtension }} // Z:\jsc.svn\core\ScriptCoreLib\JavaScript\DOM\IWindow.postMessage.cs // how do we use this thing? var c = new MessageChannel(); c.port1.onmessage += e => { Console.WriteLine("window: HopToChromeAppWindow MessageChannel onmessage " + new { e.data }); //appwindow_to_app(e.data); }; c.port1.start(); c.port2.start(); Console.WriteLine("window to iframe postMessage"); // 15ms appwindow Native.window.onmessage: {{ ports = [object MessagePort] }} //2015-08-22 20:50:18.019 view-source:53702 17ms appwindow Native.window.onmessage: {{ port = [object MessagePort] }} that.that.contentWindow.postMessage("do HopToIFrame " + new { r.shadowstate.TypeName, r.shadowstate.state }, transfer: c.port2); // now send the jump instruction... will it make it? that.that.contentWindow.postMessage(r.shadowstate); }; #endregion #region outputWindow if (that.that == null) { // TypeError: Cannot read property 'document' of null // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150822/hoptochromeappwindow // or should we predownload our source as we do for Worker? that.that = new IHTMLIFrame { src = Native.document.location.href }; // bugcheck: roslyn RC generates byref struct statemachine? //await that.that.contentWindow.async.onload; // listener ready? // Error: InvalidOperationException: inline scope sharing not yet implemented //invokeWhenReady(that.that.contentWindow, yield); invokeWhenReady(that.that, yield); //that.that.contentWindow.async.onload.ContinueWith( // async task => // { // await Native.window.async.onframe; // yield(); // } //); that.that.AttachToDocument(); return; } #endregion yield(); }; #endregion if (!isroot) { // bail as we are making the jump.. return; } #endregion // multishader variant here. // singleshader variant here. new { }.With( async delegate { //Error CS7069 Reference to type 'TaskAwaiter<>' claims it is defined in 'mscorlib', but it could not be found WebGLIFrameBuffer Z:\jsc.svn\examples\javascript\WebGL\WebGLIFrameBuffer\Application.cs 48 // cna we now have HopToChromeWebview? new IHTMLButton { "window: lets do some slow thing and see if parent stays responsive.. " }.AttachToDocument().onclick += delegate { // simulate gpu timeout Thread.Sleep(10000); // are we a webview or appview? // works as appwindow and webview are in different processes? // until iframes start living in another frame, // we can use chrome and tcp webview to get dual ui it seems. }; await new IHTMLButton { () => "window: ready " + new { DateTime.Now.Millisecond } }.AttachToDocument().async.onclick; // red cmd start. example.com // to open chrome // should actually fork to do multiple shaders at the same time... new IHTMLPre { () => "window: hopping to iframe to prep shader... " + new { DateTime.Now.Millisecond } }.AttachToDocument(); new IStyle(Native.body.css[IHTMLElement.HTMLElementEnum.iframe].style) { border = "1px dashed red", width = "800px", height = "400px" }; await default(HopToIFrame); // in the camera tracker we have semaphores after making the jump. new IHTMLPre { () => "iframe: we made it..." + new { DateTime.Now.Millisecond } }.AttachToDocument(); // need intellisense to do some meaningful tests.. // lets switch from red to asus.. // now, can we try to lock up the ui? new IHTMLButton { "iframe: lets do some slow thing and see if parent stays responsive.. " }.AttachToDocument().onclick += delegate { // simulate gpu timeout Thread.Sleep(10000); // are we a webview or appview? // works as appwindow and webview are in different processes? }; //// Cross-site iframes are currently hosted in the same process as their parent document, because we don't yet have support for hosting them in a different process. //// https://www.chromium.org/developers/design-documents/site-isolation //// ? --site-per-process in chrome://flags //// https://code.google.com/p/chromium/issues/detail?id=99379 //// http://stackoverflow.com/questions/11510483/will-a-browser-give-an-iframe-a-separate-thread-for-javascript //// https://www.chromium.org/developers/design-documents/oop-iframes //// this will block parent UI .. //Thread.Sleep(2000); //// js thread seems to block the parent iframe too... //// would it mean blockin for webgl also blocks parent? //// this would make this approach rather useless? //new IHTMLButton { "iframe: done. " }.AttachToDocument(); await new IHTMLButton { "iframe: doprograms " }.AttachToDocument().async.onclick; // only multiple gpu cards seem to fix slow fps shaders // or webgl2 will allow async program calls... doprograms(); } ); }
public static ShadowIAsyncStateMachine CLRInvoke( ShadowIAsyncStateMachine that ) { var xAsyncStateMachineTypeName = that.TypeName; Console.WriteLine(typeof(object) + " CLRInvoke " //+ typeof(SharedProgram) + new { Thread.CurrentThread.ManagedThreadId, that.TypeName, that.state }); // do we have the type mentioned loaded? //var NewStateMachine = Activator.CreateInstance(AsyncStateMachineType); //var NewStateMachineI = NewStateMachine as IAsyncStateMachine; //// this will take step into next await. ////NewStateMachineI.MoveNext(); //java.lang.Object Program prep for JVMCLRSwitchToCLRContextAsync.SharedProgram{ ManagedThreadId = 1 } //java.lang.Object enter JVMCLRSwitchToCLRContextAsync.SharedProgram{ ManagedThreadId = 1 } //java.lang.Object enter HopToCLR { ManagedThreadId = 1 } //{ continuation = ScriptCoreLib.Shared.BCLImplementation.System.__Action@123ec81 } //{ Method = void _AwaitUnsafeOnCompleted_b__1() } //{ Target = ScriptCoreLib.Shared.BCLImplementation.System.Runtime.CompilerServices.__AsyncTaskMethodBuilder___c__DisplayClass2_2@f87f48 } //{ SourceField = ScriptCoreLib.Shared.BCLImplementation.System.Runtime.CompilerServices.__IAsyncStateMachine zstateMachine, value = JVMCLRSwitchToCLRContextAsync.SharedProgram__Invoke_d__0@1405ef7 } //{ AsyncStateMachineSourceField = java.lang.String e, value = hi } //{ AsyncStateMachineSourceField = ScriptCoreLib.Shared.BCLImplementation.System.Runtime.CompilerServices.__AsyncTaskMethodBuilder __t__builder, value = ScriptCoreLib.Shared.BCLImplementation.System.Runtime.CompilerServices.__AsyncTaskMethodBuilder@1bba400 } //{ AsyncStateMachineSourceField = int __1__state, value = 0 } //{ AsyncStateMachineSourceField = JVMCLRSwitchToCLRContextAsync.HopToCLR __u___awaiter1, value = JVMCLRSwitchToCLRContextAsync.HopToCLR@19d3b25 } //{ AsyncStateMachineSourceField = java.lang.Object __t__stack, value = } //{ AsyncStateMachineSourceField = JVMCLRSwitchToCLRContextAsync.HopToThreadPoolAwaitable __u___awaiter2, value = } //{ SourceField = ScriptCoreLib.Shared.BCLImplementation.System.__Action yield, value = ScriptCoreLib.Shared.BCLImplementation.System.__Action@14989ff } //System.Object CLRInvoke { ManagedThreadId = 3, AsyncStateMachineTypeName = JVMCLRSwitchToCLRContextAsync.SharedProgram__Invoke_d__0 } //{ SourceField = System.Runtime.CompilerServices.IAsyncStateMachine m_stateMachine, value = JVMCLRSwitchToCLRContextAsync.SharedProgram+<Invoke>d__0 } // should java keep the actual type name as an attribute, like we have displayName Console.WriteLine("looking for the type..."); var xAsyncStateMachineType = typeof(CLRProgram).Assembly.GetTypes().FirstOrDefault( x => { //Console.WriteLine(new { x.FullName }); return(x.FullName.Replace("+", "_").Replace("<", "_").Replace(">", "_") == xAsyncStateMachineTypeName.Replace("+", "_").Replace("<", "_").Replace(">", "_")); } ); //looking for the type... //{ FullName = JVMCLRSwitchToCLRContextAsync.Program } //{ FullName = <module>.SHA12fc19b38aba0098236ba7fd654b62facbfa4969b@1331799119 } //{ FullName = ScriptCoreLib.Desktop.JVM.JVMLauncher } //{ FullName = <module>.SHA1e4eb4631b3cf3610d48914d2f4deba4581c74282@275784628$00000006 } //{ FullName = . } //{ FullName = . } //{ FullName = . } //{ FullName = ScriptCoreLib.Desktop.JVM.__JVMLauncherInvoke } //{ FullName = ScriptCoreLib.Desktop.JVM.__InternalGetEntryPoint } //{ FullName = ScriptCoreLib.Desktop.JVM.__InternalGetEntryPoint+ } //{ FullName = . } //{ FullName = . } //{ FullName = .? } //{ FullName = . } //{ FullName = . } //{ FullName = . } //{ FullName = . } //{ FullName = . } //{ FullName = . } //{ FullName = . } //{ FullName = .? } //{ FullName = . } //{ FullName = . } //{ FullName = JVMCLRSwitchToCLRContextAsync__i.<02000018>\\\\\\\+export } //{ FullName = <module>.SHA14908e43b60b15906983f15d5126d55d794b08a03@516876350$0000001e } //{ FullName = JVMCLRSwitchToCLRContextAsync.<02000006>\\\\\\\\\\\\\\\+<interfaceexport> } //{ FullName = JVMCLRSwitchToCLRContextAsync.CLRProgram } //{ FullName = JVMCLRSwitchToCLRContextAsync.CLRProgram+<>c__DisplayClass1 } //{ FullName = <>f__AnonymousType$34$$30$$29$$28$7`1 } //{ FullName = ScriptCoreLib.Desktop.AppDomainAssemblyResolve } //{ FullName = <module>.SHA1ece49800bcc87751341b0db5b5d43bab4e1973d0@1209331862$00000025 } //{ FullName = ScriptCoreLib.Library.StringConversions } //{ FullName = <module>.SHA17c927d0ef51414d5913d986a2a0ad52032747944@1023654678$00000027 } //{ FullName = ScriptCoreLib.Interop.IntPtrInfo } //{ FullName = <module>.SHA19ab5a45e1768fb14172603268fe7f44ab10839ae@1329949876$0000002a$0000002e$00000029 } //{ FullName = <>f__AnonymousType$42$$53$$67$$65$6`2 } //{ FullName = <>f__AnonymousType$45$$65$$70$$68$8`2 } //{ FullName = <module>.SHA111aec3ca07ebcd71f8efa6a7eb37c94e05d294eb@2139898218$00000047$00000030 } //{ FullName = <module>.SHA1d04c4f386a94a00ca9ac06112eefc7d4456dc8c4@30829592 } //{ FullName = <ExportDirectoryBridge> } Console.WriteLine(typeof(object) + " CLRInvoke " + new { Thread.CurrentThread.ManagedThreadId, xAsyncStateMachineType }); // how can we send the type ref over the wire? encypt it? var NewStateMachine = Activator.CreateInstance(xAsyncStateMachineType); var NewStateMachineI = NewStateMachine as IAsyncStateMachine; #region 1__state xAsyncStateMachineType.GetFields( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ).WithEach( AsyncStateMachineSourceField => { if (AsyncStateMachineSourceField.Name.EndsWith("1__state")) { AsyncStateMachineSourceField.SetValue( NewStateMachineI, that.state ); } } ); #endregion var ShadowIAsyncStateMachine = new ShadowIAsyncStateMachine(); var reset = new AutoResetEvent(false); HopToJVM.VirtualOnCompleted = (Action continuation) => { Console.WriteLine("time to jump back? yes"); Console.WriteLine(new { continuation }); Console.WriteLine(new { continuation.Method }); Console.WriteLine(new { continuation.Target }); // inspect target. can we reactivate it? //0001 0200000e JVMCLRSwitchToCLRContextAsync__i__d.jvm::JVMCLRSwitchToCLRContextAsync.SharedProgram+<Invoke>d__0 var f = continuation.Target.GetType().GetFields( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ); var AsyncStateMachineSource = default(IAsyncStateMachine); var AsyncStateMachineType = default(Type); var AsyncStateMachineFields = default(FieldInfo[]); // { AsyncStateMachineSourceField = Int32 <>1__state, value = 1 } f.WithEach( SourceField => { var SourceField_value = SourceField.GetValue(continuation.Target); Console.WriteLine(new { SourceField, value = SourceField_value }); var m_stateMachine = SourceField_value as IAsyncStateMachine; if (m_stateMachine != null) { AsyncStateMachineSource = m_stateMachine; AsyncStateMachineType = m_stateMachine.GetType(); AsyncStateMachineFields = AsyncStateMachineType.GetFields( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ); AsyncStateMachineFields.WithEach( AsyncStateMachineSourceField => { var value = AsyncStateMachineSourceField.GetValue(m_stateMachine); if (AsyncStateMachineSourceField.Name.EndsWith("1__state")) { ShadowIAsyncStateMachine.state = (int)value; } Console.WriteLine(new { AsyncStateMachineSourceField, value }); } ); } } ); reset.Set(); }; new Thread( delegate() { // this will take step into next await. NewStateMachineI.MoveNext(); } ).Start(); reset.WaitOne(); Console.WriteLine("time to jump back? " + new { ShadowIAsyncStateMachine.state }); return(ShadowIAsyncStateMachine); }
static Application() { new IHTMLPre { new { Native.document.currentScript.src } }.AttachToDocument(); #region HopToIFrame HopToIFrame.VirtualOnCompleted = async(that, continuation) => { new IHTMLPre { "enter HopToIFrame.VirtualOnCompleted.." }.AttachToDocument(); var r = TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine.ResumeableFromContinuation(continuation); // X:\jsc.svn\examples\javascript\Test\TestSwitchToIFrame\TestSwitchToIFrame\Application.cs //var m = await that.frame.contentWindow.async.onmessage; var m = await that.frame.async.onmessage; //new IHTMLPre { // " VirtualOnCompleted postMessageAsync " + new { r.shadowstate.state } //}.AttachToDocument(); // um. we need to tell that iframe, where to jump to.. //var firstmessageback = that.frame.contentWindow.postMessageAsync(r.shadowstate); m.postMessage(r.shadowstate); that.frame.ownerDocument.defaultView.onmessage += e => { if (e.source != that.frame.contentWindow) { return; } var shadowstate = (TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine)e.data; // are we jumping into a new statemachine? new IHTMLPre { "iframe is about to jump to parent " + new { shadowstate.state } }.AttachToDocument(); // about to invoke #region xAsyncStateMachineType var xAsyncStateMachineType = typeof(Application).Assembly.GetTypes().FirstOrDefault( item => { // safety check 1 //Console.WriteLine(new { sw.ElapsedMilliseconds, item.FullName }); var xisIAsyncStateMachine = typeof(IAsyncStateMachine).IsAssignableFrom(item); if (xisIAsyncStateMachine) { //Console.WriteLine(new { item.FullName, isIAsyncStateMachine }); return(item.FullName == shadowstate.TypeName); } return(false); } ); #endregion var NewStateMachine = FormatterServices.GetUninitializedObject(xAsyncStateMachineType); var isIAsyncStateMachine = NewStateMachine is IAsyncStateMachine; var NewStateMachineI = (IAsyncStateMachine)NewStateMachine; #region 1__state xAsyncStateMachineType.GetFields( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ).WithEach( AsyncStateMachineSourceField => { Console.WriteLine(new { AsyncStateMachineSourceField }); if (AsyncStateMachineSourceField.Name.EndsWith("1__state")) { AsyncStateMachineSourceField.SetValue( NewStateMachineI, shadowstate.state ); } } ); #endregion Console.WriteLine("invoke MoveNext"); NewStateMachineI.MoveNext(); }; }; #endregion #region HopToParent HopToParent.VirtualOnCompleted = async(that, continuation) => { // the state is in a member variable? var r = TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine.ResumeableFromContinuation(continuation); // should not be a zero state // or do we have statemachine name clash? new IHTMLPre { "enter HopToParent.VirtualOnCompleted.. " + new { r.shadowstate.state } }.AttachToDocument(); //Native.window.parent.postMessage(r.shadowstate); // we actually wont use the response yet.. }; #endregion // fsharpy look vctor = (IApp page) => { // {{ href = blob:https%3A//192.168.1.196%3A27831/bafa8242-82bd-44ef-8581-9f76f909cd86 }} new IHTMLPre { new { Native.document.location.href } }.AttachToDocument(); if (Native.window.parent != Native.window) { // X:\jsc.svn\examples\javascript\chrome\extensions\ChromeExtensionHopToTabThenIFrame\ChromeExtensionHopToTabThenIFrame\Application.cs // inside iframe new { }.With( async delegate { // start the handshake // we gain intellisense, but the type is partal, likely not respawned, acivated, initialized //var m = await Native.window.parent.postMessageAsync<TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine>(); // new IHTMLPre { // "inside iframe awaiting onmessage" //}.AttachToDocument(); var m = await Native.window.parent.postMessageAsync <TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine>(); var shadowstate = m.data; //var m = await Native.window.parent.async.onmessage; //var shadowstate = (TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine)m.data; new IHTMLPre { new { shadowstate.state } }.AttachToDocument(); // about to invoke #region xAsyncStateMachineType var xAsyncStateMachineType = typeof(Application).Assembly.GetTypes().FirstOrDefault( item => { // safety check 1 //Console.WriteLine(new { sw.ElapsedMilliseconds, item.FullName }); var xisIAsyncStateMachine = typeof(IAsyncStateMachine).IsAssignableFrom(item); if (xisIAsyncStateMachine) { //Console.WriteLine(new { item.FullName, isIAsyncStateMachine }); return(item.FullName == shadowstate.TypeName); } return(false); } ); #endregion var NewStateMachine = FormatterServices.GetUninitializedObject(xAsyncStateMachineType); var isIAsyncStateMachine = NewStateMachine is IAsyncStateMachine; var NewStateMachineI = (IAsyncStateMachine)NewStateMachine; #region 1__state xAsyncStateMachineType.GetFields( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ).WithEach( AsyncStateMachineSourceField => { Console.WriteLine(new { AsyncStateMachineSourceField }); if (AsyncStateMachineSourceField.Name.EndsWith("1__state")) { AsyncStateMachineSourceField.SetValue( NewStateMachineI, shadowstate.state ); } } ); #endregion NewStateMachineI.MoveNext(); // we can now send one hop back? } ); return; } var codetask = new WebClient().DownloadStringTaskAsync( new Uri(Worker.ScriptApplicationSource, UriKind.Relative) ); #region click to switch // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201510/20151026 new IHTMLButton { "click to switch" }.AttachToDocument().onclick += async delegate { Native.body.style.backgroundColor = "yellow"; // can we compile shaders in frames in parallel? var code = await codetask; var aFileParts = new[] { code }; var oMyBlob = new Blob(aFileParts, new { type = "text/javascript" }); //var url = oMyBlob.ToObjectURL(); var url = URL.createObjectURL(oMyBlob); var frame = new IHTMLIFrame { new XElement("script", new XAttribute("src", url), " ") }.AttachToDocument(); // can we our code in that blank document? // not fired for blank? await frame.async.onload; ////var x = frame.ownerDocument.createElement(IHTMLElement.HTMLElementEnum.button); ////x.AttachTo(frame.ownerDocument.documentElement); Native.body.style.backgroundColor = "cyan"; await(HopToIFrame) frame; var f = new IHTMLButton { "in the frame! click to notify parent" }.AttachToDocument(); // 134ms TypeError: Cannot set property 'outerscope' of null //var outerscope = "outerscope"; f.onclick += async delegate { var innerscope = "innerscope"; // can we jump back? // can we ask how many frames are there? // can we jump in any other frame? // if we jump back to another statemachine, can we reference the outer statemachine? // can we call the server? new IHTMLPre { "inside iframe about to jump to parent " + new { //outerscope, innerscope } }.AttachToDocument(); // never completes? await default(HopToParent); // cant see it? Console.WriteLine("are we back?"); new IHTMLPre { "iframe onclick, inside parent now" }.AttachToDocument(); // can we jump back? would we know where to jump back to? //await default(HopToIFrame); }; }; #endregion }; }
public Application(IApp page) { Native.body.Clear(); // X:\jsc.svn\examples\javascript\WebMessagingExample\WebMessagingExample\Application.cs Console.WriteLine( new { Native.window.parent } ); #region NewStateMachineI.MoveNext if (Native.window.parent != Native.window) { // we are an iframe? new { }.With( async delegate { var sw = Stopwatch.StartNew(); Console.WriteLine("postMessageAsync ... "); // start the handshake // we gain intellisense, but the type is partal, likely not respawned, acivated, initialized var m = await Native.window.parent.postMessageAsync <ShadowIAsyncStateMachine>(); var that = m.data; Console.WriteLine("postMessageAsync in " + new { sw.ElapsedMilliseconds, m.data.TypeName, m.data.state }); // ElapsedMilliseconds = 12, data = [object Object] }} // ElapsedMilliseconds = 13, TypeName = <Namespace>.___ctor_b__1_1_d, state = 0 }} // will we find the type based on typename? // or do we need typeindex? var types = typeof(Application).Assembly.GetTypes(); Console.WriteLine(new { sw.ElapsedMilliseconds, types = types.Length }); // X:\jsc.svn\examples\javascript\async\Test\TestSwitchToServiceContextAsync\TestSwitchToServiceContextAsync\CLRWebServiceInvoke.cs var xAsyncStateMachineType = types.FirstOrDefault( item => { // safety check 1 //Console.WriteLine(new { sw.ElapsedMilliseconds, item.FullName }); var xisIAsyncStateMachine = typeof(IAsyncStateMachine).IsAssignableFrom(item); if (xisIAsyncStateMachine) { //Console.WriteLine(new { item.FullName, isIAsyncStateMachine }); return(item.FullName == m.data.TypeName); } return(false); } ); // postMessageAsync in {{ ElapsedMilliseconds = 18, TypeName = <Namespace>.___ctor_b__1_1_d, state = 0 }} //{{ types = 77 }} //{{ FullName = <Namespace>.___ctor_b__1_0_d, isIAsyncStateMachine = true }} //{{ FullName = <Namespace>.___ctor_b__1_1_d, isIAsyncStateMachine = true }} //{{ FullName = <Namespace>.___cctor_b__1_d, isIAsyncStateMachine = true }} //Console.WriteLine(new { item.FullName, isIAsyncStateMachine }); Console.WriteLine("GetUninitializedObject " + new { sw.ElapsedMilliseconds, xAsyncStateMachineType }); var NewStateMachine = FormatterServices.GetUninitializedObject(xAsyncStateMachineType); var isIAsyncStateMachine = NewStateMachine is IAsyncStateMachine; Console.WriteLine(" " + new { sw.ElapsedMilliseconds, NewStateMachine, isIAsyncStateMachine }); // {{ ElapsedMilliseconds = 30, NewStateMachine = [object Object] }} //var NewStateMachine = Activator.CreateInstance(xAsyncStateMachineType); //var NewStateMachineI = NewStateMachine as IAsyncStateMachine; // bugcheck, as operator broken? var NewStateMachineI = (IAsyncStateMachine)NewStateMachine; Console.WriteLine(new { sw.ElapsedMilliseconds, NewStateMachineI }); Func <string, string> DecoratedString = x => x.Replace("-", "_").Replace("+", "_").Replace("<", "_").Replace(">", "_"); #region 1__state xAsyncStateMachineType.GetFields( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ).WithEach( AsyncStateMachineSourceField => { // we need to populate the data for the debugger? //var SourceField_value = AsyncStateMachineSourceField.GetValue(NewStateMachine); // it is a new type. Console.WriteLine(new { AsyncStateMachineSourceField }); if (AsyncStateMachineSourceField.Name.EndsWith("1__state")) { AsyncStateMachineSourceField.SetValue( NewStateMachineI, that.state ); } // field names/ tokens need to be encrypted like typeinfo. // or, are we supposed to initialize a string value here? // cannot move List via onmessage that easly... //var xStringField = that.StringFields.FirstOrDefault( // f => DecoratedString(f.FieldName) == DecoratedString(AsyncStateMachineSourceField.Name) // ); //if (xStringField != null) //{ // // once we are to go back to client. we need to reverse it? // AsyncStateMachineSourceField.SetValue( // NewStateMachineI, // xStringField.value // ); // // next xml? // // before lets send our strings back with the new state! // // what about exceptions? //} } ); #endregion // run it? Console.WriteLine(new { sw.ElapsedMilliseconds } +" call MoveNext.."); NewStateMachineI.MoveNext(); Console.WriteLine(new { sw.ElapsedMilliseconds } +" call MoveNext.. done"); } ); return; } #endregion // we are a window/tab? // X:\jsc.svn\examples\javascript\chrome\NestedIFrameExperiment\NestedIFrameExperiment\Application.cs new IHTMLButton { "click to switch" }.AttachToDocument().onclick += async delegate { Native.body.style.backgroundColor = "yellow"; new IHTMLPre { "on UI thread " + new { Native.document.location.href, Native.window.Width } }.AttachToDocument(); // could we sync // iprogress? // a chrome extenstion could inject itself like it to any tab? await default(HopToIFrame); // what about reload // css effects on iframe? // no scope data was synced at this point... // perhaps we should send struct data via postmessage and reattach interface methods later? // TypeError: Cannot set property 'sw' of null //var sw = Stopwatch.StartNew(); Native.window.history.replaceState(null, "iframe2", "/iframe2"); Native.body.style.borderLeft = "1em solid blue"; new IHTMLPre { "on iframe thread " + new { Native.document.location.href, Native.window.Width } , () => new { sw.ElapsedMilliseconds } }.AttachToDocument(); var b2 = new IHTMLButton { "click to switch to nested frame 2" }.AttachToDocument(); await b2.async.onclick; b2.disabled = true; // nested fram wont show up if url is the same as parent? await default(HopToIFrame); Native.body.style.borderLeft = "1em solid red"; new IHTMLPre { "on neste iframe thread " + new { Native.document.location.href, Native.window.Width } }.AttachToDocument(); // hop to parent? }; }