1 module poison.core.threading;
2 
3 import std.concurrency : send, receive, Tid, thisTid, receiveTimeout;
4 import core.thread : dur;
5 
6 import poison.core.action;
7 
8 package(poison.core) {
9   /// The tid of the ui thread.
10   __gshared Tid _uiTid;
11 }
12 
13 /// Checks whether the current thread is the UI thread.
14 @property bool isUIThread() {
15   return thisTid == _uiTid;
16 }
17 
18 /**
19 * Executes an action on the UI thread.
20 * Params:
21 *   f = The function pointer to execute.
22 */
23 void executeUI(void function() f) {
24   executeUI(new Action(f));
25 }
26 
27 /**
28 * Executes an action on the UI thread.
29 * Params:
30 *   d = The delegate to execute.
31 */
32 void executeUI(void delegate() d) {
33   executeUI(new Action(d));
34 }
35 
36 /**
37 * Executes an action on the UI thread.
38 * Params:
39 *   action =  The action to execute.
40 */
41 void executeUI(Action action) {
42   if (isUIThread) {
43     action();
44     return;
45   }
46 
47   send(_uiTid, cast(shared)action);
48 }
49 
50 /**
51 * Receives a concurrent message non-blocking.
52 * Params:
53 *   ops = The message ops.
54 */
55 private void receiveNonBlocking(T...)(T ops) {
56     receiveTimeout(
57         dur!("nsecs")(-1),
58         ops
59     );
60 }
61 
62 /// Receives all messages for the current thread and executes them.
63 void receiveMessages() {
64   receiveNonBlocking(
65     (shared(Action) a) { (cast(Action)a)(); }
66   );
67 }