From 7ba452b41168933be6a4fba997874cdbe793a2b6 Mon Sep 17 00:00:00 2001
From: Bruce Cowan <bruce@bcowan.eu>
Date: Sun, 31 Dec 2017 00:31:12 +0000
Subject: [PATCH] Replace GVariant with GPtrArray

Not the intended purpose for variants
---
 src/rugby-score-store.c | 78 +++++++++++++++++------------------------
 src/rugby-scoring.c     | 73 ++++++++++++++++++--------------------
 src/rugby-scoring.h     | 19 ++++++----
 3 files changed, 81 insertions(+), 89 deletions(-)

diff --git a/src/rugby-score-store.c b/src/rugby-score-store.c
index a838c8c..a61882d 100644
--- a/src/rugby-score-store.c
+++ b/src/rugby-score-store.c
@@ -95,58 +95,46 @@ rugby_score_store_class_init (RugbyScoreStoreClass *klass)
 }
 
 static void
-populate_store (RugbyScoreStore *store)
+populate_store_foreach (gpointer data,
+                        gpointer user_data)
 {
-	GtkListStore *lstore = GTK_LIST_STORE (store);
-	GVariant *possibilities;
-	GVariant *possibility;
-	GVariantIter iter;
-	gsize total;
+    RugbyPossibility *possiblity = (RugbyPossibility *) data;
+    GtkListStore *store = GTK_LIST_STORE (user_data);
+
+    GtkTreeIter iter;
+    gint tries = possiblity->tries;
+    gint utries = possiblity->utries;
+    gint kicks = possiblity->kicks;
+
+    g_autofree gchar *tooltip = g_strdup_printf ("%d tries, %d converted, %d kicks",
+                                                 tries, utries, kicks);
+
+    gtk_list_store_append (store, &iter);
+    gtk_list_store_set (store, &iter,
+                        RUGBY_SCORE_STORE_TRIES, tries,
+                        RUGBY_SCORE_STORE_UTRIES, utries,
+                        RUGBY_SCORE_STORE_KICKS, kicks,
+                        RUGBY_SCORE_STORE_TOOLTIP, tooltip,
+                        -1);
+}
+
+static void
+populate_store (RugbyScoreStore *self)
+{
+	GtkListStore *store = GTK_LIST_STORE (self);
+
+	g_autoptr(GPtrArray) possibilities = NULL;
 
 	/* Clear the store */
-	gtk_list_store_clear (lstore);
+	gtk_list_store_clear (store);
 
-	possibilities = rugby_scoring_get_possibilities (store->score);
-	if (possibilities == NULL)
+	possibilities = rugby_scoring_get_possibilities (self->score);
+    if (possibilities->len == 0)
 		return;
 
-	total = g_variant_iter_init (&iter, possibilities);
-
-	while ((possibility = g_variant_iter_next_value (&iter)))
-	{
-		gint tries, utries, kicks;
-		GString *tooltip;
-		GtkTreeIter iter;
-
-		g_variant_get (possibility, "(iii)", &tries, &utries, &kicks);
-		g_variant_unref (possibility);
-
-		tooltip = g_string_new_len (NULL, 20);
-		if (utries > 0 || tries > 0)
-		{
-			g_string_append_printf (tooltip, "%d tries, %d converted",
-			                        tries + utries, tries);
-			if (kicks > 0)
-				g_string_append_printf (tooltip, ", %d kicks",
-				                        kicks);
-		}
-		else if (utries == 0 && tries == 0)
-				g_string_append_printf (tooltip, "%d kicks",
-				                        kicks);
-
-		/* Put result in list store */
-		gtk_list_store_append (lstore, &iter);
-		gtk_list_store_set (lstore, &iter,
-		                    RUGBY_SCORE_STORE_TRIES, tries,
-		                    RUGBY_SCORE_STORE_UTRIES, utries,
-		                    RUGBY_SCORE_STORE_KICKS, kicks,
-		                    RUGBY_SCORE_STORE_TOOLTIP, tooltip->str,
-		                    -1);
-
-		g_string_free (tooltip, TRUE);
-	}
+    g_ptr_array_foreach (possibilities, populate_store_foreach, store);
 
-	g_signal_emit (store, signals[FINISHED], 0, (gint) total);
+    g_signal_emit (self, signals[FINISHED], 0, (gint) possibilities->len);
 }
 
 static void
