[nautilus-actions] NAIDuplicable: rewrite modification check stack



commit a92ee0f12aae2c96e27d8a8baebed1d4422a3a59
Author: Pierre Wieser <pwieser trychlos org>
Date:   Mon Feb 21 21:04:15 2011 +0100

    NAIDuplicable: rewrite modification check stack
    
    The rationale is double: first is to improve the consistency, second is to remove the iteration
    on class hierarchy, adn take advantage of 'call parent class' paradigm.

 ChangeLog                    |   16 ++++
 src/api/na-object-item.h     |    2 -
 src/api/na-object.h          |    3 +
 src/core/na-factory-object.c |    6 +-
 src/core/na-iduplicable.c    |    1 -
 src/core/na-object-action.c  |   92 +++++++++++++-----------
 src/core/na-object-id.c      |    1 -
 src/core/na-object-item.c    |  160 ++++++++++++++++++++++--------------------
 src/core/na-object-menu.c    |   13 +---
 src/core/na-object-profile.c |    7 +--
 src/core/na-object.c         |   57 ++++++++-------
 11 files changed, 185 insertions(+), 173 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7547c55..73d73d5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2011-02-21 Pierre Wieser <pwieser trychlos org>
 
+	Rewrite modification status check stack
+
+	* src/api/na-object-item.h:
+	* src/core/na-object-item.c (na_object_item_are_equal): Removed function.
+
+	* src/api/na-object.h:
+	* src/core/na-factory-object.c:
+	* src/core/na-iduplicable.c: Improve comment.
+
+	* src/core/na-object.c:
+	* src/core/na-object-id.c:
+	* src/core/na-object-menu.c:
+	* src/core/na-object-action.c:
+	* src/core/na-object-profile.c: Modification is checked from
+	NAObject-virtual method instead of NAIFactoryObject interface.
+
 	* src/api/na-iduplicable.h:
 	* src/api/na-iduplicable.c (v_are_equal, v_is_valid): Default to TRUE.
 
diff --git a/src/api/na-object-item.h b/src/api/na-object-item.h
index fd125a0..99b5cad 100644
--- a/src/api/na-object-item.h
+++ b/src/api/na-object-item.h
@@ -92,8 +92,6 @@ typedef enum {
 
 GType       na_object_item_get_type( void );
 
-gboolean    na_object_item_are_equal( const NAObjectItem *a, const NAObjectItem *b );
-
 NAObjectId *na_object_item_get_item    ( const NAObjectItem *item, const gchar *id );
 gint        na_object_item_get_position( const NAObjectItem *item, const NAObjectId *child );
 void        na_object_item_append_item ( NAObjectItem *item, const NAObjectId *child );
diff --git a/src/api/na-object.h b/src/api/na-object.h
index 7b92b93..7547b4b 100644
--- a/src/api/na-object.h
+++ b/src/api/na-object.h
@@ -120,6 +120,9 @@ typedef struct {
 	 *
 	 * Compares the two objects.
 	 *
+	 * When testing for the modification status of an object, @a stands for
+	 * the original object, while @b stands for the duplicated one.
+	 *
 	 * Each derived class should take care of implementing this function
 	 * when relevant. NAObject class will take care of calling this
 	 * function for each class of the hierarchy, starting from topmost
diff --git a/src/core/na-factory-object.c b/src/core/na-factory-object.c
index 3cf027f..185e047 100644
--- a/src/core/na-factory-object.c
+++ b/src/core/na-factory-object.c
@@ -429,6 +429,8 @@ na_factory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *
 	a_list = g_object_get_data( G_OBJECT( a ), NA_IFACTORY_OBJECT_PROP_DATA );
 	b_list = g_object_get_data( G_OBJECT( b ), NA_IFACTORY_OBJECT_PROP_DATA );
 
+	g_debug( "%s: a=%p, b=%p", thisfn, ( void * ) a, ( void * ) b );
+
 	are_equal = TRUE;
 	for( ia = a_list ; ia && are_equal ; ia = ia->next ){
 
@@ -464,9 +466,7 @@ na_factory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *
 		}
 	}
 
-	if( are_equal ){
-		are_equal = v_are_equal( a, b );
-	}
+	are_equal &= v_are_equal( a, b );
 
 	return( are_equal );
 }
