forked from mirrors/gstreamer-rs
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:
parent
9b4117ea71
commit
22113dc9cb
1 changed files with 30 additions and 17 deletions
|
@ -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>(
|
||||
|
|
Loading…
Reference in a new issue