[libgda] GdaDataModelIter: ported to GWeakRef
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] GdaDataModelIter: ported to GWeakRef
- Date: Mon, 11 Feb 2019 23:25:30 +0000 (UTC)
commit 8950e30d8154c983e13cb56200dec4583f39b29f
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date: Mon Feb 11 10:38:13 2019 -0600
GdaDataModelIter: ported to GWeakRef
Internal weak reference to a GdaDataModel is now
using GWeakRef
libgda/gda-data-model-iter.c | 179 +++++++++++++++++++++++++++++--------------
libgda/gda-data-model.h | 1 +
2 files changed, 124 insertions(+), 56 deletions(-)
---
diff --git a/libgda/gda-data-model-iter.c b/libgda/gda-data-model-iter.c
index 79a302bb3..87a381687 100644
--- a/libgda/gda-data-model-iter.c
+++ b/libgda/gda-data-model-iter.c
@@ -40,7 +40,7 @@ extern GdaAttributesManager *gda_holder_attributes_manager;
/* private structure */
typedef struct
{
- GdaDataModel *data_model; /* may be %NULL because there is only a weak ref on it */
+ GWeakRef data_model; /* may be %NULL because there is only a weak ref on it */
gulong model_changes_signals[3];
gboolean keep_param_changes;
gint row; /* -1 if row is unknown */
@@ -180,7 +180,7 @@ static void
gda_data_model_iter_init (GdaDataModelIter *iter)
{
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
- priv->data_model = NULL;
+ g_weak_ref_set (&priv->data_model, NULL);
priv->row = -1;
priv->model_changes_signals[0] = 0;
priv->model_changes_signals[1] = 0;
@@ -191,9 +191,24 @@ gda_data_model_iter_init (GdaDataModelIter *iter)
static void
model_row_updated_cb (GdaDataModel *model, gint row, GdaDataModelIter *iter)
{
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (GDA_IS_DATA_MODEL (model));
+ g_return_if_fail (iter != NULL);
+ g_return_if_fail (GDA_IS_DATA_MODEL_ITER (iter));
+
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
- g_assert (model == priv->data_model);
-
+
+ GdaDataModel *obj = g_weak_ref_get (&priv->data_model);
+ if (obj == NULL) {
+ g_warning (_("Iter has an invalid/non-existent reference to a data model"));
+ return;
+ }
+ if (model != obj) {
+ g_warning (_("Referenced data model in iterator doesn't belong to given data model"));
+ g_object_unref (obj);
+ return;
+ }
+ g_object_unref (obj);
/* sync parameters with the new values in row */
if (priv->row == row) {
priv->keep_param_changes = TRUE;
@@ -205,6 +220,11 @@ model_row_updated_cb (GdaDataModel *model, gint row, GdaDataModelIter *iter)
static void
model_row_removed_cb (G_GNUC_UNUSED GdaDataModel *model, gint row, GdaDataModelIter *iter)
{
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (GDA_IS_DATA_MODEL (model));
+ g_return_if_fail (iter != NULL);
+ g_return_if_fail (GDA_IS_DATA_MODEL_ITER (iter));
+
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
if (priv->row < 0)
@@ -227,6 +247,11 @@ model_row_removed_cb (G_GNUC_UNUSED GdaDataModel *model, gint row, GdaDataModelI
static void
define_holder_for_data_model_column (GdaDataModel *model, gint col, GdaDataModelIter *iter)
{
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (GDA_IS_DATA_MODEL (model));
+ g_return_if_fail (iter != NULL);
+ g_return_if_fail (GDA_IS_DATA_MODEL_ITER (iter));
+
gchar *str;
GdaHolder *param;
GdaColumn *column;
@@ -297,6 +322,11 @@ define_holder_for_data_model_column (GdaDataModel *model, gint col, GdaDataModel
static void
model_reset_cb (GdaDataModel *model, GdaDataModelIter *iter)
{
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (GDA_IS_DATA_MODEL (model));
+ g_return_if_fail (iter != NULL);
+ g_return_if_fail (GDA_IS_DATA_MODEL_ITER (iter));
+
gint row;
row = gda_data_model_iter_get_row (iter);
@@ -368,10 +398,13 @@ validate_holder_change_cb (GdaSet *paramlist, GdaHolder *param, const GValue *ne
iter = GDA_DATA_MODEL_ITER (paramlist);
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
+ GdaDataModel *model = g_weak_ref_get (&priv->data_model);
- g_return_val_if_fail (priv->data_model != NULL, NULL);
-
- g_return_val_if_fail (GDA_IS_DATA_MODEL (priv->data_model), NULL);
+ if (model == NULL) {
+ g_set_error (&error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_INVALID,
+ _("Invalid data model. Can't validate holder"));
+ return error;
+ }
if (new_value)
nvalue = (GValue*) new_value;
@@ -379,9 +412,9 @@ validate_holder_change_cb (GdaSet *paramlist, GdaHolder *param, const GValue *ne
nvalue = gda_value_new_null();
iter = (GdaDataModelIter *) paramlist;
- if (!priv->keep_param_changes && (priv->row >= 0) && (GDA_IS_DATA_MODEL (priv->data_model))) {
- g_signal_handler_block (priv->data_model, priv->model_changes_signals [0]);
- g_signal_handler_block (priv->data_model, priv->model_changes_signals [1]);
+ if (!priv->keep_param_changes && (priv->row >= 0) && (GDA_IS_DATA_MODEL (model))) {
+ g_signal_handler_block (model, priv->model_changes_signals [0]);
+ g_signal_handler_block (model, priv->model_changes_signals [1]);
/* propagate the value update to the data model */
col = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (param), "model_col")) - 1;
@@ -395,18 +428,22 @@ validate_holder_change_cb (GdaSet *paramlist, GdaHolder *param, const GValue *ne
}
else {
g_print ("using Data Model default set_value_at\n");
- gda_data_model_set_value_at ((GdaDataModel *) priv->data_model, col, priv->row,
nvalue, &error);
+ gda_data_model_set_value_at (model, col, priv->row, nvalue, &error);
}
- g_signal_handler_unblock (priv->data_model, priv->model_changes_signals [0]);
- g_signal_handler_unblock (priv->data_model, priv->model_changes_signals [1]);
+ g_signal_handler_unblock (model, priv->model_changes_signals [0]);
+ g_signal_handler_unblock (model, priv->model_changes_signals [1]);
}
if (!new_value)
gda_value_free (nvalue);
- if (!error && GDA_SET_CLASS(gda_data_model_iter_parent_class)->validate_holder_change)
+ if (!error && GDA_SET_CLASS(gda_data_model_iter_parent_class)->validate_holder_change) {
+ g_object_unref (model);
/* for the parent class */
return (GDA_SET_CLASS(gda_data_model_iter_parent_class))->validate_holder_change (paramlist,
param, new_value);
+ }
+
+ g_object_unref (model);
return error;
}
@@ -430,13 +467,21 @@ holder_attr_changed_cb (GdaSet *paramlist, GdaHolder *param, const gchar *att_na
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
- if (!GDA_IS_DATA_PROXY (priv->data_model))
+ GdaDataModel *model = g_weak_ref_get (&priv->data_model);
+
+ if (model == NULL) {
return;
+ }
+
+ if (!GDA_IS_DATA_PROXY (model)) {
+ g_object_unref (model);
+ return;
+ }
if (!strcmp (att_name, GDA_ATTRIBUTE_IS_DEFAULT) &&
!priv->keep_param_changes && (priv->row >= 0)) {
- g_signal_handler_block (priv->data_model, priv->model_changes_signals [0]);
- g_signal_handler_block (priv->data_model, priv->model_changes_signals [1]);
+ g_signal_handler_block (model, priv->model_changes_signals [0]);
+ g_signal_handler_block (model, priv->model_changes_signals [1]);
/* propagate the value update to the data model */
col = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (param), "model_col")) - 1;
@@ -445,17 +490,19 @@ holder_attr_changed_cb (GdaSet *paramlist, GdaHolder *param, const gchar *att_na
if (att_value && g_value_get_boolean (att_value))
toset = TRUE;
if (toset && gda_holder_get_default_value (param))
- gda_data_proxy_alter_value_attributes (GDA_DATA_PROXY (priv->data_model),
+ gda_data_proxy_alter_value_attributes (GDA_DATA_PROXY (model),
priv->row, col,
GDA_VALUE_ATTR_CAN_BE_DEFAULT |
GDA_VALUE_ATTR_IS_DEFAULT);
- g_signal_handler_unblock (priv->data_model, priv->model_changes_signals [0]);
- g_signal_handler_unblock (priv->data_model, priv->model_changes_signals [1]);
+ g_signal_handler_unblock (model, priv->model_changes_signals [0]);
+ g_signal_handler_unblock (model, priv->model_changes_signals [1]);
}
/* for the parent class */
if ((GDA_SET_CLASS(gda_data_model_iter_parent_class))->holder_attr_changed)
(GDA_SET_CLASS(gda_data_model_iter_parent_class))->holder_attr_changed (paramlist, param,
att_name, att_value);
+
+ g_object_unref (model);
}
static void
@@ -468,13 +515,12 @@ gda_data_model_iter_finalize (GObject *object)
iter = GDA_DATA_MODEL_ITER (object);
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
- if (priv->data_model) {
- g_signal_handler_disconnect (priv->data_model, priv->model_changes_signals [0]);
- g_signal_handler_disconnect (priv->data_model, priv->model_changes_signals [1]);
- g_signal_handler_disconnect (priv->data_model, priv->model_changes_signals [2]);
- g_object_remove_weak_pointer (G_OBJECT (priv->data_model),
- (gpointer*) &(priv->data_model));
- priv->data_model = NULL;
+ GdaDataModel *model = g_weak_ref_get (&priv->data_model);
+ if (model != NULL) {
+ g_signal_handler_disconnect (model, priv->model_changes_signals [0]);
+ g_signal_handler_disconnect (model, priv->model_changes_signals [1]);
+ g_signal_handler_disconnect (model, priv->model_changes_signals [2]);
+ g_object_unref (model);
}
/* parent class */
@@ -496,25 +542,26 @@ gda_data_model_iter_set_property (GObject *object,
case PROP_DATA_MODEL: {
GdaDataModel *model;
- GObject* ptr = g_value_get_object (value);
- g_return_if_fail (ptr && GDA_IS_DATA_MODEL (ptr));
+ GObject* ptr = g_value_dup_object (value);
+ if (!GDA_IS_DATA_MODEL (ptr)) {
+ g_object_unref (ptr);
+ g_warning (_("Invalid data model object. Can't set property"));
+ return;
+ }
model = GDA_DATA_MODEL (ptr);
- if (priv->data_model) {
- if (priv->data_model == model)
+ GdaDataModel *current = g_weak_ref_get (&priv->data_model);
+ if (current != NULL) {
+ if (current == model)
return;
- g_signal_handler_disconnect (priv->data_model,
+ g_signal_handler_disconnect (current,
priv->model_changes_signals [0]);
- g_signal_handler_disconnect (priv->data_model,
+ g_signal_handler_disconnect (current,
priv->model_changes_signals [1]);
- g_signal_handler_disconnect (priv->data_model,
+ g_signal_handler_disconnect (current,
priv->model_changes_signals [2]);
- g_object_remove_weak_pointer (G_OBJECT (priv->data_model),
- (gpointer*) &(priv->data_model));
}
- priv->data_model = model;
- g_object_add_weak_pointer (G_OBJECT (priv->data_model),
- (gpointer*) &(priv->data_model));
+ g_weak_ref_set (&priv->data_model, model);
priv->model_changes_signals [0] = g_signal_connect (G_OBJECT (model), "row-updated",
G_CALLBACK
(model_row_updated_cb),
@@ -525,6 +572,7 @@ gda_data_model_iter_set_property (GObject *object,
priv->model_changes_signals [2] = g_signal_connect (G_OBJECT (model), "reset",
G_CALLBACK
(model_reset_cb), iter);
model_reset_cb (GDA_DATA_MODEL (ptr), iter);
+ g_object_unref (ptr);
break;
}
case PROP_FORCED_MODEL: {
@@ -561,11 +609,23 @@ gda_data_model_iter_get_property (GObject *object,
if (priv) {
switch (param_id) {
case PROP_DATA_MODEL:
- g_value_set_object (value, G_OBJECT (priv->data_model));
+ {
+ GObject *obj = g_weak_ref_get (&priv->data_model);
+ g_value_set_object (value, obj);
+ if (obj != NULL) {
+ g_object_unref (obj);
+ }
+ }
break;
case PROP_FORCED_MODEL:
- g_warning ("Deprecated property, not to be used");
- g_value_set_object (value, G_OBJECT (priv->data_model));
+ {
+ g_warning ("Deprecated property, not to be used");
+ GObject *obj = g_weak_ref_get (&priv->data_model);
+ g_value_set_object (value, obj);
+ if (obj != NULL) {
+ g_object_unref (obj);
+ }
+ }
break;
case PROP_CURRENT_ROW:
g_value_set_int (value, priv->row);
@@ -624,12 +684,14 @@ real_gda_data_model_iter_move_to_row (GdaDataModelIter *iter, gint row)
g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (iter), FALSE);
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
- GdaDataModel *model;
-
- model = priv->data_model;
- g_return_val_if_fail (model, FALSE);
+ GdaDataModel *model = g_weak_ref_get (&priv->data_model);
+ gboolean ret = FALSE;
- return gda_data_model_iter_move_to_row_default (model, iter, row);
+ ret = gda_data_model_iter_move_to_row_default (model, iter, row);
+ if (model != NULL) {
+ g_object_unref (model);
+ }
+ return ret;
}
static void
@@ -744,12 +806,15 @@ real_gda_data_model_iter_move_next (GdaDataModelIter *iter)
g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (iter), FALSE);
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
+ gboolean ret = FALSE;
- g_return_val_if_fail (priv, FALSE);
- g_return_val_if_fail (priv->data_model, FALSE);
+ model = g_weak_ref_get (&priv->data_model);
- model = priv->data_model;
- return gda_data_model_iter_move_next_default (model, iter);
+ ret = gda_data_model_iter_move_next_default (model, iter);
+ if (model != NULL) {
+ g_object_unref (model);
+ }
+ return ret;
}
/**
@@ -849,13 +914,15 @@ real_gda_data_model_iter_move_prev (GdaDataModelIter *iter)
g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (iter), FALSE);
GdaDataModelIterPrivate *priv = gda_data_model_iter_get_instance_private (iter);
+ gboolean ret = FALSE;
- g_return_val_if_fail (priv, FALSE);
- g_return_val_if_fail (priv->data_model, FALSE);
-
- model = priv->data_model;
+ model = g_weak_ref_get (&priv->data_model);
/* default method */
- return gda_data_model_iter_move_prev_default (model, iter);
+ ret = gda_data_model_iter_move_prev_default (model, iter);
+ if (model != NULL) {
+ g_object_unref (model);
+ }
+ return ret;
}
/**
diff --git a/libgda/gda-data-model.h b/libgda/gda-data-model.h
index debffb51d..89cbd523d 100644
--- a/libgda/gda-data-model.h
+++ b/libgda/gda-data-model.h
@@ -91,6 +91,7 @@ typedef enum {
GDA_DATA_MODEL_XML_FORMAT_ERROR,
GDA_DATA_MODEL_TRUNCATED_ERROR,
+ GDA_DATA_MODEL_INVALID,
GDA_DATA_MODEL_OTHER_ERROR
} GdaDataModelError;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]