gnome-games r8475 - in trunk: aisleriot libgames-support



Author: chpe
Date: Tue Jan  6 18:19:49 2009
New Revision: 8475
URL: http://svn.gnome.org/viewvc/gnome-games?rev=8475&view=rev

Log:
Make GamesCardTexturesCache only use GamesCardTheme, not
GamesCardImages. That way, we don't keep the card pixbufs in 2 variants
(normal and tinted) around. Saves tons of memory!

Added:
   trunk/libgames-support/games-card-private.h
Modified:
   trunk/aisleriot/board.c
   trunk/aisleriot/card.c
   trunk/aisleriot/card.h
   trunk/aisleriot/slot-renderer.c
   trunk/libgames-support/Makefile.am
   trunk/libgames-support/games-card-images.c
   trunk/libgames-support/games-card-images.h
   trunk/libgames-support/games-card-textures-cache.c
   trunk/libgames-support/games-card-textures-cache.h
   trunk/libgames-support/games-card.c

Modified: trunk/aisleriot/board.c
==============================================================================
--- trunk/aisleriot/board.c	(original)
+++ trunk/aisleriot/board.c	Tue Jan  6 18:19:49 2009
@@ -111,14 +111,15 @@
 {
   AisleriotGame *game;
 
-  GdkGC *draw_gc;
-  GdkGC *bg_gc;
-  GdkGC *slot_gc;
   GdkCursor *cursor[LAST_CURSOR];
 
+  /* Card theme */
   GamesCardTheme *theme;
   CardSize card_size;
 
+  /* Cards cache */
+  GamesCardTexturesCache *textures;
+
   double width;
   double height;
 
@@ -132,10 +133,6 @@
   /* The offset within the window. */
   int xbaseoffset;
 
-  /* Cards cache */
-  GamesCardImages *images;
-  GamesCardTexturesCache *textures;
-
   /* Button press */
   int last_click_x;
   int last_click_y;
@@ -1041,11 +1038,12 @@
   GPtrArray *slots;
   guint i, n_slots;
   CardSize card_size;
-  gboolean size_changed;
 
   /* Nothing to do yet */
   if (aisleriot_game_get_state (priv->game) <= GAME_LOADED)
     return;
+  if (!priv->theme)
+    return;
 
   g_return_if_fail (GTK_WIDGET_REALIZED (widget));
   g_return_if_fail (priv->width > 0 && priv->height > 0);
@@ -1053,14 +1051,12 @@
   priv->xslotstep = ((double) widget->allocation.width) / priv->width;
   priv->yslotstep = ((double) widget->allocation.height) / priv->height;
 
-  size_changed = games_card_images_set_size (priv->images,
-                                             priv->xslotstep,
-                                             priv->yslotstep,
-                                             CARD_SLOT_PROP);
-  if (size_changed)
-    games_card_textures_cache_clear (priv->textures);
+  games_card_theme_set_size (priv->theme,
+                             priv->xslotstep,
+                             priv->yslotstep,
+                             CARD_SLOT_PROP);
 
-  card_size = priv->card_size = games_card_images_get_size (priv->images);
+  card_size = priv->card_size = games_card_theme_get_size (priv->theme);
 
   /* If the cards are too far apart, bunch them in the middle. */
   priv->xbaseoffset = 0;
@@ -1079,9 +1075,6 @@
   priv->xoffset = (priv->xslotstep - card_size.width) / 2;
   priv->yoffset = (priv->yslotstep - card_size.height) / 2;
 
-  gdk_gc_set_clip_mask (priv->slot_gc, games_card_images_get_slot_mask (priv->images));
-  gdk_gc_set_clip_mask (priv->draw_gc, games_card_images_get_card_mask (priv->images));
-
   /* NOTE! Updating the slots checks that geometry is set, so
    * we set it to TRUE already.
    */
@@ -1181,7 +1174,7 @@
 
     g_array_append_val (priv->removed_cards, removed_card);
 
-    card_tex = aisleriot_card_new (priv->textures, hcard);
+    card_tex = aisleriot_card_new (priv->textures, hcard, &priv->selection_colour);
     clutter_actor_set_position (card_tex, x, y);
     clutter_container_add (CLUTTER_CONTAINER (priv->moving_cards_group),
                            card_tex, NULL);
@@ -2490,16 +2483,9 @@
 
   display = gtk_widget_get_display (widget);
 
-  games_card_images_set_drawable (priv->images, widget->window);
-
-  priv->draw_gc = gdk_gc_new (widget->window);
-
-  priv->bg_gc = gdk_gc_new (widget->window);
   set_background_from_baize (board);
   
-  priv->slot_gc = gdk_gc_new (widget->window);
-
-#ifndef HAVE_HILDON 
+#ifndef HAVE_HILDON
   /* Create cursors */
   priv->cursor[CURSOR_DEFAULT] = gdk_cursor_new_for_display (display, GDK_LEFT_PTR);
   priv->cursor[CURSOR_OPEN] = make_cursor (widget, hand_open_data_bits, hand_open_mask_bits);
@@ -2521,22 +2507,13 @@
 
   priv->geometry_set = FALSE;
 
-  g_object_unref (priv->draw_gc);
-  priv->draw_gc = NULL;
-  g_object_unref (priv->bg_gc);
-  priv->bg_gc = NULL;
-  g_object_unref (priv->slot_gc);
-  priv->slot_gc = NULL;
-
-#ifndef HAVE_HILDON 
+#ifndef HAVE_HILDON
   for (i = 0; i < LAST_CURSOR; ++i) {
     gdk_cursor_unref (priv->cursor[i]);
     priv->cursor[i] = NULL;
   }
 #endif /* !HAVE_HILDON*/
 
-  games_card_images_set_drawable (priv->images, NULL);
-
   clear_state (board);
 
   GTK_WIDGET_CLASS (aisleriot_board_parent_class)->unrealize (widget);
@@ -2617,15 +2594,12 @@
     selection_colour = default_selection_colour;
   }
 
