gnome-games r8159 - trunk/aisleriot



Author: jclinton
Date: Tue Oct 21 19:46:47 2008
New Revision: 8159
URL: http://svn.gnome.org/viewvc/gnome-games?rev=8159&view=rev

Log:
Added an actor to render a whole slot instead of trying to create
separate actors for each visible card in the slot. For now this breaks
animations and highlights.

Added:
   trunk/aisleriot/slot-renderer.c
   trunk/aisleriot/slot-renderer.h
Modified:
   trunk/aisleriot/Makefile.am
   trunk/aisleriot/board.c
   trunk/aisleriot/game.c
   trunk/aisleriot/game.h

Modified: trunk/aisleriot/Makefile.am
==============================================================================
--- trunk/aisleriot/Makefile.am	(original)
+++ trunk/aisleriot/Makefile.am	Tue Oct 21 19:46:47 2008
@@ -29,6 +29,8 @@
 	conf.h		\
 	game.c		\
 	game.h		\
+	slot-renderer.c \
+	slot-renderer.h \
 	sol.c		\
 	stats-dialog.c	\
 	stats-dialog.h	\

Modified: trunk/aisleriot/board.c
==============================================================================
--- trunk/aisleriot/board.c	(original)
+++ trunk/aisleriot/board.c	Tue Oct 21 19:46:47 2008
@@ -43,6 +43,7 @@
 #include "baize.h"
 #include "card-cache.h"
 #include "card.h"
+#include "slot-renderer.h"
 
 #define AISLERIOT_BOARD_GET_PRIVATE(board)(G_TYPE_INSTANCE_GET_PRIVATE ((board), AISLERIOT_TYPE_BOARD, AisleriotBoardPrivate))
 
@@ -832,23 +833,6 @@
 }
 
 static void
-truncate_card_images_array (GPtrArray *card_images, guint size)
-{
-  guint i;
-
-  for (i = size; i < card_images->len; i++) {
-    ClutterActor *actor = g_ptr_array_index (card_images, i);
-
-    if (actor) {
-      clutter_actor_destroy (actor);
-      g_object_unref (actor);
-    }
-  }
-
-  g_ptr_array_set_size (card_images, size);
-}
-
-static void
 destroy_animation_data (ClutterActor *actor, AnimationData *data)
 {
   g_signal_handlers_disconnect_by_func (actor, destroy_animation_data, data);
@@ -922,6 +906,7 @@
 static void
 check_animations (AisleriotBoard *board)
 {
+#if 0
   AisleriotBoardPrivate *priv = board->priv;
   GPtrArray *slots;
   int slot_num, i;
@@ -1021,6 +1006,7 @@
   }
 
   g_array_free (removed_cards, TRUE);
+#endif
 }
 
 static void
@@ -1029,79 +1015,24 @@
                               int highlight_start_card_id)
 {
   AisleriotBoardPrivate *priv = board->priv;
-  GPtrArray *card_images;
-  guint n_cards, first_exposed_card_id, i;
-  guint8 *cards;
-  int cardx, cardy;
   ClutterActor *stage
     = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (board));
 
-  card_images = slot->card_images;
-
-  truncate_card_images_array (card_images, 0);
-
   if (!priv->geometry_set)
     return;
 
