- add progress to histogram
[FaRetSys.git] / Engine.cs
blob9b396abe45077fcfd386dc14baf4489efc0c2854
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 Progress progress;
130 private DateTime start, end;
132 public delegate void FinishCallback();
133 public delegate void Progress();
135 public Engine2(Schematic s, FinishCallback finish, Progress progress)
137 this.s = s;
138 this.finish = finish;
139 this.progress = progress;
142 private bool Tick()
144 if(stop)
146 running = false;
147 end = DateTime.Now;
148 finish();
149 return false;
152 // sprawdzenie, czy jakiś wątek nie skończył pracy
153 for(int i=Threads.Count-1; i>=0; i--)
154 if(((EngineThread)Threads[i]).Finished)
156 // w przypadku błędu praca jest skończona
157 if(stop)
159 running = false;
160 end = DateTime.Now;
161 finish();
162 return false;
165 Threads.RemoveAt(i);
168 // jeżeli są jakieś wolne sloty na wątki, to trzeba spróbować je wypełnić
169 if(Threads.Count < ConfigThreads)
171 ArrayList Blocks = s.Blocks;
173 for(int i=0; i<Blocks.Count; i++)
175 // sprawdzenie czy są wolne wątki
176 if(Threads.Count >= ConfigThreads)
177 break;
179 Block b = (Block)Blocks[i];
181 if(b.CheckState() == Block.State.Ready && b.Working != true)
182 Threads.Add(new EngineThread(this, b));
186 // sprawdzenie czy zostały jakieś wątki
187 if(Threads.Count == 0)
189 running = false;
190 end = DateTime.Now;
191 finish();
192 return false;
195 progress();
197 return true;
200 public void Start()
202 // nie powinno nigdy się zdarzyć
203 if(running)
204 throw new Exception(Catalog.GetString("Engine is already running."));
206 start = DateTime.Now;
208 ArrayList Blocks = s.Blocks;
210 stop = false;
211 running = true;
213 // przejrzenie wszystkich bloków i dodanie gotowych do pracy do listy wątków
214 for(int i=0; i<Blocks.Count; i++)
216 // sprawdzenie czy są wolne wątki
217 if(Threads.Count >= ConfigThreads)
218 break;
220 Block b = (Block)Blocks[i];
222 if(b.CheckState() == Block.State.Ready)
223 Threads.Add(new EngineThread(this, b));
226 // sprawdzanie stanu wątków co 50 ms
227 GLib.Timeout.Add(50, new GLib.TimeoutHandler(Tick));
230 // zatrzymuje wszystkie wątki
231 public void Stop()
233 stop = true;
235 foreach(EngineThread t in Threads)
236 t.Stop();
238 Threads.RemoveRange(0, Threads.Count);
241 public static void CheckGConf()
243 ConfigThreads = Config.Get("engine/threads", 1);
246 public bool Running
248 get { return running; }
251 public string ElapsedTime
255 TimeSpan ts = end - start;
257 if(ts.Days == 0)
258 if(ts.Hours == 0)
259 if(ts.Minutes == 0)
260 return String.Format("{0:00}.{1}", ts.Seconds, ts.Milliseconds);
261 else
262 return String.Format("{0:00}:{1:00}.{2}", ts.Minutes, ts.Seconds, ts.Milliseconds);
263 else
264 return String.Format("{0:00}:{1:00}:{2:00}.{3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
265 else
266 return String.Format("{0}.{1:00}:{2:00}:{3:00}.{4}", ts.Days, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);