actor-meta: Disconnect on actor destroy
authorEmmanuele Bassi <ebassi@linux.intel.com>
Mon, 24 May 2010 10:30:17 +0000 (11:30 +0100)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Tue, 25 May 2010 10:13:03 +0000 (11:13 +0100)
When destroying an Actor the various ActorMeta instance should already
be disposed - unless something is holding a reference to them, in which
case we should use the ::destroy signal to unset the ActorMeta:actor
back pointer.

clutter/clutter-actor-meta.c

index e318b8f..f86e6be 100644 (file)
@@ -24,6 +24,7 @@
 struct _ClutterActorMetaPrivate
 {
   ClutterActor *actor;
+  guint destroy_id;
 
   gchar *name;
 
@@ -44,10 +45,28 @@ G_DEFINE_ABSTRACT_TYPE (ClutterActorMeta,
                         G_TYPE_INITIALLY_UNOWNED);
 
 static void
+on_actor_destroy (ClutterActor     *actor,
+                  ClutterActorMeta *meta)
+{
+  meta->priv->actor = NULL;
+}
+
+static void
 clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
                                    ClutterActor     *actor)
 {
+  if (meta->priv->actor == actor)
+    return;
+
+  if (meta->priv->destroy_id != 0)
+    g_signal_handler_disconnect (meta->priv->actor, meta->priv->destroy_id);
+
   meta->priv->actor = actor;
+
+  if (meta->priv->actor != NULL)
+    meta->priv->destroy_id = g_signal_connect (meta->priv->actor, "destroy",
+                                               G_CALLBACK (on_actor_destroy),
+                                               meta);
 }
 
 static void
@@ -107,6 +126,9 @@ clutter_actor_meta_finalize (GObject *gobject)
 {
   ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv;
 
+  if (priv->destroy_id != 0 && priv->actor != NULL)
+    g_signal_handler_disconnect (priv->actor, priv->destroy_id);
+
   g_free (priv->name);
 
   G_OBJECT_CLASS (clutter_actor_meta_parent_class)->finalize (gobject);