goud_engine/core/providers/impls/
null_render.rs1use crate::core::error::GoudResult;
4use crate::core::providers::render::RenderProvider;
5use crate::core::providers::types::{
6 BufferDesc, BufferHandle, CameraData, DrawCommand, FrameContext, MeshDrawCommand,
7 ParticleDrawCommand, PipelineDesc, PipelineHandle, RenderCapabilities, RenderTargetDesc,
8 RenderTargetHandle, ShaderDesc, ShaderHandle, TextDrawCommand, TextureDesc, TextureHandle,
9};
10use crate::core::providers::{Provider, ProviderLifecycle};
11
12pub struct NullRenderProvider {
15 capabilities: RenderCapabilities,
16}
17
18impl NullRenderProvider {
19 pub fn new() -> Self {
21 Self {
22 capabilities: RenderCapabilities {
23 max_texture_units: 0,
24 max_texture_size: 0,
25 supports_instancing: false,
26 supports_compute: false,
27 supports_msaa: false,
28 },
29 }
30 }
31}
32
33impl Default for NullRenderProvider {
34 fn default() -> Self {
35 Self::new()
36 }
37}
38
39impl Provider for NullRenderProvider {
40 fn name(&self) -> &str {
41 "null"
42 }
43
44 fn version(&self) -> &str {
45 "0.0.0"
46 }
47
48 fn capabilities(&self) -> Box<dyn std::any::Any> {
49 Box::new(self.capabilities.clone())
50 }
51}
52
53impl ProviderLifecycle for NullRenderProvider {
54 fn init(&mut self) -> GoudResult<()> {
55 Ok(())
56 }
57
58 fn update(&mut self, _delta: f32) -> GoudResult<()> {
59 Ok(())
60 }
61
62 fn shutdown(&mut self) {}
63}
64
65impl RenderProvider for NullRenderProvider {
66 fn render_capabilities(&self) -> &RenderCapabilities {
67 &self.capabilities
68 }
69
70 fn begin_frame(&mut self) -> GoudResult<FrameContext> {
71 Ok(FrameContext { _id: 0 })
72 }
73
74 fn end_frame(&mut self, _frame: FrameContext) -> GoudResult<()> {
75 Ok(())
76 }
77
78 fn resize(&mut self, _width: u32, _height: u32) -> GoudResult<()> {
79 Ok(())
80 }
81
82 fn create_texture(&mut self, _desc: &TextureDesc) -> GoudResult<TextureHandle> {
83 Ok(TextureHandle(0))
84 }
85
86 fn destroy_texture(&mut self, _handle: TextureHandle) {}
87
88 fn create_buffer(&mut self, _desc: &BufferDesc) -> GoudResult<BufferHandle> {
89 Ok(BufferHandle(0))
90 }
91
92 fn destroy_buffer(&mut self, _handle: BufferHandle) {}
93
94 fn create_shader(&mut self, _desc: &ShaderDesc) -> GoudResult<ShaderHandle> {
95 Ok(ShaderHandle(0))
96 }
97
98 fn destroy_shader(&mut self, _handle: ShaderHandle) {}
99
100 fn create_pipeline(&mut self, _desc: &PipelineDesc) -> GoudResult<PipelineHandle> {
101 Ok(PipelineHandle(0))
102 }
103
104 fn destroy_pipeline(&mut self, _handle: PipelineHandle) {}
105
106 fn create_render_target(&mut self, _desc: &RenderTargetDesc) -> GoudResult<RenderTargetHandle> {
107 Ok(RenderTargetHandle(0))
108 }
109
110 fn destroy_render_target(&mut self, _handle: RenderTargetHandle) {}
111
112 fn draw(&mut self, _cmd: &DrawCommand) -> GoudResult<()> {
113 Ok(())
114 }
115
116 fn draw_batch(&mut self, _cmds: &[DrawCommand]) -> GoudResult<()> {
117 Ok(())
118 }
119
120 fn draw_mesh(&mut self, _cmd: &MeshDrawCommand) -> GoudResult<()> {
121 Ok(())
122 }
123
124 fn draw_text(&mut self, _cmd: &TextDrawCommand) -> GoudResult<()> {
125 Ok(())
126 }
127
128 fn draw_particles(&mut self, _cmd: &ParticleDrawCommand) -> GoudResult<()> {
129 Ok(())
130 }
131
132 fn set_viewport(&mut self, _x: i32, _y: i32, _width: u32, _height: u32) {}
133
134 fn set_camera(&mut self, _camera: &CameraData) {}
135
136 fn set_render_target(&mut self, _handle: Option<RenderTargetHandle>) {}
137
138 fn clear(&mut self, _color: [f32; 4]) {}
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144
145 #[test]
146 fn test_null_render_construction() {
147 let provider = NullRenderProvider::new();
148 assert_eq!(provider.name(), "null");
149 assert_eq!(provider.version(), "0.0.0");
150 }
151
152 #[test]
153 fn test_null_render_default() {
154 let provider = NullRenderProvider::default();
155 assert_eq!(provider.name(), "null");
156 }
157
158 #[test]
159 fn test_null_render_init_shutdown() {
160 let mut provider = NullRenderProvider::new();
161 assert!(provider.init().is_ok());
162 assert!(provider.update(0.016).is_ok());
163 provider.shutdown();
164 }
165
166 #[test]
167 fn test_null_render_capabilities() {
168 let provider = NullRenderProvider::new();
169 let caps = provider.render_capabilities();
170 assert_eq!(caps.max_texture_size, 0);
171 assert_eq!(caps.max_texture_units, 0);
172 assert!(!caps.supports_instancing);
173 assert!(!caps.supports_compute);
174 assert!(!caps.supports_msaa);
175 }
176
177 #[test]
178 fn test_null_render_generic_capabilities() {
179 let provider = NullRenderProvider::new();
180 let caps = provider.capabilities();
181 let render_caps = caps.downcast_ref::<RenderCapabilities>().unwrap();
182 assert_eq!(render_caps.max_texture_size, 0);
183 }
184
185 #[test]
186 fn test_null_render_frame_lifecycle() {
187 let mut provider = NullRenderProvider::new();
188 let frame = provider.begin_frame().unwrap();
189 assert!(provider.end_frame(frame).is_ok());
190 }
191
192 #[test]
193 fn test_null_render_resource_creation() {
194 let mut provider = NullRenderProvider::new();
195 let tex = provider.create_texture(&TextureDesc::default()).unwrap();
196 assert_eq!(tex, TextureHandle(0));
197 provider.destroy_texture(tex);
198
199 let buf = provider.create_buffer(&BufferDesc::default()).unwrap();
200 assert_eq!(buf, BufferHandle(0));
201 provider.destroy_buffer(buf);
202
203 let shader = provider.create_shader(&ShaderDesc::default()).unwrap();
204 assert_eq!(shader, ShaderHandle(0));
205 provider.destroy_shader(shader);
206
207 let pipeline = provider.create_pipeline(&PipelineDesc::default()).unwrap();
208 assert_eq!(pipeline, PipelineHandle(0));
209 provider.destroy_pipeline(pipeline);
210
211 let rt = provider
212 .create_render_target(&RenderTargetDesc::default())
213 .unwrap();
214 assert_eq!(rt, RenderTargetHandle(0));
215 provider.destroy_render_target(rt);
216 }
217
218 #[test]
219 fn test_null_render_resize() {
220 let mut provider = NullRenderProvider::new();
221 assert!(provider.resize(1920, 1080).is_ok());
222 }
223
224 #[test]
225 fn test_null_render_state_operations() {
226 let mut provider = NullRenderProvider::new();
227 provider.set_viewport(0, 0, 800, 600);
228 provider.set_camera(&CameraData::default());
229 provider.set_render_target(None);
230 provider.clear([0.0, 0.0, 0.0, 1.0]);
231 }
232}