Add initial Message/MiniObject bindings

This commit is contained in:
Sebastian Dröge 2017-07-03 13:56:26 +03:00
parent 2546045593
commit aa3581cee9
8 changed files with 531 additions and 56 deletions

View file

@ -28,11 +28,12 @@ generate = [
"Gst.ElementFactory", "Gst.ElementFactory",
"Gst.ElementFactoryListType", "Gst.ElementFactoryListType",
"Gst.Format", "Gst.Format",
"Gst.MessageType",
] ]
manual = [ manual = [
"GLib.Error", "GLib.Error",
#"Gst.Message", "Gst.Message",
] ]
[[object]] [[object]]
@ -66,6 +67,19 @@ status = "generate"
# Needs manual bindings and GSource support in glib-rs # Needs manual bindings and GSource support in glib-rs
ignore = true ignore = true
[[object.function]]
name = "timed_pop_filtered"
# Uses enum as flags
ignore = true
[[object.function]]
name = "pop_filtered"
# Uses enum as flags
ignore = true
[[object.function]]
name = "poll"
# Uses enum as flags
ignore = true
[[object]] [[object]]
name = "Gst.Clock" name = "Gst.Clock"
status = "generate" status = "generate"

View file

@ -1,10 +1,18 @@
// This file was generated by gir (33e9567) from gir-files (???) // This file was generated by gir (33e9567) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ClockTime;
use Message;
use Object; use Object;
use ffi; use ffi;
use glib;
use glib::object::Downcast;
use glib::object::IsA; use glib::object::IsA;
use glib::signal::connect;
use glib::translate::*; use glib::translate::*;
use glib_ffi;
use std::boxed::Box as Box_;
use std::mem::transmute;
glib_wrapper! { glib_wrapper! {
pub struct Bus(Object<ffi::GstBus>): Object; pub struct Bus(Object<ffi::GstBus>): Object;
@ -34,7 +42,7 @@ pub trait BusExt {
//fn add_watch_full<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, priority: i32, func: /*Unknown conversion*//*Unimplemented*/BusFunc, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify) -> u32; //fn add_watch_full<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, priority: i32, func: /*Unknown conversion*//*Unimplemented*/BusFunc, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify) -> u32;
//fn async_signal_func<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, message: /*Ignored*/&mut Message, data: P) -> bool; //fn async_signal_func<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, message: &mut Message, data: P) -> bool;
//fn create_watch(&self) -> /*Ignored*/Option<glib::Source>; //fn create_watch(&self) -> /*Ignored*/Option<glib::Source>;
@ -44,15 +52,11 @@ pub trait BusExt {
fn have_pending(&self) -> bool; fn have_pending(&self) -> bool;
//fn peek(&self) -> /*Ignored*/Option<Message>; fn peek(&self) -> Option<Message>;
//fn poll(&self, events: /*Ignored*/MessageType, timeout: ClockTime) -> /*Ignored*/Option<Message>; fn pop(&self) -> Option<Message>;
//fn pop(&self) -> /*Ignored*/Option<Message>; fn post(&self, message: &mut Message) -> bool;
//fn pop_filtered(&self, types: /*Ignored*/MessageType) -> /*Ignored*/Option<Message>;
//fn post(&self, message: /*Ignored*/&mut Message) -> bool;
fn remove_signal_watch(&self); fn remove_signal_watch(&self);
@ -60,18 +64,16 @@ pub trait BusExt {
//fn set_sync_handler<'a, P: Into<Option<&'a /*Unimplemented*/BusSyncHandler>>, Q: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, func: P, user_data: Q, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify); //fn set_sync_handler<'a, P: Into<Option<&'a /*Unimplemented*/BusSyncHandler>>, Q: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, func: P, user_data: Q, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify);
//fn sync_signal_handler<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, message: /*Ignored*/&mut Message, data: P) -> /*Ignored*/BusSyncReply; //fn sync_signal_handler<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, message: &mut Message, data: P) -> /*Ignored*/BusSyncReply;
//fn timed_pop(&self, timeout: ClockTime) -> /*Ignored*/Option<Message>; fn timed_pop(&self, timeout: ClockTime) -> Option<Message>;
//fn timed_pop_filtered(&self, timeout: ClockTime, types: /*Ignored*/MessageType) -> /*Ignored*/Option<Message>; fn connect_message<F: Fn(&Self, &Message) + Send + Sync + 'static>(&self, f: F) -> u64;
//fn connect_message<Unsupported or ignored types>(&self, f: F) -> u64; fn connect_sync_message<F: Fn(&Self, &Message) + Send + Sync + 'static>(&self, f: F) -> u64;
//fn connect_sync_message<Unsupported or ignored types>(&self, f: F) -> u64;
} }
impl<O: IsA<Bus>> BusExt for O { impl<O: IsA<Bus> + IsA<glib::object::Object>> BusExt for O {
fn add_signal_watch(&self) { fn add_signal_watch(&self) {
unsafe { unsafe {
ffi::gst_bus_add_signal_watch(self.to_glib_none().0); ffi::gst_bus_add_signal_watch(self.to_glib_none().0);
@ -92,7 +94,7 @@ impl<O: IsA<Bus>> BusExt for O {
// unsafe { TODO: call ffi::gst_bus_add_watch_full() } // unsafe { TODO: call ffi::gst_bus_add_watch_full() }
//} //}
//fn async_signal_func<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, message: /*Ignored*/&mut Message, data: P) -> bool { //fn async_signal_func<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, message: &mut Message, data: P) -> bool {
// unsafe { TODO: call ffi::gst_bus_async_signal_func() } // unsafe { TODO: call ffi::gst_bus_async_signal_func() }
//} //}
@ -118,25 +120,23 @@ impl<O: IsA<Bus>> BusExt for O {
} }
} }
//fn peek(&self) -> /*Ignored*/Option<Message> { fn peek(&self) -> Option<Message> {
// unsafe { TODO: call ffi::gst_bus_peek() } unsafe {
//} from_glib_full(ffi::gst_bus_peek(self.to_glib_none().0))
}
}
//fn poll(&self, events: /*Ignored*/MessageType, timeout: ClockTime) -> /*Ignored*/Option<Message> { fn pop(&self) -> Option<Message> {
// unsafe { TODO: call ffi::gst_bus_poll() } unsafe {
//} from_glib_full(ffi::gst_bus_pop(self.to_glib_none().0))
}
}
//fn pop(&self) -> /*Ignored*/Option<Message> { fn post(&self, message: &mut Message) -> bool {
// unsafe { TODO: call ffi::gst_bus_pop() } unsafe {
//} from_glib(ffi::gst_bus_post(self.to_glib_none().0, message.to_glib_full()))
}
//fn pop_filtered(&self, types: /*Ignored*/MessageType) -> /*Ignored*/Option<Message> { }
// unsafe { TODO: call ffi::gst_bus_pop_filtered() }
//}
//fn post(&self, message: /*Ignored*/&mut Message) -> bool {
// unsafe { TODO: call ffi::gst_bus_post() }
//}
fn remove_signal_watch(&self) { fn remove_signal_watch(&self) {
unsafe { unsafe {
@ -154,23 +154,43 @@ impl<O: IsA<Bus>> BusExt for O {
// unsafe { TODO: call ffi::gst_bus_set_sync_handler() } // unsafe { TODO: call ffi::gst_bus_set_sync_handler() }
//} //}
//fn sync_signal_handler<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, message: /*Ignored*/&mut Message, data: P) -> /*Ignored*/BusSyncReply { //fn sync_signal_handler<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, message: &mut Message, data: P) -> /*Ignored*/BusSyncReply {
// unsafe { TODO: call ffi::gst_bus_sync_signal_handler() } // unsafe { TODO: call ffi::gst_bus_sync_signal_handler() }
//} //}
//fn timed_pop(&self, timeout: ClockTime) -> /*Ignored*/Option<Message> { fn timed_pop(&self, timeout: ClockTime) -> Option<Message> {
// unsafe { TODO: call ffi::gst_bus_timed_pop() } unsafe {
//} from_glib_full(ffi::gst_bus_timed_pop(self.to_glib_none().0, timeout))
}
//fn timed_pop_filtered(&self, timeout: ClockTime, types: /*Ignored*/MessageType) -> /*Ignored*/Option<Message> { }
// unsafe { TODO: call ffi::gst_bus_timed_pop_filtered() }
//} fn connect_message<F: Fn(&Self, &Message) + Send + Sync + 'static>(&self, f: F) -> u64 {
unsafe {
//fn connect_message<Unsupported or ignored types>(&self, f: F) -> u64 { let f: Box_<Box_<Fn(&Self, &Message) + Send + Sync + 'static>> = Box_::new(Box_::new(f));
// Ignored message: Gst.Message connect(self.to_glib_none().0, "message",
//} transmute(message_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
}
//fn connect_sync_message<Unsupported or ignored types>(&self, f: F) -> u64 { }
// Ignored message: Gst.Message
//} fn connect_sync_message<F: Fn(&Self, &Message) + Send + Sync + 'static>(&self, f: F) -> u64 {
unsafe {
let f: Box_<Box_<Fn(&Self, &Message) + Send + Sync + 'static>> = Box_::new(Box_::new(f));
connect(self.to_glib_none().0, "sync-message",
transmute(sync_message_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
}
}
}
unsafe extern "C" fn message_trampoline<P>(this: *mut ffi::GstBus, message: *mut ffi::GstMessage, f: glib_ffi::gpointer)
where P: IsA<Bus> {
callback_guard!();
let f: &Box_<Fn(&P, &Message) + Send + Sync + 'static> = transmute(f);
f(&Bus::from_glib_none(this).downcast_unchecked(), &from_glib_none(message))
}
unsafe extern "C" fn sync_message_trampoline<P>(this: *mut ffi::GstBus, message: *mut ffi::GstMessage, f: glib_ffi::gpointer)
where P: IsA<Bus> {
callback_guard!();
let f: &Box_<Fn(&P, &Message) + Send + Sync + 'static> = transmute(f);
f(&Bus::from_glib_none(this).downcast_unchecked(), &from_glib_none(message))
} }

View file

@ -7,6 +7,7 @@ use ClockTime;
use ElementFactory; use ElementFactory;
use Error; use Error;
use Format; use Format;
use Message;
use Object; use Object;
use Pad; use Pad;
use PadTemplate; use PadTemplate;
@ -140,14 +141,14 @@ pub trait ElementExt {
fn lost_state(&self); fn lost_state(&self);
//fn message_full<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, type_: /*Ignored*/MessageType, domain: /*Ignored*/glib::Quark, code: i32, text: P, debug: Q, file: &str, function: &str, line: i32); //fn message_full<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, type_: MessageType, domain: /*Ignored*/glib::Quark, code: i32, text: P, debug: Q, file: &str, function: &str, line: i32);
//#[cfg(feature = "v1_10")] //#[cfg(feature = "v1_10")]
//fn message_full_with_details<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, type_: /*Ignored*/MessageType, domain: /*Ignored*/glib::Quark, code: i32, text: P, debug: Q, file: &str, function: &str, line: i32, structure: /*Ignored*/&mut Structure); //fn message_full_with_details<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, type_: MessageType, domain: /*Ignored*/glib::Quark, code: i32, text: P, debug: Q, file: &str, function: &str, line: i32, structure: /*Ignored*/&mut Structure);
fn no_more_pads(&self); fn no_more_pads(&self);
//fn post_message(&self, message: /*Ignored*/&mut Message) -> bool; fn post_message(&self, message: &mut Message) -> bool;
fn provide_clock(&self) -> Option<Clock>; fn provide_clock(&self) -> Option<Clock>;
@ -389,12 +390,12 @@ impl<O: IsA<Element> + IsA<glib::object::Object>> ElementExt for O {
} }
} }
//fn message_full<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, type_: /*Ignored*/MessageType, domain: /*Ignored*/glib::Quark, code: i32, text: P, debug: Q, file: &str, function: &str, line: i32) { //fn message_full<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, type_: MessageType, domain: /*Ignored*/glib::Quark, code: i32, text: P, debug: Q, file: &str, function: &str, line: i32) {
// unsafe { TODO: call ffi::gst_element_message_full() } // unsafe { TODO: call ffi::gst_element_message_full() }
//} //}
//#[cfg(feature = "v1_10")] //#[cfg(feature = "v1_10")]
//fn message_full_with_details<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, type_: /*Ignored*/MessageType, domain: /*Ignored*/glib::Quark, code: i32, text: P, debug: Q, file: &str, function: &str, line: i32, structure: /*Ignored*/&mut Structure) { //fn message_full_with_details<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, type_: MessageType, domain: /*Ignored*/glib::Quark, code: i32, text: P, debug: Q, file: &str, function: &str, line: i32, structure: /*Ignored*/&mut Structure) {
// unsafe { TODO: call ffi::gst_element_message_full_with_details() } // unsafe { TODO: call ffi::gst_element_message_full_with_details() }
//} //}
@ -404,9 +405,11 @@ impl<O: IsA<Element> + IsA<glib::object::Object>> ElementExt for O {
} }
} }
//fn post_message(&self, message: /*Ignored*/&mut Message) -> bool { fn post_message(&self, message: &mut Message) -> bool {
// unsafe { TODO: call ffi::gst_element_post_message() } unsafe {
//} from_glib(ffi::gst_element_post_message(self.to_glib_none().0, message.to_glib_full()))
}
}
fn provide_clock(&self) -> Option<Clock> { fn provide_clock(&self) -> Option<Clock> {
unsafe { unsafe {

View file

@ -4,6 +4,67 @@
use ffi; use ffi;
use glib::translate::*; use glib::translate::*;
bitflags! {
pub struct MessageType: u32 {
const MESSAGE_UNKNOWN = 0;
const MESSAGE_EOS = 1;
const MESSAGE_ERROR = 2;
const MESSAGE_WARNING = 4;
const MESSAGE_INFO = 8;
const MESSAGE_TAG = 16;
const MESSAGE_BUFFERING = 32;
const MESSAGE_STATE_CHANGED = 64;
const MESSAGE_STATE_DIRTY = 128;
const MESSAGE_STEP_DONE = 256;
const MESSAGE_CLOCK_PROVIDE = 512;
const MESSAGE_CLOCK_LOST = 1024;
const MESSAGE_NEW_CLOCK = 2048;
const MESSAGE_STRUCTURE_CHANGE = 4096;
const MESSAGE_STREAM_STATUS = 8192;
const MESSAGE_APPLICATION = 16384;
const MESSAGE_ELEMENT = 32768;
const MESSAGE_SEGMENT_START = 65536;
const MESSAGE_SEGMENT_DONE = 131072;
const MESSAGE_DURATION_CHANGED = 262144;
const MESSAGE_LATENCY = 524288;
const MESSAGE_ASYNC_START = 1048576;
const MESSAGE_ASYNC_DONE = 2097152;
const MESSAGE_REQUEST_STATE = 4194304;
const MESSAGE_STEP_START = 8388608;
const MESSAGE_QOS = 16777216;
const MESSAGE_PROGRESS = 33554432;
const MESSAGE_TOC = 67108864;
const MESSAGE_RESET_TIME = 134217728;
const MESSAGE_STREAM_START = 268435456;
const MESSAGE_NEED_CONTEXT = 536870912;
const MESSAGE_HAVE_CONTEXT = 1073741824;
const MESSAGE_EXTENDED = 2147483648;
const MESSAGE_DEVICE_ADDED = 2147483649;
const MESSAGE_DEVICE_REMOVED = 2147483650;
const MESSAGE_PROPERTY_NOTIFY = 2147483651;
const MESSAGE_STREAM_COLLECTION = 2147483652;
const MESSAGE_STREAMS_SELECTED = 2147483653;
const MESSAGE_REDIRECT = 2147483654;
const MESSAGE_ANY = 4294967295;
}
}
#[doc(hidden)]
impl ToGlib for MessageType {
type GlibType = ffi::GstMessageType;
fn to_glib(&self) -> ffi::GstMessageType {
ffi::GstMessageType::from_bits_truncate(self.bits())
}
}
#[doc(hidden)]
impl FromGlib<ffi::GstMessageType> for MessageType {
fn from_glib(value: ffi::GstMessageType) -> MessageType {
MessageType::from_bits_truncate(value.bits())
}
}
bitflags! { bitflags! {
pub struct SeekFlags: u32 { pub struct SeekFlags: u32 {
const SEEK_FLAG_NONE = 0; const SEEK_FLAG_NONE = 0;

View file

@ -52,6 +52,47 @@ pub use self::enums::StateChangeReturn;
pub use self::enums::URIType; pub use self::enums::URIType;
mod flags; mod flags;
pub use self::flags::MessageType;
pub use self::flags::MESSAGE_UNKNOWN;
pub use self::flags::MESSAGE_EOS;
pub use self::flags::MESSAGE_ERROR;
pub use self::flags::MESSAGE_WARNING;
pub use self::flags::MESSAGE_INFO;
pub use self::flags::MESSAGE_TAG;
pub use self::flags::MESSAGE_BUFFERING;
pub use self::flags::MESSAGE_STATE_CHANGED;
pub use self::flags::MESSAGE_STATE_DIRTY;
pub use self::flags::MESSAGE_STEP_DONE;
pub use self::flags::MESSAGE_CLOCK_PROVIDE;
pub use self::flags::MESSAGE_CLOCK_LOST;
pub use self::flags::MESSAGE_NEW_CLOCK;
pub use self::flags::MESSAGE_STRUCTURE_CHANGE;
pub use self::flags::MESSAGE_STREAM_STATUS;
pub use self::flags::MESSAGE_APPLICATION;
pub use self::flags::MESSAGE_ELEMENT;
pub use self::flags::MESSAGE_SEGMENT_START;
pub use self::flags::MESSAGE_SEGMENT_DONE;
pub use self::flags::MESSAGE_DURATION_CHANGED;
pub use self::flags::MESSAGE_LATENCY;
pub use self::flags::MESSAGE_ASYNC_START;
pub use self::flags::MESSAGE_ASYNC_DONE;
pub use self::flags::MESSAGE_REQUEST_STATE;
pub use self::flags::MESSAGE_STEP_START;
pub use self::flags::MESSAGE_QOS;
pub use self::flags::MESSAGE_PROGRESS;
pub use self::flags::MESSAGE_TOC;
pub use self::flags::MESSAGE_RESET_TIME;
pub use self::flags::MESSAGE_STREAM_START;
pub use self::flags::MESSAGE_NEED_CONTEXT;
pub use self::flags::MESSAGE_HAVE_CONTEXT;
pub use self::flags::MESSAGE_EXTENDED;
pub use self::flags::MESSAGE_DEVICE_ADDED;
pub use self::flags::MESSAGE_DEVICE_REMOVED;
pub use self::flags::MESSAGE_PROPERTY_NOTIFY;
pub use self::flags::MESSAGE_STREAM_COLLECTION;
pub use self::flags::MESSAGE_STREAMS_SELECTED;
pub use self::flags::MESSAGE_REDIRECT;
pub use self::flags::MESSAGE_ANY;
pub use self::flags::SeekFlags; pub use self::flags::SeekFlags;
pub use self::flags::SEEK_FLAG_NONE; pub use self::flags::SEEK_FLAG_NONE;
pub use self::flags::SEEK_FLAG_FLUSH; pub use self::flags::SEEK_FLAG_FLUSH;

View file

@ -32,6 +32,11 @@ pub use glib::{
pub use auto::*; pub use auto::*;
mod auto; mod auto;
pub mod miniobject;
pub use miniobject::GstRc;
pub mod message;
pub use message::Message;
use std::ptr; use std::ptr;
pub fn init() -> Result<(), glib::Error> { pub fn init() -> Result<(), glib::Error> {

73
gstreamer/src/message.rs Normal file
View file

@ -0,0 +1,73 @@
// Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ffi;
use Object;
use MessageType;
use miniobject::*;
use std::ffi::CStr;
use glib;
use glib::translate::{from_glib, from_glib_none, from_glib_full, ToGlibPtr, ToGlib};
#[repr(C)]
pub struct MessageImpl(ffi::GstMessage);
pub type Message = GstRc<MessageImpl>;
unsafe impl MiniObject for MessageImpl {
type GstType = ffi::GstMessage;
}
impl MessageImpl {
pub fn new_eos(src: &Object) -> GstRc<Self> {
unsafe {
from_glib_full(ffi::gst_message_new_eos(src.to_glib_none().0))
}
}
pub fn get_src(&self) -> Object {
unsafe {
from_glib_none((*self.as_ptr()).src)
}
}
pub fn get_message_type(&self) -> MessageType {
unsafe {
from_glib((*self.as_ptr()).type_)
}
}
pub fn get_message_type_name(&self) -> &'static str {
unsafe {
CStr::from_ptr(ffi::gst_message_type_get_name(self.get_message_type().to_glib())).to_str().unwrap()
}
}
pub fn get_seqnum(&self) -> u32 {
unsafe {
ffi::gst_message_get_seqnum(self.as_mut_ptr())
}
}
pub fn set_seqnum(&mut self, seqnum: u32) {
unsafe {
ffi::gst_message_set_seqnum(self.as_mut_ptr(), seqnum)
}
}
// TODO get_structure(), get_mut_structure()
}
impl glib::types::StaticType for GstRc<MessageImpl> {
fn static_type() -> glib::types::Type {
unsafe {
from_glib(ffi::gst_message_get_type())
}
}
}

258
gstreamer/src/miniobject.rs Normal file
View file

@ -0,0 +1,258 @@
// Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::{fmt, ops, borrow};
use std::mem;
use std::marker::PhantomData;
use ffi;
use glib;
use glib::translate::{from_glib, Stash, StashMut, ToGlibPtr, ToGlibPtrMut, FromGlibPtrNone, FromGlibPtrFull, FromGlibPtrBorrow};
#[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct GstRc<T: MiniObject> {
obj: *mut T,
borrowed: bool,
phantom: PhantomData<T>,
}
impl<T: MiniObject> GstRc<T> {
pub unsafe fn from_glib_none(ptr: *const T::GstType) -> Self {
assert!(!ptr.is_null());
ffi::gst_mini_object_ref(ptr as *mut ffi::GstMiniObject);
GstRc {
obj: T::from_mut_ptr(ptr as *mut T::GstType) as *mut T,
borrowed: false,
phantom: PhantomData,
}
}
pub unsafe fn from_glib_full(ptr: *const T::GstType) -> Self {
assert!(!ptr.is_null());
GstRc {
obj: T::from_mut_ptr(ptr as *mut T::GstType) as *mut T,
borrowed: false,
phantom: PhantomData,
}
}
pub unsafe fn from_glib_borrow(ptr: *const T::GstType) -> Self {
assert!(!ptr.is_null());
GstRc {
obj: T::from_mut_ptr(ptr as *mut T::GstType) as *mut T,
borrowed: true,
phantom: PhantomData,
}
}
pub fn make_mut(&mut self) -> &mut T {
unsafe {
if self.is_writable() {
return &mut *self.obj;
}
self.obj = T::from_mut_ptr(
ffi::gst_mini_object_make_writable(
self.as_mut_ptr() as *mut ffi::GstMiniObject
) as *mut T::GstType
);
assert!(self.is_writable());
&mut *self.obj
}
}
pub fn get_mut(&mut self) -> Option<&mut T> {
if self.is_writable() {
Some(unsafe { &mut *self.obj })
} else {
None
}
}
pub fn copy(&self) -> Self {
unsafe {
GstRc::from_glib_full(
ffi::gst_mini_object_copy(
self.as_ptr() as *const ffi::GstMiniObject
) as *const T::GstType
)
}
}
pub fn is_writable(&self) -> bool {
unsafe {
from_glib(ffi::gst_mini_object_is_writable(self.as_ptr() as *const ffi::GstMiniObject))
}
}
pub unsafe fn into_ptr(self) -> *mut T::GstType {
let ptr = self.as_mut_ptr();
mem::forget(self);
ptr
}
}
impl<T: MiniObject> ops::Deref for GstRc<T> {
type Target = T;
fn deref(&self) -> &T {
self.as_ref()
}
}
impl<T: MiniObject> AsRef<T> for GstRc<T> {
fn as_ref(&self) -> &T {
unsafe { &*self.obj }
}
}
impl<T: MiniObject> borrow::Borrow<T> for GstRc<T> {
fn borrow(&self) -> &T {
self.as_ref()
}
}
// FIXME: Not generally possible because neither T nor ToOwned are defined here...
//impl<T: MiniObject> ToOwned for T {
// type Owned = GstRc<T>;
//
// fn to_owned(&self) -> GstRc<T> {
// unsafe { GstRc::from_unowned_ptr(self.as_ptr()) }
// }
//}
impl<T: MiniObject> Clone for GstRc<T> {
fn clone(&self) -> GstRc<T> {
unsafe { GstRc::from_glib_none(self.as_ptr()) }
}
}
impl<T: MiniObject> Drop for GstRc<T> {
fn drop(&mut self) {
if !self.borrowed {
unsafe {
ffi::gst_mini_object_unref(self.as_mut_ptr() as *mut ffi::GstMiniObject);
}
}
}
}
unsafe impl<T: MiniObject + Sync> Sync for GstRc<T> {}
unsafe impl<T: MiniObject + Send> Send for GstRc<T> {}
impl<T: MiniObject + fmt::Display> fmt::Display for GstRc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(unsafe { &*self.obj }).fmt(f)
}
}
pub unsafe trait MiniObject
where
Self: Sized,
{
type GstType;
unsafe fn as_ptr(&self) -> *const Self::GstType {
self as *const Self as *const Self::GstType
}
unsafe fn as_mut_ptr(&self) -> *mut Self::GstType {
self as *const Self as *mut Self::GstType
}
unsafe fn from_ptr<'a>(ptr: *const Self::GstType) -> &'a Self {
assert!(!ptr.is_null());
&*(ptr as *const Self)
}
unsafe fn from_mut_ptr<'a>(ptr: *mut Self::GstType) -> &'a mut Self {
assert!(!ptr.is_null());
&mut *(ptr as *mut Self)
}
}
impl<'a, T: MiniObject + 'static> ToGlibPtr<'a, *const T::GstType> for GstRc<T> {
type Storage = &'a Self;
fn to_glib_none(&'a self) -> Stash<'a, *const T::GstType, Self> {
Stash(unsafe { self.as_ptr() }, self)
}
fn to_glib_full(&self) -> *const T::GstType {
unsafe {
ffi::gst_mini_object_ref(self.as_mut_ptr() as *mut ffi::GstMiniObject);
self.as_ptr()
}
}
}
impl<'a, T: MiniObject + 'static> ToGlibPtr<'a, *mut T::GstType> for GstRc<T> {
type Storage = &'a Self;
fn to_glib_none(&'a self) -> Stash<'a, *mut T::GstType, Self> {
Stash(unsafe { self.as_mut_ptr() }, self)
}
fn to_glib_full(&self) -> *mut T::GstType {
unsafe {
ffi::gst_mini_object_ref(self.as_mut_ptr() as *mut ffi::GstMiniObject);
self.as_mut_ptr()
}
}
}
impl<'a, T: MiniObject + 'static> ToGlibPtrMut<'a, *mut T::GstType> for GstRc<T> {
type Storage = &'a mut Self;
fn to_glib_none_mut(&'a mut self) -> StashMut<*mut T::GstType, Self> {
self.make_mut();
StashMut(unsafe { self.as_mut_ptr() }, self)
}
}
impl<T: MiniObject + 'static> FromGlibPtrNone<*const T::GstType> for GstRc<T> {
unsafe fn from_glib_none(ptr: *const T::GstType) -> Self {
Self::from_glib_none(ptr)
}
}
impl<T: MiniObject + 'static> FromGlibPtrNone<*mut T::GstType> for GstRc<T> {
unsafe fn from_glib_none(ptr: *mut T::GstType) -> Self {
Self::from_glib_none(ptr)
}
}
impl<T: MiniObject + 'static> FromGlibPtrFull<*const T::GstType> for GstRc<T> {
unsafe fn from_glib_full(ptr: *const T::GstType) -> Self {
Self::from_glib_full(ptr)
}
}
impl<T: MiniObject + 'static> FromGlibPtrFull<*mut T::GstType> for GstRc<T> {
unsafe fn from_glib_full(ptr: *mut T::GstType) -> Self {
Self::from_glib_full(ptr)
}
}
impl<T: MiniObject + 'static> FromGlibPtrBorrow<*const T::GstType> for GstRc<T> {
unsafe fn from_glib_borrow(ptr: *const T::GstType) -> Self {
Self::from_glib_borrow(ptr)
}
}
impl<T: MiniObject + 'static> FromGlibPtrBorrow<*mut T::GstType> for GstRc<T> {
unsafe fn from_glib_borrow(ptr: *mut T::GstType) -> Self {
Self::from_glib_borrow(ptr)
}
}