1 /** 2 * Module for vectors. 3 * 4 * Authors: 5 * Jacob Jensen 6 * License: 7 * https://github.com/PoisonEngine/poison-ui/blob/master/LICENSE 8 */ 9 module poison.core.vector; 10 11 /** 12 * Vector mixin template to create vector types. 13 * Params: 14 * T = The type of the vector. 15 * names = The names of all members of the vector. 16 */ 17 private mixin template Vector(T, string[] names) { 18 /// Format for members. 19 enum memberFormat = q{ 20 private %s _%s; 21 }; 22 23 /// Format for properties. 24 enum propertyFormat = q{ 25 @property { 26 public auto %s() { return _%s; } 27 28 public void %s(%s newValue) { _%s = newValue; } 29 } 30 }; 31 32 /// Format for parameters. 33 enum paramFormat = "%s %s,"; 34 35 /// Format for member sets. 36 enum memberSetFormat = "_%s = %s;"; 37 38 /// Generates the constructor. 39 static string generateConstructor() { 40 import std..string : format; 41 42 auto paramsString = ""; 43 auto memberSetString = ""; 44 45 foreach (name; names) { 46 paramsString ~= paramFormat.format(T.stringof, name); 47 48 memberSetString ~= memberSetFormat.format(name, name); 49 } 50 51 if (paramsString) { 52 paramsString.length -= 1; 53 } 54 55 return "this(" ~ paramsString ~ ") { " ~ memberSetString ~ " }"; 56 } 57 58 mixin(generateConstructor); 59 60 /// Generates the members. 61 static string generateMembers() { 62 import std..string : format; 63 64 auto membersString = ""; 65 66 foreach (name; names) { 67 membersString ~= memberFormat.format(T.stringof, name); 68 } 69 70 return membersString; 71 } 72 73 mixin(generateMembers); 74 75 /// Generates the properties. 76 static string generateProperties() { 77 import std..string : format; 78 79 auto propertiesString = ""; 80 81 foreach (name; names) { 82 propertiesString ~= propertyFormat.format(name, name, name, T.stringof, name); 83 } 84 85 return propertiesString; 86 } 87 88 mixin(generateProperties); 89 } 90 91 /// A 2d point vector. 92 private class Point2dVector(T) { 93 mixin Vector!(T, ["x", "y"]); 94 } 95 96 /// Alias to create a 2d point vector of ptrdiff_t. 97 public alias Point = Point2dVector!ptrdiff_t; 98 99 /// Alias to create a 2d point vector of float. 100 public alias PointF = Point2dVector!float; 101 102 /// A 3d point vector. 103 private class Point3dVector(T) { 104 mixin Vector!(T, ["x", "y", "z"]); 105 } 106 107 /// Alias to create a 3d point vector of ptrdiff_t. 108 public alias Point3d = Point3dVector!ptrdiff_t; 109 110 /// Alias to create a 3d point vector of float. 111 public alias Point3dF = Point3dVector!float; 112 113 /// A 2d size vector. 114 private class Size2dVector(T) { 115 mixin Vector!(T, ["width", "height"]); 116 } 117 118 /// Alias to create a 2d size vector of size_t. 119 public alias Size = Size2dVector!size_t; 120 121 /// Alias to create a 2d size vector of float. 122 public alias SizeF = Size2dVector!float; 123 124 /// A 3d size vector. 125 private class Size3dVector(T) { 126 mixin Vector!(T, ["width", "height", "depth"]); 127 } 128 129 /// Alias to create a 3d size vector of size_t. 130 public alias Size3d = Size3dVector!size_t; 131 132 /// Alias to create a 3d size vector of float. 133 public alias Size3dF = Size3dVector!float; 134 135 /// An edge vector. 136 private class EdgeVector(T) { 137 mixin Vector!(T, ["top", "right", "bottom", "left"]); 138 } 139 140 /// Alias to create an edge vector of ptrdiff_t. 141 public alias Edge = EdgeVector!ptrdiff_t; 142 143 /// Alias to create an edge vector of float. 144 public alias EdgeF = EdgeVector!float;