diff --git a/src/core/na-iduplicable.c b/src/core/na-iduplicable.c
index ed79e40..954bc45 100644
--- a/src/core/na-iduplicable.c
+++ b/src/core/na-iduplicable.c
@@ -365,7 +365,6 @@ na_iduplicable_check_status( const NAIDuplicable *object )
 	g_return_if_fail( NA_IS_IDUPLICABLE( object ));
 
 	if( st_initialized && !st_finalized ){
-
 		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
 
 		str = get_duplicable_str( object );
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 2e69849..efdb22b 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -72,14 +72,14 @@ static void         instance_set_property( GObject *object, guint property_id, c
 static void         instance_dispose( GObject *object );
 static void         instance_finalize( GObject *object );
 
-static void         object_copy( NAObject *target, const NAObject *source, gboolean recursive );
 static void         object_dump( const NAObject *object );
+static void         object_copy( NAObject *target, const NAObject *source, gboolean recursive );
+static gboolean     object_are_equal( const NAObject *a, const NAObject *b );
 static gboolean     object_is_valid( const NAObject *object );
 
 static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
 static guint        ifactory_object_get_version( const NAIFactoryObject *instance );
 static NADataGroup *ifactory_object_get_groups( const NAIFactoryObject *instance );
-static gboolean     ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
 static gboolean     ifactory_object_is_valid( const NAIFactoryObject *object );
 static void         ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
 static guint        ifactory_object_write_start( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
@@ -169,9 +169,9 @@ class_init( NAObjectActionClass *klass )
 	object_class->finalize = instance_finalize;
 
 	naobject_class = NA_OBJECT_CLASS( klass );
-	naobject_class->copy = object_copy;
 	naobject_class->dump = object_dump;
-	naobject_class->are_equal = NULL;
+	naobject_class->copy = object_copy;
+	naobject_class->are_equal = object_are_equal;
 	naobject_class->is_valid = object_is_valid;
 
 	klass->private = g_new0( NAObjectActionClassPrivate, 1 );
@@ -262,19 +262,6 @@ instance_finalize( GObject *object )
 }
 
 static void
-object_copy( NAObject *target, const NAObject *source, gboolean recursive )
-{
-	g_return_if_fail( NA_IS_OBJECT_ACTION( target ));
-	g_return_if_fail( NA_IS_OBJECT_ACTION( source ));
-
-	if( !NA_OBJECT_ACTION( target )->private->dispose_has_run &&
-		!NA_OBJECT_ACTION( source )->private->dispose_has_run ){
-
-		na_factory_object_copy( NA_IFACTORY_OBJECT( target ), NA_IFACTORY_OBJECT( source ));
-	}
-}
-
-static void
 object_dump( const NAObject *object )
 {
 	static const char *thisfn = "na_object_action_object_dump";
@@ -297,6 +284,51 @@ object_dump( const NAObject *object )
 	}
 }
 
+static void
+object_copy( NAObject *target, const NAObject *source, gboolean recursive )
+{
+	g_return_if_fail( NA_IS_OBJECT_ACTION( target ));
+	g_return_if_fail( NA_IS_OBJECT_ACTION( source ));
+
+	if( !NA_OBJECT_ACTION( target )->private->dispose_has_run &&
+		!NA_OBJECT_ACTION( source )->private->dispose_has_run ){
+
+		na_factory_object_copy( NA_IFACTORY_OBJECT( target ), NA_IFACTORY_OBJECT( source ));
+	}
+}
+
+/*
+ * @a is the original object
+ * @b is the current one
+ *
+ * Even if they have both the same children list, the current action is
+ * considered modified as soon as one of its profile is itself modified.
+ */
+static gboolean
+object_are_equal( const NAObject *a, const NAObject *b )
+{
+	static const gchar *thisfn = "na_object_action_object_are_equal";
+	GList *it;
+	gboolean are_equal;
+
+	g_debug( "%s: a=%p, b=%p", thisfn, ( void * ) a, ( void * ) b );
+
+	for( it = na_object_get_items( b ) ; it ; it = it->next ){
+		if( na_object_is_modified( it->data )){
+			return( FALSE );
+		}
+	}
+
+	are_equal = TRUE;
+
+	/* chain call to parent class */
+	if( NA_OBJECT_CLASS( st_parent_class )->are_equal ){
+		are_equal &= NA_OBJECT_CLASS( st_parent_class )->are_equal( a, b );
+	}
+
+	return( are_equal );
+}
+
 static gboolean
 object_is_valid( const NAObject *object )
 {
@@ -314,10 +346,7 @@ ifactory_object_iface_init( NAIFactoryObjectInterface *iface )
 
 	iface->get_version = ifactory_object_get_version;
 	iface->get_groups = ifactory_object_get_groups;
-	iface->copy = NULL;
-	iface->are_equal = ifactory_object_are_equal;
 	iface->is_valid = ifactory_object_is_valid;
-	iface->read_start = NULL;
 	iface->read_done = ifactory_object_read_done;
 	iface->write_start = ifactory_object_write_start;
 	iface->write_done = ifactory_object_write_done;
@@ -335,29 +364,6 @@ ifactory_object_get_groups( const NAIFactoryObject *instance )
 	return( action_data_groups );
 }
 
-/*
- * @a is the original object
- * @b is the current one
- *
- * Even if they have both the same children list, the current action is
- * considered modified as soon as one of its profile is itself modified.
- */
-static gboolean
-ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b )
-{
-	GList *it;
-
-	if( na_object_item_are_equal( NA_OBJECT_ITEM( a ), NA_OBJECT_ITEM( b ))){
-		for( it = na_object_get_items( b ) ; it ; it = it->next ){
-			if( na_object_is_modified( it->data )){
-				return( FALSE );
-			}
-		}
-	}
-
-	return( TRUE );
-}
-
 static gboolean
 ifactory_object_is_valid( const NAIFactoryObject *object )
 {
diff --git a/src/core/na-object-id.c b/src/core/na-object-id.c
index 44c8eff..cbae954 100644
--- a/src/core/na-object-id.c
+++ b/src/core/na-object-id.c
@@ -115,7 +115,6 @@ class_init( NAObjectIdClass *klass )
 
 	naobject_class = NA_OBJECT_CLASS( klass );
 	naobject_class->copy = NULL;
-	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = object_is_valid;
 
 	klass->private = g_new0( NAObjectIdClassPrivate, 1 );
diff --git a/src/core/na-object-item.c b/src/core/na-object-item.c
index 040869b..40a4651 100644
--- a/src/core/na-object-item.c
+++ b/src/core/na-object-item.c
@@ -62,20 +62,21 @@ struct _NAObjectItemPrivate {
 
 static NAObjectIdClass *st_parent_class = NULL;
 
-static GType   register_type( void );
-static void    class_init( NAObjectItemClass *klass );
-static void    instance_init( GTypeInstance *instance, gpointer klass );
-static void    instance_dispose( GObject *object );
-static void    instance_finalize( GObject *object );
+static GType    register_type( void );
+static void     class_init( NAObjectItemClass *klass );
+static void     instance_init( GTypeInstance *instance, gpointer klass );
+static void     instance_dispose( GObject *object );
+static void     instance_finalize( GObject *object );
 
-static void    object_copy( NAObject*target, const NAObject *source, gboolean recursive );
-static void    object_dump( const NAObject *object );
+static void     object_dump( const NAObject *object );
+static void     object_copy( NAObject*target, const NAObject *source, gboolean recursive );
+static gboolean object_are_equal( const NAObject *a, const NAObject *b );
 
-static gchar  *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
+static gchar   *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
 
-static void    count_items_rec( GList *items, gint *menus, gint *actions, gint *profiles, gboolean recurse );
-static GSList *get_children_slist( const NAObjectItem *item );
-static void    copy_children( NAObjectItem *target, const NAObjectItem *source );
+static void     count_items_rec( GList *items, gint *menus, gint *actions, gint *profiles, gboolean recurse );
+static GSList  *get_children_slist( const NAObjectItem *item );
+static void     copy_children( NAObjectItem *target, const NAObjectItem *source );
 
 GType
 na_object_item_get_type( void )
@@ -133,7 +134,7 @@ class_init( NAObjectItemClass *klass )
 	naobject_class = NA_OBJECT_CLASS( klass );
 	naobject_class->dump = object_dump;
 	naobject_class->copy = object_copy;
-	naobject_class->are_equal = NULL;
+	naobject_class->are_equal = object_are_equal;
 	naobject_class->is_valid = NULL;
 
 	naobjectid_class = NA_OBJECT_ID_CLASS( klass );
@@ -201,6 +202,28 @@ instance_finalize( GObject *object )
 }
 
 static void
+object_dump( const NAObject *object )
+{
+	static const gchar *thisfn = "na_object_item_object_dump";
+	NAObjectItem *item;
+
+	g_return_if_fail( NA_IS_OBJECT_ITEM( object ));
+
+	item = NA_OBJECT_ITEM( object );
+
+	if( !item->private->dispose_has_run ){
+
+		g_debug( "| %s:      writable=%s", thisfn, item->private->writable ? "True":"False" );
+		g_debug( "| %s:        reason=%u", thisfn, item->private->reason );
+
+		/* chain up to the parent class */
+		if( NA_OBJECT_CLASS( st_parent_class )->dump ){
+			NA_OBJECT_CLASS( st_parent_class )->dump( object );
+		}
+	}
+}
+
+static void
 object_copy( NAObject *target, const NAObject *source, gboolean recursive )
 {
 	static const gchar *thisfn = "na_object_item_object_copy";
@@ -238,26 +261,61 @@ object_copy( NAObject *target, const NAObject *source, gboolean recursive )
 	}
 }
 