-  games_card_images_set_selection_color (priv->images,
-                                         &selection_colour);
-
-  /* Update the existing slots */
   priv->selection_colour.red   = selection_colour.red   >> 8;
   priv->selection_colour.green = selection_colour.green >> 8;
   priv->selection_colour.blue  = selection_colour.blue  >> 8;
-  priv->selection_colour.alpha = 0;
+  priv->selection_colour.alpha = 0xff;
 
+  /* Update the existing slots */
   slots = aisleriot_game_get_slots (priv->game);
   n_slots = slots->len;
   for (i = 0; i < n_slots; ++i) {
@@ -3172,8 +3146,7 @@
 
   g_assert (priv->game != NULL);
 
-  priv->images = games_card_images_new ();
-  priv->textures = games_card_textures_cache_new (priv->images);
+  priv->textures = games_card_textures_cache_new ();
 
   return object;
 }
@@ -3196,7 +3169,6 @@
   if (priv->theme) {
     g_object_unref (priv->theme);
   }
-  g_object_unref (priv->images);
 
 #if 0
   screen = gtk_widget_get_settings (widget);
@@ -3490,8 +3462,7 @@
 
   priv->theme = g_object_ref (theme);
 
-  games_card_images_set_theme (priv->images, priv->theme);
-  games_card_textures_cache_clear (priv->textures); // FIXMEchpe make this automatic
+  games_card_textures_cache_set_theme (priv->textures, priv->theme);
 
   if (GTK_WIDGET_REALIZED (widget)) {
     /* Update card size and slot locations for new card theme (might have changed aspect!)*/
@@ -3560,24 +3531,5 @@
 aisleriot_board_set_pixbuf_drawing (AisleriotBoard *board,
                                     gboolean use_pixbuf_drawing)
 {
-  AisleriotBoardPrivate *priv = board->priv;
-  GtkWidget *widget = GTK_WIDGET (board);
-
-  use_pixbuf_drawing = use_pixbuf_drawing != FALSE;
-
-  if (use_pixbuf_drawing == priv->use_pixbuf_drawing)
-    return;
-
-  priv->use_pixbuf_drawing = use_pixbuf_drawing;
-
-  games_card_images_set_cache_mode (priv->images,
-                                    use_pixbuf_drawing ? CACHE_PIXBUFS : CACHE_PIXMAPS);
-
-  if (GTK_WIDGET_REALIZED (widget) &&
-      priv->geometry_set) {
-    /* Need to update the geometry, so we update the cached card images! */
-    aisleriot_board_setup_geometry (board);
-
-    gtk_widget_queue_draw (widget);
-  }
+  /* makes no sense for Clutter */
 }

Modified: trunk/aisleriot/card.c
==============================================================================
--- trunk/aisleriot/card.c	(original)
+++ trunk/aisleriot/card.c	Tue Jan  6 18:19:49 2009
@@ -45,6 +45,8 @@
    % CLUTTER_INT_TO_FIXED (360)                 \
    >= CLUTTER_INT_TO_FIXED (180))
 
+static const ClutterColor default_highlight_color = { 0, 0, 0xaa, 0xff };
+
 G_DEFINE_TYPE (AisleriotCard, aisleriot_card, CLUTTER_TYPE_ACTOR);
 
 #define AISLERIOT_CARD_GET_PRIVATE(obj) \
@@ -54,6 +56,7 @@
 struct _AisleriotCardPrivate
 {
   Card card;
+  ClutterColor highlight_color;
   gboolean highlighted;
 
   GamesCardTexturesCache *cache;
@@ -65,10 +68,27 @@
 
   PROP_CACHE,
   PROP_CARD,
-  PROP_HIGHLIGHTED
+  PROP_HIGHLIGHTED,
+  PROP_HIGHLIGHT_COLOR
 };
 
 static void
+aisleriot_card_set_highlight_color (AisleriotCard *card,
+                                    const ClutterColor *color)
+{
+  AisleriotCardPrivate *priv = card->priv;
+
+  g_return_if_fail (color != NULL);
+
+  if (clutter_color_equal (color, &priv->highlight_color))
+    return;
+
+  priv->highlight_color = *color;
+
+  g_object_notify (G_OBJECT (card), "highlight-color");
+}
+
+static void
 aisleriot_card_class_init (AisleriotCardClass *klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -110,6 +130,15 @@
                                 G_PARAM_STATIC_BLURB);
   g_object_class_install_property (gobject_class, PROP_HIGHLIGHTED, pspec);
 
+  pspec = clutter_param_spec_color ("highlight-color", NULL, NULL,
+                                    &default_highlight_color,
+                                    G_PARAM_WRITABLE |
+                                    G_PARAM_STATIC_NAME |
+                                    G_PARAM_STATIC_NICK |
+                                    G_PARAM_STATIC_BLURB |
+                                    G_PARAM_CONSTRUCT);
+  g_object_class_install_property (gobject_class, PROP_HIGHLIGHT_COLOR, pspec);
+
   g_type_class_add_private (klass, sizeof (AisleriotCardPrivate));
 }
 
