- add progress to edge, dct and fft plugins
[FaRetSys.git] / Engine.cs
blobd345463d6d4a66cb9e4925fa6e327b4324323c6f
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 static bool ConfigProgress = Config.Get("block/progress", true);
125 private Schematic s;
126 private ArrayList Threads = new ArrayList();
127 private bool stop = false;
128 private bool running = false;
129 private FinishCallback finish;
130 private Progress progress;
131 private DateTime start, end;
133 public delegate void FinishCallback();
134 public delegate void Progress();
136 public Engine2(Schematic s, FinishCallback finish, Progress progress)
138 this.s = s;
139 this.finish = finish;
140 this.progress = progress;
143 private bool Tick()
145 if(stop)
147 running = false;
148 end = DateTime.Now;
149 finish();
150 return false;
153 // sprawdzenie, czy jakiś wątek nie skończył pracy
154 for(int i=Threads.Count-1; i>=0; i--)
155 if(((EngineThread)Threads[i]).Finished)
157 // w przypadku błędu praca jest skończona
158 if(stop)
160 running = false;
161 end = DateTime.Now;
162 finish();
163 return false;
166 Threads.RemoveAt(i);
169 // jeżeli są jakieś wolne sloty na wątki, to trzeba spróbować je wypełnić
170 if(Threads.Count < ConfigThreads)
172 ArrayList Blocks = s.Blocks;
174 for(int i=0; i<Blocks.Count; i++)
176 // sprawdzenie czy są wolne wątki
177 if(Threads.Count >= ConfigThreads)
178 break;
180 Block b = (Block)Blocks[i];
182 if(b.CheckState() == Block.State.Ready && b.Working != true)
183 Threads.Add(new EngineThread(this, b));
187 // sprawdzenie czy zostały jakieś wątki
188 if(Threads.Count == 0)
190 running = false;
191 end = DateTime.Now;
192 finish();
193 return false;
196 progress();
198 if(ConfigProgress)
199 MainWindow.RedrawSchematic();
201 return true;
204 public void Start()
206 // nie powinno nigdy się zdarzyć
207 if(running)
208 throw new Exception(Catalog.GetString("Engine is already running."));
210 start = DateTime.Now;
212 ArrayList Blocks = s.Blocks;
214 stop = false;
215 running = true;
217 // przejrzenie wszystkich bloków i dodanie gotowych do pracy do listy wątków
218 for(int i=0; i<Blocks.Count; i++)
220 // sprawdzenie czy są wolne wątki
221 if(Threads.Count >= ConfigThreads)
222 break;
224 Block b = (Block)Blocks[i];
226 if(b.CheckState() == Block.State.Ready)
227 Threads.Add(new EngineThread(this, b));
230 // sprawdzanie stanu wątków co 50 ms
231 GLib.Timeout.Add(50, new GLib.TimeoutHandler(Tick));
234 // zatrzymuje wszystkie wątki
235 public void Stop()
237 stop = true;
239 foreach(EngineThread t in Threads)
240 t.Stop();
242 Threads.RemoveRange(0, Threads.Count);
245 public static void CheckGConf()
247 ConfigThreads = Config.Get("engine/threads", 1);
248 ConfigProgress = Config.Get("block/progress", true);
251 public bool Running
253 get { return running; }
256 public string ElapsedTime
260 TimeSpan ts = end - start;
262 if(ts.Days == 0)
263 if(ts.Hours == 0)
264 if(ts.Minutes == 0)
265 return String.Format("{0:00}.{1}", ts.Seconds, ts.Milliseconds);
266 else
267 return String.Format("{0:00}:{1:00}.{2}", ts.Minutes, ts.Seconds, ts.Milliseconds);
268 else
269 return String.Format("{0:00}:{1:00}:{2:00}.{3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
270 else
271 return String.Format("{0}.{1:00}:{2:00}:{3:00}.{4}", ts.Days, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);