From 47caee805149a62880a3f77e3317d43d2b9a9205 Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Mon, 17 Aug 2009 21:55:49 +0200 Subject: [PATCH] [AdgEntity] Improved "invalidate" signal Using "invalidate" about the same way the "render" signal is managed, but revering the meaning. This means the default "invalidate" handler is not overridable but instead call the render() virtual method. If render() is not implemented, a valid empty invalidate callback is assumed (useful for entities without cache). At the end, if the callback run succesfully (that is, returned TRUE) the RENDERED flag is reset. --- adg/adg-entity.c | 46 ++++++++++++++++++++++++++++++++-------------- adg/adg-entity.h | 2 +- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/adg/adg-entity.c b/adg/adg-entity.c index cc08f1dc..ec0889a4 100644 --- a/adg/adg-entity.c +++ b/adg/adg-entity.c @@ -79,7 +79,8 @@ static void set_global_map (AdgEntity *entity, const AdgMatrix *map); static void set_local_map (AdgEntity *entity, const AdgMatrix *map); -static void invalidate (AdgEntity *entity); +static void real_invalidate (AdgEntity *entity, + gpointer user_data); static void real_render (AdgEntity *entity, cairo_t *cr, gpointer user_data); @@ -110,7 +111,7 @@ adg_entity_class_init(AdgEntityClass *klass) klass->set_parent = set_parent; klass->parent_set = parent_set; klass->get_context = get_context; - klass->invalidate = invalidate; + klass->invalidate = NULL; klass->render = NULL; param = g_param_spec_object("parent", @@ -156,24 +157,29 @@ adg_entity_class_init(AdgEntityClass *klass) * AdgEntity::invalidate: * @entity: an #AdgEntity * - * Clears the cached data of @entity. + * The inverse of the rendering. Usually, invalidation causes the + * cache of @entity to be cleared. After a succesful invalidation + * the rendered flag is reset: you can access its state using + * adg_entity_get_rendered(). **/ - signals[INVALIDATE] = g_signal_new("invalidate", - G_OBJECT_CLASS_TYPE(gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(AdgEntityClass, invalidate), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 0); + closure = g_cclosure_new(G_CALLBACK(real_invalidate), + (gpointer)0xdeadbeaf, NULL); + signals[INVALIDATE] = g_signal_newv("invalidate", ADG_TYPE_ENTITY, + G_SIGNAL_RUN_LAST, closure, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, param_types); /** * AdgEntity::render: * @entity: an #AdgEntity * @cr: a #cairo_t drawing context * - * Causes the rendering of @entity on @cr. + * Causes the rendering of @entity on @cr. After a succesful rendering + * the rendered flag is set: you can access its state using + * adg_entity_get_rendered(). **/ - closure = g_cclosure_new(G_CALLBACK(real_render), (gpointer)0xdeadbeaf, NULL); + closure = g_cclosure_new(G_CALLBACK(real_render), + (gpointer)0xdeadbeaf, NULL); param_types[0] = G_TYPE_POINTER; signals[RENDER] = g_signal_newv("render", ADG_TYPE_ENTITY, G_SIGNAL_RUN_LAST, closure, NULL, NULL, @@ -753,10 +759,21 @@ set_local_map(AdgEntity *entity, const AdgMatrix *map) } static void -invalidate(AdgEntity *entity) +real_invalidate(AdgEntity *entity, gpointer user_data) { - AdgEntityPrivate *data = entity->data; + AdgEntityClass *entity_class; + AdgEntityPrivate *data; + g_assert(user_data == (gpointer) 0xdeadbeaf); + + entity_class = ADG_ENTITY_GET_CLASS(entity); + if (entity_class->invalidate == NULL) { + /* Assume the entity does not have cache to be cleared */ + } else if (!entity_class->invalidate(entity)) { + return; + } + + data = entity->data; ADG_UNSET(data->flags, RENDERED); } @@ -770,6 +787,7 @@ real_render(AdgEntity *entity, cairo_t *cr, gpointer user_data) entity_class = ADG_ENTITY_GET_CLASS(entity); if (entity_class->render == NULL) { + /* The render method must be defined */ g_warning("%s: `render' method not implemented for type `%s'", G_STRLOC, g_type_name(G_OBJECT_TYPE(entity))); return; diff --git a/adg/adg-entity.h b/adg/adg-entity.h index ee36e225..617da932 100644 --- a/adg/adg-entity.h +++ b/adg/adg-entity.h @@ -61,13 +61,13 @@ struct _AdgEntityClass { /* Signals */ void (*parent_set) (AdgEntity *entity, AdgContainer *old_parent); - void (*invalidate) (AdgEntity *entity); /* Virtual Table */ AdgContainer * (*get_parent) (AdgEntity *entity); void (*set_parent) (AdgEntity *entity, AdgContainer *parent); AdgContext * (*get_context) (AdgEntity *entity); + gboolean (*invalidate) (AdgEntity *entity); gboolean (*render) (AdgEntity *entity, cairo_t *cr); }; -- 2.11.4.GIT