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}