gstreamer/iterator: Store filter types in a hash table

Static variables in generic functions only exist once and not once per
type parameter, so before we were only able to register exactly one
filter type.
This commit is contained in:
Sebastian Dröge 2020-06-04 12:35:11 +03:00
parent 9b4117ea71
commit 22113dc9cb

View file

@ -358,38 +358,51 @@ unsafe extern "C" fn filter_boxed_unref<T: 'static>(boxed: gpointer) {
}
unsafe extern "C" fn filter_boxed_get_type<T: StaticType + 'static>() -> glib_sys::GType {
use std::sync::Once;
use once_cell::sync::Lazy;
use std::collections::HashMap;
use std::sync::Mutex;
static mut TYPE: glib_sys::GType = gobject_sys::G_TYPE_INVALID;
static ONCE: Once = Once::new();
static mut TYPES: Lazy<Mutex<HashMap<String, glib_sys::GType>>> =
Lazy::new(|| Mutex::new(HashMap::new()));
ONCE.call_once(|| {
let type_name = {
let mut types = TYPES.lock().unwrap();
let type_name = T::static_type().name();
if let Some(type_) = types.get(&type_name) {
return *type_;
}
let type_ = {
let iter_type_name = {
let mut idx = 0;
loop {
let type_name = CString::new(format!(
"GstRsIteratorFilterBoxed-{}-{}",
T::static_type().name(),
idx
))
.unwrap();
if gobject_sys::g_type_from_name(type_name.as_ptr()) == gobject_sys::G_TYPE_INVALID
let iter_type_name =
CString::new(format!("GstRsIteratorFilterBoxed-{}-{}", type_name, idx))
.unwrap();
if gobject_sys::g_type_from_name(iter_type_name.as_ptr())
== gobject_sys::G_TYPE_INVALID
{
break type_name;
break iter_type_name;
}
idx += 1;
}
};
TYPE = gobject_sys::g_boxed_type_register_static(
type_name.as_ptr(),
let type_ = gobject_sys::g_boxed_type_register_static(
iter_type_name.as_ptr(),
Some(filter_boxed_ref::<T>),
Some(filter_boxed_unref::<T>),
);
});
TYPE
assert_ne!(type_, gobject_sys::G_TYPE_INVALID);
type_
};
types.insert(type_name, type_);
type_
}
unsafe extern "C" fn find_trampoline<T, F: FnMut(T) -> bool>(