Skip to content

Commit 2faf74a

Browse files
committed
Functional: Add more utility to the Vector classes.
Includes a minor breaking change, however I believe it to be worth it.
1 parent 4ff44e3 commit 2faf74a

19 files changed

+3763
-210
lines changed

functional/generate_vector_classes.sh

Lines changed: 217 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This file exists to generate all of the Vector classes (Vector3f, Vector3d, etc).
22

33
template_vectorClass="/*
4-
Copyright 2022 Casterlabs
4+
Copyright 2024 Casterlabs
55
66
Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License.
77
You may obtain a copy of the License at
@@ -12,33 +12,219 @@ Unless required by applicable law or agreed to in writing, software distributed
1212
See the License for the specific language governing permissions and limitations under the License.
1313
*/
1414
15-
// This class was auto-generated by \"generate_vector_classes.sh\".
16-
// DO NOT edit this file directly! Instead, edit the template at the top of the generator script.
17-
1815
package co.casterlabs.commons.functional.vectors;
1916
20-
import lombok.AllArgsConstructor;
21-
import lombok.NoArgsConstructor;
17+
import lombok.NonNull;
18+
import lombok.RequiredArgsConstructor;
19+
import lombok.ToString;
20+
21+
// This class was auto-generated by \"generate_vector_classes.sh\".
22+
// DO NOT edit this file directly! Instead, edit the template at the top of the generator script.
2223
2324
/**
24-
* A Vector class with *size components: *fieldNames. This class is mutable.
25+
* A Vector class with *size components: *fieldNames. This class is immutable.
2526
*/
26-
@NoArgsConstructor
27-
@AllArgsConstructor
27+
@ToString
28+
@RequiredArgsConstructor
2829
public class Vector*size*type_s {
29-
public *type *fieldNames;
30+
public final *type *fieldNames;
31+
32+
public final int components = *size;
3033
34+
/**
35+
* Constructs a vector, using the provided array for the fields.
36+
* @apiNote the array must be at least *size elements long.
37+
*/
38+
public Vector*size*type_s(@NonNull *type[] arr) {
39+
this(*arrSpread);
40+
}
41+
3142
/**
3243
* @return An array with all *size components.
3344
*/
3445
public *type[] toArray() {
3546
return new *type[] { *fieldNames };
3647
}
48+
49+
/* -------------------- */
50+
/* Math */
51+
/* -------------------- */
52+
53+
/**
54+
* Adds the given vector with this one, returning a new vector with the result.
55+
*/
56+
public Vector*size*type_s add(@NonNull Vector*size*type_s other) {
57+
*type[] arr = this.toArray();
58+
*type[] otherArr = other.toArray();
59+
60+
for (int idx = 0; idx < this.components; idx++) {
61+
arr[idx] += otherArr[idx];
62+
}
63+
64+
return new Vector*size*type_s(arr);
65+
}
66+
67+
/**
68+
* Subtracts the given vector with this one, returning a new vector with the result.
69+
*/
70+
public Vector*size*type_s sub(@NonNull Vector*size*type_s other) {
71+
*type[] arr = this.toArray();
72+
*type[] otherArr = other.toArray();
73+
74+
for (int idx = 0; idx < this.components; idx++) {
75+
arr[idx] -= otherArr[idx];
76+
}
77+
78+
return new Vector*size*type_s(arr);
79+
}
80+
81+
/**
82+
* Multiplies this vector with given number, returning a new vector with the result.
83+
*/
84+
public Vector*size*type_s mul(*type by) {
85+
*type[] arr = this.toArray();
86+
87+
for (int idx = 0; idx < this.components; idx++) {
88+
arr[idx] *= by;
89+
}
90+
91+
return new Vector*size*type_s(arr);
92+
}
93+
94+
/**
95+
* Divides this vector with given number, returning a new vector with the result.
96+
*/
97+
public Vector*size*type_s div(*type by) {
98+
*type[] arr = this.toArray();
99+
100+
for (int idx = 0; idx < this.components; idx++) {
101+
arr[idx] /= by;
102+
}
103+
104+
return new Vector*size*type_s(arr);
105+
}
106+
107+
/**
108+
* @implNote Not guaranteed to be strict (or accurate). This has the advantage
109+
* of possibly being faster than software-based strict math.
110+
*/
111+
public *type magnitude() {
112+
*mathType mag = 0;
113+
114+
*type[] thisArr = this.toArray();
115+
for (int idx = 0; idx < this.components; idx++) {
116+
mag += thisArr[idx] * thisArr[idx];
117+
}
118+
119+
return (*type) Math.sqrt(mag);
120+
}
121+
122+
/**
123+
* @implNote Performs a strict sqrt to get the resulting magnitude.
124+
*/
125+
public *type magnitude_strict() {
126+
*mathType mag = 0;
127+
128+
*type[] thisArr = this.toArray();
129+
for (int idx = 0; idx < this.components; idx++) {
130+
mag += thisArr[idx] * thisArr[idx];
131+
}
132+
133+
return (*type) StrictMath.sqrt(mag);
134+
}
135+
136+
/* -------------------- */
137+
/* Conversions */
138+
/* -------------------- */
139+
140+
/**
141+
* Converts this vector to a byte vector.
142+
*/
143+
public Vector*sizeb toByteVector() {
144+
byte[] arr = new byte[this.components];
145+
*type[] thisArr = this.toArray();
146+
147+
for (int idx = 0; idx < this.components; idx++) {
148+
arr[idx] = (byte) thisArr[idx];
149+
}
150+
151+
return new Vector*sizeb(arr);
152+
}
153+
154+
/**
155+
* Converts this vector to a short vector.
156+
*/
157+
public Vector*sizes toShortVector() {
158+
short[] arr = new short[this.components];
159+
*type[] thisArr = this.toArray();
160+
161+
for (int idx = 0; idx < this.components; idx++) {
162+
arr[idx] = (short) thisArr[idx];
163+
}
164+
165+
return new Vector*sizes(arr);
166+
}
167+
168+
/**
169+
* Converts this vector to a int vector.
170+
*/
171+
public Vector*sizei toIntVector() {
172+
int[] arr = new int[this.components];
173+
*type[] thisArr = this.toArray();
174+
175+
for (int idx = 0; idx < this.components; idx++) {
176+
arr[idx] = (int) thisArr[idx];
177+
}
178+
179+
return new Vector*sizei(arr);
180+
}
181+
182+
/**
183+
* Converts this vector to a float vector.
184+
*/
185+
public Vector*sizef toFloatVector() {
186+
float[] arr = new float[this.components];
187+
*type[] thisArr = this.toArray();
188+
189+
for (int idx = 0; idx < this.components; idx++) {
190+
arr[idx] = (float) thisArr[idx];
191+
}
192+
193+
return new Vector*sizef(arr);
194+
}
195+
196+
/**
197+
* Converts this vector to a long vector.
198+
*/
199+
public Vector*sizel toLongVector() {
200+
long[] arr = new long[this.components];
201+
*type[] thisArr = this.toArray();
202+
203+
for (int idx = 0; idx < this.components; idx++) {
204+
arr[idx] = (long) thisArr[idx];
205+
}
206+
207+
return new Vector*sizel(arr);
208+
}
209+
210+
/**
211+
* Converts this vector to a double vector.
212+
*/
213+
public Vector*sized toDoubleVector() {
214+
double[] arr = new double[this.components];
215+
*type[] thisArr = this.toArray();
216+
217+
for (int idx = 0; idx < this.components; idx++) {
218+
arr[idx] = (double) thisArr[idx];
219+
}
220+
221+
return new Vector*sized(arr);
222+
}
37223
38224
}"
39225