-static void
-object_dump( const NAObject *object )
+/*
+ * object_are_equal:
+ * @a: the first (original) #NAObjectItem instance.
+ * @b: the second #NAObjectItem instance.
+ *
+ * This function participates to the #na_iduplicable_check_status() stack,
+ * and is triggered after all comparable elementary data (in #NAIFactoryObject
+ * sense) have already been successfully compared.
+ *
+ * We have to deal here with the subitems: comparing children by their ids
+ * between @a and @b.
+ *
+ * Returns: %TRUE if @a is equal to @b.
+ */
+static gboolean
+object_are_equal( const NAObject *a, const NAObject *b )
 {
-	static const gchar *thisfn = "na_object_item_object_dump";
-	NAObjectItem *item;
+	static const gchar *thisfn = "na_object_item_object_are_equal";
+	gboolean are_equal;
+	NAObjectItem *origin, *duplicate;
+	GSList *a_slist, *b_slist;
+	gchar *a_list, *b_list;
 
-	g_return_if_fail( NA_IS_OBJECT_ITEM( object ));
+	g_return_val_if_fail( NA_IS_OBJECT_ITEM( a ), FALSE );
+	g_return_val_if_fail( NA_IS_OBJECT_ITEM( b ), FALSE );
 
-	item = NA_OBJECT_ITEM( object );
+	are_equal = FALSE;
+	origin = NA_OBJECT_ITEM( a );
+	duplicate = NA_OBJECT_ITEM( b );
 
-	if( !item->private->dispose_has_run ){
+	if( !origin->private->dispose_has_run &&
+		!duplicate->private->dispose_has_run ){
 
-		g_debug( "| %s:      writable=%s", thisfn, item->private->writable ? "True":"False" );
-		g_debug( "| %s:        reason=%u", thisfn, item->private->reason );
+		g_debug( "%s: a=%p, b=%p", thisfn, ( void * ) a, ( void * ) b );
 
-		/* chain up to the parent class */
-		if( NA_OBJECT_CLASS( st_parent_class )->dump ){
-			NA_OBJECT_CLASS( st_parent_class )->dump( object );
-		}
+		a_slist = get_children_slist( origin );
+		a_list = na_core_utils_slist_join_at_end( a_slist, ";" );
+		na_core_utils_slist_free( a_slist );
+
+		b_slist = get_children_slist( duplicate );
+		b_list = na_core_utils_slist_join_at_end( b_slist, ";" );
+		na_core_utils_slist_free( b_slist );
+
+		are_equal = ( strcmp( a_list, b_list ) == 0 );
+
+		g_free( a_list );
+		g_free( b_list );
+	}
+
+	/* chain call to parent class */
+	if( NA_OBJECT_CLASS( st_parent_class )->are_equal ){
+		are_equal &= NA_OBJECT_CLASS( st_parent_class )->are_equal( a, b );
 	}
+
+	return( are_equal );
 }
 
 /*
@@ -294,58 +352,6 @@ object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent )
 }
 
 /**
- * na_object_item_are_equal:
- * @a: the first (original) #NAObjectItem instance.
- * @b: the second #NAObjectItem instance.
- *
- * This function participates to the #na_iduplicable_check_status() stack,
- * and is triggered after all comparable elementary data (in #NAIFactoryObject
- * sense) have already been successfully compared.
- *
- * We have to deal here with the subitems: comparing children by their ids
- * between @a and @b.
- *
- * Note that, when called from na_object_check_status, the status of children
- * have already been checked, and so we should be able to rely on them.
- *
- * Returns: %TRUE if @a is equal to @b.
- *
- * Since: 2.30
- */
-gboolean
-na_object_item_are_equal( const NAObjectItem *a, const NAObjectItem *b )
-{
-	/*static const gchar *thisfn = "na_object_item_are_equal";*/
-	gboolean equal;
-	GSList *a_slist, *b_slist;
-	gchar *a_list, *b_list;
-
-	g_return_val_if_fail( NA_IS_OBJECT_ITEM( a ), FALSE );
-	g_return_val_if_fail( NA_IS_OBJECT_ITEM( b ), FALSE );
-
-	equal = FALSE;
-
-	if( !NA_OBJECT_ITEM( a )->private->dispose_has_run &&
-		!NA_OBJECT_ITEM( b )->private->dispose_has_run ){
-
-		a_slist = get_children_slist( a );
-		a_list = na_core_utils_slist_join_at_end( a_slist, ";" );
-		na_core_utils_slist_free( a_slist );
-
-		b_slist = get_children_slist( b );
-		b_list = na_core_utils_slist_join_at_end( b_slist, ";" );
-		na_core_utils_slist_free( b_slist );
-
-		equal = ( strcmp( a_list, b_list ) == 0 );
-
-		g_free( a_list );
-		g_free( b_list );
-	}
-
-	return( equal );
-}
-
-/**
  * na_object_item_get_item:
  * @item: the #NAObjectItem from which we want retrieve a subitem.
  * @id: the id of the searched subitem.
diff --git a/src/core/na-object-menu.c b/src/core/na-object-menu.c
index 7f6e3ff..6f2dc4c 100644
--- a/src/core/na-object-menu.c
+++ b/src/core/na-object-menu.c
@@ -76,7 +76,6 @@ static gboolean     object_is_valid( const NAObject *object );
 static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
 static guint        ifactory_object_get_version( const NAIFactoryObject *instance );
 static NADataGroup *ifactory_object_get_groups( const NAIFactoryObject *instance );
-static gboolean     ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
 static gboolean     ifactory_object_is_valid( const NAIFactoryObject *object );
 static void         ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
 static guint        ifactory_object_write_start( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
@@ -160,9 +159,8 @@ class_init( NAObjectMenuClass *klass )
 	object_class->finalize = instance_finalize;
 
 	naobject_class = NA_OBJECT_CLASS( klass );
-	naobject_class->copy = object_copy;
 	naobject_class->dump = object_dump;
-	naobject_class->are_equal = NULL;
+	naobject_class->copy = object_copy;
 	naobject_class->is_valid = object_is_valid;
 
 	klass->private = g_new0( NAObjectMenuClassPrivate, 1 );
@@ -306,10 +304,7 @@ ifactory_object_iface_init( NAIFactoryObjectInterface *iface )
 
 	iface->get_version = ifactory_object_get_version;
 	iface->get_groups = ifactory_object_get_groups;
-	iface->copy = NULL;
-	iface->are_equal = ifactory_object_are_equal;
 	iface->is_valid = ifactory_object_is_valid;
-	iface->read_start = NULL;
 	iface->read_done = ifactory_object_read_done;
 	iface->write_start = ifactory_object_write_start;
 	iface->write_done = ifactory_object_write_done;
@@ -328,12 +323,6 @@ ifactory_object_get_groups( const NAIFactoryObject *instance )
 }
 
 static gboolean
-ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b )
-{
-	return( na_object_item_are_equal( NA_OBJECT_ITEM( a ), NA_OBJECT_ITEM( b )));
-}
-
-static gboolean
 ifactory_object_is_valid( const NAIFactoryObject *object )
 {
 	g_return_val_if_fail( NA_IS_OBJECT_MENU( object ), FALSE );
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index ce20ec9..21c267c 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -170,9 +170,8 @@ class_init( NAObjectProfileClass *klass )
 	object_class->finalize = instance_finalize;
 
 	naobject_class = NA_OBJECT_CLASS( klass );
-	naobject_class->copy = object_copy;
 	naobject_class->dump = object_dump;
-	naobject_class->are_equal = NULL;
+	naobject_class->copy = object_copy;
 	naobject_class->is_valid = object_is_valid;
 
 	naobjectid_class = NA_OBJECT_ID_CLASS( klass );
@@ -321,12 +320,8 @@ ifactory_object_iface_init( NAIFactoryObjectInterface *iface )
 
 	iface->get_version = ifactory_object_get_version;
 	iface->get_groups = ifactory_object_get_groups;
-	iface->copy = NULL;
-	iface->are_equal = NULL;
 	iface->is_valid = ifactory_object_is_valid;
-	iface->read_start = NULL;
 	iface->read_done = ifactory_object_read_done;
-	iface->write_start = NULL;
 	iface->write_done = ifactory_object_write_done;
 }
 
diff --git a/src/core/na-object.c b/src/core/na-object.c
index e6300fb..b7b57f3 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -79,12 +79,12 @@ static void     object_dump( const NAObject *object );
 static void     iduplicable_iface_init( NAIDuplicableInterface *iface );
 static void     iduplicable_copy( NAIDuplicable *target, const NAIDuplicable *source );
 static gboolean iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b );
-static gboolean iduplicable_are_equal_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str );
 static gboolean iduplicable_is_valid( const NAIDuplicable *object );
 static gboolean iduplicable_is_valid_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str );
 
 static void     check_status_down_rec( const NAObject *object );
 static void     check_status_up_rec( const NAObject *object, gboolean was_modified, gboolean was_valid );
+static gboolean v_are_equal( const NAObject *a, const NAObject *b );
 static gboolean object_copy_iter( GObjectClass *class, const NAObject *source, CopyIter *data );
 static void     dump_tree( GList *tree, gint level );
 static void     iter_on_class_hierarchy( const NAObject *object, HierarchyIterFunc pfn, void *user_data );
@@ -263,7 +263,6 @@ iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b )
 {
 	static const gchar *thisfn = "na_object_iduplicable_are_equal";
 	gboolean are_equal;
-	HierarchyIter *str;
 
 	g_return_val_if_fail( NA_IS_OBJECT( a ), FALSE );
 	g_return_val_if_fail( NA_IS_OBJECT( b ), FALSE );
@@ -275,36 +274,16 @@ iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b )
 
 		g_debug( "%s: a=%p (%s), b=%p", thisfn, ( void * ) a, G_OBJECT_TYPE_NAME( a ), ( void * ) b );
 
-		if( NA_IS_IFACTORY_OBJECT( a )){
-			are_equal = na_factory_object_are_equal( NA_IFACTORY_OBJECT( a ), NA_IFACTORY_OBJECT( b ));
-
-		} else {
-			str = g_new0( HierarchyIter, 1 );
-			str->object = NA_OBJECT( b );
-			str->result = FALSE;
-
-			iter_on_class_hierarchy( NA_OBJECT( a ), ( HierarchyIterFunc ) &iduplicable_are_equal_iter, str );
-
-			are_equal = str->result;
+		are_equal = TRUE;
 
-			g_free( str );
+		if( NA_IS_IFACTORY_OBJECT( a )){
+			are_equal &= na_factory_object_are_equal( NA_IFACTORY_OBJECT( a ), NA_IFACTORY_OBJECT( b ));
 		}
-	}
 
-	return( are_equal );
-}
-
-static gboolean
-iduplicable_are_equal_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str )
-{
-	gboolean stop = FALSE;
-
-	if( NA_OBJECT_CLASS( class )->are_equal ){
-		str->result = NA_OBJECT_CLASS( class )->are_equal( a, str->object );
-		stop = !str->result;
+		are_equal &= v_are_equal( NA_OBJECT( a ), NA_OBJECT( b ));
 	}
 
-	return( stop );
+	return( are_equal );
 }
 
 static gboolean
@@ -366,7 +345,19 @@ iduplicable_is_valid_iter( GObjectClass *class, const NAObject *a, HierarchyIter
  * na_object_object_check_status_rec( object )
  *  +- na_iduplicable_check_status( object )
  *      +- get_origin( object )
- *      +- modified_status = v_are_equal( origin, object ) -> interface <structfield>NAObjectClass::are_equal</structfield>
+ *      +- modified_status = v_are_equal( origin, object )
+ *         +-> interface <structfield>NAObjectClass::are_equal</structfield>
+ *             which happens to be iduplicable_are_equal( a, b )
+ *              +- v_are_equal( a, b )
+ *                  +- NAObjectAction::are_equal()
+ *                      +- na_factory_object_are_equal()
+ *                      +- check NAObjectActionPrivate data
+ *                      +- call parent class
+ *                         +- NAObjectItem::are_equal()
+ *                             +- check NAObjectItemPrivate data
+ *                             +- call parent class
+ *                                 +- NAObjectId::are_equal()
+ *
  *      +- valid_status = v_is_valid( object )             -> interface <structfield>NAObjectClass::is_valid</structfield>
  *
  * Note that the recursivity is managed here, so that we can be sure
@@ -439,6 +430,16 @@ check_status_up_rec( const NAObject *object, gboolean was_modified, gboolean was
 	}
 }
 
+static gboolean
+v_are_equal( const NAObject *a, const NAObject *b )
+{
+	if( NA_OBJECT_GET_CLASS( a )->are_equal ){
+		return( NA_OBJECT_GET_CLASS( a )->are_equal( a, b ));
+	}
+
+	return( TRUE );
+}
+
 /**
  * na_object_object_copy:
  * @target: the target #NAObject -derived object.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]