@@ -119,24 +148,31 @@
   AisleriotCardPrivate *priv;
 
   priv = self->priv = AISLERIOT_CARD_GET_PRIVATE (self);
+
+  priv->highlighted = FALSE;
+  priv->highlight_color = default_highlight_color;
 }
 
 static void
 aisleriot_card_dispose (GObject *self)
 {
-  aisleriot_card_unref_cache ((AisleriotCard *) self);
+  AisleriotCard *card = AISLERIOT_CARD (self);
+
+  aisleriot_card_unref_cache (card);
 
-  ((GObjectClass *) aisleriot_card_parent_class)->dispose (self);
+  G_OBJECT_CLASS (aisleriot_card_parent_class)->dispose (self);
 }
 
 ClutterActor *
-aisleriot_card_new (GamesCardTexturesCache *cache, Card card)
-{
-  ClutterActor *self = g_object_new (AISLERIOT_TYPE_CARD,
-                                     "cache", cache,
-                                     "card", card.value, NULL);
-
-  return self;
+aisleriot_card_new (GamesCardTexturesCache *cache,
+                    Card card,
+                    const ClutterColor *highlight_color)
+{
+  return g_object_new (AISLERIOT_TYPE_CARD,
+                       "cache", cache,
+                       "card", card.value,
+                       "highlight-color", highlight_color,
+                       NULL);
 }
 
 static void
@@ -151,10 +187,12 @@
   gboolean x_swapped = FALSE;
   static const ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
 
-  g_return_if_fail (priv->cache != NULL);
-
   card_num = priv->card;
 
+  tex = games_card_textures_cache_get_card_texture (priv->cache, card_num);
+  if (G_UNLIKELY (tex == COGL_INVALID_HANDLE))
+    return;
+
   x_angle = clutter_actor_get_rotationx (actor, CLUTTER_X_AXIS,
                                          NULL, NULL, NULL);
   y_angle = clutter_actor_get_rotationx (actor, CLUTTER_Y_AXIS,
@@ -173,9 +211,6 @@
       x_swapped = TRUE;
   }
 
-  tex = games_card_textures_cache_get_card_texture (priv->cache, card_num,
-                                               priv->highlighted);
-
   tex_width = CLUTTER_INT_TO_FIXED (cogl_texture_get_width (tex));
   tex_height = CLUTTER_INT_TO_FIXED (cogl_texture_get_height (tex));
 
@@ -188,7 +223,12 @@
     cogl_translate (-CLUTTER_FIXED_TO_INT (tex_width) / 2, 0, 0);
   }
 
-  cogl_color (&white);
+  if (priv->highlighted) {
+    cogl_color (&priv->highlight_color);
+  } else {
+    cogl_color (&white);
+  }
+
   cogl_texture_rectangle (tex, 0, 0,
                           tex_width, tex_height,
                           0, 0, CFX_ONE, CFX_ONE);
@@ -224,6 +264,10 @@
       aisleriot_card_set_highlighted (card, g_value_get_boolean (value));
       break;
 
+    case PROP_HIGHLIGHT_COLOR:
+      aisleriot_card_set_highlight_color (card, g_value_get_boxed (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec);
       break;
@@ -252,6 +296,7 @@
       g_value_set_boolean (value, priv->highlighted);
       break;
 
+    case PROP_HIGHLIGHT_COLOR:
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec);
       break;
@@ -299,7 +344,7 @@
 
   clutter_actor_queue_redraw (CLUTTER_ACTOR (card));
 
-  g_object_notify (G_OBJECT (cache), "card-images");
+  g_object_notify (G_OBJECT (card), "cache");
 }
 
 void

Modified: trunk/aisleriot/card.h
==============================================================================
--- trunk/aisleriot/card.h	(original)
+++ trunk/aisleriot/card.h	Tue Jan  6 18:19:49 2009
@@ -63,7 +63,9 @@
 
 GType aisleriot_card_get_type (void) G_GNUC_CONST;
 
-ClutterActor *aisleriot_card_new (GamesCardTexturesCache *cache, Card card);
+ClutterActor *aisleriot_card_new (GamesCardTexturesCache *cache,
+                                  Card card,
+                                  const ClutterColor *highlight_color);
 
 void aisleriot_card_set_card (AisleriotCard *card, Card card_num);
 

Modified: trunk/aisleriot/slot-renderer.c
==============================================================================
--- trunk/aisleriot/slot-renderer.c	(original)
+++ trunk/aisleriot/slot-renderer.c	Tue Jan  6 18:19:49 2009
@@ -46,6 +46,7 @@
 static void completed_cb (AisleriotSlotRenderer *srend);
 
 static const ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
+static const ClutterColor default_highlight_color = { 0, 0, 0xaa, 0xff };
 
 G_DEFINE_TYPE (AisleriotSlotRenderer, aisleriot_slot_renderer,
                CLUTTER_TYPE_ACTOR);
