📄 gtype.c
字号:
* by allocating it in one chunk with tdata */ g_free (tdata); if (ptype) type_data_unref_Wm (lookup_type_node_I (ptype), FALSE); G_WRITE_UNLOCK (&type_rw_lock); g_type_plugin_unuse (node->plugin); G_WRITE_LOCK (&type_rw_lock); }}voidg_type_add_class_cache_func (gpointer cache_data, GTypeClassCacheFunc cache_func){ guint i; g_return_if_fail (cache_func != NULL); G_WRITE_LOCK (&type_rw_lock); i = static_n_class_cache_funcs++; static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs); static_class_cache_funcs[i].cache_data = cache_data; static_class_cache_funcs[i].cache_func = cache_func; G_WRITE_UNLOCK (&type_rw_lock);}voidg_type_remove_class_cache_func (gpointer cache_data, GTypeClassCacheFunc cache_func){ gboolean found_it = FALSE; guint i; g_return_if_fail (cache_func != NULL); G_WRITE_LOCK (&type_rw_lock); for (i = 0; i < static_n_class_cache_funcs; i++) if (static_class_cache_funcs[i].cache_data == cache_data && static_class_cache_funcs[i].cache_func == cache_func) { static_n_class_cache_funcs--; g_memmove (static_class_cache_funcs + i, static_class_cache_funcs + i + 1, sizeof (static_class_cache_funcs[0]) * (static_n_class_cache_funcs - i)); static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs); found_it = TRUE; break; } G_WRITE_UNLOCK (&type_rw_lock); if (!found_it) g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p", cache_func, cache_data);}/* --- type registration --- */GTypeg_type_register_fundamental (GType type_id, const gchar *type_name, const GTypeInfo *info, const GTypeFundamentalInfo *finfo, GTypeFlags flags){ GTypeFundamentalInfo *node_finfo; TypeNode *node; g_return_val_if_uninitialized (static_quark_type_flags, g_type_init, 0); g_return_val_if_fail (type_id > 0, 0); g_return_val_if_fail (type_name != NULL, 0); g_return_val_if_fail (info != NULL, 0); g_return_val_if_fail (finfo != NULL, 0); if (!check_type_name_I (type_name)) return 0; if ((type_id & TYPE_ID_MASK) || type_id > G_TYPE_FUNDAMENTAL_MAX) { g_warning ("attempt to register fundamental type `%s' with invalid type id (%lu)", type_name, type_id); return 0; } if ((finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) && !(finfo->type_flags & G_TYPE_FLAG_CLASSED)) { g_warning ("cannot register instantiatable fundamental type `%s' as non-classed", type_name); return 0; } if (lookup_type_node_I (type_id)) { g_warning ("cannot register existing fundamental type `%s' (as `%s')", type_descriptive_name_I (type_id), type_name); return 0; } G_WRITE_LOCK (&type_rw_lock); node = type_node_fundamental_new_W (type_id, type_name, finfo->type_flags); node_finfo = type_node_fundamental_info_I (node); type_add_flags_W (node, flags); if (check_type_info_I (NULL, NODE_FUNDAMENTAL_TYPE (node), type_name, info)) type_data_make_W (node, info, check_value_table_I (type_name, info->value_table) ? info->value_table : NULL); G_WRITE_UNLOCK (&type_rw_lock); return NODE_TYPE (node);}GTypeg_type_register_static (GType parent_type, const gchar *type_name, const GTypeInfo *info, GTypeFlags flags){ TypeNode *pnode, *node; GType type = 0; g_return_val_if_uninitialized (static_quark_type_flags, g_type_init, 0); g_return_val_if_fail (parent_type > 0, 0); g_return_val_if_fail (type_name != NULL, 0); g_return_val_if_fail (info != NULL, 0); if (!check_type_name_I (type_name) || !check_derivation_I (parent_type, type_name)) return 0; if (info->class_finalize) { g_warning ("class finalizer specified for static type `%s'", type_name); return 0; } pnode = lookup_type_node_I (parent_type); G_WRITE_LOCK (&type_rw_lock); type_data_ref_Wm (pnode); if (check_type_info_I (pnode, NODE_FUNDAMENTAL_TYPE (pnode), type_name, info)) { node = type_node_new_W (pnode, type_name, NULL); type_add_flags_W (node, flags); type = NODE_TYPE (node); type_data_make_W (node, info, check_value_table_I (type_name, info->value_table) ? info->value_table : NULL); } G_WRITE_UNLOCK (&type_rw_lock); return type;}GTypeg_type_register_dynamic (GType parent_type, const gchar *type_name, GTypePlugin *plugin, GTypeFlags flags){ TypeNode *pnode, *node; GType type; g_return_val_if_uninitialized (static_quark_type_flags, g_type_init, 0); g_return_val_if_fail (parent_type > 0, 0); g_return_val_if_fail (type_name != NULL, 0); g_return_val_if_fail (plugin != NULL, 0); if (!check_type_name_I (type_name) || !check_derivation_I (parent_type, type_name) || !check_plugin_U (plugin, TRUE, FALSE, type_name)) return 0; G_WRITE_LOCK (&type_rw_lock); pnode = lookup_type_node_I (parent_type); node = type_node_new_W (pnode, type_name, plugin); type_add_flags_W (node, flags); type = NODE_TYPE (node); G_WRITE_UNLOCK (&type_rw_lock); return type;}voidg_type_add_interface_static (GType instance_type, GType interface_type, const GInterfaceInfo *info){ /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */ g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type)); g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE); G_WRITE_LOCK (&type_rw_lock); if (check_add_interface_L (instance_type, interface_type)) { TypeNode *node = lookup_type_node_I (instance_type); TypeNode *iface = lookup_type_node_I (interface_type); if (check_interface_info_I (iface, NODE_TYPE (node), info)) { type_add_interface_W (node, iface, info, NULL); /* if we have a class already, the interface vtable needs to * be initialized as well */ if (node->data && node->data->class.class) type_iface_vtable_init_Wm (iface, node); } } G_WRITE_UNLOCK (&type_rw_lock);}voidg_type_add_interface_dynamic (GType instance_type, GType interface_type, GTypePlugin *plugin){ TypeNode *node; /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */ g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type)); g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE); node = lookup_type_node_I (instance_type); if (!check_plugin_U (plugin, FALSE, TRUE, NODE_NAME (node))) return; G_WRITE_LOCK (&type_rw_lock); if (check_add_interface_L (instance_type, interface_type)) { TypeNode *iface = lookup_type_node_I (interface_type); type_add_interface_W (node, iface, NULL, plugin); /* if we have a class already, the interface vtable needs to * be initialized as well */ if (node->data && node->data->class.class) type_iface_vtable_init_Wm (iface, node); } G_WRITE_UNLOCK (&type_rw_lock);}/* --- public API functions --- */gpointerg_type_class_ref (GType type){ TypeNode *node; /* optimize for common code path */ G_WRITE_LOCK (&type_rw_lock); node = lookup_type_node_I (type); if (node && node->is_classed && node->data && node->data->class.class && node->data->common.ref_count > 0) { type_data_ref_Wm (node); G_WRITE_UNLOCK (&type_rw_lock); return node->data->class.class; } if (!node || !node->is_classed || (node->data && node->data->common.ref_count < 1)) { G_WRITE_UNLOCK (&type_rw_lock); g_warning ("cannot retrieve class for invalid (unclassed) type `%s'", type_descriptive_name_I (type)); return NULL; } type_data_ref_Wm (node); if (!node->data->class.class) { GType ptype = NODE_PARENT_TYPE (node); GTypeClass *pclass = NULL; if (ptype) { G_WRITE_UNLOCK (&type_rw_lock); pclass = g_type_class_ref (ptype); if (node->data->class.class) INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node)); G_WRITE_LOCK (&type_rw_lock); } type_class_init_Wm (node, pclass); } G_WRITE_UNLOCK (&type_rw_lock); return node->data->class.class;}voidg_type_class_unref (gpointer g_class){ TypeNode *node; GTypeClass *class = g_class; g_return_if_fail (g_class != NULL); node = lookup_type_node_I (class->g_type); G_WRITE_LOCK (&type_rw_lock); if (node && node->is_classed && node->data && node->data->class.class == class && node->data->common.ref_count > 0) type_data_unref_Wm (node, FALSE); else g_warning ("cannot unreference class of invalid (unclassed) type `%s'", type_descriptive_name_I (class->g_type)); G_WRITE_UNLOCK (&type_rw_lock);}voidg_type_class_unref_uncached (gpointer g_class){ TypeNode *node; GTypeClass *class = g_class; g_return_if_fail (g_class != NULL); G_WRITE_LOCK (&type_rw_lock); node = lookup_type_node_I (class->g_type); if (node && node->is_classed && node->data && node->data->class.class == class && node->data->common.ref_count > 0) type_data_unref_Wm (node, TRUE); else g_warning ("cannot unreference class of invalid (unclassed) type `%s'", type_descriptive_name_I (class->g_type)); G_WRITE_UNLOCK (&type_rw_lock);}gpointerg_type_class_peek (GType type){ TypeNode *node; gpointer class; node = lookup_type_node_I (type); G_READ_LOCK (&type_rw_lock); if (node && node->is_classed && node->data && node->data->class.class) /* common.ref_count _may_ be 0 */ class = node->data->class.class; else class = NULL; G_READ_UNLOCK (&type_rw_lock); return class;}gpointerg_type_class_peek_parent (gpointer g_class){ TypeNode *node; gpointer class = NULL; g_return_val_if_fail (g_class != NULL, NULL); node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class)); G_READ_LOCK (&type_rw_lock); if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node)) { node = lookup_type_node_I (NODE_PARENT_TYPE (node)); class = node->data->class.class; } else if (NODE_PARENT_TYPE (node)) g_warning (G_STRLOC ": invalid class pointer `%p'", g_class); G_READ_UNLOCK (&type_rw_lock); return class;}gpointerg_type_interface_peek (gpointer instance_class, GType iface_type){ TypeNode *node; TypeNode *iface; gpointer vtable = NULL; GTypeClass *class = instance_class; g_return_val_if_fail (instance_class != NULL, NULL); node = lookup_type_node_I (class->g_type); iface = lookup_type_node_I (iface_type); if (node && node->is_instantiatable && iface) { IFaceEntry *entry; G_READ_LOCK (&type_rw_lock); entry = type_lookup_iface_entry_L (node, iface); if (entry && entry->vtable) /* entry is relocatable */ vtable = entry->vtable; G_READ_UNLOCK (&type_rw_lock); } else g_warning (G_STRLOC ": invalid class pointer `%p'", class); return vtable;}gpointerg_type_interface_peek_parent (gpointer g_iface){ TypeNode *node; TypeNode *iface; gpointer vtable = NULL; GTypeInterface *iface_class = g_iface; g_return_val_if_fail (g_iface != NULL, NULL); iface = lookup_type_node_I (iface_class->g_type); node = lookup_type_node_I (iface_class->g_instance_type); if (node) node = lookup_type_node_I (NODE_PARENT_TYPE (node)); if (node && node->is_instantiatable && iface) { IFaceEntry *entry; G_READ_LOCK (&typ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -