13 private static Application instance; |
13 private static Application instance; |
14 |
14 |
15 private System.Windows.Application application; |
15 private System.Windows.Application application; |
16 |
16 |
17 private Thread thread; |
17 private Thread thread; |
18 private Queue<Action> queue = new Queue<Action>(); |
|
19 private object sync = new object(); |
|
20 private object result = new object(); |
|
21 private Boolean main = false; |
|
22 |
18 |
23 public String Name; |
19 public String Name; |
|
20 |
|
21 public IApplicationCallbacks callbacks; |
|
22 |
24 public List<Window> Windows = new List<Window>(); |
23 public List<Window> Windows = new List<Window>(); |
25 public ApplicationMenu Menu = new ApplicationMenu(); |
24 public ApplicationMenu Menu = new ApplicationMenu(); |
26 public MainToolBar ToolBar = new MainToolBar(); |
25 public MainToolBar ToolBar = new MainToolBar(); |
27 |
26 |
28 private Application() : base() |
27 private Application() : base() |
29 { |
28 { |
30 thread = new Thread(() => Run()); |
29 thread = new Thread(() => RunApplication()); |
31 thread.SetApartmentState(ApartmentState.STA); |
30 thread.SetApartmentState(ApartmentState.STA); |
32 thread.Start(); |
|
33 } |
31 } |
34 |
32 |
35 public static Application GetInstance() |
33 public static Application GetInstance() |
36 { |
34 { |
37 if (instance == null) |
35 if (instance == null) |
42 return instance; |
40 return instance; |
43 } |
41 } |
44 |
42 |
45 public Thread Start() |
43 public Thread Start() |
46 { |
44 { |
47 lock(sync) |
45 thread.Start(); |
48 { |
|
49 queue.Enqueue(() => RunApplication()); |
|
50 Monitor.Pulse(sync); |
|
51 } |
|
52 return thread; |
46 return thread; |
53 } |
47 } |
54 |
48 |
55 private void RunApplication() |
49 private void RunApplication() |
56 { |
50 { |
57 application = new System.Windows.Application(); |
51 application = new System.Windows.Application(); |
58 main = true; |
52 |
|
53 if(callbacks != null) |
|
54 { |
|
55 callbacks.OnStartup(); |
|
56 } |
59 application.Run(); |
57 application.Run(); |
60 } |
58 if(callbacks != null) |
61 |
|
62 public void Run() |
|
63 { |
|
64 lock(sync) |
|
65 { |
59 { |
66 for (;;) |
60 callbacks.OnExit(); |
67 { |
|
68 Monitor.Wait(sync); |
|
69 Action action = queue.Dequeue(); |
|
70 action.Invoke(); |
|
71 lock (result) |
|
72 { |
|
73 Monitor.Pulse(result); |
|
74 } |
|
75 if (main) |
|
76 { |
|
77 // end loop after shutdown |
|
78 break; |
|
79 } |
|
80 } |
|
81 } |
|
82 } |
|
83 |
|
84 public T Exec<T>(Func<T> func) |
|
85 { |
|
86 ResultExec<T> e = new ResultExec<T>(); |
|
87 e.Func = func; |
|
88 |
|
89 if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) |
|
90 { |
|
91 e.Exec(); |
|
92 return e.Result; |
|
93 } |
|
94 else |
|
95 { |
|
96 lock (sync) |
|
97 { |
|
98 queue.Enqueue(() => e.Exec()); |
|
99 Monitor.Pulse(sync); |
|
100 } |
|
101 lock (result) |
|
102 { |
|
103 Monitor.Wait(result); |
|
104 } |
|
105 |
|
106 return e.Result; |
|
107 } |
|
108 } |
|
109 |
|
110 public void Exec(Action action) |
|
111 { |
|
112 if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) |
|
113 { |
|
114 action.Invoke(); |
|
115 } |
|
116 else |
|
117 { |
|
118 lock (sync) |
|
119 { |
|
120 queue.Enqueue(action); |
|
121 Monitor.Pulse(sync); |
|
122 } |
|
123 lock (result) |
|
124 { |
|
125 Monitor.Wait(result); |
|
126 } |
|
127 } |
61 } |
128 } |
62 } |
129 |
63 |
130 public void AddWindow(Window window) |
64 public void AddWindow(Window window) |
131 { |
65 { |