@@ -96,7 +97,6 @@
 static void
 aisleriot_slot_renderer_class_init (AisleriotSlotRendererClass *klass)
 {
-  static const ClutterColor default_highlight_color = { 0, 0, 0xaa, 0xff };
   GObjectClass *gobject_class = (GObjectClass *) klass;
   ClutterActorClass *actor_class = (ClutterActorClass *) klass;
   GParamSpec *pspec;
@@ -127,7 +127,7 @@
   g_object_class_install_property (gobject_class, PROP_SLOT, pspec);
 
   pspec = g_param_spec_int ("highlight", NULL, NULL,
-                            -1, G_MAXINT, -1,
+                            -1, G_MAXINT, G_MAXINT,
                             G_PARAM_WRITABLE |
                             G_PARAM_READABLE |
                             G_PARAM_STATIC_NAME |
@@ -135,17 +135,20 @@
                             G_PARAM_STATIC_BLURB);
   g_object_class_install_property (gobject_class, PROP_HIGHLIGHT, pspec);
 
+
+  /* Don't make this CONSTRUCT, since older clutter 0.8.x releases
+   * have a bug with that leading to an invalid free.
+   */
   pspec = clutter_param_spec_color ("highlight-color", NULL, NULL,
                                     &default_highlight_color,
                                     G_PARAM_WRITABLE |
                                     G_PARAM_STATIC_NAME |
                                     G_PARAM_STATIC_NICK |
-                                    G_PARAM_STATIC_BLURB |
-                                    G_PARAM_CONSTRUCT);
+                                    G_PARAM_STATIC_BLURB);
   g_object_class_install_property (gobject_class, PROP_HIGHLIGHT_COLOR, pspec);
 
   pspec = g_param_spec_int ("revealed-card", NULL, NULL,
-                            -1, G_MAXINT, 0,
+                            -1, G_MAXINT, -1,
                             G_PARAM_WRITABLE |
                             G_PARAM_READABLE |
                             G_PARAM_STATIC_NAME |
@@ -172,13 +175,14 @@
 
   priv = self->priv = AISLERIOT_SLOT_RENDERER_GET_PRIVATE (self);
 
+  priv->revealed_card = -1;
   priv->highlight_start = G_MAXINT;
+  priv->highlight_color = default_highlight_color;
+
   priv->animations = g_array_new (FALSE, FALSE, sizeof (AnimationData));
   priv->timeline = clutter_timeline_new_for_duration (500);
   g_signal_connect_swapped (priv->timeline, "completed",
                             G_CALLBACK (completed_cb), self);
-
-  priv->revealed_card = -1;
 }
 
 static void
@@ -230,6 +234,9 @@
 {
   AisleriotSlotRendererPrivate *priv = srend->priv;
 
+  if (cache == priv->cache)
+    return;
+
   if (cache)
     g_object_ref (cache);
 
@@ -323,9 +330,10 @@
   CoglHandle cogl_tex;
   guint tex_width, tex_height;
   int cardx, cardy;
-  const ClutterColor *color;
 
-  cogl_tex = games_card_textures_cache_get_card_texture (priv->cache, card, FALSE);
+  cogl_tex = games_card_textures_cache_get_card_texture (priv->cache, card);
+  if (G_UNLIKELY (cogl_tex == COGL_INVALID_HANDLE))
+    return;
 
   tex_width = cogl_texture_get_width (cogl_tex);
   tex_height = cogl_texture_get_height (cogl_tex);
@@ -335,12 +343,11 @@
                                   &cardx, &cardy);
 
   if (priv->show_highlight && (card_num >= priv->highlight_start)) {
-    color = &priv->highlight_color;
+    cogl_color (&priv->highlight_color);
   } else {
-    color = &white;
+    cogl_color (&white);
   }
 
-  cogl_color (color);
   cogl_texture_rectangle (cogl_tex,
                           CLUTTER_INT_TO_FIXED (cardx),
                           CLUTTER_INT_TO_FIXED (cardy),
@@ -371,8 +378,10 @@
     CoglHandle cogl_tex;
     guint tex_width, tex_height;
 
-    cogl_tex = games_card_textures_cache_get_slot_texture (priv->cache,
-                                                      priv->show_highlight);
+    cogl_tex = games_card_textures_cache_get_slot_texture (priv->cache);
+    if (G_UNLIKELY (cogl_tex == COGL_INVALID_HANDLE))
+      goto paint_cards;
+
     tex_width = cogl_texture_get_width (cogl_tex);
     tex_height = cogl_texture_get_height (cogl_tex);
 
@@ -389,6 +398,8 @@
                             0, 0, CFX_ONE, CFX_ONE);
   }
 
+paint_cards:
+
   if (n_cards > priv->animations->len) {
     guint first_card, last_card;
 
@@ -401,7 +412,8 @@
         aisleriot_slot_renderer_paint_card (srend, i);
 
     /* Paint the revealed card after all of the other cards so that it
-       will appeear on top */
+     * will appeear on top.
+     */
     if (priv->revealed_card >= first_card && priv->revealed_card < last_card)
       aisleriot_slot_renderer_paint_card (srend, priv->revealed_card);
   }
@@ -445,7 +457,6 @@
     return;
 
   priv->highlight_color = *color;
-  priv->highlight_color.alpha = 0xff;
 
   g_object_notify (G_OBJECT (srend), "highlight-color");
 }
@@ -549,21 +560,16 @@
     ClutterAlpha *alpha;
     ClutterKnot knots[2];
     Card card = CARD (priv->slot->cards->data[card_num]);
-    guint card_width, card_height;
-    CoglHandle cogl_tex;
+    guint card_width = 0, card_height = 0;
 
     memset (&anim_data, 0, sizeof (anim_data));
 
-    anim_data.card_tex = aisleriot_card_new (priv->cache, card);
+    anim_data.card_tex = aisleriot_card_new (priv->cache, card, &priv->highlight_color);
     g_object_ref_sink (anim_data.card_tex);
     if (priv->animation_layer)
       clutter_container_add (priv->animation_layer,
                              CLUTTER_ACTOR (anim_data.card_tex), NULL);
 
