macro_rules! pass_ids {
($($(#[$doc:meta])* $variant:ident => $name:literal,)*) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum PassId {
$($(#[$doc])* $variant,)*
}
pub const PASS_NAMES: [&str; PASS_COUNT] = [$($name,)*];
pub const PASS_COUNT: usize = [$(PassId::$variant,)*].len();
impl PassId {
pub const ALL: [PassId; PASS_COUNT] = [$(PassId::$variant,)*];
}
};
}
pass_ids! {
Cull => "cull",
Shadow => "shadow",
SsrPrepass => "ssr_prepass",
SsaoPrepass => "ssao_prepass",
SsaoKernel => "ssao_kernel",
SsaoBlur => "ssao_blur",
Main => "main",
AutoExposure => "auto_exposure",
Decals => "decals",
Fog => "fog",
ParticlesSim => "particles_sim",
ParticlesDraw => "particles_draw",
SsrResolve => "ssr_resolve",
Velocity => "velocity",
TaaResolve => "taa_resolve",
Bloom => "bloom",
Composite => "composite",
FogFroxel => "fog_froxel",
Upscale => "upscale",
Transparent => "transparent",
Raymarch => "raymarch",
HizBuild => "hiz_build",
Cull2 => "cull2",
Main2 => "main2",
Ssgi => "ssgi",
RtReflections => "rt_reflections",
GBufferPrepass => "gbuffer_prepass",
ReflectionComposite => "reflection_composite",
LightCull => "light_cull",
SpotShadow => "spot_shadow",
Lines => "lines",
HizFinal => "hiz_final",
}
impl PassId {
pub fn name(self) -> &'static str {
PASS_NAMES[self as usize]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_pass_id_indexes_its_own_name() {
for (i, &pass) in PassId::ALL.iter().enumerate() {
assert_eq!(pass as usize, i, "{pass:?} index out of order");
assert_eq!(pass.name(), PASS_NAMES[i], "{pass:?} name table mismatch");
assert!(!pass.name().is_empty(), "{pass:?} has an empty name");
}
assert_eq!(PASS_NAMES.len(), PASS_COUNT);
}
#[test]
fn pass_names_are_unique() {
let mut seen = hashbrown::HashSet::new();
for &name in PASS_NAMES.iter() {
assert!(seen.insert(name), "duplicate pass name {name:?}");
}
}
}