40226
dataTypes=("byte" "short" "int" "float" "long" "double")
41-
allFieldNames=(_ "a" "b" "c" "d")
227+
allFieldNames=(_ "x" "y" "z" "w" "v" "u" "t" "s" "r" "q" "p")
42228
sizes=(2 3 4)
43229

44230
baseDir="src/main/java/co/casterlabs/commons/functional/vectors"
@@ -56,21 +242,40 @@ for size in ${sizes[@]}; do
56242
fieldName=${allFieldNames[$idx]}
57243
fieldNames="$fieldNames, $fieldName"
58244
done
59-
# Turn ", a, b, ..." into "a, b, ...""
245+
# Turn ", a, b, ..." into "a, b, ..."
60246
fieldNames=${fieldNames:2}
61247

248+
# Build the arrSpread string. When done, this looks like:
249+
# , arr[0], arr[1] ...
250+
arrSpread=""
251+
for idx in $(seq $size); do
252+
arrSpread="$arrSpread, arr[$idx]"
253+
done
254+
# Turn ", arr[0], arr[1] ..." into "arr[0], arr[1] ..."
255+
arrSpread=${arrSpread:2}
256+
62257
# Generate the template, replacing the `*size`, `*fields`, and `*fieldNames` placeholders.
63258
template="$template_vectorClass";
64259
template="${template//"*size"/$size}";
65260
template="${template//"*fieldNames"/$fieldNames}";
261+
template="${template//"*arrSpread"/$arrSpread}";
66262

67263
for type in ${dataTypes[@]}; do
68264
type_s=${type:0:1}
265+
266+
floatTypes=("double" "float")
267+
if [[ ${floatTypes[@]} =~ $type ]]
268+
then
269+
mathType="double"
270+
else
271+
mathType="long"
272+
fi
69273

70274
# Generate the class file, replacing the remaining placeholders.
71275
classFile="$template"
72276
classFile="${classFile//"*type_s"/$type_s}"
73277
classFile="${classFile//"*type"/$type}"
278+
classFile="${classFile//"*mathType"/$mathType}"
74279

75280
fileName="Vector$size$type_s.java"
76281

0 commit comments

Comments
 (0)