1 module wayland.server.listener;
2 
3 import wayland.native.server;
4 import wayland.native.util;
5 import wayland.util;
6 
7 
8 class WlListener : Native!wl_listener
9 {
10     alias NotifyDg = void delegate(void* data);
11 
12     private wl_listener _native;
13     private NotifyDg _notify;
14 
15     this()
16     {
17         wl_list_init(&_native.link);
18         _native.notify = &wl_d_listener_notify;
19     }
20 
21     this(NotifyDg notify)
22     {
23         this();
24         _notify = notify;
25     }
26 
27     @property inout(wl_listener*) native() inout
28     {
29         return &_native;
30     }
31 
32     @property NotifyDg notify()
33     {
34         return _notify;
35     }
36 
37     @property void notify(NotifyDg notify)
38     {
39         _notify = notify;
40     }
41 }
42 
43 class WlSignal : Native!wl_signal
44 {
45     private wl_signal _native;
46     WlListener[] _listeners;
47 
48     this()
49     {
50         wl_signal_init(&_native);
51     }
52 
53     @property inout(wl_signal*) native() inout
54     {
55         return &_native;
56     }
57 
58     void add(WlListener listener)
59     {
60         wl_signal_add(native, listener.native);
61         _listeners ~= listener;
62     }
63 
64     WlListener get(WlListener.NotifyDg notify)
65     {
66         foreach(l; _listeners)
67         {
68             if (l._notify is notify)
69             {
70                 return l;
71             }
72         }
73         return null;
74     }
75 
76     void emit(void* data)
77     {
78         wl_signal_emit(native, data);
79     }
80 }
81 
82 class Signal(Args...)
83 {
84     alias Listener = void delegate(Args args);
85 
86     private Listener[] _listeners;
87 
88     this() {}
89 
90     void add(Listener listener)
91     {
92         _listeners ~= listener;
93     }
94 
95     void emit(Args args)
96     {
97         foreach(l; _listeners)
98         {
99             l(args);
100         }
101     }
102 }
103 
104 private extern(C) nothrow
105 {
106     void wl_d_listener_notify(wl_listener* l, void* data)
107     {
108         nothrowFnWrapper!({
109             auto dl = cast(WlListener)(
110                 cast(void*)l - WlListener._native.offsetof
111             );
112             assert(dl && (l is &dl._native));
113             if (dl._notify) dl._notify(data);
114         });
115     }
116 }