1 /** 2 * License: 3 * $(TABLE 4 * $(TR $(TD cairoD wrapper/bindings) 5 * $(TD $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0))) 6 * $(TR $(TD $(LINK2 http://cgit.freedesktop.org/cairo/tree/COPYING, _cairo)) 7 * $(TD $(LINK2 http://cgit.freedesktop.org/cairo/tree/COPYING-LGPL-2.1, LGPL 2.1) / 8 * $(LINK2 http://cgit.freedesktop.org/cairo/plain/COPYING-MPL-1.1, MPL 1.1))) 9 * ) 10 * Authors: 11 * $(TABLE 12 * $(TR $(TD Johannes Pfau) $(TD cairoD)) 13 * $(TR $(TD $(LINK2 http://cairographics.org, _cairo team)) $(TD _cairo)) 14 * ) 15 */ 16 /* 17 * Distributed under the Boost Software License, Version 1.0. 18 * (See accompanying file LICENSE_1_0.txt or copy at 19 * http://www.boost.org/LICENSE_1_0.txt) 20 */ 21 module cairo.util; 22 23 /** 24 * Mixin used by cairoD classes which wrap a reference counted 25 * cairo handle. 26 */ 27 mixin template CairoCountedClass(T, string prefix) 28 { 29 protected: 30 /** 31 * Reference count. For use in child classes 32 */ 33 @property uint _count() 34 { 35 mixin("return " ~ prefix ~ "get_reference_count(this.nativePointer);"); 36 } 37 38 /** 39 * Increase reference count. For use in child classes 40 */ 41 void _reference() 42 { 43 mixin(prefix ~ "reference(this.nativePointer);"); 44 } 45 46 /** 47 * Decrease reference count. For use in child classes 48 */ 49 void _dereference() 50 { 51 mixin(prefix ~ "destroy(this.nativePointer);"); 52 } 53 54 public: 55 /** 56 * The underlying $(T) handle 57 */ 58 T nativePointer; 59 version(D_Ddoc) 60 { 61 /** 62 * Enable / disable memory management debugging for this 63 * instance. Only available if both cairoD and the cairoD user 64 * code were compiled with "debug=RefCounted" 65 * 66 * Output is written to stdout, see 67 * $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#debugging) 68 * for more information 69 */ 70 bool debugging; 71 } 72 else debug(RefCounted) 73 { 74 bool debugging; 75 } 76 77 /** 78 * Explicitly drecrease the reference count. 79 * 80 * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#3-RC-class) 81 * for more information. 82 */ 83 void dispose() 84 { 85 debug(RefCounted) 86 { 87 if(this.debugging && this.nativePointer is null) 88 writeln(typeof(this).stringof, 89 "@", cast(void*)this, ": dispose() Already disposed"); 90 } 91 if(this.nativePointer !is null) 92 { 93 debug(RefCounted) 94 { 95 if(this.debugging) 96 writeln(typeof(this).stringof, 97 "@", cast(void*)this, ": dispose() Cairo reference count is: ", 98 this._count); 99 } 100 mixin(prefix ~ "destroy(this.nativePointer);"); 101 this.nativePointer = null; 102 } 103 } 104 105 /** 106 * Destructor. Call $(D dispose()) if it hasn't been called manually. 107 */ 108 ~this() 109 { 110 debug(RefCounted) 111 { 112 if(this.debugging) 113 writeln(typeof(this).stringof, 114 "@", cast(void*)this, ": Destructor called"); 115 } 116 dispose(); 117 } 118 } 119 120 /** 121 * Checks whether TargetType matches any subsequent types. 122 * Use as: isOneOf!(TargetType, Type1, Type2..); 123 */ 124 template isOneOf(X, T...) 125 { 126 static if (!T.length) 127 enum bool isOneOf = false; 128 else static if (is (X == T[0])) 129 enum bool isOneOf = true; 130 else 131 enum bool isOneOf = isOneOf!(X, T[1..$]); 132 }