12547b5bcb
the binary size by approximately 20% by default.
96 lines
3.7 KiB
Rust
96 lines
3.7 KiB
Rust
use std::fs::File;
|
|
use std::io::Write;
|
|
use std::path::Path;
|
|
use std::env;
|
|
use std::string::String;
|
|
|
|
/// Generate the name of the swizzle function and what it returns.
|
|
/// NOTE: This function assumes that variables are in ASCII format
|
|
#[cfg(feature = "swizzle")]
|
|
fn gen_swizzle_nth<'a>(variables: &'a str, mut i: usize, upto: usize) -> Option<(String, String)> {
|
|
debug_assert!(i > 0); // zeroth permutation is empty
|
|
let mut swizzle_impl = String::new();
|
|
let mut swizzle = String::new();
|
|
let n = variables.len()+1;
|
|
for _ in 0..upto {
|
|
if i == 0 { break; }
|
|
if i % n == 0 { return None; }
|
|
let c = variables.as_bytes()[i%n - 1] as char;
|
|
swizzle.push(c);
|
|
swizzle_impl.push_str(&format!("self.{}, ", c));
|
|
i = i/n;
|
|
}
|
|
Some((swizzle, swizzle_impl))
|
|
}
|
|
|
|
/// A function that generates swizzle functions as a string.
|
|
/// `variables`: swizzle variables (e.g. "xyz")
|
|
/// `upto`: largest output vector size (e.g. for `variables = "xy"` and `upto = 4`, `xyxy()` is a
|
|
/// valid swizzle operator.
|
|
/// NOTE: This function assumes that variables are in ASCII format
|
|
#[cfg(feature = "swizzle")]
|
|
fn gen_swizzle_functions(variables: &'static str, upto: usize) -> String {
|
|
let mut result = String::new();
|
|
let nn = (variables.len()+1).pow(upto as u32);
|
|
for i in 1..nn {
|
|
if let Some((swizzle_name, swizzle_impl)) = gen_swizzle_nth(variables, i, upto) {
|
|
let dim = format!("{}", swizzle_name.len());
|
|
result.push_str(
|
|
&format!("
|
|
/// Swizzle operator that creates a new type with dimension {2} from variables `{0}`.
|
|
#[inline] pub fn {0}(&self) -> $vector_type{2}<$S> {{ $vector_type{2}::new({1}) }}\n",
|
|
swizzle_name, swizzle_impl, dim));
|
|
}
|
|
}
|
|
result
|
|
}
|
|
|
|
#[cfg(not(feature = "swizzle"))]
|
|
fn gen_swizzle_functions(_: &'static str, _: usize) -> String {
|
|
String::new()
|
|
}
|
|
|
|
|
|
/// This script generates the macro for building swizzle operators for multidimensional
|
|
/// vectors and points. This macro is included in macros.rs
|
|
fn main() {
|
|
// save the file to output directory
|
|
let out_dir = env::var("OUT_DIR").unwrap();
|
|
let swizzle_file_path = Path::new(&out_dir).join("swizzle_operator_macro.rs");
|
|
|
|
// This is the string representing the generated macro
|
|
let data = format!(
|
|
"/// Generate glm/glsl style swizzle operators
|
|
macro_rules! impl_swizzle_functions {{
|
|
($vector_type1:ident, $vector_type2:ident, $vector_type3:ident, $S:ident, x) => {{
|
|
{x3}
|
|
}};
|
|
($vector_type1:ident, $vector_type2:ident, $vector_type3:ident, $S:ident, xy) => {{
|
|
{xy3}
|
|
}};
|
|
($vector_type1:ident, $vector_type2:ident, $vector_type3:ident, $S:ident, xyz) => {{
|
|
{xyz3}
|
|
}};
|
|
($vector_type1:ident, $vector_type2:ident, $vector_type3:ident, $vector_type4:ident, $S:ident, x) => {{
|
|
{x4}
|
|
}};
|
|
($vector_type1:ident, $vector_type2:ident, $vector_type3:ident, $vector_type4:ident, $S:ident, xy) => {{
|
|
{xy4}
|
|
}};
|
|
($vector_type1:ident, $vector_type2:ident, $vector_type3:ident, $vector_type4:ident, $S:ident, xyz) => {{
|
|
{xyz4}
|
|
}};
|
|
($vector_type1:ident, $vector_type2:ident, $vector_type3:ident, $vector_type4:ident, $S:ident, xyzw) => {{
|
|
{xyzw4}
|
|
}};
|
|
}}", x3 = gen_swizzle_functions("x", 3),
|
|
xy3 = gen_swizzle_functions("xy", 3),
|
|
xyz3 = gen_swizzle_functions("xyz", 3),
|
|
x4 = gen_swizzle_functions("x", 4),
|
|
xy4 = gen_swizzle_functions("xy", 4),
|
|
xyz4 = gen_swizzle_functions("xyz", 4),
|
|
xyzw4 = gen_swizzle_functions("xyzw", 4));
|
|
let mut f = File::create(swizzle_file_path)
|
|
.expect("Unable to create file that defines the swizzle operator macro.");
|
|
f.write_all(data.as_bytes()).expect("Unable to write swizzle operator macro.");
|
|
}
|