1 // Copyright © 2017 Rémi Thebault 2 module wayland.util; 3 4 import wayland.native.util; 5 6 /// Implemented by type that wrap a native wayland struct pointer. 7 interface Native(wl_native) 8 { 9 /// Access the wrapped struct. 10 @property inout(wl_native)* native() inout; 11 } 12 13 /// Utility mixin that implements Native for a type. 14 mixin template nativeImpl(wl_native) 15 { 16 private wl_native* _native; 17 18 public final override @property inout(wl_native)* native() inout 19 { 20 return _native; 21 } 22 } 23 24 25 immutable class WlInterface 26 { 27 immutable wl_interface* _native; 28 29 immutable this(immutable wl_interface* native) 30 { 31 this._native = native; 32 } 33 34 @property immutable(wl_interface)* native() immutable 35 { 36 return _native; 37 } 38 39 @property string name() immutable 40 { 41 import std.string : fromStringz; 42 return fromStringz(_native.name); 43 } 44 } 45 46 /+ 47 + Wraps a function literal into a try-catch statement. 48 + 49 + Use this in functions called by C as exception cannot propagate there. 50 + The try-catch statement will print a warning if an exception is thrown. 51 + The try-catch statement will terminate runtime and exit program if an error is thrown. 52 +/ 53 auto nothrowFnWrapper(alias fn)() nothrow 54 { 55 try 56 { 57 return fn(); 58 } 59 catch(Exception ex) 60 { 61 import std.exception : collectException; 62 import std.stdio : stderr; 63 collectException(stderr.writeln("wayland-d: error in listener stub: "~ex.msg)); 64 } 65 catch(Throwable err) 66 { 67 import core.runtime : Runtime; 68 import core.stdc.stdlib : exit; 69 import std.exception : collectException; 70 import std.stdio : stderr; 71 collectException(stderr.writeln("wayland-d: aborting due to error in listener stub: "~err.msg)); 72 collectException(Runtime.terminate()); 73 exit(1); 74 } 75 alias rt = typeof(fn()); 76 static if (!is(rt == void)) 77 { 78 return rt.init; 79 } 80 } 81 82 83 84 /// static cache of objects that are looked-up by the address of their native 85 /// counter part 86 struct ObjectCache 87 { 88 private __gshared Object[void*] _cache; 89 90 static void set (void* native, Object obj) 91 { 92 _cache[native] = obj; 93 } 94 95 static Object get (void* native) 96 { 97 auto op = native in _cache; 98 return op ? *op : null; 99 } 100 101 static void remove (void* native) 102 { 103 _cache.remove(native); 104 } 105 } 106 107 /** 108 * Fixed-point number 109 * 110 * A `WlFixed` is a 24.8 signed fixed-point number with a sign bit, 23 bits 111 * of integer precision and 8 bits of decimal precision. 112 */ 113 struct WlFixed 114 { 115 private uint _raw; 116 private union DI 117 { 118 long i; 119 double d; 120 } 121 122 public this(uint raw) 123 { 124 _raw = raw; 125 } 126 127 /** 128 * Converts an integer to a fixed-point number. 129 */ 130 public static WlFixed create(in int val) 131 { 132 return WlFixed(val * 256); 133 } 134 135 /** 136 * Converts a floating-point number to a fixed-point number. 137 */ 138 public static WlFixed create(in double val) 139 { 140 DI u; 141 u.d = val + (3L << (51 - 8)); 142 return WlFixed(cast(uint)(u.i)); 143 } 144 145 @property uint raw() const 146 { 147 return _raw; 148 } 149 150 /** 151 * Converts a fixed-point number to an integer. 152 */ 153 int opCast(T : int)() const 154 { 155 return _raw / 256; 156 } 157 158 /** 159 * Converts a fixed-point number to a floating-point number. 160 */ 161 double opCast(T : double)() const 162 { 163 DI u; 164 u.i = ((1023L + 44L) << 52) + (1L << 51) + f; 165 return u.d - (3L << 43); 166 } 167 }