added g_list_insert_before().

Sat Jun 30 23:14:32 2001  Tim Janik  <timj@gtk.org>

        * glib/glist.[hc]: added g_list_insert_before().

        * glib/gslist.c (g_slist_insert_before): provide an implementation,
        prototype was already present...

Sat Jun 30 11:07:00 2001  Tim Janik  <timj@gtk.org>

        * gobject.[hc]: provide weak_ref/weak_unref functions,
        invoked from ->dispose. renamed ->shutdown() to ->dispose(),
        provide "public" API entry here: g_object_run_dispose(), this
        fucntion should _only_ be called from object system implementations
        (e.g. gtkobject.c) if at all.

        * gtypemodule.c (g_type_module_dispose): s/shutdown/dispose/

        * gsignal.h: removed compat aliases.

        * gobject.c (g_object_connect): support data objects.
This commit is contained in:
Tim Janik 2001-07-02 05:02:13 +00:00 committed by Tim Janik
parent 4f96a13cba
commit 69f32ba7c9
19 changed files with 370 additions and 94 deletions

View File

@ -1,3 +1,10 @@
Sat Jun 30 23:14:32 2001 Tim Janik <timj@gtk.org>
* glib/glist.[hc]: added g_list_insert_before().
* glib/gslist.c (g_slist_insert_before): provide an implementation,
prototype was already present...
Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com> Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com>
* glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS * glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS

View File

@ -1,3 +1,10 @@
Sat Jun 30 23:14:32 2001 Tim Janik <timj@gtk.org>
* glib/glist.[hc]: added g_list_insert_before().
* glib/gslist.c (g_slist_insert_before): provide an implementation,
prototype was already present...
Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com> Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com>
* glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS * glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS

View File

@ -1,3 +1,10 @@
Sat Jun 30 23:14:32 2001 Tim Janik <timj@gtk.org>
* glib/glist.[hc]: added g_list_insert_before().
* glib/gslist.c (g_slist_insert_before): provide an implementation,
prototype was already present...
Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com> Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com>
* glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS * glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS

View File

@ -1,3 +1,10 @@
Sat Jun 30 23:14:32 2001 Tim Janik <timj@gtk.org>
* glib/glist.[hc]: added g_list_insert_before().
* glib/gslist.c (g_slist_insert_before): provide an implementation,
prototype was already present...
Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com> Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com>
* glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS * glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS

View File

@ -1,3 +1,10 @@
Sat Jun 30 23:14:32 2001 Tim Janik <timj@gtk.org>
* glib/glist.[hc]: added g_list_insert_before().
* glib/gslist.c (g_slist_insert_before): provide an implementation,
prototype was already present...
Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com> Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com>
* glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS * glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS

View File

@ -1,3 +1,10 @@
Sat Jun 30 23:14:32 2001 Tim Janik <timj@gtk.org>
* glib/glist.[hc]: added g_list_insert_before().
* glib/gslist.c (g_slist_insert_before): provide an implementation,
prototype was already present...
Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com> Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com>
* glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS * glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS

View File

@ -1,3 +1,10 @@
Sat Jun 30 23:14:32 2001 Tim Janik <timj@gtk.org>
* glib/glist.[hc]: added g_list_insert_before().
* glib/gslist.c (g_slist_insert_before): provide an implementation,
prototype was already present...
Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com> Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com>
* glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS * glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS

View File

@ -1,3 +1,10 @@
Sat Jun 30 23:14:32 2001 Tim Janik <timj@gtk.org>
* glib/glist.[hc]: added g_list_insert_before().
* glib/gslist.c (g_slist_insert_before): provide an implementation,
prototype was already present...
Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com> Sun Jul 1 20:16:25 2001 Owen Taylor <otaylor@redhat.com>
* glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS * glib/guniprop.c (g_unichar_totitle): Use G_N_ELEMENTS

View File