diff --git a/src/rugby-scoring.c b/src/rugby-scoring.c
index 920e9e2..5e5bd60 100644
--- a/src/rugby-scoring.c
+++ b/src/rugby-scoring.c
@@ -1,60 +1,57 @@
 #include "rugby-scoring.h"
 
+static inline void
+possibility_free (gpointer possibility)
+{
+    g_slice_free (RugbyPossibility, possibility);
+}
+
 /**
  * rugby_scoring_get_possibilities:
  * @score: the score of a team
  *
- * Gets the possible ways of scoring @score points, as a %GVariant of the
- * type "a(iii)", in the order "tries, utries, pens".
+ * Gets the possible ways of scoring @score points.
  *
- * Returns: (transfer-none): the possibilities, or %NULL in the case there are
- * none
+ * Returns: (transfer-full): the possibilities
  */
-GVariant *
+GPtrArray *
 rugby_scoring_get_possibilities (gint score)
 {
-	GVariantBuilder builder;
-	gint possibilities = 0;
-	gint max_tries, max_utries;
-	gint tries, utries;
-
-	g_return_val_if_fail (score >= 0, NULL);
+    GPtrArray *array;
 
-	g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+    g_return_val_if_fail (score >= 0, NULL);
 
-	max_tries = (gint) (score / TRY_POINTS);
-	max_utries = (gint) (score / UTRY_POINTS);
+    array = g_ptr_array_new_with_free_func (possibility_free);
 
-	for (tries = 0; tries <= max_tries; tries++)
-	{
-		for (utries = 0; utries <= max_utries; utries++)
-		{
-			gint left;
+    gint possibilities = 0;
+    gint max_tries = score / TRY_POINTS;
+    gint max_utries = score / UTRY_POINTS;
 
-			/* Calculate left over score for penalties */
-			left = score - (tries * TRY_POINTS) - (utries * UTRY_POINTS);
+    for (gint tries = 0; tries <= max_tries; tries++)
+    {
+        for (gint utries = 0; utries <= max_utries; utries++)
+        {
+            gint left = score - (tries * TRY_POINTS) - (utries * UTRY_POINTS);
 
-			if (left < 0)
-				continue;
+            if (left < 0)
+                continue;
 
-			/* If the score after pens is 0, it's a possibility */
-			if (left % KICK_POINTS == 0)
-			{
-				gint pens;
+            if (left % KICK_POINTS == 0)
+            {
+                gint kicks = left / KICK_POINTS;
 
-				pens = left / KICK_POINTS;
+                RugbyPossibility *possibility = g_slice_new (RugbyPossibility);
+                possibility->tries = tries;
+                possibility->utries = utries;
+                possibility->kicks = kicks;
 
-				/* Add result to variant */
-				g_variant_builder_add (&builder, "(iii)", tries, utries, pens);
-				possibilities++;
-			}
-		}
-	}
+                g_ptr_array_add (array, possibility);
+                possibilities++;
+            }
+        }
+    }
 
-	if (possibilities == 0)
-		return NULL;
-	else
-		return g_variant_builder_end (&builder);
+    return array;
 }
 
 /**
diff --git a/src/rugby-scoring.h b/src/rugby-scoring.h
index c3207cd..9b57191 100644
--- a/src/rugby-scoring.h
+++ b/src/rugby-scoring.h
@@ -11,14 +11,21 @@ G_BEGIN_DECLS
 
 typedef enum
 {
-	RUGBY_SCORE_TYPE_TRY,
-	RUGBY_SCORE_TYPE_UTRY,
-	RUGBY_SCORE_TYPE_KICK
+    RUGBY_SCORE_TYPE_TRY,
+    RUGBY_SCORE_TYPE_UTRY,
+    RUGBY_SCORE_TYPE_KICK
 } RugbyScoreType;
 
-GVariant * rugby_scoring_get_possibilities (gint score);
-gint       rugby_scoring_get_max_tries     (gint score);
-gint       rugby_scoring_get_max_kicks     (gint score);
+typedef struct
+{
+    gint tries;
+    gint utries;
+    gint kicks;
+} RugbyPossibility;
+
+GPtrArray * rugby_scoring_get_possibilities (gint score);
+gint        rugby_scoring_get_max_tries     (gint score);
+gint        rugby_scoring_get_max_kicks     (gint score);
 
 G_END_DECLS
 
-- 
GitLab