Skip to main content

khora_data/ecs/components/
light.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 Light component for the ECS.
16//!
17//! This component represents a light source attached to an entity in the scene.
18//! The entity's `GlobalTransform` provides the position and orientation of the light.
19
20use khora_core::renderer::light::LightType;
21use khora_macros::Component;
22
23/// A component that adds a light source to an entity.
24///
25/// This component works in conjunction with the entity's `GlobalTransform`
26/// to determine the light's world-space position and orientation.
27///
28/// # Examples
29///
30/// ```ignore
31/// use khora_data::ecs::components::Light;
32/// use khora_core::renderer::light::{LightType, DirectionalLight};
33///
34/// // Create a sun light
35/// let sun_light = Light {
36///     light_type: LightType::Directional(DirectionalLight::default()),
37///     enabled: true,
38/// };
39/// ```
40#[derive(Debug, Clone, Component)]
41#[component(domain = Render)]
42pub struct Light {
43    /// The type and properties of the light source.
44    pub light_type: LightType,
45
46    /// Whether the light is currently active.
47    ///
48    /// Disabled lights are not extracted for rendering and have no
49    /// performance impact on the scene.
50    pub enabled: bool,
51}
52
53impl Default for Light {
54    fn default() -> Self {
55        Self {
56            light_type: LightType::default(),
57            enabled: true,
58        }
59    }
60}
61
62impl Light {
63    /// Creates a new enabled light with the given type.
64    pub fn new(light_type: LightType) -> Self {
65        Self {
66            light_type,
67            enabled: true,
68        }
69    }
70
71    /// Creates a new directional light (sun-like).
72    pub fn directional() -> Self {
73        Self::new(LightType::Directional(
74            khora_core::renderer::light::DirectionalLight::default(),
75        ))
76    }
77
78    /// Creates a new point light.
79    pub fn point() -> Self {
80        Self::new(LightType::Point(
81            khora_core::renderer::light::PointLight::default(),
82        ))
83    }
84
85    /// Creates a new spot light.
86    pub fn spot() -> Self {
87        Self::new(LightType::Spot(
88            khora_core::renderer::light::SpotLight::default(),
89        ))
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[test]
98    fn test_light_default() {
99        let light = Light::default();
100        assert!(light.enabled);
101        assert!(matches!(light.light_type, LightType::Directional(_)));
102    }
103
104    #[test]
105    fn test_light_directional() {
106        let light = Light::directional();
107        assert!(light.enabled);
108        assert!(matches!(light.light_type, LightType::Directional(_)));
109    }
110
111    #[test]
112    fn test_light_point() {
113        let light = Light::point();
114        assert!(light.enabled);
115        assert!(matches!(light.light_type, LightType::Point(_)));
116    }
117
118    #[test]
119    fn test_light_spot() {
120        let light = Light::spot();
121        assert!(light.enabled);
122        assert!(matches!(light.light_type, LightType::Spot(_)));
123    }
124
125    #[test]
126    fn test_light_enabled_toggle() {
127        let mut light = Light::default();
128        assert!(light.enabled);
129
130        light.enabled = false;
131        assert!(!light.enabled);
132    }
133}