-  cards = slot->cards->data;
-  n_cards = slot->cards->len;
-
-  g_assert (n_cards >= slot->exposed);
-  first_exposed_card_id = n_cards - slot->exposed;
-
-  /* No need to get invisible cards from cache, which will just
-   * slow us down!
-   */
-  for (i = 0; i < first_exposed_card_id; ++i) {
-    g_ptr_array_add (card_images, NULL);
-  }
-
-  cardx = slot->rect.x;
-  cardy = slot->rect.y;
-
-  if (slot->slot_texture) {
-    clutter_actor_destroy (slot->slot_texture);
-    g_object_unref (slot->slot_texture);
-    slot->slot_texture = NULL;
-  }
-
-  if (slot->cards->len == 0) {
-    CoglHandle cogl_tex;
-    gboolean show_highlight;
-
-    slot->slot_texture = g_object_ref_sink (clutter_texture_new ());
-
-    show_highlight = priv->show_highlight && slot == priv->highlight_slot;
-    cogl_tex = aisleriot_card_cache_get_slot_texture (priv->textures,
-                                                      show_highlight);
-
-    clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (slot->slot_texture),
-                                      cogl_tex);
+  if (slot->slot_renderer == NULL) {
+    slot->slot_renderer = aisleriot_slot_renderer_new (priv->textures, slot);
+    g_object_ref_sink (slot->slot_renderer);
 
-    clutter_actor_set_position (slot->slot_texture, cardx, cardy);
+    clutter_actor_set_position (slot->slot_renderer,
+                                slot->rect.x, slot->rect.y);
 
-    clutter_container_add (CLUTTER_CONTAINER (stage), slot->slot_texture, NULL);
+    clutter_container_add (CLUTTER_CONTAINER (stage),
+                           slot->slot_renderer, NULL);
   }
 
-  for (i = first_exposed_card_id; i < n_cards; ++i) {
-    Card card = CARD (cards[i]);
-    gboolean is_highlighted;
-    ClutterActor *card_tex = aisleriot_card_new (priv->textures, card);
-
-    is_highlighted = (i >= highlight_start_card_id);
-
-    aisleriot_card_set_highlighted (AISLERIOT_CARD (card_tex),
-                                    is_highlighted);
-
-    clutter_actor_set_position (card_tex, cardx, cardy);
-
-    clutter_container_add (CLUTTER_CONTAINER (stage), card_tex, NULL);
-
-    g_ptr_array_add (card_images, g_object_ref_sink (card_tex));
-
-    cardx += slot->pixeldx;
-    cardy += slot->pixeldy;
-  }
+  clutter_actor_queue_redraw (slot->slot_renderer);
 }
 
 static void
@@ -1258,8 +1189,6 @@
 
   /* Take the cards off of the stack */
   g_byte_array_set_size (cards, priv->moving_cards_origin_card_id);
-  truncate_card_images_array (hslot->card_images,
-                              priv->moving_cards_origin_card_id);
 
   width = priv->card_size.width + (num_moving_cards - 1) * hslot->pixeldx;
   height = priv->card_size.height + (num_moving_cards - 1) * hslot->pixeldy;

