- cosmetics
[FaRetSys.git] / Engine.cs
blob0f697f3af9ebd95d8a8d7b83360b2c823a6aa436
1 using System;
2 using System.Collections;
3 using System.Threading;
4 using Gtk;
5 using Mono.Unix;
7 namespace Eithne
9 class EngineThread
11 private IPlugin Plugin;
12 private Block b;
13 private Thread t;
14 private Exception Error;
15 private Engine2 engine;
16 private bool finished = false;
18 private void ThreadedWork()
20 Error = null;
22 try
24 Plugin.Work();
26 catch(Exception e)
28 Error = e;
32 public EngineThread(Engine2 engine, Block b)
34 this.b = b;
35 this.engine = engine;
37 b.Working = true;
38 MainWindow.RedrawSchematic();
40 try
42 if(b.Plugin.NumIn != 0)
44 CommSocket cs = new CommSocket(b.Plugin.NumIn);
46 for(int i=0; i<b.Plugin.NumIn; i++)
48 Socket other = b.SocketIn[i].Other;
50 if(other.Parent.Plugin.Out == null)
52 b.Working = false;
53 b = other.Parent;
54 throw new PluginException(Catalog.GetString("Plugin has no data on output sockets."));
57 cs[i] = other.Parent.Plugin.Out[other.Num];
60 b.Plugin.In = cs;
63 Plugin = b.Plugin;
64 t = new Thread(ThreadedWork);
65 t.Start();
67 catch(Exception e)
69 engine.Stop();
71 b.ShowError = true;
72 MainWindow.RedrawSchematic();
73 new PluginError(e, b, false);
77 public void Stop()
79 if(!finished)
80 t.Abort();
82 b.Working = false;
83 MainWindow.RedrawSchematic();
86 public bool Finished
88 get
90 if(finished)
91 return true;
93 try
95 if(t.Join(0))
97 finished = true;
98 b.Working = false;
100 if(Error != null)
101 throw Error;
103 MainWindow.RedrawSchematic();
106 catch(Exception e)
108 engine.Stop();
110 b.ShowError = true;
111 MainWindow.RedrawSchematic();
112 new PluginError(e, b, false);
113 finished = true;
116 return finished;
121 class Engine2
123 private static int ConfigThreads = Config.Get("engine/threads", 1);
124 private Schematic s;
125 private ArrayList Threads = new ArrayList();
126 private bool stop = false;
127 private bool running = false;
128 private FinishCallback finish;
129 private DateTime start, end;
131 public delegate void FinishCallback();
133 public Engine2(Schematic s, FinishCallback finish)
135 this.s = s;
136 this.finish = finish;
139 private bool Tick()
141 if(stop)
143 running = false;
144 end = DateTime.Now;
145 finish();
146 return false;
149 // sprawdzenie, czy jakiś wątek nie skończył pracy
150 for(int i=Threads.Count-1; i>=0; i--)
151 if(((EngineThread)Threads[i]).Finished)
153 // w przypadku błędu praca jest skończona
154 if(stop)
156 running = false;
157 end = DateTime.Now;
158 finish();
159 return false;
162 Threads.RemoveAt(i);
165 // jeżeli są jakieś wolne sloty na wątki, to trzeba spróbować je wypełnić
166 if(Threads.Count < ConfigThreads)
168 ArrayList Blocks = s.Blocks;
170 for(int i=0; i<Blocks.Count; i++)
172 // sprawdzenie czy są wolne wątki
173 if(Threads.Count >= ConfigThreads)
174 break;
176 Block b = (Block)Blocks[i];
178 if(b.CheckState() == Block.State.Ready && b.Working != true)
179 Threads.Add(new EngineThread(this, b));
183 // sprawdzenie czy zostały jakieś wątki
184 if(Threads.Count == 0)
186 running = false;
187 end = DateTime.Now;
188 finish();
189 return false;
192 return true;
195 public void Start()
197 // nie powinno nigdy się zdarzyć
198 if(running)
199 throw new Exception(Catalog.GetString("Engine is already running."));
201 start = DateTime.Now;
203 ArrayList Blocks = s.Blocks;
205 stop = false;
206 running = true;
208 // przejrzenie wszystkich bloków i dodanie gotowych do pracy do listy wątków
209 for(int i=0; i<Blocks.Count; i++)
211 // sprawdzenie czy są wolne wątki
212 if(Threads.Count >= ConfigThreads)
213 break;
215 Block b = (Block)Blocks[i];
217 if(b.CheckState() == Block.State.Ready)
218 Threads.Add(new EngineThread(this, b));
221 // sprawdzanie stanu wątków co 50 ms
222 GLib.Timeout.Add(50, new GLib.TimeoutHandler(Tick));
225 // zatrzymuje wszystkie wątki
226 public void Stop()
228 stop = true;
230 foreach(EngineThread t in Threads)
231 t.Stop();
233 Threads.RemoveRange(0, Threads.Count);
236 public static void CheckGConf()
238 ConfigThreads = Config.Get("engine/threads", 1);
241 public bool Running
243 get { return running; }
246 public string ElapsedTime
250 TimeSpan ts = end - start;
252 if(ts.Days == 0)
253 if(ts.Hours == 0)
254 if(ts.Minutes == 0)
255 return String.Format("{0:00}.{1}", ts.Seconds, ts.Milliseconds);
256 else
257 return String.Format("{0:00}:{1:00}.{2}", ts.Minutes, ts.Seconds, ts.Milliseconds);
258 else
259 return String.Format("{0:00}:{1:00}:{2:00}.{3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
260 else
261 return String.Format("{0}.{1:00}:{2:00}:{3:00}.{4}", ts.Days, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);