1 /**
2 * This module defines the notion of a $(PALETTE). $(PALETTE)s abstract the
3 * process of determining how to render the $(I cells) in a $(LATTICE) by the
4 * $(RENDERER), Allowing for more customization.
5 *
6 * It provides templates for testing whether a given object is a $(PALETTE),
7 * and what kind of $(PALETTE) it is.
8 *
9 * $(CALIB_ABSTRACT_DESC)
10 *
11 * Macros:
12 * IS_ANY = 
13 *     Tests if something is a $(B $0).
14 *     $(DDOC_BLANKLINE)
15 *     returns $(DDOC_BACKQUOTED true) if $(DDOC_BACKQUOTED T) is a $(B $0) where
16 *     the value specifing how a $(RENDERER) should display a $(I cell) can be of
17 *     any type. The $(I cell) can also be of any type.
18 *     $(DDOC_BLANKLINE)
19 *     This template is the same as $(B is$0) but the type of the display-value and
20 *     type of the $(I cells) need not be specified. Refer to $(B is$0) for more details about
21 *     what a $(B $0) is.
22 *     $(DDOC_BLANKLINE)
23 *     $(DDOC_PARAMS T type to be tested)
24 *     $(DDOC_RETURNS $(B true) if $(B T) is any $(B $0), $(B false) if not)
25 */
26 
27 module caLib_abstract.palette;
28 
29 import caLib_abstract.util : hasCellStateType, isCellStateTypesCompatible,
30     hasDisplayValueType, isDisplayValueTypesCompatible;
31 import caLib_util.structs : Color;
32 
33 
34 
35 /**
36 * Tests if something is a $(B Palette).
37 *
38 * Returns `true` if `T` is a $(B Palette) where `Dv` is the type of the value
39 * specifing how a $(RENDERER) should display a $(I cell) of type `Ct`
40 *
41 * A $(B Palette) is the most basic for of a $(PALETTE) defining the primitives: $(BR)
42 * `Dv getDisplayValue(string behaviour)(Ct cellState)` and
43 * `Dv getDisplayValue(Ct cellState)` where `Dv` is the type of the value describing
44 * how the cell `cellState` of type `Ct` should be rendererd.
45 *
46 * Params:
47 *	  T  = type to be tested
48 *     Ct = type of the cell
49 *     Dv = type whoms value describes how a cell of type Ct should be rendererd
50 *
51 * Returns: true if T is a $(B Neighbourhood), false if not
52 */
53 template isPalette(T, Ct, Dv)
54 {
55 	enum isPalette = 
56 		hasCellStateType!T &&
57 		hasDisplayValueType!T &&
58 		is(typeof(T.init.getDisplayValue!"_test"(Ct.init)) : Dv) &&
59 		is(typeof(T.init.getDisplayValue(Ct.init)) : Dv);
60 }
61 
62 unittest
63 {
64 	static assert( isPalette!(Palette!(string, byte), string, byte));
65 	static assert( isPalette!(Palette!(string, int), string, uint));
66 	static assert(!isPalette!(Palette!(string, int), int, string));
67 	static assert(!isPalette!(char[], int, int));
68 }
69 
70 
71 
72 ///$(IS_ANY Palette)
73 template isAnyPalette(T)
74 {
75 	static if(hasCellStateType!T && hasDisplayValueType!T)
76 	{
77 		enum isAnyPalette = isPalette!(T, T.CellStateType, T.DisplayValueType);
78 	}
79 	else
80 	{
81 		enum isAnyPalette = false;
82 	}
83 }
84 
85 unittest
86 {
87 	static assert( isAnyPalette!(Palette!(int, uint)));
88 	static assert(!isAnyPalette!string); 
89 }
90 
91 
92 
93 /// Example of a $(B Palette)
94 struct Palette(Ct, Dv)
95 {	
96 	alias CellStateType = Ct;
97 	alias DisplayValueType = Dv;
98 
99 	Dv getDisplayValue(string behaviour)(Ct cellState) { return Dv.init; }
100 	Dv getDisplayValue(Ct cellState) { return Dv.init; }
101 }
102 
103 ///
104 unittest
105 {
106 	alias palette = Palette!(int, char);
107 
108 	assert(isPalette!(palette, int, char));
109 	assert(isAnyPalette!(palette));
110 }
111 
112 
113 
114 /**
115 * Convinience template, same as $(B isPalette) but `Dv` is set to be of type
116 *`Color`.
117 *
118 * In almost all cases a $(PALETTE) will decide in what color a $(RENDERER) should
119 * render the $(LATTICE)s $(I cells). Thus this enum is added for convinience.
120 */
121 enum isColorPalette(T, Ct) = isPalette!(T, Ct, Color);
122 
123 
124 
125 ///$(IS_ANY ColorPalette)
126 template isAnyColorPalette(T)
127 {
128 	static if(hasDisplayValueType!T && is(T.DisplayValueType == Color))
129 	{
130 		enum isAnyColorPalette = isAnyPalette!(T);
131 	}
132 	else
133 	{
134 		enum isAnyColorPalette = false;
135 	}
136 }
137 
138 ///
139 unittest
140 {
141 	// a palette template
142 	struct A(Ct, Dv) {
143 		Dv getDisplayValue(string behaviour)(Ct cellState) {
144 			return Ct.init;
145 		}
146 
147 		Dv getDisplayValue(Ct cellState) { return getDisplayValue!""(cellState); }
148 	}
149 
150 	bool a =       isAnyPalette!(A!(int, byte)); // true for any values of A
151 	bool b = !isAnyColorPalette!(A!(int, int )); // false since A!(int, int ) does not return uint 
152 	bool c = !isAnyColorPalette!(A!(int, uint)); // true  since A!(int, uint) does     return uint
153 }
154 
155 
156 
157 /// Example of a $(B ColorPalette)
158 struct ColorPalette(Ct)
159 {	
160 	alias CellStateType = Ct;
161 	alias DisplayValueType = Color;
162 
163 	Color getDisplayValue(string behaviour)(Ct cellState) { return Color(0); }
164 	Color getDisplayValue(Ct cellState) { return Color(0); }
165 }
166 
167 ///
168 unittest
169 {
170 	alias palette = ColorPalette!(int);
171 
172 	assert(isPalette!(palette, int, Color));
173 	assert(isColorPalette!(palette, int));
174 	assert(isAnyColorPalette!(palette));
175 }