khora_data/ecs/
registry.rs

1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Defines the `ComponentRegistry` and `SemanticDomain` for the CRPECS.
16
17use crate::ecs::Component;
18use std::{any::TypeId, collections::HashMap};
19
20/// Defines the semantic domains a component can belong to.
21///
22/// This is used by the [`ComponentRegistry`] to map a component type to its
23/// corresponding `ComponentPage` group. This grouping is the core principle that
24/// allows the CRPECS to have fast, domain-specific queries.
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26pub enum SemanticDomain {
27    /// For components related to position, physics, and the scene graph.
28    Spatial,
29    /// For components related to rendering, such as mesh and material handles.
30    Render,
31}
32
33/// A registry that maps component types to their semantic domains.
34///
35/// This is a critical internal part of the `World`. It provides a single source
36/// of truth for determining which semantic group a component's data belongs to,
37/// enabling the `World` to correctly store and retrieve component data from pages.
38#[derive(Debug, Default)]
39pub struct ComponentRegistry {
40    /// The core map from a component's `TypeId` to its assigned `SemanticDomain`.
41    mapping: HashMap<TypeId, SemanticDomain>,
42}
43
44impl ComponentRegistry {
45    /// (Internal) Registers a component type with a specific semantic domain.
46    ///
47    /// This should be called by the engine or `World` setup logic for all known component types.
48    pub(crate) fn register<T: Component>(&mut self, domain: SemanticDomain) {
49        self.mapping.insert(TypeId::of::<T>(), domain);
50    }
51
52    /// (Internal) Looks up the `SemanticDomain` for a given component type.
53    pub fn domain_of<T: Component>(&self) -> Option<SemanticDomain> {
54        self.mapping.get(&TypeId::of::<T>()).copied()
55    }
56}