/synch/thread.d
D | 297 lines | 202 code | 69 blank | 26 comment | 17 complexity | c34cb2f64ba99c8374ef220c1cee74fe MD5 | raw file
1module synch.thread; 2 3import gui.window; 4 5// Awww... my only runtime dependency 6version(Tango) { 7 import Tango = tango.core.Thread; 8} 9else { 10 import Phobos = std.thread; 11} 12 13import platform.vars.thread; 14 15import scaffold.thread; 16 17// access to exception handler 18import analyzing.debugger; 19 20// Access to the threads array 21import core.main; 22import core.system; 23 24import io.console; 25 26// Section: Core/Synchronization 27 28// Description: This class represents a thread. You can create and override the call function to use, or use a delegate to specify an external function to call. 29class Thread { 30 31 // Description: Will create a normal thread that does not have any external callback functions. 32 this() { 33 stdThread = new overrideThread(); 34 stdThread.thread = this; 35 36 startTime = time = System.time; 37 } 38 39 // Description: Will create a thread using the given delegate as the callback function. 40 this(void delegate(bool) callback) { 41 _thread_callback = callback; 42 _thread_f_callback = null; 43 44 stdThread = new overrideThread(); 45 stdThread.thread = this; 46 47 startTime = time = System.time; 48 } 49 50 // Description: Will create a thread using the given function as the callback function. 51 this(void function(bool) callback) { 52 _thread_f_callback = callback; 53 _thread_callback = null; 54 55 stdThread = new overrideThread(); 56 stdThread.thread = this; 57 } 58 59 ~this() { 60 stop(); 61 } 62 63 // the common function for the thread 64 65 // Description: This will be called upon execution of the thread. Normally, it will call the delegate, but if overriden, you can provide a function within the class to use as the execution space. 66 void run() { 67 if (_thread_callback !is null) { 68 _thread_callback(false); 69 } 70 else if (_thread_f_callback !is null) { 71 _thread_f_callback(false); 72 } 73 74 _inited = false; 75 } 76 77 // Description: This will allow an arbitrary member function to be used as the execution space. 78 // callback: An address to a member function or a delegate literal. 79 void callback(void delegate(bool) callback) { 80 _thread_callback = callback; 81 _thread_f_callback = null; 82 } 83 84 // Description: This will allow an arbitrary function to be used as the execution space. 85 // callback: An address to a function or a function literal. 86 void callback(void function(bool) callback) { 87 _thread_f_callback = callback; 88 _thread_callback = null; 89 } 90 91 // Description: This function will tell whether or not the current thread being executed is the thread created via this class. 92 // Returns: Will return true when this thread is the current thread executing and false otherwise. 93 bool isCurrentThread() { 94 if (_inited) { 95 return this is this.current(); //return ThreadIsCurrent(_pfvars); 96 } 97 98 return false; 99 } 100 101 // Description: This function will yield the thread for a certain amount of time. 102 // milliseconds: The number of milliseconds to yield. 103 void sleep(ulong milliseconds) { 104 // we are given a long for length, windows only has an int function 105 if (_inited) { 106 ThreadSleep(_pfvars, milliseconds); 107 } 108 } 109 110 // Description: This function will start the thread and call the threadProc() function, which will in turn execute an external delegate if provided. 111 void start() { 112 if (!_inited) { 113 RegisterThread(this); 114 //ThreadStart(_pfvars, this); 115 116 startTime = time = System.time; 117 118 if (stdThread is null) { 119 stdThread = new overrideThread(); 120 } 121 122 _inited = true; 123 stdThread.start(); 124 } 125 } 126 127 // Description: This function will stop the thread prematurely. 128 void stop() { 129 if (_inited) { 130 //ThreadStop(_pfvars); 131 stdThread = null; 132 UnregisterThread(this); 133 } 134 _inited = false; 135 } 136 137 void pleaseStop() { 138 if (_thread_callback !is null) { 139 _thread_callback(true); 140 } 141 else if (_thread_f_callback !is null) { 142 _thread_f_callback(true); 143 } 144 } 145 146 long getElapsed() { 147 return System.time - time; 148 } 149 150 long getDelta() { 151 long oldTime = time; 152 time = System.time; 153 154 return time - oldTime; 155 } 156 157 static Thread current() { 158 Thread ret; 159 160 version(LDC) { 161 if (Tango.Thread.getThis() in threadById) { 162 ret = threadById[Tango.Thread.getThis()]; 163 } 164 } 165 else { 166 if (Phobos.Thread.getThis() in threadById) { 167 ret = threadById[Phobos.Thread.getThis()]; 168 } 169 } 170 171 if (ret is null) { 172 } 173 174 return ret; 175 } 176 177protected: 178 179 void delegate (bool) _thread_callback = null; 180 void function (bool) _thread_f_callback = null; 181 182 int _threadProc() { 183 run(); 184 185 stdThread = null; 186 187 return 0; 188 } 189 190 bool _inited; 191 192 long startTime; 193 long time; 194 195 Window wnd; 196 197 ThreadPlatformVars _pfvars; 198 199 overrideThread stdThread; 200 201 version(GNU) 202 { 203 } 204 version(LDC) 205 { 206 alias Tango.Thread RuntimeThread; 207 class overrideThread : Tango.Thread 208 { 209 Thread thread; 210 RuntimeThread runtimeThread; 211 212 this() { 213 super(&run); 214 } 215 216 void run() 217 { 218 threadById[Tango.Thread.getThis()] = thread; 219 220 try { 221 thread.run(); 222 } 223 catch (Object o) { 224 // Catch any unhandled exceptions 225 Debugger.raiseException(cast(Exception)o, thread.wnd, thread); 226 } 227 228 stdThread = null; 229 230 UnregisterThread(thread); 231 232 return; 233 } 234 } 235 } 236 else 237 { 238 alias Phobos.Thread RuntimeThread; 239 class overrideThread 240 { 241 Thread thread; 242 RuntimeThread runtimeThread; 243 244 this() { 245 runtimeThread = new Phobos.Thread(&run); 246 } 247 248 void start() { 249 runtimeThread.start(); 250 } 251 252 int run() { 253 threadById[Phobos.Thread.getThis()] = thread; 254 255 try { 256 thread.run(); 257 } 258 catch (Object o) { 259 // Catch any unhandled exceptions 260 Debugger.raiseException(cast(Exception)o, thread.wnd, thread); 261 } 262 263 stdThread = null; 264 265 UnregisterThread(thread); 266 267 return 0; 268 } 269 } 270 } 271 272 static Thread[RuntimeThread] threadById; 273} 274 275void ThreadModuleInit() { 276 277 // create a Thread for the main thread 278 Thread mainThread = new Thread(); 279 mainThread._inited = true; 280 281 version(Tango) { 282 mainThread.stdThread.runtimeThread = Tango.Thread.getThis(); 283 } 284 else { 285 mainThread.stdThread.runtimeThread = Phobos.Thread.getThis(); 286 } 287 288 Thread.threadById[mainThread.stdThread.runtimeThread] = mainThread; 289} 290 291void ThreadUninit(ref Thread t) { 292 t._inited = false; 293} 294 295void ThreadSetWindow(ref Thread t, Window w) { 296 t.wnd = w; 297}