- renamed aa to offset
[FaRetSys.git] / Engine.cs
blob881c601aaf45098558d6700bda6c8a2c2d518836
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 Plugin.Base 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)
81 Plugin.Lock();
82 t.Abort();
83 Plugin.Unlock();
86 b.Working = false;
87 MainWindow.RedrawSchematic();
90 public bool Finished
92 get
94 if(finished)
95 return true;
97 try
99 if(t.Join(0))
101 finished = true;
102 b.Working = false;
104 if(Error != null)
105 throw Error;
107 MainWindow.RedrawSchematic();
110 catch(Exception e)
112 engine.Stop();
114 b.ShowError = true;
115 MainWindow.RedrawSchematic();
116 new PluginError(e, b, false);
117 finished = true;
120 return finished;
125 class Engine2
127 private static int ConfigThreads = Config.Get("engine/threads", 2);
128 private static bool ConfigProgress = Config.Get("block/progress", true);
129 private Schematic s;
130 private ArrayList Threads = new ArrayList();
131 private bool stop = false;
132 private bool running = false;
133 private FinishCallback finish;
134 private Progress progress;
135 private DateTime start, end;
137 public delegate void FinishCallback();
138 public delegate void Progress();
140 public Engine2(Schematic s, FinishCallback finish, Progress progress)
142 this.s = s;
143 this.finish = finish;
144 this.progress = progress;
147 private bool Tick()
149 if(stop)
151 running = false;
152 end = DateTime.Now;
153 finish();
154 return false;
157 // check if any thread has finished work
158 for(int i=Threads.Count-1; i>=0; i--)
159 if(((EngineThread)Threads[i]).Finished)
161 // in case of error working is stopped
162 if(stop)
164 running = false;
165 end = DateTime.Now;
166 finish();
167 return false;
170 Threads.RemoveAt(i);
173 // if there are free slots for threads try to fill them
174 if(Threads.Count < ConfigThreads)
176 ArrayList Blocks = s.Blocks;
178 for(int i=0; i<Blocks.Count; i++)
180 // check if there are free threads
181 if(Threads.Count >= ConfigThreads)
182 break;
184 Block b = (Block)Blocks[i];
186 if(b.CheckState() == Block.State.Ready && b.Working != true)
187 Threads.Add(new EngineThread(this, b));
191 // check if there are some threads left
192 if(Threads.Count == 0)
194 running = false;
195 end = DateTime.Now;
196 finish();
197 return false;
200 progress();
202 if(ConfigProgress)
203 MainWindow.RedrawSchematic();
205 return true;
208 public void Start()
210 // shouldn't happen
211 if(running)
212 throw new Exception(Catalog.GetString("Engine is already running."));
214 start = DateTime.Now;
216 ArrayList Blocks = s.Blocks;
218 stop = false;
219 running = true;
221 // check all blocks and add ones ready to work to the thread list
222 for(int i=0; i<Blocks.Count; i++)
224 // check if there are free threads
225 if(Threads.Count >= ConfigThreads)
226 break;
228 Block b = (Block)Blocks[i];
230 if(b.CheckState() == Block.State.Ready)
231 Threads.Add(new EngineThread(this, b));
234 // check threads status every 50 ms
235 GLib.Timeout.Add(50, new GLib.TimeoutHandler(Tick));
238 // stops all threads
239 public void Stop()
241 stop = true;
243 foreach(EngineThread t in Threads)
244 t.Stop();
246 Threads.RemoveRange(0, Threads.Count);
249 public static void CheckGConf()
251 ConfigThreads = Config.Get("engine/threads", 2);
252 ConfigProgress = Config.Get("block/progress", true);
255 public bool Running
257 get { return running; }
260 public string ElapsedTime
264 TimeSpan ts = end - start;
266 if(ts.Days == 0)
267 if(ts.Hours == 0)
268 if(ts.Minutes == 0)
269 return String.Format("{0:00}.{1}", ts.Seconds, ts.Milliseconds);
270 else
271 return String.Format("{0:00}:{1:00}.{2}", ts.Minutes, ts.Seconds, ts.Milliseconds);
272 else
273 return String.Format("{0:00}:{1:00}:{2:00}.{3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
274 else
275 return String.Format("{0}.{1:00}:{2:00}:{3:00}.{4}", ts.Days, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);