I've managed to convert QofCollection to a GObject. The API for this object is unchanged, the only affectation was QofInstance, to set/get its property "collection" from a gpointer to a GObject.
-- Trabajar, la mejor arma para tu superación "de grano en grano, se hace la arena" (R) (entrámite, pero para los cuates: LIBRE)
Index: lib/libqof/qof/qofinstance.c =================================================================== --- lib/libqof/qof/qofinstance.c (revisión: 16217) +++ lib/libqof/qof/qofinstance.c (copia de trabajo) @@ -145,12 +145,13 @@ g_object_class_install_property (object_class, PROP_COLLECTION, - g_param_spec_pointer ("collection", + g_param_spec_object ("collection", "Object Collection", "A collection of like objects of which this " "particular object is amember. E.g.. A " "collection of accounts, or a collection of " "splits.", + QOF_TYPE_COLLECTION, G_PARAM_READWRITE)); g_object_class_install_property @@ -363,7 +364,7 @@ g_value_set_boxed(value, &priv->guid); break; case PROP_COLLECTION: - g_value_set_pointer(value, priv->collection); + g_value_set_object(value, priv->collection); break; case PROP_BOOK: g_value_set_object(value, priv->book); @@ -421,7 +422,7 @@ qof_instance_set_guid(inst, g_value_get_boxed(value)); break; case PROP_COLLECTION: - qof_instance_set_collection(inst, g_value_get_pointer(value)); + qof_instance_set_collection(inst, (QofCollection*) g_value_get_object(value)); break; case PROP_BOOK: qof_instance_set_book(inst, g_value_get_object(value)); Index: lib/libqof/qof/qofid.c =================================================================== --- lib/libqof/qof/qofid.c (revisión: 16217) +++ lib/libqof/qof/qofid.c (copia de trabajo) @@ -33,8 +33,14 @@ static QofLogModule log_module = QOF_MOD_ENGINE; static gboolean qof_alt_dirty_mode = FALSE; -struct QofCollection_s +static guint id_hash (gconstpointer key); +static gboolean id_compare(gconstpointer key_1, gconstpointer key_2); + +typedef struct _QofCollectionPrivate QofCollectionPrivate; + +struct _QofCollectionPrivate { + QofIdType e_type; gboolean is_dirty; @@ -42,6 +48,176 @@ gpointer data; /* place where object class can hang arbitrary data */ }; +enum { + PROP_0, + PROP_DIRTY, + PROP_E_TYPE +}; + +#define GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), QOF_TYPE_COLLECTION, QofCollectionPrivate)) + +static void qof_collection_class_init(QofCollectionClass *klass); +static void qof_collection_finalize (GObject *object); +static void qof_collection_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void qof_collection_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); + +static GObjectClass *parent_class = NULL; + +static void qof_collection_class_init(QofCollectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = qof_collection_finalize; + object_class->set_property = qof_collection_set_property; + object_class->get_property = qof_collection_get_property; + + g_type_class_add_private(klass, sizeof(QofCollectionPrivate)); + + g_object_class_install_property + (object_class, + PROP_E_TYPE, + g_param_spec_string ("e_type", + "Object Sring Type", + "The object's string type.", + NULL, + G_PARAM_READABLE|G_PARAM_CONSTRUCT_ONLY)); + + + g_object_class_install_property + (object_class, + PROP_DIRTY, + g_param_spec_boolean ("dirty", + "Object Dirty", + "This flag is set to TRUE if the object has " + "unsaved changes.", + FALSE, + G_PARAM_READWRITE)); + + + +} + +static void +qof_collection_init (QofCollection *col) +{ + QofCollectionPrivate *priv; + + priv = GET_PRIVATE(col); + priv->e_type = NULL; + priv->hash_of_entities = g_hash_table_new (id_hash, id_compare); + priv->data = NULL; + priv->is_dirty = FALSE; + +} + +static void +qof_collection_finalize (GObject *object) +{ + QofCollectionPrivate *priv; + QofCollection* col = QOF_COLLECTION (object); + + priv = GET_PRIVATE(object); + CACHE_REMOVE (priv->e_type); + g_hash_table_destroy(priv->hash_of_entities); + priv->e_type = NULL; + priv->hash_of_entities = NULL; + if(priv->data) + { + if (G_IS_OBJECT (priv->data)) + g_object_unref (priv->data); + else + g_free (priv->data); /** XXX there should be a destroy notifier for this */ + } + parent_class->finalize(object); +} + +static void +qof_collection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + QofCollection *col; + QofCollectionPrivate *priv; + + g_return_if_fail(QOF_IS_COLLECTION(object)); + + col = QOF_COLLECTION (object); + priv = GET_PRIVATE (col); + + switch (prop_id) { + + case PROP_E_TYPE: + g_value_set_string (value, priv->e_type); + break; + + case PROP_DIRTY: + g_value_set_boolean(value, priv->is_dirty); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +qof_collection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + QofCollection *col; + QofCollectionPrivate *priv; + Timespec *ts; + + g_return_if_fail(QOF_IS_COLLECTION(object)); + + col = QOF_COLLECTION(object); + priv = GET_PRIVATE(col); + + switch (prop_id) { + + case PROP_E_TYPE: + /* Set it only at construction time */ + priv->e_type = CACHE_INSERT (g_value_get_string (value)); + break; + + case PROP_DIRTY: + priv->is_dirty = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +GType +qof_collection_get_gtype (void) +{ + static GType type = 0; + + if (!type) { + static const GTypeInfo info = { + sizeof (QofCollectionClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) qof_collection_class_init, + NULL, + NULL, + sizeof (QofCollection), + 0, + (GInstanceInitFunc) qof_collection_init + }; + type = g_type_register_static (G_TYPE_OBJECT, "QofCollection", &info, 0); + } + return type; +} + /* =============================================================== */ gboolean @@ -97,22 +273,15 @@ qof_collection_new (QofIdType type) { QofCollection *col; - col = g_new0(QofCollection, 1); - col->e_type = CACHE_INSERT (type); - col->hash_of_entities = g_hash_table_new (id_hash, id_compare); - col->data = NULL; + col = QOF_COLLECTION (g_object_new (QOF_TYPE_COLLECTION, "e_type", type)); + return col; } void qof_collection_destroy (QofCollection *col) { - CACHE_REMOVE (col->e_type); - g_hash_table_destroy(col->hash_of_entities); - col->e_type = NULL; - col->hash_of_entities = NULL; - col->data = NULL; /** XXX there should be a destroy notifier for this */ - g_free (col); + g_object_unref (col); } /* =============================================================== */ @@ -121,7 +290,13 @@ QofIdType qof_collection_get_type (const QofCollection *col) { - return col->e_type; + QofCollectionPrivate *priv; + + g_return_val_if_fail(QOF_IS_COLLECTION(col), NULL); + + priv = GET_PRIVATE(col); + + return priv->e_type; } /* =============================================================== */ @@ -131,14 +306,23 @@ { QofCollection *col; const GUID *guid; + QofCollectionPrivate *priv; + + + g_return_if_fail (QOF_IS_INSTANCE (ent)); + + col = qof_instance_get_collection(ent); - if (!ent) return; - col = qof_instance_get_collection(ent); - if (!col) return; + g_return_if_fail(QOF_IS_COLLECTION(col)); + priv = GET_PRIVATE(col); + guid = qof_instance_get_guid(ent); - g_hash_table_remove (col->hash_of_entities, guid); + + g_hash_table_remove (priv->hash_of_entities, guid); + if (!qof_alt_dirty_mode) qof_collection_mark_dirty(col); + qof_instance_set_collection(ent, NULL); } @@ -146,34 +330,58 @@ qof_collection_insert_entity (QofCollection *col, QofInstance *ent) { const GUID *guid; + QofCollectionPrivate *priv; + + g_return_if_fail(QOF_IS_COLLECTION(col)); - if (!col || !ent) return; + priv = GET_PRIVATE(col); + + g_return_if_fail (QOF_IS_INSTANCE(ent)); + guid = qof_instance_get_guid(ent); + if (guid_equal(guid, guid_null())) return; - g_return_if_fail (col->e_type == ent->e_type); + + g_return_if_fail (priv->e_type == ent->e_type); + qof_collection_remove_entity (ent); - g_hash_table_insert (col->hash_of_entities, (gpointer)guid, ent); + + g_hash_table_insert (priv->hash_of_entities, (gpointer)guid, ent); + if (!qof_alt_dirty_mode) qof_collection_mark_dirty(col); + qof_instance_set_collection(ent, col); + } gboolean -qof_collection_add_entity (QofCollection *coll, QofInstance *ent) +qof_collection_add_entity (QofCollection *col, QofInstance *ent) { QofInstance *e; - const GUID *guid; + const GUID *guid; + QofCollectionPrivate *priv; + + g_return_val_if_fail(QOF_IS_COLLECTION(col) && QOF_IS_INSTANCE (ent), FALSE); + priv = GET_PRIVATE(col); + e = NULL; - if (!coll || !ent) { return FALSE; } - guid = qof_instance_get_guid(ent); - if (guid_equal(guid, guid_null())) { return FALSE; } - g_return_val_if_fail (coll->e_type == ent->e_type, FALSE); - e = qof_collection_lookup_entity(coll, guid); - if ( e != NULL ) { return FALSE; } - g_hash_table_insert (coll->hash_of_entities, (gpointer)guid, ent); + guid = qof_instance_get_guid(ent); + + if (guid_equal(guid, guid_null())) { return FALSE; } + + g_return_val_if_fail (priv->e_type == ent->e_type, FALSE); + + e = qof_collection_lookup_entity(col, guid); + + g_return_val_if_fail (QOF_IS_INSTANCE (e), FALSE); + + g_hash_table_insert (priv->hash_of_entities, (gpointer)guid, ent); + if (!qof_alt_dirty_mode) - qof_collection_mark_dirty(coll); + qof_collection_mark_dirty(col); + return TRUE; } @@ -182,15 +390,18 @@ { QofCollection *target; - target = (QofCollection*)data; + target = (QofCollection*) data; + qof_collection_add_entity(target, ent); } gboolean qof_collection_merge (QofCollection *target, QofCollection *merge) { - if(!target || !merge) { return FALSE; } - g_return_val_if_fail (target->e_type == merge->e_type, FALSE); + g_return_val_if_fail (QOF_IS_COLLECTION (target) && QOF_IS_COLLECTION (merge), FALSE); + + g_return_val_if_fail (GET_PRIVATE (target)->e_type == GET_PRIVATE(merge)->e_type, FALSE); + qof_collection_foreach(merge, collection_merge_cb, target); return TRUE; } @@ -202,11 +413,19 @@ QofInstance *e; const GUID *guid; gint value; + QofCollectionPrivate *priv; + + e = NULL; target = (QofCollection*)user_data; - if (!target || !ent) { return; } + + priv = GET_PRIVATE(target); + + if (!QOF_IS_COLLECTION(target) || !QOF_IS_INSTANCE(ent)) return; + value = *(gint*)qof_collection_get_data(target); + if (value != 0) { return; } guid = qof_instance_get_guid(ent); if (guid_equal(guid, guid_null())) @@ -215,7 +434,7 @@ qof_collection_set_data(target, &value); return; } - g_return_if_fail (target->e_type == ent->e_type); + g_return_if_fail (priv->e_type == ent->e_type); e = qof_collection_lookup_entity(target, guid); if ( e == NULL ) { @@ -231,13 +450,18 @@ qof_collection_compare (QofCollection *target, QofCollection *merge) { gint value; + QofCollectionPrivate *target_col; + QofCollectionPrivate *merge_col; + + target_col = GET_PRIVATE(target); + merge_col = GET_PRIVATE(merge); value = 0; if (!target && !merge) { return 0; } if (target == merge) { return 0; } if (!target && merge) { return -1; } if (target && !merge) { return 1; } - if(target->e_type != merge->e_type) { return -1; } + if(target_col->e_type != merge_col->e_type) { return -1; } qof_collection_set_data(target, &value); qof_collection_foreach(merge, collection_compare_cb, target); value = *(gint*)qof_collection_get_data(target); @@ -253,9 +477,14 @@ qof_collection_lookup_entity (const QofCollection *col, const GUID * guid) { QofInstance *ent; - g_return_val_if_fail (col, NULL); + QofCollectionPrivate *col_priv; + + col_priv = GET_PRIVATE(col); + + g_return_val_if_fail (QOF_IS_COLLECTION (col), NULL); + if (guid == NULL) return NULL; - ent = g_hash_table_lookup (col->hash_of_entities, guid); + ent = g_hash_table_lookup (col_priv->hash_of_entities, guid); return ent; } @@ -282,8 +511,11 @@ qof_collection_count (const QofCollection *col) { guint c; + QofCollectionPrivate *col_priv; + + col_priv = GET_PRIVATE (col); - c = g_hash_table_size(col->hash_of_entities); + c = g_hash_table_size(col_priv->hash_of_entities); return c; } @@ -292,26 +524,30 @@ gboolean qof_collection_is_dirty (const QofCollection *col) { - return col ? col->is_dirty : FALSE; + return col ? GET_PRIVATE (col)->is_dirty : FALSE; } void qof_collection_mark_clean (QofCollection *col) { - if (col) { col->is_dirty = FALSE; } + if (col) { GET_PRIVATE (col)->is_dirty = FALSE; } } void qof_collection_mark_dirty (QofCollection *col) { - if (col) { col->is_dirty = TRUE; } + if (col) { GET_PRIVATE (col)->is_dirty = TRUE; } } void qof_collection_print_dirty (const QofCollection *col, gpointer dummy) { - if (col->is_dirty) - printf("%s collection is dirty.\n", col->e_type); + QofCollectionPrivate *col_priv; + + col_priv = GET_PRIVATE (col); + + if (col_priv->is_dirty) + printf("%s collection is dirty.\n", col_priv->e_type); qof_collection_foreach(col, (QofInstanceForeachCB)qof_instance_print_dirty, NULL); } @@ -320,13 +556,13 @@ gpointer qof_collection_get_data (const QofCollection *col) { - return col ? col->data : NULL; + return col ? GET_PRIVATE (col)->data : NULL; } void qof_collection_set_data (QofCollection *col, gpointer user_data) { - if (col) { col->data = user_data; } + if (col) { GET_PRIVATE (col)->data = user_data; } } /* =============================================================== */ @@ -356,7 +592,7 @@ iter.fcn = cb_func; iter.data = user_data; - g_hash_table_foreach (col->hash_of_entities, foreach_cb, &iter); + g_hash_table_foreach (GET_PRIVATE (col)->hash_of_entities, foreach_cb, &iter); } /* =============================================================== */ Index: lib/libqof/qof/qofid.h =================================================================== --- lib/libqof/qof/qofid.h (revisión: 16217) +++ lib/libqof/qof/qofid.h (copia de trabajo) @@ -83,8 +83,36 @@ /** QofLogModule declaration */ typedef const gchar* QofLogModule; +/* GObject Definitions */ + +#define QOF_TYPE_COLLECTION (qof_collection_get_gtype ()) +#define QOF_COLLECTION(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), QOF_TYPE_COLLECTION, QofCollection)) +#define QOF_COLLECTION_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST((k), QOF_TYPE_COLLECTION, QofCollectionClass)) +#define QOF_IS_COLLECTION(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), QOF_TYPE_COLLECTION)) +#define QOF_IS_COLLECTION_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), QOF_TYPE_COLLECTION)) +#define QOF_COLLECTION_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), QOF_TYPE_COLLECTION, QofCollectionClass)) + typedef struct QofCollection_s QofCollection; +typedef struct _QofCollectionClass QofCollectionClass; + +struct QofCollection_s +{ + GObject parent; +}; + +struct _QofCollectionClass +{ + GObjectClass parent_class; +}; + +GType qof_collection_get_gtype (void); + #include "qofinstance.h" #define QOF_ID_NONE NULL
_______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel