ui/wpf/UIcore/Application.cs

changeset 78
135920fe441b
child 81
5eb765a7a793
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/wpf/UIcore/Application.cs	Sat Jan 24 19:14:29 2015 +0100
@@ -0,0 +1,141 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+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 Running = false;
+        public String Name;
+        
+        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();
+            application.Run();
+        }
+
+        public void Run()
+        {
+            lock(sync)
+            {
+                for (;;)
+                {
+                    Monitor.Wait(sync);
+                    Action action = queue.Dequeue();
+                    action.Invoke();
+                    lock (result)
+                    {
+                        Monitor.Pulse(result);
+                    }
+                }
+            }
+        }
+
+        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 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();
+        }
+    }
+}

mercurial