From addc71056d1ad1815932cecb4b737b50b8692a1c Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Sat, 24 Apr 2010 01:41:12 +0200 Subject: [PATCH] [AdgPoint] Improved API and updated accordingly Removed adg_point_set() because adg_point_copy() yet provides a similar behavior. Implemented new adg_point_unset() API to make it clear how unset an AdgPoint, avoiding to rely on a NULL value passed in as parameter to other _set() methods. Provided a convenient method in AdgEntity to set a point that must update also the dependencies on the model (when that point is a named pair) and used throughout the dimensioning entities. --- src/adg/adg-adim.c | 51 ++++++++------------- src/adg/adg-dim.c | 42 +++++++++-------- src/adg/adg-entity.c | 59 +++++++++++++----------- src/adg/adg-entity.h | 6 +-- src/adg/adg-point.c | 124 +++++++++++++++++++++------------------------------ src/adg/adg-point.h | 3 +- 6 files changed, 130 insertions(+), 155 deletions(-) diff --git a/src/adg/adg-adim.c b/src/adg/adg-adim.c index 547b96ca..52a68bb7 100644 --- a/src/adg/adg-adim.c +++ b/src/adg/adg-adim.c @@ -164,22 +164,19 @@ adg_adim_init(AdgADim *adim) static void dispose(GObject *object) { - AdgADim *adim; + AdgEntity *entity; AdgADimPrivate *data; - adim = (AdgADim *) object; - data = adim->data; + entity = (AdgEntity *) object; + data = ((AdgADim *) object)->data; dispose_markers((AdgADim *) object); - if (data->org1 != NULL) { - adg_point_destroy(data->org1); - data->org1 = NULL; - } - if (data->org2 != NULL) { - adg_point_destroy(data->org2); - data->org2 = NULL; - } + if (data->org1 != NULL) + data->org1 = adg_entity_point(entity, data->org1, NULL); + + if (data->org2 != NULL) + data->org2 = adg_entity_point(entity, data->org2, NULL); if (PARENT_OBJECT_CLASS->dispose) PARENT_OBJECT_CLASS->dispose(object); @@ -213,18 +210,20 @@ static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - AdgADim *adim; + AdgEntity *entity; AdgADimPrivate *data; - adim = (AdgADim *) object; - data = adim->data; + entity = (AdgEntity *) object; + data = ((AdgADim *) object)->data; switch (prop_id) { case PROP_ORG1: - adg_point_set(&data->org1, g_value_get_boxed(value)); + data->org1 = adg_entity_point(entity, data->org1, + g_value_get_boxed(value)); break; case PROP_ORG2: - adg_point_set(&data->org2, g_value_get_boxed(value)); + data->org2 = adg_entity_point(entity, data->org2, + g_value_get_boxed(value)); break; case PROP_HAS_EXTENSION1: data->has_extension1 = g_value_get_boolean(value); @@ -370,19 +369,13 @@ adg_adim_new_full_from_model(AdgModel *model, * point was bound to a named pair (hence, possibly destroying * the model if this was the last reference). * - * @org1 can be %NULL, in which case the point is unset. + * @org1 can be %NULL, in which case the point is destroyed. **/ void adg_adim_set_org1(AdgADim *adim, const AdgPoint *org1) { - AdgADimPrivate *data; - g_return_if_fail(ADG_IS_ADIM(adim)); - - data = adim->data; - - if (adg_point_set(&data->org1, org1)) - g_object_notify((GObject *) adim, "org1"); + g_object_set((GObject *) adim, "org1", org1, NULL); } /** @@ -484,19 +477,13 @@ adg_adim_get_org1(AdgADim *adim) * point was bound to a named pair (hence, possibly destroying * the model if this was the last reference). * - * @org2 can be %NULL, in which case the point is unset. + * @org2 can be %NULL, in which case the point is destroyed. **/ void adg_adim_set_org2(AdgADim *adim, const AdgPoint *org2) { - AdgADimPrivate *data; - g_return_if_fail(ADG_IS_ADIM(adim)); - - data = adim->data; - - if (adg_point_set(&data->org2, org2)) - g_object_notify((GObject *) adim, "org2"); + g_object_set((GObject *) adim, "org2", org2, NULL); } /** diff --git a/src/adg/adg-dim.c b/src/adg/adg-dim.c index dacee6ec..3e3b6095 100644 --- a/src/adg/adg-dim.c +++ b/src/adg/adg-dim.c @@ -209,24 +209,25 @@ adg_dim_init(AdgDim *dim) static void _adg_dispose(GObject *object) { - AdgDimPrivate *data = ((AdgDim *) object)->data; + AdgEntity *entity; + AdgDimPrivate *data; + + entity = (AdgEntity *) object; + data = ((AdgDim *) object)->data; if (data->quote.entity != NULL) { g_object_unref(data->quote.entity); data->quote.entity = NULL; } - if (data->ref1 != NULL) { - adg_point_destroy(data->ref1); - data->ref1 = NULL; - } - if (data->ref2 != NULL) { - adg_point_destroy(data->ref2); - data->ref2 = NULL; - } - if (data->pos != NULL) { - adg_point_destroy(data->pos); - data->pos = NULL; - } + + if (data->ref1 != NULL) + data->ref1 = adg_entity_point(entity, data->ref1, NULL); + + if (data->ref2 != NULL) + data->ref2 = adg_entity_point(entity, data->ref2, NULL); + + if (data->pos != NULL) + data->pos = adg_entity_point(entity, data->pos, NULL); if (PARENT_OBJECT_CLASS->dispose) PARENT_OBJECT_CLASS->dispose(object); @@ -305,13 +306,16 @@ _adg_set_property(GObject *object, guint prop_id, data->dim_dress = g_value_get_int(value); break; case PROP_REF1: - adg_entity_point_set(entity, &data->ref1, g_value_get_boxed(value)); + data->ref1 = adg_entity_point(entity, data->ref1, + g_value_get_boxed(value)); break; case PROP_REF2: - adg_entity_point_set(entity, &data->ref2, g_value_get_boxed(value)); + data->ref2 = adg_entity_point(entity, data->ref2, + g_value_get_boxed(value)); break; case PROP_POS: - adg_entity_point_set(entity, &data->pos, g_value_get_boxed(value)); + data->pos = adg_entity_point(entity, data->pos, + g_value_get_boxed(value)); break; case PROP_LEVEL: data->level = g_value_get_double(value); @@ -388,7 +392,7 @@ adg_dim_get_dim_dress(AdgDim *dim) * point was bound to a named pair (hence, possibly destroying * the model if this was the last reference). * - * @ref1 can be %NULL, in which case the point is unset. + * @ref1 can be %NULL, in which case the point is destroyed. **/ void adg_dim_set_ref1(AdgDim *dim, const AdgPoint *ref1) @@ -496,7 +500,7 @@ adg_dim_get_ref1(AdgDim *dim) * point was bound to a named pair (hence, possibly destroying * the model if it was the last reference). * - * @ref2 can be %NULL, in which case the point is unset. + * @ref2 can be %NULL, in which case the point is destroyed. **/ void adg_dim_set_ref2(AdgDim *dim, const AdgPoint *ref2) @@ -604,7 +608,7 @@ adg_dim_get_ref2(AdgDim *dim) * point was bound to a named pair (hence, possibly destroying * the model if it was the last reference). * - * @pos can be %NULL, in which case the point is unset. + * @pos can be %NULL, in which case the point is destroyed. **/ void adg_dim_set_pos(AdgDim *dim, const AdgPoint *pos) diff --git a/src/adg/adg-entity.c b/src/adg/adg-entity.c index 37525250..310e4004 100644 --- a/src/adg/adg-entity.c +++ b/src/adg/adg-entity.c @@ -975,45 +975,50 @@ adg_entity_render(AdgEntity *entity, cairo_t *cr) } /** - * adg_entity_point_set: + * adg_entity_point: * @entity: an #AdgEntity - * @p_point: a pointer to an #AdgPoint - * @new_point: the new point to assign + * @point: the #AdgPoint to define + * @new_point: the new #AdgPoint value * - * A convenient method to assign @new_point to the #AdgPoint pointed - * by @p_point. Similar to adg_point_set() but assuming the #AdgPoint - * is owned by @entity, this function also takes care of the - * dependencies between @entity and the model bound to the #AdgPoint, - * if the point is a named pair. + * A convenient method to set an #AdgPoint with old value of @point + * to the new value @new_point. It assumes the points are owned by + * @entity, so it takes also care of the dependencies between + * @entity and the model bound to the #AdgPoint. * - * If the destination point is yet @new_point, %FALSE is returned. + * @point can be %NULL, in which case a new #AdgPoint is created. + * Also, @new_point can be %NULL in which case @point is destroyed. * - * Returns: %TRUE if the pointer pointed by @p_point has been changed, - * %FALSE otherwise + * Returns: the new properly defined point **/ -gboolean -adg_entity_point_set(AdgEntity *entity, AdgPoint **p_point, - const AdgPoint *new_point) +AdgPoint * +adg_entity_point(AdgEntity *entity, AdgPoint *point, AdgPoint *new_point) { - AdgModel *old_model, *new_model; - - g_return_val_if_fail(p_point != NULL, FALSE); + g_return_val_if_fail(ADG_IS_ENTITY(entity), NULL); - old_model = *p_point ? adg_point_get_model(*p_point) : NULL; + if (!adg_point_equal(point, new_point)) { + AdgModel *old_model, *new_model; - if (!adg_point_set(p_point, new_point)) - return FALSE; + old_model = point ? adg_point_get_model(point) : NULL; + new_model = new_point ? adg_point_get_model(new_point) : NULL; - new_model = adg_point_get_model(*p_point); + if (new_model != old_model) { + if (new_model) + adg_model_add_dependency(new_model, entity); + if (old_model) + adg_model_remove_dependency(old_model, entity); + } - if (new_model != old_model) { - if (new_model) - adg_model_add_dependency(new_model, entity); - if (old_model) - adg_model_remove_dependency(old_model, entity); + if (new_point && point) { + adg_point_copy(point, new_point); + } else if (new_point) { + point = adg_point_dup(new_point); + } else { + adg_point_destroy(point); + point = NULL; + } } - return TRUE; + return point; } diff --git a/src/adg/adg-entity.h b/src/adg/adg-entity.h index 9aba688b..ddf81ce9 100644 --- a/src/adg/adg-entity.h +++ b/src/adg/adg-entity.h @@ -124,9 +124,9 @@ void adg_entity_invalidate (AdgEntity *entity); void adg_entity_arrange (AdgEntity *entity); void adg_entity_render (AdgEntity *entity, cairo_t *cr); -gboolean adg_entity_point_set (AdgEntity *entity, - AdgPoint **p_point, - const AdgPoint *new_point); +AdgPoint * adg_entity_point (AdgEntity *entity, + AdgPoint *old_point, + AdgPoint *new_point); G_END_DECLS diff --git a/src/adg/adg-point.c b/src/adg/adg-point.c index 9d35886c..f1c41248 100644 --- a/src/adg/adg-point.c +++ b/src/adg/adg-point.c @@ -123,8 +123,7 @@ adg_point_destroy(AdgPoint *point) { g_return_if_fail(point != NULL); - adg_point_set_pair_from_model(point, NULL, NULL); - + adg_point_unset(point); g_free(point); } @@ -133,9 +132,10 @@ adg_point_destroy(AdgPoint *point) * @point: an #AdgPoint * @src: the source point to copy * - * Copies @src into @point. If @point was linked to a named pair, the - * reference to the old model is dropped. Similary, if @src is linked - * to a model, a new reference to this new model is added. + * Copies @src into @point. If the old content of @point was linked + * to the named pair of a model, the reference to that model is + * dropped. Similary, if @src is a named pair, a new reference to + * the new model is added. **/ void adg_point_copy(AdgPoint *point, const AdgPoint *src) @@ -145,6 +145,7 @@ adg_point_copy(AdgPoint *point, const AdgPoint *src) if (src->model != NULL) g_object_ref(src->model); + if (point->model != NULL) g_object_unref(point->model); @@ -156,44 +157,6 @@ adg_point_copy(AdgPoint *point, const AdgPoint *src) } /** - * adg_point_set: - * @p_point: a pointer to an #AdgPoint - * @new_point: the new point to assign - * - * Convenient method to assign @new_point to the #AdgPoint pointed - * by @p_point. This is useful while implementing #AdgPoint - * property setters. - * - * At the end *@p_point will be set to @new_point, allocating a new - * #AdgPoint or destroying the previous one when necessary. It is - * allowed to use %NULL as @new_point to unset *@p_point. - * - * Returns: %TRUE if the pointer pointed by @p_point has been changed, - * %FALSE otherwise - **/ -gboolean -adg_point_set(AdgPoint **p_point, const AdgPoint *new_point) -{ - g_return_val_if_fail(p_point != NULL, FALSE); - - if ((*p_point == new_point) || - (*p_point && new_point && adg_point_equal(*p_point, new_point))) - return FALSE; - - if (*p_point == NULL) - *p_point = adg_point_new(); - - if (new_point) { - adg_point_copy(*p_point, new_point); - } else { - adg_point_destroy(*p_point); - *p_point = NULL; - } - - return TRUE; -} - -/** * adg_point_set_pair: * @point: an #AdgPoint * @pair: the #AdgPair to use @@ -225,9 +188,7 @@ adg_point_set_pair_explicit(AdgPoint *point, gdouble x, gdouble y) { g_return_if_fail(point != NULL); - /* Unlink the named pair dependency, if any */ - adg_point_set_pair_from_model(point, NULL, NULL); - + adg_point_unset(point); point->pair.x = x; point->pair.y = y; point->is_uptodate = TRUE; @@ -240,48 +201,61 @@ adg_point_set_pair_explicit(AdgPoint *point, gdouble x, gdouble y) * @name: the id of a named pair in @model * * Links the @name named pair of @model to @point, so any subsequent - * call to adg_point_update() will read the named pair content. A - * new reference is added to @model while the previous model (if any) + * call to adg_point_get_pair() will return the named pair value. + * A new reference is added to @model while the previous model (if any) * is unreferenced. - * - * It is allowed to use %NULL as @model, in which case the possible - * link between @point and the named pair is dropped. **/ void adg_point_set_pair_from_model(AdgPoint *point, AdgModel *model, const gchar *name) { g_return_if_fail(point != NULL); - g_return_if_fail(model == NULL || name != NULL); + g_return_if_fail(ADG_IS_MODEL(model)); + g_return_if_fail(name != NULL); - /* Check if unlinking a yet unlinked point */ - if (model == NULL && point->model == NULL) + /* Return if the new named pair is the same of the old one */ + if (model == point->model && strcmp(point->name, name) == 0) return; - /* Return if the named pair is not changed */ - if (model == point->model && - (model == NULL || strcmp(point->name, name) == 0)) { - return; - } - - if (model != NULL) - g_object_ref(model); + g_object_ref(model); - if (point->model != NULL) { + if (point->model) { /* Remove the old named pair */ g_object_unref(point->model); g_free(point->name); - point->model = NULL; - point->name = NULL; } + /* Set the new named pair */ point->is_uptodate = FALSE; + point->model = model; + point->name = g_strdup(name); +} + +/** + * adg_point_unset: + * @point: a pointer to an #AdgPoint + * + * Unsets @point by resetting the internal "is_updated" flag. + * This also means @point is unlinked from the model if it is + * a named pair. In any cases, after this call the content of + * @point is undefined, that is calling adg_point_get_pair() + * raises an error. + **/ +void +adg_point_unset(AdgPoint *point) +{ + g_return_if_fail(point != NULL); - if (model != NULL) { - /* Set the new named pair */ - point->model = model; - point->name = g_strdup(name); + if (point->model) { + /* Remove the old named pair */ + g_object_unref(point->model); + g_free(point->name); } + + /* Set the new named pair */ + point->is_uptodate = FALSE; + point->model = NULL; + point->name = NULL; } /** @@ -321,6 +295,7 @@ adg_point_get_pair(AdgPoint *point) } cpml_pair_copy(&point->pair, pair); + point->is_uptodate = TRUE; } return (AdgPair *) point; @@ -373,7 +348,7 @@ adg_point_invalidate(AdgPoint *point) { g_return_if_fail(point != NULL); - if (point->model != NULL) + if (point->model) point->is_uptodate = FALSE; } @@ -391,13 +366,18 @@ adg_point_invalidate(AdgPoint *point) * adg_pair_equal(adg_point_get_pair(point1), adg_point_get_pair(point2)); * ]| * + * %NULL values are handled gracefully. + * * Returns: %TRUE if @point1 is equal to @point2, %FALSE otherwise **/ gboolean adg_point_equal(const AdgPoint *point1, const AdgPoint *point2) { - g_return_val_if_fail(point1 != NULL, FALSE); - g_return_val_if_fail(point2 != NULL, FALSE); + if (point1 == point2) + return TRUE; + + if (point1 == NULL || point2 == NULL) + return FALSE; /* Check if the points are not bound to the same model * or if only one of the two points is explicit */ diff --git a/src/adg/adg-point.h b/src/adg/adg-point.h index 36706307..d3d07b2a 100644 --- a/src/adg/adg-point.h +++ b/src/adg/adg-point.h @@ -47,8 +47,6 @@ AdgPoint * adg_point_dup (const AdgPoint *src); void adg_point_destroy (AdgPoint *point); void adg_point_copy (AdgPoint *point, const AdgPoint *src); -gboolean adg_point_set (AdgPoint **p_point, - const AdgPoint *new_point); void adg_point_set_pair (AdgPoint *point, const AdgPair *pair); void adg_point_set_pair_explicit (AdgPoint *point, @@ -57,6 +55,7 @@ void adg_point_set_pair_explicit (AdgPoint *point, void adg_point_set_pair_from_model (AdgPoint *point, AdgModel *model, const gchar *name); +void adg_point_unset (AdgPoint *point); const AdgPair * adg_point_get_pair (AdgPoint *point); AdgModel * adg_point_get_model (AdgPoint *point); const gchar * adg_point_get_name (AdgPoint *point); -- 2.11.4.GIT