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)]
41pub struct Light {
42    /// The type and properties of the light source.
43    pub light_type: LightType,
44
45    /// Whether the light is currently active.
46    ///
47    /// Disabled lights are not extracted for rendering and have no
48    /// performance impact on the scene.
49    pub enabled: bool,
50}
51
52impl Default for Light {
53    fn default() -> Self {
54        Self {
55            light_type: LightType::default(),
56            enabled: true,
57        }
58    }
59}
60
61impl Light {
62    /// Creates a new enabled light with the given type.
63    pub fn new(light_type: LightType) -> Self {
64        Self {
65            light_type,
66            enabled: true,
67        }
68    }
69
70    /// Creates a new directional light (sun-like).
71    pub fn directional() -> Self {
72        Self::new(LightType::Directional(
73            khora_core::renderer::light::DirectionalLight::default(),
74        ))
75    }
76
77    /// Creates a new point light.
78    pub fn point() -> Self {
79        Self::new(LightType::Point(
80            khora_core::renderer::light::PointLight::default(),
81        ))
82    }
83
84    /// Creates a new spot light.
85    pub fn spot() -> Self {
86        Self::new(LightType::Spot(
87            khora_core::renderer::light::SpotLight::default(),
88        ))
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95
96    #[test]
97    fn test_light_default() {
98        let light = Light::default();
99        assert!(light.enabled);
100        assert!(matches!(light.light_type, LightType::Directional(_)));
101    }
102
103    #[test]
104    fn test_light_directional() {
105        let light = Light::directional();
106        assert!(light.enabled);
107        assert!(matches!(light.light_type, LightType::Directional(_)));
108    }
109
110    #[test]
111    fn test_light_point() {
112        let light = Light::point();
113        assert!(light.enabled);
114        assert!(matches!(light.light_type, LightType::Point(_)));
115    }
116
117    #[test]
118    fn test_light_spot() {
119        let light = Light::spot();
120        assert!(light.enabled);
121        assert!(matches!(light.light_type, LightType::Spot(_)));
122    }
123
124    #[test]
125    fn test_light_enabled_toggle() {
126        let mut light = Light::default();
127        assert!(light.enabled);
128
129        light.enabled = false;
130        assert!(!light.enabled);
131    }
132}