@ -61,6 +61,23 @@
@closure: @closure:
@Returns: @Returns:
<!-- ##### MACRO g_signal_newc ##### -->
<para>
</para>
@Returns:
@signal_name:
@itype:
@signal_flags:
@class_offset:
@accumulator:
@accu_data:
@c_marshaller:
@return_type:
@n_params:
@Varargs:
<!-- ##### FUNCTION g_type_value_is_a ##### --> <!-- ##### FUNCTION g_type_value_is_a ##### -->
<para> <para>
Determines if @value is a #GValue whose type conforms to @type. Determines if @value is a #GValue whose type conforms to @type.

View File

@ -207,25 +207,6 @@ filled in by the g_signal_query() function.
<!-- ##### MACRO g_signal_newc ##### -->
<para>
</para>
@Returns:
<!-- # Unused Parameters # -->
@signal_name:
@itype:
@signal_flags:
@class_offset:
@accumulator:
@accu_data:
@c_marshaller:
@return_type:
@n_params:
@Varargs:
<!-- ##### FUNCTION g_signal_newv ##### --> <!-- ##### FUNCTION g_signal_newv ##### -->
<para> <para>

View File

@ -317,6 +317,56 @@ g_list_insert (GList *list,
return list; return list;
} }
GList*
g_list_insert_before (GList *list,
GList *sibling,
gpointer data)
{
if (!list)
{
list = g_list_alloc ();
list->data = data;
g_return_val_if_fail (sibling == NULL, list);
return list;
}
else if (sibling)
{
GList *node;
node = g_list_alloc ();
node->data = data;
if (sibling->prev)
{
node->prev = sibling->prev;
node->prev->next = node;
node->next = sibling;
sibling->prev = node;
return list;
}
else
{
node->next = sibling;
sibling->prev = node;
g_return_val_if_fail (sibling == list, node);
return node;
}
}
else
{
GList *last;
last = list;
while (last->next)
last = last->next;
last->next = g_list_alloc ();
last->next->data = data;
last->next->prev = last;
return list;
}
}
GList * GList *
g_list_concat (GList *list1, GList *list2) g_list_concat (GList *list1, GList *list2)
{ {

View File

@ -57,6 +57,9 @@ GList* g_list_insert (GList *list,
GList* g_list_insert_sorted (GList *list, GList* g_list_insert_sorted (GList *list,
gpointer data, gpointer data,
GCompareFunc func); GCompareFunc func);
GList* g_list_insert_before (GList *list,
GList *sibling,
gpointer data);
GList* g_list_concat (GList *list1, GList* g_list_concat (GList *list1,
GList *list2); GList *list2);
GList* g_list_remove (GList *list, GList* g_list_remove (GList *list,

View File

@ -307,6 +307,45 @@ g_slist_insert (GSList *list,
return list; return list;
} }
GSList*
g_slist_insert_before (GSList *slist,
GSList *sibling,
gpointer data)
{
if (!slist)
{
slist = g_slist_alloc ();
slist->data = data;
g_return_val_if_fail (sibling == NULL, slist);
return slist;
}
else
{
GSList *node, *last = NULL;
for (node = slist; node; last = node, node = last->next)
if (node == sibling)
break;
if (!last)
{
node = g_slist_alloc ();
node->data = data;
node->next = slist;
return node;
}
else
{
node = g_slist_alloc ();
node->data = data;
node->next = last->next;
last->next = node;
return slist;
}
}
}
GSList * GSList *
g_slist_concat (GSList *list1, GSList *list2) g_slist_concat (GSList *list1, GSList *list2)
{ {

View File

@ -1,3 +1,17 @@
Sat Jun 30 11:07:00 2001 Tim Janik <timj@gtk.org>
* gobject.[hc]: provide weak_ref/weak_unref functions,
invoked from ->dispose. renamed ->shutdown() to ->dispose(),
provide "public" API entry here: g_object_run_dispose(), this
fucntion should _only_ be called from object system implementations
(e.g. gtkobject.c) if at all.
* gtypemodule.c (g_type_module_dispose): s/shutdown/dispose/
* gsignal.h: removed compat aliases.
* gobject.c (g_object_connect): support data objects.
Sat Jun 30 13:17:12 2001 Owen Taylor <otaylor@redhat.com> Sat Jun 30 13:17:12 2001 Owen Taylor <otaylor@redhat.com>
* testgruntime.c (test_object_class_init) * testgruntime.c (test_object_class_init)

View File

@ -61,7 +61,7 @@ static GObject* g_object_constructor (GType type,
guint n_construct_properties, guint n_construct_properties,
GObjectConstructParam *construct_params); GObjectConstructParam *construct_params);
static void g_object_last_unref (GObject *object); static void g_object_last_unref (GObject *object);
static void g_object_shutdown (GObject *object); static void g_object_real_dispose (GObject *object);
static void g_object_finalize (GObject *object); static void g_object_finalize (GObject *object);
static void g_object_do_set_property (GObject *object, static void g_object_do_set_property (GObject *object,
guint property_id, guint property_id,
@ -103,6 +103,7 @@ static inline void object_set_property (GObject *object,
/* --- variables --- */ /* --- variables --- */
static GQuark quark_closure_array = 0; static GQuark quark_closure_array = 0;
static GQuark quark_weak_refs = 0;
static GParamSpecPool *pspec_pool = NULL; static GParamSpecPool *pspec_pool = NULL;
static GObjectNotifyContext property_notify_context = { 0, }; static GObjectNotifyContext property_notify_context = { 0, };
static gulong gobject_signals[LAST_SIGNAL] = { 0, }; static gulong gobject_signals[LAST_SIGNAL] = { 0, };
@ -133,11 +134,8 @@ debug_objects_atexit (void)
IF_DEBUG (OBJECTS) IF_DEBUG (OBJECTS)
{ {
G_LOCK (debug_objects); G_LOCK (debug_objects);
if (debug_objects_ht) g_message ("stale GObjects: %u", debug_objects_count);
{ g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
g_message ("stale GObjects: %u", debug_objects_count);
g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
}
G_UNLOCK (debug_objects); G_UNLOCK (debug_objects);
} }
} }
@ -186,7 +184,10 @@ g_object_type_init (void) /* sync with gtype.c */
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
IF_DEBUG (OBJECTS) IF_DEBUG (OBJECTS)
g_atexit (debug_objects_atexit); {
debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
g_atexit (debug_objects_atexit);
}
#endif /* G_ENABLE_DEBUG */ #endif /* G_ENABLE_DEBUG */
} }
@ -236,6 +237,7 @@ static void
g_object_do_class_init (GObjectClass *class) g_object_do_class_init (GObjectClass *class)
{ {
quark_closure_array = g_quark_from_static_string ("GObject-closure-array"); quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
quark_weak_refs = g_quark_from_static_string ("GObject-weak-references");
pspec_pool = g_param_spec_pool_new (TRUE); pspec_pool = g_param_spec_pool_new (TRUE);
property_notify_context.quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue"); property_notify_context.quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
property_notify_context.dispatcher = g_object_notify_dispatcher; property_notify_context.dispatcher = g_object_notify_dispatcher;
@ -243,7 +245,7 @@ g_object_do_class_init (GObjectClass *class)
class->constructor = g_object_constructor; class->constructor = g_object_constructor;
class->set_property = g_object_do_set_property; class->set_property = g_object_do_set_property;
class->get_property = g_object_do_get_property; class->get_property = g_object_do_get_property;
class->shutdown = g_object_shutdown; class->dispose = g_object_real_dispose;
class->finalize = g_object_finalize; class->finalize = g_object_finalize;
class->dispatch_properties_changed = g_object_dispatch_properties_changed; class->dispatch_properties_changed = g_object_dispatch_properties_changed;
class->notify = NULL; class->notify = NULL;
@ -344,8 +346,6 @@ g_object_init (GObject *object)
IF_DEBUG (OBJECTS) IF_DEBUG (OBJECTS)
{ {
G_LOCK (debug_objects); G_LOCK (debug_objects);
if (!debug_objects_ht)
debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
debug_objects_count++; debug_objects_count++;
g_hash_table_insert (debug_objects_ht, object, object); g_hash_table_insert (debug_objects_ht, object, object);
G_UNLOCK (debug_objects); G_UNLOCK (debug_objects);
@ -382,51 +382,25 @@ g_object_do_get_property (GObject *object,
} }
static void static void
g_object_last_unref (GObject *object) g_object_real_dispose (GObject *object)
{ {
g_return_if_fail (object->ref_count > 0); guint ref_count;
if (object->ref_count == 1) /* may have been re-referenced meanwhile */
G_OBJECT_GET_CLASS (object)->shutdown (object);
#ifdef G_ENABLE_DEBUG
if (g_trap_object_ref == object)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
object->ref_count -= 1; g_signal_handlers_destroy (object);
g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
if (object->ref_count == 0) /* may have been re-referenced meanwhile */
{
g_signal_handlers_destroy (object);
g_object_set_qdata (object, quark_closure_array, NULL);
G_OBJECT_GET_CLASS (object)->finalize (object);
#ifdef G_ENABLE_DEBUG
IF_DEBUG (OBJECTS)
{
G_LOCK (debug_objects);
if (debug_objects_ht)
g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
G_UNLOCK (debug_objects);
}
#endif /* G_ENABLE_DEBUG */
g_type_free_instance ((GTypeInstance*) object);
}
}
static void /* yes, temporarily altering the ref_count is hackish, but that
g_object_shutdown (GObject *object) * enforces people not jerking around with weak_ref notifiers
{
/* this function needs to be always present for unconditional
* chaining, we also might add some code here later.
* beware though, subclasses may invoke shutdown() arbitrarily.
*/ */
ref_count = object->ref_count;
object->ref_count = 0;
g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
object->ref_count = ref_count;
} }
static void static void
g_object_finalize (GObject *object) g_object_finalize (GObject *object)
{ {
g_signal_handlers_destroy (object);
g_datalist_clear (&object->qdata); g_datalist_clear (&object->qdata);
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
@ -441,6 +415,38 @@ g_object_finalize (GObject *object)
#endif /* G_ENABLE_DEBUG */ #endif /* G_ENABLE_DEBUG */
} }
static void
g_object_last_unref (GObject *object)
{
g_return_if_fail (object->ref_count > 0);
if (object->ref_count == 1) /* may have been re-referenced meanwhile */
G_OBJECT_GET_CLASS (object)->dispose (object);
#ifdef G_ENABLE_DEBUG
if (g_trap_object_ref == object)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
object->ref_count -= 1;
if (object->ref_count == 0) /* may have been re-referenced meanwhile */
{
g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
G_OBJECT_GET_CLASS (object)->finalize (object);
#ifdef G_ENABLE_DEBUG
IF_DEBUG (OBJECTS)
{
/* catch objects not chaining finalize handlers */
G_LOCK (debug_objects);
g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
G_UNLOCK (debug_objects);
}
#endif /* G_ENABLE_DEBUG */
g_type_free_instance ((GTypeInstance*) object);
}
}
static void static void
g_object_dispatch_properties_changed (GObject *object, g_object_dispatch_properties_changed (GObject *object,
guint n_pspecs, guint n_pspecs,
@ -452,6 +458,17 @@ g_object_dispatch_properties_changed (GObject *object,
g_signal_emit (object, gobject_signals[NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]); g_signal_emit (object, gobject_signals[NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
} }
void
g_object_run_dispose (GObject *object)
{
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (object->ref_count > 0);
g_object_ref (object);
G_OBJECT_GET_CLASS (object)->dispose (object);
g_object_unref (object);
}
void void
g_object_freeze_notify (GObject *object) g_object_freeze_notify (GObject *object)
{ {
@ -1068,24 +1085,40 @@ g_object_connect (gpointer _object,
{ {
gpointer callback = va_arg (var_args, gpointer); gpointer callback = va_arg (var_args, gpointer);
gpointer data = va_arg (var_args, gpointer); gpointer data = va_arg (var_args, gpointer);
guint sid; gulong sid;
if (strncmp (signal_spec, "signal::", 8) == 0) if (strncmp (signal_spec, "signal::", 8) == 0)
sid = g_signal_connect_data (object, signal_spec + 8, sid = g_signal_connect_data (object, signal_spec + 8,
callback, data, NULL, callback, data, NULL,
0); 0);
else if (strncmp (signal_spec, "object_signal::", 15) == 0)
sid = g_signal_connect_object (object, signal_spec + 15,
callback, data,
0);
else if (strncmp (signal_spec, "swapped_signal::", 16) == 0) else if (strncmp (signal_spec, "swapped_signal::", 16) == 0)
sid = g_signal_connect_data (object, signal_spec + 16, sid = g_signal_connect_data (object, signal_spec + 16,
callback, data, NULL, callback, data, NULL,
G_CONNECT_SWAPPED); G_CONNECT_SWAPPED);
else if (strncmp (signal_spec, "swapped_object_signal::", 23) == 0)
sid = g_signal_connect_object (object, signal_spec + 23,
callback, data,
G_CONNECT_SWAPPED);
else if (strncmp (signal_spec, "signal_after::", 14) == 0) else if (strncmp (signal_spec, "signal_after::", 14) == 0)
sid = g_signal_connect_data (object, signal_spec + 14, sid = g_signal_connect_data (object, signal_spec + 14,
callback, data, NULL, callback, data, NULL,
G_CONNECT_AFTER); G_CONNECT_AFTER);
else if (strncmp (signal_spec, "object_signal_after::", 21) == 0)
sid = g_signal_connect_object (object, signal_spec + 21,
callback, data,
G_CONNECT_AFTER);
else if (strncmp (signal_spec, "swapped_signal_after::", 22) == 0) else if (strncmp (signal_spec, "swapped_signal_after::", 22) == 0)
sid = g_signal_connect_data (object, signal_spec + 22, sid = g_signal_connect_data (object, signal_spec + 22,
callback, data, NULL, callback, data, NULL,
G_CONNECT_SWAPPED | G_CONNECT_AFTER); G_CONNECT_SWAPPED | G_CONNECT_AFTER);
else if (strncmp (signal_spec, "swapped_object_signal_after::", 29) == 0)
sid = g_signal_connect_object (object, signal_spec + 29,
callback, data,
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
else else
{ {
g_warning ("%s: invalid signal spec \"%s\"", G_STRLOC, signal_spec); g_warning ("%s: invalid signal spec \"%s\"", G_STRLOC, signal_spec);
@ -1146,6 +1179,88 @@ g_object_disconnect (gpointer _object,
return object; return object;
} }
typedef struct {
guint n_weak_refs;
struct {
GWeakNotify notify;
gpointer data;
} weak_refs[1]; /* flexible array */
} WeakRefStack;
static void
weak_refs_notify (gpointer data)
{
WeakRefStack *wstack = data;
guint i;
for (i = 0; i < wstack->n_weak_refs; i++)
wstack->weak_refs[i].notify (wstack->weak_refs[i].data);
g_free (wstack);
}
void
g_object_weak_ref (GObject *object,
GWeakNotify notify,
gpointer data)
{
WeakRefStack *wstack;
guint i;
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (notify != NULL);
g_return_if_fail (object->ref_count >= 1);
wstack = g_datalist_id_remove_no_notify (&object->qdata, quark_weak_refs);
if (wstack)
{
i = wstack->n_weak_refs++;
wstack = g_realloc (wstack, sizeof (*wstack) + sizeof (wstack->weak_refs[0]) * i);
}
else
{
wstack = g_renew (WeakRefStack, NULL, 1);
wstack->n_weak_refs = 1;
i = wstack->n_weak_refs;
}
wstack->weak_refs[i].notify = notify;
wstack->weak_refs[i].data = data;
g_datalist_id_set_data_full (&object->qdata, quark_weak_refs, wstack, weak_refs_notify);
}
void
g_object_weak_unref (GObject *object,
GWeakNotify notify,
gpointer data)
{
WeakRefStack *wstack;
gboolean found_one = FALSE;
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (notify != NULL);
wstack = g_datalist_id_get_data (&object->qdata, quark_weak_refs);
if (wstack)
{
guint i;
for (i = 0; i < wstack->n_weak_refs; i++)
if (wstack->weak_refs[i].notify == notify &&
wstack->weak_refs[i].data == data)
{
found_one = TRUE;
wstack->n_weak_refs -= 1;
if (i != wstack->n_weak_refs)
{
wstack->weak_refs[i].notify = wstack->weak_refs[wstack->n_weak_refs].notify;
wstack->weak_refs[i].data = wstack->weak_refs[wstack->n_weak_refs].data;
}
break;
}
}
if (!found_one)
g_warning (G_STRLOC ": couldn't find weak ref %p(%p)", notify, data);
}
gpointer gpointer
g_object_ref (gpointer _object) g_object_ref (gpointer _object)
{ {
@ -1482,6 +1597,7 @@ g_object_watch_closure (GObject *object,
GClosure *closure) GClosure *closure)
{ {
CArray *carray; CArray *carray;
guint i;
g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (closure != NULL); g_return_if_fail (closure != NULL);
@ -1493,23 +1609,21 @@ g_object_watch_closure (GObject *object,
g_closure_add_marshal_guards (closure, g_closure_add_marshal_guards (closure,
object, (GClosureNotify) g_object_ref, object, (GClosureNotify) g_object_ref,
object, (GClosureNotify) g_object_unref); object, (GClosureNotify) g_object_unref);
carray = g_object_steal_qdata (object, quark_closure_array); carray = g_datalist_id_remove_no_notify (&object->qdata, quark_closure_array);
if (!carray) if (!carray)
{ {
carray = g_renew (CArray, NULL, 1); carray = g_renew (CArray, NULL, 1);
carray->object = object; carray->object = object;
carray->n_closures = 1; carray->n_closures = 1;
carray->closures[0] = closure; i = carray->n_closures;
g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
} }
else else
{ {
guint i = carray->n_closures++; i = carray->n_closures++;
carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i); carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
carray->closures[i] = closure;
g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
} }
carray->closures[i] = closure;
g_datalist_id_set_data_full (&object->qdata, quark_closure_array, carray, destroy_closure_array);
} }
GClosure* GClosure*

View File

@ -54,6 +54,7 @@ typedef void (*GObjectSetPropertyFunc) (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
typedef void (*GObjectFinalizeFunc) (GObject *object); typedef void (*GObjectFinalizeFunc) (GObject *object);
typedef void (*GWeakNotify) (gpointer data);
struct _GObject struct _GObject
{ {
GTypeInstance g_type_instance; GTypeInstance g_type_instance;
@ -73,17 +74,17 @@ struct _GObjectClass
GObject* (*constructor) (GType type, GObject* (*constructor) (GType type,
guint n_construct_properties, guint n_construct_properties,
GObjectConstructParam *construct_properties); GObjectConstructParam *construct_properties);
void (*set_property) (GObject *object, void (*set_property) (GObject *object,
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
void (*get_property) (GObject *object, void (*get_property) (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
void (*shutdown) (GObject *object); void (*dispose) (GObject *object);
void (*finalize) (GObject *object); void (*finalize) (GObject *object);
/* seldomly overidden */ /* seldomly overidden */
void (*dispatch_properties_changed) (GObject *object, void (*dispatch_properties_changed) (GObject *object,
guint n_pspecs, guint n_pspecs,
@ -147,6 +148,12 @@ void g_object_notify (GObject *object,
void g_object_thaw_notify (GObject *object); void g_object_thaw_notify (GObject *object);
gpointer g_object_ref (gpointer object); gpointer g_object_ref (gpointer object);
void g_object_unref (gpointer object); void g_object_unref (gpointer object);
void g_object_weak_ref (GObject *object,
GWeakNotify notify,
gpointer data);
void g_object_weak_unref (GObject *object,
GWeakNotify notify,
gpointer data);
gpointer g_object_get_qdata (GObject *object, gpointer g_object_get_qdata (GObject *object,
GQuark quark); GQuark quark);
void g_object_set_qdata (GObject *object, void g_object_set_qdata (GObject *object,
@ -188,6 +195,10 @@ guint g_signal_connect_object (gpointer instance,
GConnectFlags connect_flags); GConnectFlags connect_flags);
/*< protected >*/
void g_object_run_dispose (GObject *object);
/* --- implementation macros --- */ /* --- implementation macros --- */
#define G_OBJECT_WARN_INVALID_PSPEC(object, pname, property_id, pspec) \ #define G_OBJECT_WARN_INVALID_PSPEC(object, pname, property_id, pspec) \
G_STMT_START { \ G_STMT_START { \

View File

@ -238,15 +238,6 @@ guint g_signal_handlers_disconnect_matched (gpointer instance,
g_signal_handlers_unblock_matched ((instance), G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, \ g_signal_handlers_unblock_matched ((instance), G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, \
0, 0, NULL, (func), (data)) 0, 0, NULL, (func), (data))
#ifndef G_DISABLE_COMPAT
/* tmp compat, to be nuked soon */
#define g_signal_connectc(instance, detailed_signal, c_handler, data, swapped) \
g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (swapped)?G_CONNECT_SWAPPED:0);
#define g_signal_newc g_signal_new
#define g_signal_disconnect_by_func g_signal_handlers_disconnect_by_func
#define g_signal_block_by_func g_signal_handlers_block_by_func
#define g_signal_unblock_by_func g_signal_handlers_unblock_by_func
#endif
/*< private >*/ /*< private >*/
void g_signal_handlers_destroy (gpointer instance); void g_signal_handlers_destroy (gpointer instance);

View File

@ -171,7 +171,7 @@ struct _GTypeQuery
#define G_TYPE_FROM_INTERFACE(g_iface) (((GTypeInterface*) (g_iface))->g_type) #define G_TYPE_FROM_INTERFACE(g_iface) (((GTypeInterface*) (g_iface))->g_type)
/* debug flags for g_type_init() */ /* debug flags for g_type_init_with_debug_flags() */
typedef enum /*< skip >*/ typedef enum /*< skip >*/
{ {
G_TYPE_DEBUG_NONE = 0, G_TYPE_DEBUG_NONE = 0,

View File

@ -51,21 +51,21 @@ static void g_type_module_complete_interface_info (GTypePlugin *plugin,
GType interface_type, GType interface_type,
GInterfaceInfo *info); GInterfaceInfo *info);
static GObjectClass *parent_class; static gpointer parent_class = NULL;
static void static void
g_type_module_shutdown (GObject *object) g_type_module_dispose (GObject *object)
{ {
GTypeModule *module = G_TYPE_MODULE (object); GTypeModule *module = G_TYPE_MODULE (object);
if (module->type_infos || module->interface_infos) if (module->type_infos || module->interface_infos)
{ {
g_warning (G_STRLOC ": shutdown should never happen for static type plugins once types or interfaces have been registered"); g_warning (G_STRLOC ": unsolicitated invocation of g_object_dispose() on GTypeModule");
g_object_ref (object); g_object_ref (object);
} }
parent_class->shutdown (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
static void static void
@ -75,7 +75,7 @@ g_type_module_finalize (GObject *object)
g_free (module->name); g_free (module->name);
parent_class->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
static void static void
@ -85,7 +85,7 @@ g_type_module_class_init (GTypeModuleClass *class)
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class)); parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class));
gobject_class->shutdown = g_type_module_shutdown; gobject_class->dispose = g_type_module_dispose;
gobject_class->finalize = g_type_module_finalize; gobject_class->finalize = g_type_module_finalize;
} }