gpointer cache_data;
GTypeClassCacheFunc cache_func;
} ClassCacheFunc;
+typedef struct {
+ gpointer check_data;
+ GTypeInterfaceCheckFunc check_func;
+} IFaceCheckFunc;
/* --- variables --- */
static guint static_n_class_cache_funcs = 0;
static ClassCacheFunc *static_class_cache_funcs = NULL;
+static guint static_n_iface_check_funcs = 0;
+static IFaceCheckFunc *static_iface_check_funcs = NULL;
static GQuark static_quark_type_flags = 0;
static GQuark static_quark_iface_holder = 0;
static GQuark static_quark_dependants_array = 0;
g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info);
+ entry->init_state = IFACE_INIT;
+
pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
if (pnode) /* want to copy over parent iface contents */
{
TypeNode *node)
{
IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
- IFaceHolder *iholder;
+ IFaceHolder *iholder = type_iface_peek_holder_L (iface, NODE_TYPE (node));
GTypeInterface *vtable = NULL;
+ guint i;
- iholder = type_iface_peek_holder_L (iface, NODE_TYPE (node));
- if (!iholder)
- return;
-
/* iholder->info should have been filled in by type_iface_vtable_base_init_Wm() */
- g_assert (iface->data && entry && iholder->info);
+ g_assert (iface->data && entry && iholder && iholder->info);
+ entry->init_state = INITIALIZED;
+
vtable = entry->vtable;
if (iholder->info->interface_init)
iholder->info->interface_init (vtable, iholder->info->interface_data);
G_WRITE_LOCK (&type_rw_lock);
}
+
+ for (i = 0; i < static_n_iface_check_funcs; i++)
+ {
+ GTypeInterfaceCheckFunc check_func = static_iface_check_funcs[i].check_func;
+ gpointer check_data = static_iface_check_funcs[i].check_data;
+
+ G_WRITE_UNLOCK (&type_rw_lock);
+ check_func (check_data, (gpointer)vtable);
+ G_WRITE_LOCK (&type_rw_lock);
+ }
}
static gboolean
if (i == CLASSED_NODE_N_IFACES (node))
break;
- entry->init_state = IFACE_INIT;
-
if (!type_iface_vtable_base_init_Wm (lookup_type_node_I (entry->iface_type), node))
{
guint j;
if (i == CLASSED_NODE_N_IFACES (node))
break;
- entry->init_state = INITIALIZED;
-
type_iface_vtable_iface_init_Wm (lookup_type_node_I (entry->iface_type), node);
/* As in the loop above, additional initialized entries might be inserted
{
InitState class_state =
node->data ? node->data->class.init_state : UNINITIALIZED;
- InitState new_state = UNINITIALIZED;
if (class_state >= BASE_IFACE_INIT)
- {
- type_iface_vtable_base_init_Wm (iface, node);
- new_state = IFACE_INIT;
- }
-
- if (class_state >= IFACE_INIT)
- {
- type_iface_vtable_iface_init_Wm (iface, node);
- new_state = INITIALIZED;
- }
+ type_iface_vtable_base_init_Wm (iface, node);
- if (class_state != UNINITIALIZED && class_state != INITIALIZED)
- {
- /* The interface was added while we were initializing the class
- */
- IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
- g_assert (entry);
-
- entry->init_state = new_state;
- }
+ if (class_state >= IFACE_INIT)
+ type_iface_vtable_iface_init_Wm (iface, node);
}
static void
}
+void
+g_type_add_interface_check (gpointer check_data,
+ GTypeInterfaceCheckFunc check_func)
+{
+ guint i;
+
+ g_return_if_fail (check_func != NULL);
+
+ G_WRITE_LOCK (&type_rw_lock);
+ i = static_n_iface_check_funcs++;
+ static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs);
+ static_iface_check_funcs[i].check_data = check_data;
+ static_iface_check_funcs[i].check_func = check_func;
+ G_WRITE_UNLOCK (&type_rw_lock);
+}
+
+void
+g_type_remove_interface_check (gpointer check_data,
+ GTypeInterfaceCheckFunc check_func)
+{
+ gboolean found_it = FALSE;
+ guint i;
+
+ g_return_if_fail (check_func != NULL);
+
+ G_WRITE_LOCK (&type_rw_lock);
+ for (i = 0; i < static_n_iface_check_funcs; i++)
+ if (static_iface_check_funcs[i].check_data == check_data &&
+ static_iface_check_funcs[i].check_func == check_func)
+ {
+ static_n_iface_check_funcs--;
+ g_memmove (static_iface_check_funcs + i,
+ static_iface_check_funcs + i + 1,
+ sizeof (static_iface_check_funcs[0]) * (static_n_iface_check_funcs - i));
+ static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs);
+ found_it = TRUE;
+ break;
+ }
+ G_WRITE_UNLOCK (&type_rw_lock);
+
+ if (!found_it)
+ g_warning (G_STRLOC ": cannot remove unregistered class check func %p with data %p",
+ check_func, check_data);
+}
+
/* --- type registration --- */
GType
g_type_register_fundamental (GType type_id,
gpointer iface_data);
typedef gboolean (*GTypeClassCacheFunc) (gpointer cache_data,
GTypeClass *g_class);
+typedef void (*GTypeInterfaceCheckFunc) (gpointer func_data,
+ gpointer g_iface);
typedef enum /*< skip >*/
{
G_TYPE_FLAG_CLASSED = (1 << 0),
GType g_type_fundamental (GType type_id);
GTypeInstance* g_type_create_instance (GType type);
void g_type_free_instance (GTypeInstance *instance);
+
void g_type_add_class_cache_func (gpointer cache_data,
GTypeClassCacheFunc cache_func);
void g_type_remove_class_cache_func (gpointer cache_data,
GTypeClassCacheFunc cache_func);
void g_type_class_unref_uncached (gpointer g_class);
+
+void g_type_add_interface_check (gpointer check_data,
+ GTypeInterfaceCheckFunc check_func);
+void g_type_remove_interface_check (gpointer check_data,
+ GTypeInterfaceCheckFunc chec_func);
+
GTypeValueTable* g_type_value_table_peek (GType type);