-    cogl_tex = games_card_textures_cache_get_card_texture (priv->cache, card, FALSE);
-    card_width = cogl_texture_get_width (cogl_tex);
-    card_height = cogl_texture_get_height (cogl_tex);
-
     clutter_actor_set_position (anim_data.card_tex,
                                 anims[i].cardx, anims[i].cardy);
 
@@ -583,6 +589,15 @@
     clutter_behaviour_apply (anim_data.move, anim_data.card_tex);
 
     if (anims[i].face_down != card.attr.face_down) {
+      CoglHandle cogl_tex;
+
+      cogl_tex = games_card_textures_cache_get_card_texture (priv->cache, card);
+      if (G_UNLIKELY (cogl_tex == COGL_INVALID_HANDLE))
+        continue; // FIXMEchpe this doesn't look right...
+
+      card_width = cogl_texture_get_width (cogl_tex);
+      card_height = cogl_texture_get_height (cogl_tex);
+
       gint center_x = card_width / 2;
       gint center_y = card_height / 2;
 

Modified: trunk/libgames-support/Makefile.am
==============================================================================
--- trunk/libgames-support/Makefile.am	(original)
+++ trunk/libgames-support/Makefile.am	Tue Jan  6 18:19:49 2009
@@ -26,6 +26,7 @@
 	$(BUILT_SOURCES)		\
 	games-card.c			\
 	games-card.h			\
+	games-card-private.h		\
 	games-card-images.c		\
 	games-card-images.h		\
 	games-card-theme.c		\

Modified: trunk/libgames-support/games-card-images.c
==============================================================================
--- trunk/libgames-support/games-card-images.c	(original)
+++ trunk/libgames-support/games-card-images.c	Tue Jan  6 18:19:49 2009
@@ -26,12 +26,14 @@
 #include <glib.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
+#include "games-card-images.h"
+
 #include "games-find-file.h"
 #include "games-files.h"
 #include "games-preimage.h"
 #include "games-pixbuf-utils.h"
-
-#include "games-card-images.h"
+#include "games-card.h"
+#include "games-card-private.h"
 
 enum {
   PROP_0,
@@ -61,8 +63,6 @@
 #define CARD_ALPHA_THRESHOLD  (127)
 #define SLOT_ALPHA_THRESHOLD  (255)
 
-#define GAMES_CARD_ID(suit, rank) ((13*(suit)) + ((rank-1)%13))
-
 static void
 games_card_images_clear_cache (GamesCardImages * images)
 {
@@ -95,30 +95,6 @@
   games_card_images_clear_cache (images);
 }
 
-guint
-games_card_images_card_to_index (Card card)
-{
-  guint card_id;
-
-  if (CARD_GET_FACE_DOWN (card)) {
-    card_id = GAMES_CARD_BACK;
-  } else if (G_UNLIKELY (CARD_GET_RANK (card) == 0)) {
-    /* A joker */
-    if (CARD_GET_SUIT (card) == GAMES_CARDS_CLUBS ||
-        CARD_GET_SUIT (card) == GAMES_CARDS_SPADES) {
-      /* A black joker. */
-      card_id = GAMES_CARD_BLACK_JOKER;
-    } else {
-      /* A red joker. */
-      card_id = GAMES_CARD_RED_JOKER;
-    }
-  } else {
-    card_id = GAMES_CARD_ID (CARD_GET_SUIT (card), CARD_GET_RANK (card));
-  }
-
-  return card_id;
-}
-
 /* Consider the cache as a 2-dimensional array: [0..TOTAL-1 , 0..1]:
  *
  * When creating cache[i][0], we _always_ store a reference to the _pixbuf_ in cache[i][1],
@@ -569,7 +545,7 @@
 games_card_images_get_card_pixbuf (GamesCardImages * images,
                                    Card card, gboolean highlighted)
 {
-  guint index = games_card_images_card_to_index (card);
+  guint index = _games_card_to_index (card);
 
   return games_card_images_get_card_pixbuf_by_id (images,
                                                   index,
@@ -714,7 +690,7 @@
 games_card_images_get_card_pixmap (GamesCardImages * images,
                                    Card card, gboolean highlighted)
 {
-  guint index = games_card_images_card_to_index (card);
+  guint index = _games_card_to_index (card);
 
   return games_card_images_get_card_pixmap_by_id (images,
                                                   index,

Modified: trunk/libgames-support/games-card-images.h
==============================================================================
--- trunk/libgames-support/games-card-images.h	(original)
+++ trunk/libgames-support/games-card-images.h	Tue Jan  6 18:19:49 2009
@@ -117,8 +117,6 @@
 
 GdkBitmap *games_card_images_get_slot_mask (GamesCardImages * images);
 
-guint games_card_images_card_to_index (Card card);
-
 /* Deprecated */
 GdkPixbuf *games_card_images_get_card_pixbuf_by_suit_and_rank (GamesCardImages
                                                                * images,

Added: trunk/libgames-support/games-card-private.h
==============================================================================
--- (empty file)
+++ trunk/libgames-support/games-card-private.h	Tue Jan  6 18:19:49 2009
@@ -0,0 +1,33 @@
+/*
+   Copyright  2004 Callum McKenzie
+   Copyright  2007, 2008 Christian Persch
+
+   This library is free software; you can redistribute it and'or modify
+   it under the terms of the GNU Library General Public License as published 
+   by the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This library 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 Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Authors:   Callum McKenzie <callum physics otago ac nz> */
+
+
+#ifndef GAMES_CARD_PRIVATE_H
+#define GAMES_CARD_PRIVATE_H
+
+G_BEGIN_DECLS
+
+#define GAMES_CARD_ID(suit, rank) ((13*(suit)) + ((rank-1)%13))
+
+guint _games_card_to_index (Card card);
+
+G_END_DECLS
+
+#endif /* !GAMES_CARD_PRIVATE_H */

Modified: trunk/libgames-support/games-card-textures-cache.c
==============================================================================
--- trunk/libgames-support/games-card-textures-cache.c	(original)
+++ trunk/libgames-support/games-card-textures-cache.c	Tue Jan  6 18:19:49 2009
@@ -1,5 +1,6 @@
 /*
  *  Copyright  2008 Neil Roberts
+ *  Copyright  2008 Christian Persch
  *
  *  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
@@ -24,23 +25,25 @@
 
 #include "games-card-textures-cache.h"
 
+#include "games-card-private.h"
+
 struct _GamesCardTexturesCachePrivate
 {
-  CoglHandle *cards;
-  GamesCardImages *card_images;
+  GamesCardTheme *theme;
+  guint theme_changed_handler;
 
-  guint theme_handler;
+  CoglHandle *cards;
 };
 
 enum
 {
   PROP_0,
-  PROP_CARD_IMAGES
+  PROP_THEME
 };
 
 /* This is an invalid value for a CoglHandle, and distinct from COGL_INVALID_HANDLE */
-#define FAILED_POINTER ((gpointer) 0x1)
-#define IS_FAILED_POINTER(ptr) (G_UNLIKELY ((ptr) == FAILED_POINTER))
+#define FAILED_HANDLE ((gpointer) 0x1)
+#define IS_FAILED_HANDLE(ptr) (G_UNLIKELY ((ptr) == FAILED_HANDLE))
 
 static void games_card_textures_cache_dispose (GObject *object);
 static void games_card_textures_cache_finalize (GObject *object);
@@ -52,43 +55,40 @@
 /* Helper functions */
 
 static void
-games_card_textures_cache_unref_images (GamesCardTexturesCache *cache)
+games_card_textures_cache_clear (GamesCardTexturesCache *cache)
 {
   GamesCardTexturesCachePrivate *priv = cache->priv;
+  int i;
+
+  g_print ("games_card_textures_cache_clear\n");
+
+  for (i = 0; i < GAMES_CARDS_TOTAL; i++) {
+    CoglHandle *handle = priv->cards[i];
 
-  if (priv->card_images) {
-    g_signal_handler_disconnect (priv->card_images, priv->theme_handler);
-    g_object_unref (priv->card_images);
-    priv->card_images = NULL;
+    if (handle != COGL_INVALID_HANDLE &&
+        !IS_FAILED_HANDLE (handle)) {
+      cogl_texture_unref (handle);
+    }
+
+    priv->cards[i] = COGL_INVALID_HANDLE;
   }
 }
 
 static void
-games_card_textures_cache_set_card_images (GamesCardTexturesCache *cache,
-                                           GamesCardImages *card_images)
+games_card_textures_cache_unset_theme (GamesCardTexturesCache *cache)
 {
   GamesCardTexturesCachePrivate *priv = cache->priv;
 
-  if (card_images)
-    g_object_ref (card_images);
-
-  games_card_textures_cache_unref_images (cache);
-
-  priv->card_images = card_images;
-
-  if (card_images)
-    priv->theme_handler = g_signal_connect_swapped (card_images, "notify::theme",
-                                                    G_CALLBACK (games_card_textures_cache_clear),
-                                                    cache);
-
-  games_card_textures_cache_clear (cache);
-
-  g_object_notify (G_OBJECT (cache), "card-images");
+  if (priv->theme) {
+    g_signal_handler_disconnect (priv->theme, priv->theme_changed_handler);
+    g_object_unref (priv->theme);
+    priv->theme = NULL;
+    priv->theme_changed_handler = 0;
+  }
 }
 
 /* Class implementation */
 
-
 static void
 games_card_textures_cache_init (GamesCardTexturesCache *self)
 {
@@ -96,17 +96,16 @@
 
   priv = self->priv = GAMES_CARD_TEXTURES_CACHE_GET_PRIVATE (self);
 
-  priv->cards = g_malloc0 (sizeof (ClutterActor *) * GAMES_CARDS_TOTAL * 2);
+  priv->cards = g_malloc0 (sizeof (ClutterActor *) * GAMES_CARDS_TOTAL);
 }
 
 static void
 games_card_textures_cache_dispose (GObject *object)
 {
-  GamesCardTexturesCache *self = (GamesCardTexturesCache *) object;
-
-  games_card_textures_cache_clear (self);
+  GamesCardTexturesCache *cache = GAMES_CARD_TEXTURES_CACHE (object);
 
-  games_card_textures_cache_unref_images (self);
+  games_card_textures_cache_clear (cache);
+  games_card_textures_cache_unset_theme (cache);
 
   G_OBJECT_CLASS (games_card_textures_cache_parent_class)->dispose (object);
 }
@@ -124,15 +123,15 @@
 
 static void
 games_card_textures_cache_set_property (GObject *self,
-                                   guint property_id,
-                                   const GValue *value,
-                                   GParamSpec *pspec)
+                                        guint property_id,
+                                        const GValue *value,
+                                        GParamSpec *pspec)
 {
   GamesCardTexturesCache *cache = GAMES_CARD_TEXTURES_CACHE (self);
 
   switch (property_id) {
-    case PROP_CARD_IMAGES:
-      games_card_textures_cache_set_card_images (cache, g_value_get_object (value));
+    case PROP_THEME:
+      games_card_textures_cache_set_theme (cache, g_value_get_object (value));
       break;
 
     default:
@@ -143,16 +142,15 @@
 
 static void
 games_card_textures_cache_get_property (GObject *self,
-                                   guint property_id,
-                                   GValue *value,
-                                   GParamSpec *pspec)
+                                        guint property_id,
+                                        GValue *value,
+                                        GParamSpec *pspec)
 {
   GamesCardTexturesCache *cache = GAMES_CARD_TEXTURES_CACHE (self);
-  GamesCardTexturesCachePrivate *priv = cache->priv;
 
   switch (property_id) {
-    case PROP_CARD_IMAGES:
-      g_value_set_object (value, priv->card_images);
+    case PROP_THEME:
+      g_value_set_object (value, games_card_textures_cache_get_theme (cache));
       break;
 
     default:
@@ -164,7 +162,7 @@
 static void
 games_card_textures_cache_class_init (GamesCardTexturesCacheClass *klass)
 {
-  GObjectClass *gobject_class = (GObjectClass *) klass;
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GParamSpec *pspec;
 
   gobject_class->dispose = games_card_textures_cache_dispose;
@@ -174,14 +172,14 @@
 
   g_type_class_add_private (klass, sizeof (GamesCardTexturesCachePrivate));
 
-  pspec = g_param_spec_object ("card-images", NULL, NULL,
-                               GAMES_TYPE_CARD_IMAGES,
+  pspec = g_param_spec_object ("theme", NULL, NULL,
+                               GAMES_TYPE_CARD_THEME,
                                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_CARD_IMAGES, pspec);
+  g_object_class_install_property (gobject_class, PROP_THEME, pspec);
 }
 
 /* Public API */
@@ -192,72 +190,85 @@
  * Returns: a new #GamesCardTexturesCache object
  */
 GamesCardTexturesCache *
-games_card_textures_cache_new (GamesCardImages *images)
+games_card_textures_cache_new (void)
 {
-  return g_object_new (GAMES_TYPE_CARD_TEXTURES_CACHE,
-                       "card-images", images,
-                       NULL);
+  return g_object_new (GAMES_TYPE_CARD_TEXTURES_CACHE, NULL);
 }
 
-/* FIXME: make this private and automatic */
+/**
+ * games_card_textures_cache_set_theme:
+ * @cache:
+ * @theme:
+ *
+ * Sets the card theme.
+ */
 void
-games_card_textures_cache_clear (GamesCardTexturesCache *cache)
+games_card_textures_cache_set_theme (GamesCardTexturesCache *cache,
+                                     GamesCardTheme *theme)
 {
   GamesCardTexturesCachePrivate *priv = cache->priv;
-  int i;
 
-  for (i = 0; i < GAMES_CARDS_TOTAL * 2; i++) {
-    CoglHandle *handle = priv->cards[i];
+  g_return_if_fail (GAMES_IS_CARD_TEXTURES_CACHE (cache));
+  g_return_if_fail (theme == NULL || GAMES_IS_CARD_THEME (theme));
 
-    if (handle != COGL_INVALID_HANDLE &&
-        !IS_FAILED_POINTER (handle)) {
-      cogl_texture_unref (handle);
-    }
+  if (priv->theme == theme)
+    return;
 
-    priv->cards[i] = COGL_INVALID_HANDLE;
+  games_card_textures_cache_clear (cache);
+  games_card_textures_cache_unset_theme (cache);
+
+  priv->theme = theme;
+  if (theme) {
+    g_object_ref (theme);
+
+    priv->theme_changed_handler = g_signal_connect_swapped (theme, "changed",
+                                                            G_CALLBACK (games_card_textures_cache_clear),
+                                                            cache);
   }
+
+  g_object_notify (G_OBJECT (cache), "theme");
+}
+
+/**
+ * games_card_textures_cache_get_theme:
+ * @cache:
+ *
+ * Returns: the the card theme of @cache
+ */
+GamesCardTheme *
+games_card_textures_cache_get_theme (GamesCardTexturesCache *cache)
+{
+  g_return_val_if_fail (GAMES_IS_CARD_TEXTURES_CACHE (cache), NULL);
+
+  return cache->priv->theme;
 }
 
 /**
  * games_card_textures_cache_get_card_texture_by_id:
  * @cache:
  * @card_id:
- * @highlighted:
  *
  * Returns: a cached #CoglHandle for @card_id.
  */
 CoglHandle
 games_card_textures_cache_get_card_texture_by_id (GamesCardTexturesCache *cache,
-                                                  guint card_id,
-                                                  gboolean highlighted)
+                                                  guint card_id)
 {
-  GamesCardTexturesCachePrivate *priv;
-  guint index;
+  GamesCardTexturesCachePrivate *priv = cache->priv;
   CoglHandle handle;
 
-  g_return_val_if_fail (GAMES_IS_CARD_TEXTURES_CACHE (cache), NULL);
   g_return_val_if_fail (card_id < GAMES_CARDS_TOTAL , NULL);
 
-  priv = cache->priv;
-
-  g_return_val_if_fail (priv->card_images != NULL, NULL);
-
-  index = card_id;
-  if (highlighted)
-    index += GAMES_CARDS_TOTAL;
-
-  handle = priv->cards[index];
-  if (IS_FAILED_POINTER (handle))
-    return NULL;
+  handle = priv->cards[card_id];
+  if (IS_FAILED_HANDLE (handle))
+    return COGL_INVALID_HANDLE;
 
   if (handle == COGL_INVALID_HANDLE) {
-    GdkPixbuf *pixbuf
-      = games_card_images_get_card_pixbuf_by_id (priv->card_images,
-                                                 card_id,
-                                                 highlighted);
+    GdkPixbuf *pixbuf;
 
+    pixbuf = games_card_theme_get_card_pixbuf (priv->theme, card_id);
     if (!pixbuf) {
-      priv->cards[index] = FAILED_POINTER;
+      priv->cards[card_id] = FAILED_HANDLE;
       return COGL_INVALID_HANDLE;
     }
 
@@ -270,12 +281,14 @@
                                          COGL_PIXEL_FORMAT_ANY,
                                          gdk_pixbuf_get_rowstride (pixbuf),
                                          gdk_pixbuf_get_pixels (pixbuf));
-    if (!handle) {
-      priv->cards[index] = FAILED_POINTER;
+    g_object_unref (pixbuf);
+
+    if (handle == COGL_INVALID_HANDLE) {
+      priv->cards[card_id] = FAILED_HANDLE;
       return COGL_INVALID_HANDLE;
     }
 
-    priv->cards[index] = handle;
+    priv->cards[card_id] = handle;
   }
 
   return handle;
@@ -291,13 +304,11 @@
  */
 CoglHandle
 games_card_textures_cache_get_card_texture (GamesCardTexturesCache *cache,
-                                            Card card,
-                                            gboolean highlighted)
+                                            Card card)
 {
-  guint card_id = games_card_images_card_to_index (card);
+  guint card_id = _games_card_to_index (card);
 
-  return games_card_textures_cache_get_card_texture_by_id (cache, card_id,
-                                                           highlighted);
+  return games_card_textures_cache_get_card_texture_by_id (cache, card_id);
 }
 
 /**
@@ -308,10 +319,7 @@
  * Returns: a cached #CoglHandle for the slot.
  */
 CoglHandle
-games_card_textures_cache_get_slot_texture (GamesCardTexturesCache *cache,
-                                            gboolean highlighted)
+games_card_textures_cache_get_slot_texture (GamesCardTexturesCache *cache)
 {
-  return games_card_textures_cache_get_card_texture_by_id (cache,
-                                                           GAMES_CARD_SLOT,
-                                                           highlighted);
+  return games_card_textures_cache_get_card_texture_by_id (cache, GAMES_CARD_SLOT);
 }

Modified: trunk/libgames-support/games-card-textures-cache.h
==============================================================================
--- trunk/libgames-support/games-card-textures-cache.h	(original)
+++ trunk/libgames-support/games-card-textures-cache.h	Tue Jan  6 18:19:49 2009
@@ -1,5 +1,6 @@
 /*
  *  Copyright  2008 Neil Roberts
+ *  Copyright  2008 Christian Persch
  *
  *  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
@@ -22,7 +23,8 @@
 #include <glib-object.h>
 #include <cogl/cogl.h>
 
-#include "games-card-images.h"
+#include "games-card.h"
+#include "games-card-theme.h"
 
 G_BEGIN_DECLS
 
@@ -51,20 +53,20 @@
 
 GType games_card_textures_cache_get_type (void);
 
-GamesCardTexturesCache *games_card_textures_cache_new (GamesCardImages *images);
+GamesCardTexturesCache *games_card_textures_cache_new (void);
+
+void games_card_textures_cache_set_theme (GamesCardTexturesCache *cache,
+                                          GamesCardTheme *theme);
+
+GamesCardTheme *games_card_textures_cache_get_theme (GamesCardTexturesCache *cache);
 
 CoglHandle games_card_textures_cache_get_card_texture (GamesCardTexturesCache *cache,
-                                                       Card card,
-                                                       gboolean highlighted);
+                                                       Card card);
 
 CoglHandle games_card_textures_cache_get_card_texture_by_id (GamesCardTexturesCache *cache,
-                                                             guint card_id,
-                                                             gboolean highlighted);
-
-CoglHandle games_card_textures_cache_get_slot_texture (GamesCardTexturesCache *cache,
-                                                       gboolean highlighted);
+                                                             guint card_id);
 
-void games_card_textures_cache_clear (GamesCardTexturesCache *cache);
+CoglHandle games_card_textures_cache_get_slot_texture (GamesCardTexturesCache *cache);
 
 G_END_DECLS
 

Modified: trunk/libgames-support/games-card.c
==============================================================================
--- trunk/libgames-support/games-card.c	(original)
+++ trunk/libgames-support/games-card.c	Tue Jan  6 18:19:49 2009
@@ -22,6 +22,7 @@
 #include <glib/gi18n.h>
 
 #include "games-card.h"
+#include "games-card-private.h"
 
 static const char extra_cards[] =
   "black_joker\0"
@@ -221,3 +222,27 @@
   return ranks[rank];
 #endif /* GLIB >= 2.18.0 */
 }
+
+guint
+_games_card_to_index (Card card)
+{
+  guint card_id;
+
+  if (CARD_GET_FACE_DOWN (card)) {
+    card_id = GAMES_CARD_BACK;
+  } else if (G_UNLIKELY (CARD_GET_RANK (card) == 0)) {
+    /* A joker */
+    if (CARD_GET_SUIT (card) == GAMES_CARDS_CLUBS ||
+        CARD_GET_SUIT (card) == GAMES_CARDS_SPADES) {
+      /* A black joker. */
+      card_id = GAMES_CARD_BLACK_JOKER;
+    } else {
+      /* A red joker. */
+      card_id = GAMES_CARD_RED_JOKER;
+    }
+  } else {
+    card_id = GAMES_CARD_ID (CARD_GET_SUIT (card), CARD_GET_RANK (card));
+  }
+
+  return card_id;
+}



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