blue_engine_core/prelude/
mod.rs

1use downcast::{Any, downcast};
2/// re-exports from dependencies that are useful
3pub mod imports;
4pub use imports::*;
5/// contains definition for some 2D and 3D shapes. They are basic shapes and
6/// can be used as examples of how to create your own content.
7pub mod primitive_shapes;
8pub use crate::camera::{Camera, CameraContainer, Projection};
9pub use crate::definition::{
10    Pipeline, PipelineData, ShaderSettings, TextureData, TextureMode, VertexBuffers,
11    pixel_to_cartesian,
12};
13pub use crate::objects::{
14    Instance, InstanceRaw, Object, ObjectSettings, ObjectStorage, RotateAmount, RotateAxis,
15};
16pub use crate::render::Renderer;
17pub use crate::window::{Window, WindowDescriptor};
18
19/// The uint type used for indices and more
20#[cfg(not(feature = "u32"))]
21pub type UnsignedIntType = u16;
22#[cfg(feature = "u32")]
23pub type UnsignedIntType = u32;
24
25///
26pub mod macros {
27    macro_rules! impl_deref {
28        ($struct:ty,$type:ty) => {
29            impl std::ops::Deref for $struct {
30                type Target = $type;
31
32                fn deref(&self) -> &Self::Target {
33                    &self.0
34                }
35            }
36            impl std::ops::DerefMut for $struct {
37                fn deref_mut(&mut self) -> &mut Self::Target {
38                    &mut self.0
39                }
40            }
41        };
42    }
43
44    macro_rules! impl_deref_field {
45        ($struct:ty,$type:ty,$field:ident) => {
46            impl std::ops::Deref for $struct {
47                type Target = $type;
48
49                fn deref(&self) -> &Self::Target {
50                    &self.$field
51                }
52            }
53            impl std::ops::DerefMut for $struct {
54                fn deref_mut(&mut self) -> &mut Self::Target {
55                    &mut self.$field
56                }
57            }
58        };
59    }
60
61    pub(crate) use impl_deref;
62    pub(crate) use impl_deref_field;
63}
64
65/// Will contain all details about a vertex and will be sent to GPU
66// Will be turned to C code and sent to GPU
67#[repr(C)]
68#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
69pub struct Vertex {
70    /// Contains position data for the vertex in 3D space
71    pub position: [f32; 3],
72    /// Contains uv position data for the vertex
73    pub uv: [f32; 2],
74    /// Contains the normal face of the vertex
75    pub normal: [f32; 3],
76}
77impl Vertex {
78    pub(crate) fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
79        wgpu::VertexBufferLayout {
80            array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
81            step_mode: wgpu::VertexStepMode::Vertex,
82            attributes: &[
83                wgpu::VertexAttribute {
84                    offset: 0,
85                    shader_location: 0,
86                    format: wgpu::VertexFormat::Float32x3,
87                },
88                wgpu::VertexAttribute {
89                    // This should be replaced with `std::mem::size_of::<Vector3>() as wgpu::BufferAddress`
90                    offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
91                    shader_location: 1,
92                    format: wgpu::VertexFormat::Float32x2,
93                },
94                wgpu::VertexAttribute {
95                    offset: std::mem::size_of::<[f32; 5]>() as wgpu::BufferAddress,
96                    shader_location: 2,
97                    format: wgpu::VertexFormat::Float32x3,
98                },
99            ],
100        }
101    }
102}
103unsafe impl Send for Vertex {}
104unsafe impl Sync for Vertex {}
105
106/// The engine is the main starting point of using the Blue Engine.
107/// Everything that runs on Blue Engine will be under this struct.
108/// The structure of engine is monolithic, but the underlying data and the way it works is not.
109/// It gives a set of default data to work with,
110/// but also allow you to go beyond that and work as low level as you wish to.
111///
112/// You can also use the Engine to build you own custom structure the way you wish for it to be.
113/// Possibilities are endless!
114///
115/// To start using the Blue Engine, you can start by creating a new Engine like follows:
116/// ```
117/// use blue_engine::prelude::{Engine, WindowDescriptor};
118///
119/// fn main() {
120///     let engine = Engine::new().expect("Couldn't create the engine");
121/// }
122/// ```
123/// The WindowDescriptor simply holds what features you would like for your window.
124/// If you are reading this on later version of
125/// the engine, you might be able to even run the engine in headless mode
126/// meaning there would not be a need for a window and the
127/// renders would come as image files.
128///
129/// If you so wish to have a window, you would need to start a window update loop.
130/// The update loop of window runs a frame every few millisecond,
131/// and gives you details of what is happening during this time, like input events.
132/// You can also modify existing parts of the engine during
133/// this update loop, such as changing camera to look differently,
134/// or creating a new object on the scene, or even changing window details!
135///
136/// The update loop is just a method of the Engine struct
137/// that have one argument which is a callback function.
138/// ```
139///
140/// ```
141/// [THE DATA HERE IS WORK IN PROGRESS!]
142pub struct Engine {
143    /// The renderer does exactly what it is called.
144    /// It works with the GPU to render frames according to the data you gave it.
145    pub renderer: Renderer,
146    /// The event_loop handles the events of the window and inputs.
147    ///
148    /// #### USED INTERNALLY
149    pub event_loop_control_flow: crate::winit::event_loop::ControlFlow,
150    /// The window handles everything about window and inputs.
151    /// This includes ability to modify window and listen toinput devices for changes.
152    ///
153    /// ### The window is not available before update_loop.
154    pub window: Window,
155    /// The object system is a way to make it easier to work with the engine.
156    /// Obviously you can work without it, but it's for those who
157    /// do not have the know-how, or wish to handle all the work of rendering data manually.
158    pub objects: ObjectStorage,
159    /// The camera handles the way the scene looks when rendered.
160    /// You can modify everything there is to camera through this.
161    pub camera: CameraContainer,
162    /// Handles all engine plugins
163    pub signals: SignalStorage,
164
165    /// holds the update_loop function
166    ///
167    /// #### USED INTERNALLY
168    #[allow(clippy::type_complexity)]
169    pub update_loop: Option<
170        Box<
171            dyn 'static
172                + FnMut(
173                    // Core
174                    &mut Renderer,
175                    &mut Window,
176                    &mut ObjectStorage,
177                    &crate::utils::winit_input_helper::WinitInputHelper,
178                    &mut CameraContainer,
179                    &mut crate::SignalStorage,
180                ),
181        >,
182    >,
183
184    /// input events
185    ///
186    /// #### USED INTERNALLY
187    pub input_events: crate::utils::winit_input_helper::WinitInputHelper,
188}
189unsafe impl Send for Engine {}
190unsafe impl Sync for Engine {}
191
192/// Allows all events to be fetched directly, making it easier to add custom additions to the engine.
193pub trait Signal: Any {
194    /// This is ran as soon as the engine is properly initialized and all components are ready
195    #[allow(clippy::too_many_arguments)]
196    fn init(
197        &mut self,
198        _renderer: &mut crate::Renderer,
199        _window: &crate::Window,
200        _objects: &mut ObjectStorage,
201        _camera: &mut crate::CameraContainer,
202    ) {
203    }
204
205    /// This is ran at the device events when available
206    #[allow(clippy::too_many_arguments)]
207    fn device_events(
208        &mut self,
209        _renderer: &mut crate::Renderer,
210        _window: &crate::Window,
211        _objects: &mut ObjectStorage,
212        _events: &crate::DeviceEvent,
213        _input: &crate::InputHelper,
214        _camera: &mut crate::CameraContainer,
215    ) {
216    }
217
218    /// This is ran at the window events when available
219    #[allow(clippy::too_many_arguments)]
220    fn window_events(
221        &mut self,
222        _renderer: &mut crate::Renderer,
223        _window: &crate::Window,
224        _objects: &mut ObjectStorage,
225        _events: &crate::WindowEvent,
226        _input: &crate::InputHelper,
227        _camera: &mut crate::CameraContainer,
228    ) {
229    }
230
231    /// ran before the frame is rendered
232    #[allow(clippy::too_many_arguments)]
233    fn frame(
234        &mut self,
235        _renderer: &mut crate::Renderer,
236        _window: &crate::Window,
237        _objects: &mut ObjectStorage,
238        _camera: &mut crate::CameraContainer,
239        _input: &crate::InputHelper,
240        _encoder: &mut crate::CommandEncoder,
241        _view: &crate::TextureView,
242    ) {
243    }
244}
245// The engine needs to know the functions of Signal to do things internally,
246// so we use downcast and not the std::any::Any
247downcast!(dyn Signal);
248
249/// Handles the live events in the engine
250pub struct SignalStorage {
251    /// list of events with key and the event
252    pub events: Vec<(String, Box<dyn Signal>)>,
253}
254
255/// A unified way to handle strings
256pub trait StringBuffer: StringBufferTrait + Clone {}
257/// A trait for [StringBuffer]
258pub trait StringBufferTrait {
259    /// Returns the string as &[`str`]
260    fn as_str(&self) -> &str;
261    /// Returns the string as [`String`]
262    fn as_string(&self) -> String;
263    /// Returns Arc<str> for ease of computation
264    fn as_arc(&self) -> std::sync::Arc<str>;
265}
266
267impl StringBufferTrait for String {
268    fn as_str(&self) -> &str {
269        self.as_ref()
270    }
271    fn as_string(&self) -> String {
272        self.clone()
273    }
274    fn as_arc(&self) -> std::sync::Arc<str> {
275        self.as_str().into()
276    }
277}
278impl StringBuffer for String {}
279impl StringBufferTrait for &str {
280    fn as_str(&self) -> &str {
281        self
282    }
283    fn as_string(&self) -> String {
284        self.to_string()
285    }
286    fn as_arc(&self) -> std::sync::Arc<str> {
287        self.as_str().into()
288    }
289}
290impl StringBuffer for &str {}