1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using Xwt; 10 using System.Threading; 11 using System.Collections.Concurrent; 12 using Antmicro.Renode.Exceptions; 13 14 namespace Antmicro.Renode.UI 15 { 16 public static class ApplicationExtensions 17 { ApplicationExtensions()18 static ApplicationExtensions() 19 { 20 actionsToRunInUIThread = new BlockingCollection<Action>(); 21 var t = new Thread(() => 22 { 23 while(true) 24 { 25 var a = actionsToRunInUIThread.Take(); 26 Application.Invoke(a); 27 } 28 }); 29 t.IsBackground = true; 30 t.Name = "ApplicationExtensions GUI invoker"; 31 t.Start(); 32 } 33 InvokeInUIThread(Action action)34 public static void InvokeInUIThread(Action action) 35 { 36 CheckXwtStatus(); 37 if(Thread.CurrentThread.ManagedThreadId == XwtProvider.UiThreadId) 38 { 39 action(); 40 } 41 else 42 { 43 Application.Invoke(action); 44 } 45 } 46 InvokeInUIThreadNonBlocking(Action action)47 public static void InvokeInUIThreadNonBlocking(Action action) 48 { 49 CheckXwtStatus(); 50 if(Thread.CurrentThread.ManagedThreadId == XwtProvider.UiThreadId) 51 { 52 actionsToRunInUIThread.Add(action); 53 } 54 else 55 { 56 Application.Invoke(action); 57 } 58 } 59 InvokeInUIThreadAndWait(Func<T> function)60 public static T InvokeInUIThreadAndWait<T>(Func<T> function) 61 { 62 CheckXwtStatus(); 63 if(Thread.CurrentThread.ManagedThreadId == XwtProvider.UiThreadId) 64 { 65 return function(); 66 } 67 68 T result = default(T); 69 var mre = new ManualResetEventSlim(); 70 71 Application.Invoke(() => 72 { 73 result = function(); 74 mre.Set(); 75 }); 76 77 mre.Wait(); 78 return result; 79 } 80 InvokeInUIThreadAndWait(Action action)81 public static void InvokeInUIThreadAndWait(Action action) 82 { 83 CheckXwtStatus(); 84 if(Thread.CurrentThread.ManagedThreadId == XwtProvider.UiThreadId) 85 { 86 action(); 87 return; 88 } 89 90 var mre = new ManualResetEventSlim(); 91 Application.Invoke(() => 92 { 93 action(); 94 mre.Set(); 95 }); 96 97 mre.Wait(); 98 } 99 CheckXwtStatus()100 private static void CheckXwtStatus() 101 { 102 if(XwtProvider.UiThreadId == -1) 103 { 104 throw new RecoverableException("An action requiring GUI environment detected, but the XWT provider is not started."); 105 } 106 } 107 108 private static BlockingCollection<Action> actionsToRunInUIThread; 109 } 110 } 111 112