Skip to content
Snippets Groups Projects
Commit 76dee610 authored by Alexandre Janniaux's avatar Alexandre Janniaux
Browse files

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.
parent 03233bec
No related branches found
No related tags found
1 merge request!6676vlcrs-core: object: add Object::new()
Pipeline #559666 passed with stage
in 16 minutes and 35 seconds
#![deny(unsafe_op_in_unsafe_fn)]
#![feature(extern_types)]
#![feature(associated_type_defaults)]
#![feature(c_size_t)]
//! The `vlcrs-core` crate.
//!
......
......@@ -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);
}
}
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);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment