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