/// <summary> /// Runs the given action on the UI thread and blocks the current thread while the action is running. /// If the current thread is the UI thread, the action will run immediately. /// </summary> /// <param name="action">The action to be run on the UI thread</param> internal static void BlockOnUIThread(Action action) { if (action == null) { throw new ArgumentNullException("action"); } #if (DIRECTX && !WINDOWS_PHONE) || PSM action(); #else // If we are already on the UI thread, just call the action and be done with it if (IsOnUIThread()) { try { action(); } catch (UnauthorizedAccessException ex) { // Need to be on a different thread #if WINDOWS_PHONE BlockOnContainerThread(Deployment.Current.Dispatcher, action); #else throw (ex); #endif } return; } #if IOS lock (BackgroundContext) { // Make the context current on this thread if it is not already if (!Object.ReferenceEquals(EAGLContext.CurrentContext, BackgroundContext)) { EAGLContext.SetCurrentContext(BackgroundContext); } // Execute the action action(); // Must flush the GL calls so the GPU asset is ready for the main context to use it GL.Flush(); GraphicsExtensions.CheckGLError(); } #elif WINDOWS || LINUX || ANGLE lock (BackgroundContext) { // Make the context current on this thread BackgroundContext.MakeCurrent(WindowInfo); // Execute the action action(); // Must flush the GL calls so the texture is ready for the main context to use GL.Flush(); GraphicsExtensions.CheckGLError(); // Must make the context not current on this thread or the next thread will get error 170 from the MakeCurrent call BackgroundContext.MakeCurrent(null); } #elif WINDOWS_PHONE BlockOnContainerThread(Deployment.Current.Dispatcher, action); #else ManualResetEventSlim resetEvent = new ManualResetEventSlim(false); #if MONOMAC MonoMac.AppKit.NSApplication.SharedApplication.BeginInvokeOnMainThread(() => #else Add(() => #endif { #if ANDROID //if (!Game.Instance.Window.GraphicsContext.IsCurrent) ((AndroidGameWindow)Game.Instance.Window).GameView.MakeCurrent(); #endif action(); resetEvent.Set(); }); resetEvent.Wait(); #endif #endif }
/// <summary> /// Runs the given action on the UI thread and blocks the current thread while the action is running. /// If the current thread is the UI thread, the action will run immediately. /// </summary> /// <param name="action">The action to be run on the UI thread</param> internal static void BlockOnUIThread(Action action) { if (action == null) { throw new ArgumentNullException("action"); } #if DIRECTX || PSM action(); #else // If we are already on the UI thread, just call the action and be done with it if (mainThreadId == Thread.CurrentThread.ManagedThreadId) { action(); return; } #if IOS lock (BackgroundContext) { // Make the context current on this thread if it is not already if (!Object.ReferenceEquals(EAGLContext.CurrentContext, BackgroundContext)) { EAGLContext.SetCurrentContext(BackgroundContext); } // Execute the action action(); // Must flush the GL calls so the GPU asset is ready for the main context to use it GL.Flush(); GraphicsExtensions.CheckGLError(); } #elif WINDOWS || LINUX lock (BackgroundContext) { // Make the context current on this thread BackgroundContext.MakeCurrent(WindowInfo); // Execute the action action(); // Must flush the GL calls so the texture is ready for the main context to use GL.Flush(); GraphicsExtensions.CheckGLError(); // Must make the context not current on this thread or the next thread will get error 170 from the MakeCurrent call BackgroundContext.MakeCurrent(null); } #elif !PORTABLE ManualResetEventSlim resetEvent = new ManualResetEventSlim(false); #if MONOMAC MonoMac.AppKit.NSApplication.SharedApplication.BeginInvokeOnMainThread(() => #else Add(() => #endif { #if ANDROID //if (!Game.Instance.Window.GraphicsContext.IsCurrent) Game.Instance.Window.MakeCurrent(); #endif action(); resetEvent.Set(); }); resetEvent.Wait(); #endif #endif }