mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-06-07 16:08:55 +00:00
Store type ids in a static BTreeMap
static variables inside generic functions are shared between all instances of the function, we can't use that for storing our generated type id.
This commit is contained in:
parent
1260dc42bb
commit
395a002f4a
1 changed files with 45 additions and 34 deletions
|
@ -10,6 +10,9 @@ use std::ffi::CString;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
use std::any::TypeId;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use glib_ffi;
|
use glib_ffi;
|
||||||
use gobject_ffi;
|
use gobject_ffi;
|
||||||
|
@ -373,48 +376,56 @@ unsafe extern "C" fn set_property<T: ObjectType>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mut TYPES: *mut Mutex<BTreeMap<TypeId, glib::Type>> = 0 as *mut _;
|
||||||
|
|
||||||
pub unsafe fn get_type<T: ObjectType>() -> glib_ffi::GType {
|
pub unsafe fn get_type<T: ObjectType>() -> glib_ffi::GType {
|
||||||
use std::sync::{Once, ONCE_INIT};
|
use std::sync::{Once, ONCE_INIT};
|
||||||
|
|
||||||
static mut TYPE: glib_ffi::GType = gobject_ffi::G_TYPE_INVALID;
|
|
||||||
static ONCE: Once = ONCE_INIT;
|
static ONCE: Once = ONCE_INIT;
|
||||||
|
|
||||||
ONCE.call_once(|| {
|
ONCE.call_once(|| {
|
||||||
let type_info = gobject_ffi::GTypeInfo {
|
TYPES = Box::into_raw(Box::new(Mutex::new(BTreeMap::new())));
|
||||||
class_size: mem::size_of::<ClassStruct<T>>() as u16,
|
|
||||||
base_init: None,
|
|
||||||
base_finalize: None,
|
|
||||||
class_init: Some(class_init::<T>),
|
|
||||||
class_finalize: None,
|
|
||||||
class_data: ptr::null_mut(),
|
|
||||||
instance_size: mem::size_of::<InstanceStruct<T>>() as u16,
|
|
||||||
n_preallocs: 0,
|
|
||||||
instance_init: None,
|
|
||||||
value_table: ptr::null(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let type_name = {
|
|
||||||
let mut idx = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let type_name = CString::new(format!("{}-{}", T::NAME, idx)).unwrap();
|
|
||||||
if gobject_ffi::g_type_from_name(type_name.as_ptr()) == gobject_ffi::G_TYPE_INVALID
|
|
||||||
{
|
|
||||||
break type_name;
|
|
||||||
}
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TYPE = gobject_ffi::g_type_register_static(
|
|
||||||
T::glib_type().to_glib(),
|
|
||||||
type_name.as_ptr(),
|
|
||||||
&type_info,
|
|
||||||
gobject_ffi::G_TYPE_FLAG_ABSTRACT,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
TYPE
|
let mut types = (*TYPES).lock().unwrap();
|
||||||
|
types
|
||||||
|
.entry(TypeId::of::<T>())
|
||||||
|
.or_insert_with(|| {
|
||||||
|
let type_info = gobject_ffi::GTypeInfo {
|
||||||
|
class_size: mem::size_of::<ClassStruct<T>>() as u16,
|
||||||
|
base_init: None,
|
||||||
|
base_finalize: None,
|
||||||
|
class_init: Some(class_init::<T>),
|
||||||
|
class_finalize: None,
|
||||||
|
class_data: ptr::null_mut(),
|
||||||
|
instance_size: mem::size_of::<InstanceStruct<T>>() as u16,
|
||||||
|
n_preallocs: 0,
|
||||||
|
instance_init: None,
|
||||||
|
value_table: ptr::null(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let type_name = {
|
||||||
|
let mut idx = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let type_name = CString::new(format!("{}-{}", T::NAME, idx)).unwrap();
|
||||||
|
if gobject_ffi::g_type_from_name(type_name.as_ptr()) ==
|
||||||
|
gobject_ffi::G_TYPE_INVALID
|
||||||
|
{
|
||||||
|
break type_name;
|
||||||
|
}
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
from_glib(gobject_ffi::g_type_register_static(
|
||||||
|
T::glib_type().to_glib(),
|
||||||
|
type_name.as_ptr(),
|
||||||
|
&type_info,
|
||||||
|
gobject_ffi::G_TYPE_FLAG_ABSTRACT,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.to_glib()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn sub_class_init<T: ObjectType>(
|
unsafe extern "C" fn sub_class_init<T: ObjectType>(
|
||||||
|
|
Loading…
Reference in a new issue