Modified: trunk/aisleriot/game.c
==============================================================================
--- trunk/aisleriot/game.c	(original)
+++ trunk/aisleriot/game.c	Tue Oct 21 19:46:47 2008
@@ -232,28 +232,19 @@
 clear_slots (AisleriotGame *game,
              gboolean notify)
 {
-  guint i, n_slots, card_num;
+  guint i, n_slots;
 
   n_slots = game->slots->len;
   for (i = 0; i < n_slots; ++i) {
     Slot *slot = game->slots->pdata[i];
 
-    for (card_num = 0; card_num < slot->card_images->len; card_num++) {
-      ClutterActor *actor = g_ptr_array_index (slot->card_images, card_num);
-      if (actor) {
-        clutter_actor_destroy (actor);
-        g_object_unref (actor);
-      }
-    }
-
-    if (slot->slot_texture) {
-      clutter_actor_destroy (slot->slot_texture);
-      g_object_unref (slot->slot_texture);
+    if (slot->slot_renderer) {
+      clutter_actor_destroy (slot->slot_renderer);
+      g_object_unref (slot->slot_renderer);
     }
 
     g_byte_array_free (slot->cards, TRUE);
     g_byte_array_free (slot->old_cards, TRUE);
-    g_ptr_array_free (slot->card_images, TRUE);
 
     g_slice_free (Slot, slot);
   }
@@ -599,8 +590,6 @@
   slot->expanded_down = expanded_down != FALSE;
   slot->expanded_right = expanded_right != FALSE;
 
-  slot->card_images = g_ptr_array_sized_new (SLOT_CARDS_N_PREALLOC);
-
   slot->needs_update = TRUE;
 
   /* this will update the slot length too */

Modified: trunk/aisleriot/game.h
==============================================================================
--- trunk/aisleriot/game.h	(original)
+++ trunk/aisleriot/game.h	Tue Oct 21 19:46:47 2008
@@ -57,10 +57,8 @@
   /* The location in pixel units. Filled in by the scaling code. */
   GdkRectangle rect;
 
-  /* ClutterActor *, reference owned */
-  GPtrArray *card_images;
   /* Actor for the slot */
-  ClutterActor *slot_texture;
+  ClutterActor *slot_renderer;
 
   guint expanded_right : 1;
   guint expanded_down : 1;

Added: trunk/aisleriot/slot-renderer.c
==============================================================================
--- (empty file)
+++ trunk/aisleriot/slot-renderer.c	Tue Oct 21 19:46:47 2008
@@ -0,0 +1,252 @@
+/*
+ *  Copyright  2008 Neil Roberts
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <clutter/clutter-actor.h>
+#include <gtk/gtk.h>
+#include <cogl/cogl.h>
+
+#include "slot-renderer.h"
+
+static void aisleriot_slot_renderer_dispose (GObject *object);
+static void aisleriot_slot_renderer_finalize (GObject *object);
+
+static void aisleriot_slot_renderer_set_property (GObject *object,
+                                                  guint property_id,
+                                                  const GValue *value,
+                                                  GParamSpec *pspec);
+static void aisleriot_slot_renderer_get_property (GObject *object,
+                                                  guint property_id,
+                                                  GValue *value,
+                                                  GParamSpec *pspec);
+
+static void aisleriot_slot_renderer_paint (ClutterActor *actor);
+
+static void aisleriot_slot_renderer_set_cache (AisleriotSlotRenderer *srend,
+                                               AisleriotCardCache *cache);
+
+G_DEFINE_TYPE (AisleriotSlotRenderer, aisleriot_slot_renderer,
+               CLUTTER_TYPE_ACTOR);
+
+#define AISLERIOT_SLOT_RENDERER_GET_PRIVATE(obj) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), AISLERIOT_TYPE_SLOT_RENDERER, \
+                                AisleriotSlotRendererPrivate))
+
+struct _AisleriotSlotRendererPrivate
+{
+  AisleriotCardCache *cache;
+  Slot *slot;
+  gboolean show_highlight;
+  guint highlight_start_card_id;
+};
+
+enum
+{
+  PROP_0,
+
+  PROP_CACHE,
+  PROP_SLOT
+};
+
+static void
+aisleriot_slot_renderer_class_init (AisleriotSlotRendererClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+  ClutterActorClass *actor_class = (ClutterActorClass *) klass;
+  GParamSpec *pspec;
+
+  gobject_class->dispose = aisleriot_slot_renderer_dispose;
+  gobject_class->finalize = aisleriot_slot_renderer_finalize;
+
+  gobject_class->set_property = aisleriot_slot_renderer_set_property;
+  gobject_class->get_property = aisleriot_slot_renderer_get_property;
+
+  actor_class->paint = aisleriot_slot_renderer_paint;
+
+  pspec = g_param_spec_object ("cache", NULL, NULL,
+                               AISLERIOT_TYPE_CARD_CACHE,
+                               G_PARAM_WRITABLE |
+                               G_PARAM_CONSTRUCT_ONLY |
+                               G_PARAM_STATIC_NAME |
+                               G_PARAM_STATIC_NICK |
+                               G_PARAM_STATIC_BLURB);
+  g_object_class_install_property (gobject_class, PROP_CACHE, pspec);
+
+  pspec = g_param_spec_pointer ("slot", NULL, NULL,
+                                G_PARAM_WRITABLE |
+                                G_PARAM_CONSTRUCT_ONLY |
+                                G_PARAM_STATIC_NAME |
+                                G_PARAM_STATIC_NICK |
+                                G_PARAM_STATIC_BLURB);
+  g_object_class_install_property (gobject_class, PROP_SLOT, pspec);
+
+  g_type_class_add_private (klass, sizeof (AisleriotSlotRendererPrivate));
+}
+
+static void
+aisleriot_slot_renderer_init (AisleriotSlotRenderer *self)
+{
+  AisleriotSlotRendererPrivate *priv;
+
+  priv = self->priv = AISLERIOT_SLOT_RENDERER_GET_PRIVATE (self);
+
+  priv->highlight_start_card_id = G_MAXUINT;
+}
+
+static void
+aisleriot_slot_renderer_dispose (GObject *object)
+{
+  AisleriotSlotRenderer *self = (AisleriotSlotRenderer *) object;
+
+  aisleriot_slot_renderer_set_cache (self, NULL);
+
+  G_OBJECT_CLASS (aisleriot_slot_renderer_parent_class)->dispose (object);
+}
+
+static void
+aisleriot_slot_renderer_finalize (GObject *object)
+{
+  AisleriotSlotRenderer *self = (AisleriotSlotRenderer *) object;
+
+  G_OBJECT_CLASS (aisleriot_slot_renderer_parent_class)->finalize (object);
+}
+
+ClutterActor *
+aisleriot_slot_renderer_new (AisleriotCardCache *cache, Slot *slot)
+{
+  ClutterActor *self = g_object_new (AISLERIOT_TYPE_SLOT_RENDERER,
+                                     "cache", cache,
+                                     "slot", slot,
+                                     NULL);
+
+  return self;
+}
+
+static void
+aisleriot_slot_renderer_set_cache (AisleriotSlotRenderer *srend,
+                                   AisleriotCardCache *cache)
+{
+  AisleriotSlotRendererPrivate *priv = srend->priv;
+
+  if (cache)
+    g_object_ref (cache);
+
+  if (priv->cache)
+    g_object_unref (priv->cache);
+
+  priv->cache = cache;
+}
+
+static void
+aisleriot_slot_renderer_set_property (GObject *object,
+                                      guint property_id,
+                                      const GValue *value,
+                                      GParamSpec *pspec)
+{
+  AisleriotSlotRenderer *srend = AISLERIOT_SLOT_RENDERER (object);
+  AisleriotSlotRendererPrivate *priv = srend->priv;
+
+  switch (property_id) {
+    case PROP_CACHE:
+      aisleriot_slot_renderer_set_cache (srend, g_value_get_object (value));
+      break;
+
+    case PROP_SLOT:
+      priv->slot = g_value_get_pointer (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+aisleriot_slot_renderer_get_property (GObject *object,
+                                      guint property_id,
+                                      GValue *value,
+                                      GParamSpec *pspec)
+{
+  /* All properties are write-only */
+  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+aisleriot_slot_renderer_paint (ClutterActor *actor)
+{
+  AisleriotSlotRenderer *srend = (AisleriotSlotRenderer *) actor;
+  AisleriotSlotRendererPrivate *priv = srend->priv;
+  guint n_cards, first_exposed_card_id, i;
+  guint8 *cards;
+  int cardx, cardy;
+
+  g_return_if_fail (priv->cache != NULL);
+  g_return_if_fail (priv->slot != NULL);
+
+  cards = priv->slot->cards->data;
+  n_cards = priv->slot->cards->len;
+
+  g_assert (n_cards >= priv->slot->exposed);
+  first_exposed_card_id = n_cards - priv->slot->exposed;
+
+  if (priv->slot->cards->len == 0) {
+    CoglHandle cogl_tex;
+    guint tex_width, tex_height;
+
+    cogl_tex = aisleriot_card_cache_get_slot_texture (priv->cache,
+                                                      priv->show_highlight);
+    tex_width = cogl_texture_get_width (cogl_tex);
+    tex_height = cogl_texture_get_height (cogl_tex);
+
+    cogl_texture_rectangle (cogl_tex,
+                            0, 0,
+                            CLUTTER_INT_TO_FIXED (tex_width),
+                            CLUTTER_INT_TO_FIXED (tex_height),
+                            0, 0, CFX_ONE, CFX_ONE);
+  }
+
+  cardx = 0;
+  cardy = 0;
+
+  for (i = first_exposed_card_id; i < n_cards; ++i) {
+    Card card = CARD (cards[i]);
+    gboolean is_highlighted;
+    CoglHandle cogl_tex;
+    guint tex_width, tex_height;
+
+    is_highlighted = (i >= priv->highlight_start_card_id);
+
+    cogl_tex = aisleriot_card_cache_get_card_texture (priv->cache,
+                                                      card,
+                                                      is_highlighted);
+
+    tex_width = cogl_texture_get_width (cogl_tex);
+    tex_height = cogl_texture_get_height (cogl_tex);
+
+    cogl_texture_rectangle (cogl_tex,
+                            CLUTTER_INT_TO_FIXED (cardx),
+                            CLUTTER_INT_TO_FIXED (cardy),
+                            CLUTTER_INT_TO_FIXED (cardx + tex_width),
+                            CLUTTER_INT_TO_FIXED (cardy + tex_height),
+                            0, 0, CFX_ONE, CFX_ONE);
+
+    cardx += priv->slot->pixeldx;
+    cardy += priv->slot->pixeldy;
+  }
+}

Added: trunk/aisleriot/slot-renderer.h
==============================================================================
--- (empty file)
+++ trunk/aisleriot/slot-renderer.h	Tue Oct 21 19:46:47 2008
@@ -0,0 +1,73 @@
+/*
+ *  Copyright  2008 Neil Roberts
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __AISLERIOT_SLOT_RENDERER_H__
+#define __AISLERIOT_SLOT_RENDERER_H__
+
+#include <clutter/clutter-actor.h>
+#include <libgames-support/games-card-images.h>
+#include "card-cache.h"
+#include "game.h"
+
+G_BEGIN_DECLS
+
+#define AISLERIOT_TYPE_SLOT_RENDERER                                    \
+  (aisleriot_slot_renderer_get_type())
+#define AISLERIOT_SLOT_RENDERER(obj)                                    \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj),                                   \
+                               AISLERIOT_TYPE_SLOT_RENDERER,            \
+                               AisleriotSlotRenderer))
+#define AISLERIOT_SLOT_RENDERER_CLASS(klass)                            \
+  (G_TYPE_CHECK_CLASS_CAST ((klass),                                    \
+                            AISLERIOT_TYPE_SLOT_RENDERER,               \
+                            AisleriotSlotRendererClass))
+#define AISLERIOT_IS_SLOT_RENDERER(obj)                                 \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj),                                   \
+                               AISLERIOT_TYPE_SLOT_RENDERER))
+#define AISLERIOT_IS_SLOT_RENDERER_CLASS(klass)                         \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass),                                    \
+                            AISLERIOT_TYPE_SLOT_RENDERER))
+#define AISLERIOT_SLOT_RENDERER_GET_CLASS(obj)                          \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj),                                    \
+                              AISLERIOT_TYPE_SLOT_RENDERER,             \
+                              AisleriotSlotRendererClass))
+
+typedef struct _AisleriotSlotRenderer        AisleriotSlotRenderer;
+typedef struct _AisleriotSlotRendererClass   AisleriotSlotRendererClass;
+typedef struct _AisleriotSlotRendererPrivate AisleriotSlotRendererPrivate;
+
+struct _AisleriotSlotRendererClass
+{
+  ClutterActorClass parent_class;
+};
+
+struct _AisleriotSlotRenderer
+{
+  ClutterActor parent;
+
+  AisleriotSlotRendererPrivate *priv;
+};
+
+GType aisleriot_slot_renderer_get_type (void) G_GNUC_CONST;
+
+ClutterActor *aisleriot_slot_renderer_new (AisleriotCardCache *cache,
+                                           Slot *slot);
+
+G_END_DECLS
+
+#endif /* __AISLERIOT_SLOT_RENDERER_H__ */



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