diff options
Diffstat (limited to 'engine')
| -rw-r--r-- | engine/src/opengl/buffer.rs | 13 | ||||
| -rw-r--r-- | engine/src/opengl/vertex_array.rs | 11 | ||||
| -rw-r--r-- | engine/src/renderer/opengl.rs | 49 | ||||
| -rw-r--r-- | engine/src/util.rs | 73 | 
4 files changed, 69 insertions, 77 deletions
diff --git a/engine/src/opengl/buffer.rs b/engine/src/opengl/buffer.rs index 2be7f12..68a75fb 100644 --- a/engine/src/opengl/buffer.rs +++ b/engine/src/opengl/buffer.rs @@ -39,19 +39,6 @@ impl<Item> Buffer<Item>      {          self.buf      } - -    /// Does a weak clone of this buffer. The buffer itself is NOT copied in any way this -    /// function only copies the internal buffer ID. -    /// -    /// # Safety -    /// The returned `Buffer` must not be dropped if another `Buffer` referencing the -    /// same buffer ID is used later or if a [`VertexArray`] is used later. -    /// -    /// [`VertexArray`]: crate::opengl::vertex_array::VertexArray -    pub unsafe fn clone_weak(&self) -> Self -    { -        Self { buf: self.buf, _pd: PhantomData } -    }  }  impl<Item> Drop for Buffer<Item> diff --git a/engine/src/opengl/vertex_array.rs b/engine/src/opengl/vertex_array.rs index da5d91e..e1e1a15 100644 --- a/engine/src/opengl/vertex_array.rs +++ b/engine/src/opengl/vertex_array.rs @@ -125,17 +125,6 @@ impl VertexArray      {          unsafe { gl::BindVertexArray(self.array) }      } - -    /// Does a weak clone of this vertex array. The vertex array itself is NOT copied in -    /// any way this function only copies the internal vertex array ID. -    /// -    /// # Safety -    /// The returned `VertexArray` must not be dropped if another `VertexArray` -    /// referencing the same vertex array ID is used later. -    pub unsafe fn clone_unsafe(&self) -> Self -    { -        Self { array: self.array } -    }  }  impl Drop for VertexArray diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index c098548..6a571eb 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -64,7 +64,7 @@ use crate::opengl::{  use crate::projection::{ClipVolume, Projection};  use crate::texture::{Id as TextureId, Texture};  use crate::transform::{Position, Scale}; -use crate::util::NeverDrop; +use crate::util::{defer, Defer, RefOrValue};  use crate::vector::{Vec2, Vec3};  use crate::vertex::{AttributeComponentType, Vertex};  use crate::window::Window; @@ -174,21 +174,17 @@ fn render(              .map(|material_flags| material_flags.clone())              .unwrap_or_default(); -        let new_gl_objects; - -        let gl_objects = if let Some(gl_objects) = gl_objects.as_deref() { -            gl_objects -        } else { -            // TODO: Account for when meshes are changed -            let gl_objects = GlObjects::new(&mesh); - -            new_gl_objects = Some(gl_objects.clone()); - -            actions.add_components(euid, (gl_objects,)); - -            &*new_gl_objects.unwrap() +        let gl_objs = match gl_objects.as_deref() { +            Some(gl_objs) => RefOrValue::Ref(gl_objs), +            None => RefOrValue::Value(Some(GlObjects::new(&mesh))),          }; +        defer!(|gl_objs| { +            if let RefOrValue::Value(opt_gl_objs) = gl_objs { +                actions.add_components(euid, (opt_gl_objs.take().unwrap(),)); +            }; +        }); +          apply_transformation_matrices(              Transformation {                  position: position.map(|pos| *pos).unwrap_or_default().position, @@ -235,7 +231,7 @@ fn render(              );          } -        draw_mesh(gl_objects); +        draw_mesh(gl_objs.get().unwrap());          if draw_flags.is_some() {              let default_polygon_mode_config = PolygonModeConfig::default(); @@ -360,7 +356,7 @@ fn get_glsl_shader_content(path: &Path) -> Result<Vec<u8>, std::io::Error>  struct GlObjects  {      /// Vertex and index buffer has to live as long as the vertex array -    vertex_buffer: Buffer<Vertex>, +    _vertex_buffer: Buffer<Vertex>,      index_buffer: Option<Buffer<u32>>,      element_cnt: u32, @@ -415,7 +411,7 @@ impl GlObjects              vertex_arr.bind_element_buffer(&index_buffer);              return Self { -                vertex_buffer, +                _vertex_buffer: vertex_buffer,                  index_buffer: Some(index_buffer),                  element_cnt: indices                      .len() @@ -426,7 +422,7 @@ impl GlObjects          }          Self { -            vertex_buffer, +            _vertex_buffer: vertex_buffer,              index_buffer: None,              element_cnt: mesh                  .vertices() @@ -436,23 +432,6 @@ impl GlObjects              vertex_arr,          }      } - -    pub fn clone(&self) -> NeverDrop<Self> -    { -        NeverDrop::new(Self { -            // SAFETY: The vertex buffer will never become dropped (NeverDrop ensures it) -            vertex_buffer: unsafe { self.vertex_buffer.clone_weak() }, -            index_buffer: self -                .index_buffer -                .as_ref() -                // SAFETY: The index buffer will never become dropped (NeverDrop ensures -                // it) -                .map(|index_buffer| unsafe { index_buffer.clone_weak() }), -            element_cnt: self.element_cnt, -            // SAFETY: The vertex array will never become dropped (NeverDrop ensures it) -            vertex_arr: unsafe { self.vertex_arr.clone_unsafe() }, -        }) -    }  }  fn apply_transformation_matrices( diff --git a/engine/src/util.rs b/engine/src/util.rs index a505a38..0f6c78c 100644 --- a/engine/src/util.rs +++ b/engine/src/util.rs @@ -1,3 +1,5 @@ +use std::marker::PhantomData; +  macro_rules! try_option {      ($expr: expr) => {          match $expr { @@ -9,9 +11,6 @@ macro_rules! try_option {      };  } -use std::mem::ManuallyDrop; -use std::ops::{Deref, DerefMut}; -  pub(crate) use try_option;  macro_rules! or { @@ -97,36 +96,74 @@ macro_rules! builder {  pub(crate) use builder; -/// Wrapper that ensures the contained value will never be dropped. -#[derive(Debug)] -pub struct NeverDrop<Value> +pub enum RefOrValue<'a, T>  { -    value: ManuallyDrop<Value>, +    Ref(&'a T), +    Value(Option<T>),  } -impl<Value> NeverDrop<Value> +impl<'a, T> RefOrValue<'a, T>  { -    #[must_use] -    pub fn new(value: Value) -> Self +    pub fn get(&self) -> Option<&T>      { -        Self { value: ManuallyDrop::new(value) } +        match self { +            Self::Ref(val_ref) => Some(val_ref), +            Self::Value(val_cell) => val_cell.as_ref(), +        }      }  } -impl<Value> Deref for NeverDrop<Value> +#[derive(Debug)] +pub struct Defer<'func, Func, Data> +where +    Func: FnMut(&mut Data) + 'func,  { -    type Target = Value; +    func: Func, +    pub data: Data, +    _pd: PhantomData<&'func ()>, +} -    fn deref(&self) -> &Self::Target +impl<'func, Func, Data> Defer<'func, Func, Data> +where +    Func: FnMut(&mut Data) + 'func, +{ +    pub fn new(data: Data, func: Func) -> Self      { -        &self.value +        Self { func, data, _pd: PhantomData }      }  } -impl<Value> DerefMut for NeverDrop<Value> +impl<'func, Func, Data> Drop for Defer<'func, Func, Data> +where +    Func: FnMut(&mut Data) + 'func,  { -    fn deref_mut(&mut self) -> &mut Self::Target +    fn drop(&mut self)      { -        &mut self.value +        (self.func)(&mut self.data)      }  } + +/// Defines a function that will be called at the end of the current scope. +/// +/// Only captured variables that are later mutably borrowed needs to specified as +/// captures. +macro_rules! defer { +    (|$capture: ident| {$($tt: tt)*}) => { +        // This uses the automatic temporary lifetime extension behaviour introduced +        // in Rust 1.79.0 (https://blog.rust-lang.org/2024/06/13/Rust-1.79.0.html) to +        // create a unnamable variable for the Defer struct. The variable should be +        // unnamable so that it cannot be missused and so that this macro can be used +        // multiple times without having to give it a identifier for the Defer struct +        // variable +        let Defer { data: $capture, .. } = if true { +            &Defer::new($capture, |$capture| { +                $($tt)* +            }) +        } +        else { +            unreachable!(); +        }; +    }; +} + +pub(crate) use defer;  | 
