Sun, 22 Jan 2017 11:48:50 +0100
adds new app callbacks (Motif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; namespace UI { public class Application { private static Application instance; private System.Windows.Application application; private Thread thread; private Queue<Action> queue = new Queue<Action>(); private object sync = new object(); private object result = new object(); private Boolean main = false; public String Name; public List<Window> Windows = new List<Window>(); public ApplicationMenu Menu = new ApplicationMenu(); public MainToolBar ToolBar = new MainToolBar(); private Application() : base() { thread = new Thread(() => Run()); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } public static Application GetInstance() { if (instance == null) { instance = new Application(); GC.KeepAlive(instance); } return instance; } public Thread Start() { lock(sync) { queue.Enqueue(() => RunApplication()); Monitor.Pulse(sync); } return thread; } private void RunApplication() { application = new System.Windows.Application(); main = true; application.Run(); } public void Run() { lock(sync) { for (;;) { Monitor.Wait(sync); Action action = queue.Dequeue(); action.Invoke(); lock (result) { Monitor.Pulse(result); } if (main) { // end loop after shutdown break; } } } } public T Exec<T>(Func<T> func) { ResultExec<T> e = new ResultExec<T>(); e.Func = func; if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) { e.Exec(); return e.Result; } else { lock (sync) { queue.Enqueue(() => e.Exec()); Monitor.Pulse(sync); } lock (result) { Monitor.Wait(result); } return e.Result; } } public void Exec(Action action) { if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) { action.Invoke(); } else { lock (sync) { queue.Enqueue(action); Monitor.Pulse(sync); } lock (result) { Monitor.Wait(result); } } } public void AddWindow(Window window) { Windows.Add(window); } public void RemoveWindow(Window window) { Windows.Remove(window); if (Windows.Count == 0) { application.Shutdown(); } } } public class ResultExec<T> { public T Result; public Func<T> Func; public void Exec() { Result = Func.Invoke(); } } public class VoidExec { public Action Action; public void Exec() { Action.Invoke(); } } }