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}