[vlc-commits] [Git][videolan/vlc][master] vlcrs-core: object: add Object::new()

Alexandre Janniaux (@alexandre-janniaux) gitlab at videolan.org
Mon Jan 27 12:32:44 UTC 2025



Alexandre Janniaux pushed to branch master at VideoLAN / VLC


Commits:
76dee610 by Alexandre Janniaux at 2025-01-27T11:47:32+00:00
vlcrs-core: object: add Object::new()

This allows creating objects from existing objects (in a libvlc tree) or
dummy objects (parent = None) for tests, and provide the Drop
implementation to delete the objects when they go out of scope.

- - - - -


3 changed files:

- src/rust/vlcrs-core/src/lib.rs
- src/rust/vlcrs-core/src/object/mod.rs
- src/rust/vlcrs-core/src/object/sys.rs


Changes:

=====================================
src/rust/vlcrs-core/src/lib.rs
=====================================
@@ -1,6 +1,7 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 #![feature(extern_types)]
 #![feature(associated_type_defaults)]
+#![feature(c_size_t)]
 
 //! The `vlcrs-core` crate.
 //!


=====================================
src/rust/vlcrs-core/src/object/mod.rs
=====================================
@@ -3,17 +3,78 @@ mod sys;
 use sys::ObjectInternalData;
 use vlcrs_messages::Logger;
 
+use std::{
+    ops::{Deref, DerefMut},
+    ptr::NonNull,
+};
+
 #[repr(C)]
-pub struct Object {
+pub struct Object<'a> {
     logger: Option<Logger>,
-    internal_data: ObjectInternalData,
+    internal_data: ObjectInternalData<'a>,
     no_interact: bool,
     force: bool,
 }
 
-impl Object {
+pub struct ObjectHandle<'a> {
+    obj: NonNull<Object<'a>>,
+}
 
+impl Object<'_> {
     pub fn logger(&self) -> Option<&Logger> {
         self.logger.as_ref()
-    } 
+    }
+}
+
+impl ObjectHandle<'_> {
+    ///
+    /// Create a new VLC Object as child of an existing object or from scratch.
+    ///
+    /// The new object cannot be used after its parent has been destroyed, so
+    /// the following code is forbidden:
+    ///
+    /// ```compile_fail
+    /// use vlcrs_core::object::ObjectHandle;
+    /// let mut obj = ObjectHandle::new(None).unwrap();
+    /// let obj2 = ObjectHandle::new(Some(&obj)).unwrap();
+    /// drop(obj);
+    /// drop(obj2);
+    /// ````
+    pub fn new<'parent>(parent: Option<&'parent Object>) -> Option<ObjectHandle<'parent>> {
+        let obj = unsafe { sys::vlc_object_create(parent, size_of::<Object>())? };
+        Some(ObjectHandle { obj })
+    }
+}
+
+impl<'a> Deref for ObjectHandle<'a> {
+    type Target = Object<'a>;
+
+    fn deref(&self) -> &Self::Target {
+        return unsafe { self.obj.as_ref() };
+    }
+}
+
+impl<'a> DerefMut for ObjectHandle<'a> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        return unsafe { self.obj.as_mut() };
+    }
+}
+
+impl Drop for ObjectHandle<'_> {
+    fn drop(&mut self) {
+        unsafe { sys::vlc_object_delete(self.obj.as_mut()) };
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::object::ObjectHandle;
+
+    #[test]
+    fn test_create_and_destroy_object() {
+        let mut obj = ObjectHandle::new(None).unwrap();
+        let obj2 = ObjectHandle::new(Some(&mut obj)).unwrap();
+        drop(obj2);
+        drop(obj);
+    }
 }


=====================================
src/rust/vlcrs-core/src/object/sys.rs
=====================================
@@ -1,3 +1,5 @@
+use crate::object::Object;
+use std::marker::PhantomData;
 use std::ptr::NonNull;
 
 #[repr(C)]
@@ -12,7 +14,26 @@ pub(super) struct ObjectMarker {
 
 #[repr(C)]
 #[derive(Copy, Clone)]
-pub(super) union ObjectInternalData {
+pub(super) union ObjectInternalData<'parent> {
     pub internals: Option<NonNull<ObjectInternals>>,
     pub marker: Option<NonNull<ObjectMarker>>,
+    pub _parent: PhantomData<&'parent Object<'parent>>,
+}
+
+extern "C" {
+
+    ///
+    /// Create a VLC object, with an optional parent.
+    ///
+    /// For now, the lifetime is more constrained than necessary so that
+    /// the function can be used in test without creating unsound situations.
+    ///
+    pub(crate) fn vlc_object_create<'parent, 'child>(
+        parent: Option<&'_ Object<'parent>>,
+        length: core::ffi::c_size_t,
+    ) -> Option<NonNull<Object<'child>>>
+    where
+        'parent: 'child;
+
+    pub(crate) fn vlc_object_delete(obj: &mut Object);
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/76dee6106e1c9fb5eb1ac584f99a0e1389c8e13c

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/76dee6106e1c9fb5eb1ac584f99a0e1389c8e13c
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list