primase-core 0.2.0

primase core: the world store, core components, frames, the pass manager and gates
Documentation
//! Every component and resource core declares, by the name each declares for itself ([`Component::NAME`],
//! [`Resource::NAME`]): what a coverage report lists, whether or not a reader, pass or writer mentions it. The types
//! are listed once here; an architecture test holds the list to every `Component` and `Resource` core implements.

use crate::IncomingTransition;
use crate::asset::Asset;
use crate::atmosphere::{Atmosphere, PostProcessingStatus};
use crate::clip::{Clip, ClipBinding};
use crate::clip_effects::ClipEffects;
use crate::clip_events::ClipEvents;
use crate::clip_identity::{ClipKey, ClipLength};
use crate::collider::{Collider, Heightfield};
use crate::components::{
    Collision, Instance, Light, MaterialVariants, Mesh, MeshFile, Name, Shadows, Source, Surfaces, Texture,
    TextureAbsent, TextureFile, Tile, Transform,
};
use crate::content::{ContentNote, DisplayName, Record};
use crate::controller::{Controller, ControllerBinding};
use crate::convert::{PartScope, PartitionPlan};
use crate::detail::DetailedMaterial;
use crate::draw_groups::{DrawGroupDefaults, DrawGroups};
use crate::draw_order::DrawOrder;
use crate::environment::{Environment, TimeOfDay};
use crate::irradiance_volume::IrradianceVolume;
use crate::layered::LayeredMaterial;
use crate::light_unit::{DirectionalLightUnit, LightUnit};
use crate::lod::Lods;
use crate::lod_switch::{LodSwitch, LodSwitchView};
use crate::marker::{Curve, Marker};
use crate::material_parameters::MaterialParameters;
use crate::material_usage::MaterialUsage;
use crate::morphs::Morphs;
use crate::opening::OpeningSuggestions;
use crate::particles::ParticleSystem;
use crate::pass::memo::Memo;
use crate::pbr::PbrMaterial;
use crate::primitive_keys::PrimitiveKeys;
use crate::priority::Priority;
use crate::provenance::Provenance;
use crate::read_scope::ReadScopes;
use crate::reflection_probe::ReflectionProbeRegion;
use crate::render_graph::RenderGraph;
use crate::rig::{
    Attachment, JointMap, JointPlacement, MorphWeights, RigInstance, RigPose, SkinInstance, Sockets,
};
use crate::shader::{
    LiftedShader, MaterialPrograms, ProgramFacts, ProgramFrame, Shader, ShaderBinding, ShaderDerivation,
    ShaderSpecialisations,
};
use crate::skeleton::{AssemblyReference, Skeleton};
use crate::skin::Skin;
use crate::sky_anchor::SkyAnchor;
use crate::state::{Condition, PrimitiveCondition, StateAssignment, StateAxis, StateOverride};
use crate::step_bindings::{StepBindings, StepDraws};
use crate::texture_forms::TextureForms;
use crate::texture_layers::TextureLayers;
use crate::texture_switch::{TextureSwitch, TextureSwitchView};
use crate::vertex_color::VertexColor;
use crate::world::{Component, Resource};
use crate::{LightFalloff, LightTranslucency, SpotFrustum, WaterBody};
use primase_foundations::parallel::Threads;

/// What a name of core's names: a component (on entities) or a resource (one per world).
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Declared {
    Component,
    Resource,
}

macro_rules! declared {
    (components: $($c:ident),* $(,)?; resources: $($r:ident),* $(,)?) => {
        /// Every component and resource core declares, by its name, in the order listed.
        pub fn names() -> Vec<(&'static str, Declared)> {
            vec![
                $((<$c as Component>::NAME, Declared::Component),)*
                $((<$r as Resource>::NAME, Declared::Resource),)*
            ]
        }

        /// The types [`names`] lists, by their names in the source (for the architecture test that holds the list
        /// to core's implementations).
        pub const LISTED: &[&str] = &[$(stringify!($c),)* $(stringify!($r),)*];
    };
}

declared! {
    components: Collider, Heightfield, Name, Source, Transform, Instance, Shadows, Mesh, Texture, Light, Collision,
        TextureFile, TextureAbsent, MeshFile, MaterialVariants, Tile, DrawOrder, LayeredMaterial, Lods, LodSwitch, TextureForms, TextureSwitch, Marker, Curve, MaterialUsage,
        PbrMaterial, DetailedMaterial, Priority, Provenance, StateAxis, Condition, PrimitiveCondition, StateOverride, VertexColor, Skeleton, AssemblyReference, Skin, Morphs, RigInstance,
        RigPose, SkinInstance, MorphWeights, Sockets, Attachment, JointMap, JointPlacement, Clip, ClipBinding, Asset, Shader, ShaderBinding, LiftedShader, ShaderSpecialisations, ShaderDerivation,
        TextureLayers, MaterialPrograms, ProgramFacts, ClipKey, ClipLength, IncomingTransition, ClipEvents, ClipEffects, Controller, ControllerBinding,
        DrawGroups, DrawGroupDefaults, ContentNote, Record, DisplayName, PrimitiveKeys, MaterialParameters, SkyAnchor,
        ParticleSystem, IrradianceVolume, ReflectionProbeRegion, StepBindings, StepDraws, LightFalloff, LightTranslucency, SpotFrustum, WaterBody;
    resources: PartScope, PartitionPlan, Environment, Atmosphere, PostProcessingStatus, StateAssignment, Surfaces, Threads, Memo, RenderGraph,
        LightUnit, DirectionalLightUnit, TimeOfDay, TextureSwitchView, LodSwitchView, ReadScopes, OpeningSuggestions, ProgramFrame,
}

#[cfg(test)]
mod tests {
    use super::*;

    /// Each name is listed once, and every listed type is a distinct name.
    #[test]
    fn every_name_once() {
        let names = names();
        let set: std::collections::BTreeSet<&str> = names.iter().map(|(n, _)| *n).collect();
        assert_eq!(set.len(), names.len());
        assert_eq!(names.len(), LISTED.len());
        assert!(
            set.contains("core.mesh") && set.contains("pbr.material") && set.contains("core.environment")
        );
    }

    #[test]
    fn animation_and_content_types_are_listed_with_their_storage_kind() {
        let names = names();
        for name in [
            "core.clip_key",
            "core.clip_length",
            "core.incoming_transition",
            "core.clip_events",
            "core.controller",
            "core.controller_binding",
            "core.draw_groups",
            "core.draw_group_defaults",
            "core.content_note",
            "core.record",
            "core.display_name",
            "core.primitive_keys",
            "core.material_parameters",
        ] {
            assert!(names.contains(&(name, Declared::Component)), "{name}");
        }
        assert!(!names.iter().any(|(name, _)| *name == "core.clip_catalog"));
    }
}