~ubuntu-branches/ubuntu/precise/gnome-games/precise-proposed

« back to all changes in this revision

Viewing changes to libgames-support/games-scores.c

  • Committer: Package Import Robot
  • Author(s): Rodrigo Moya
  • Date: 2011-05-30 13:32:04 UTC
  • mfrom: (1.3.4)
  • mto: (163.1.3 precise)
  • mto: This revision was merged to the branch mainline in revision 143.
  • Revision ID: package-import@ubuntu.com-20110530133204-celaq1v1dsxc48q1
Tags: upstream-3.0.2
ImportĀ upstreamĀ versionĀ 3.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
/* FIXME: Document */
23
23
 
24
 
/* FIXME: Add a finaliser to get rid of some of the strings. */
25
 
 
26
24
#include <config.h>
27
25
 
28
26
#include <fcntl.h>
40
38
  GamesScoresBackend *backend;
41
39
} GamesScoresCategoryInternal;
42
40
 
43
 
struct _GamesScoresPrivate {
 
41
struct GamesScoresPrivate {
44
42
  GHashTable *categories;
45
43
  GSList *catsordered;
46
44
  gchar *currentcat;
48
46
  gchar *basename;
49
47
  gboolean last_score_significant;
50
48
  gint last_score_position;
51
 
  GamesScoreValue last_score_value;
 
49
  GamesScore *last_score;
52
50
  GamesScoreStyle style;
53
51
  GamesScoresCategoryInternal dummycat;
54
52
};
64
62
}
65
63
 
66
64
/**
67
 
 * get_current:
 
65
 * games_scores_get_current:
68
66
 * @self: A scores object.
69
67
 *
70
68
 * Retrieves the current category and make sure it is in a state to be used.
99
97
 
100
98
G_DEFINE_TYPE (GamesScores, games_scores, G_TYPE_OBJECT);
101
99
 
102
 
/** 
 
100
/**
103
101
 * games_scores_new:
104
102
 * @app_name: the (old) app name (for backward compatibility),
105
103
 *   used as the basename of the category filenames
106
 
 * @categories: the score categories, or %NULL to use an anonymous category
107
 
 * @n_categories: the number of category entries in @categories
108
 
 * @categories_context: the translation context to use for the category names,
 
104
 * @categories: (allow-none): the score categories, or %NULL to use an anonymous category
 
105
 * @n_categories: (allow-none): the number of category entries in @categories
 
106
 * @categories_context: (allow-none): the translation context to use for the category names,
109
107
 *   or %NULL to use no translation context
110
 
 * @categories_domain: the translation domain to use for the category names,
 
108
 * @categories_domain: (allow-none): the translation domain to use for the category names,
111
109
 *   or %NULL to use the default domain
112
 
 * @default_category: the key of the default category, or %NULL
 
110
 * @default_category_index: (allow-none): the key of the default category, or %NULL
113
111
 * @style: the category style
114
112
 * 
115
113
 *
125
123
                  GamesScoreStyle style)
126
124
{
127
125
  GamesScores *self;
128
 
  GamesScoresPrivate *priv;
129
126
 
130
127
  self = GAMES_SCORES (g_object_new (GAMES_TYPE_SCORES, NULL));
131
 
  priv = self->priv;
132
128
 
133
129
  /* FIXME: Input sanity checks. */
134
130
 
135
 
  priv->categories = g_hash_table_new_full (g_str_hash, g_str_equal,
136
 
                                            g_free,
137
 
                                            (GDestroyNotify) games_scores_category_free);
 
131
  self->priv->categories = g_hash_table_new_full (g_str_hash, g_str_equal,
 
132
                                                  g_free,
 
133
                                                  (GDestroyNotify) games_scores_category_free);
138
134
 
139
135
  /* catsordered is a record of the ordering of the categories. 
140
136
   * Its data is shared with the hash table. */
141
 
  priv->catsordered = NULL;
 
137
  self->priv->catsordered = NULL;
142
138
 
143
139
  if (n_categories > 0) {
144
140
    int i;
158
154
      games_scores_add_category (self, category->key, display_name);
159
155
    }
160
156
 
161
 
    priv->defcat = g_strdup (categories[default_category_index].key);
162
 
    priv->currentcat = g_strdup (priv->defcat);
163
 
  } else {
164
 
    priv->currentcat = NULL;
165
 
    priv->defcat = NULL;
 
157
    self->priv->defcat = g_strdup (categories[default_category_index].key);
 
158
    self->priv->currentcat = g_strdup (self->priv->defcat);
166
159
  }
167
160
 
168
 
  priv->basename = g_strdup (app_name);
 
161
  self->priv->basename = g_strdup (app_name);
169
162
  /* FIXME: Do some sanity checks on the default and the like. */
170
163
 
171
 
  priv->style = style;
 
164
  self->priv->style = style;
172
165
 
173
166
  /* Set up the anonymous category for use when no categories are specified. */
174
 
  priv->dummycat.category.key = (char *) "";
175
 
  priv->dummycat.category.name = (char *) "";
176
 
  priv->dummycat.backend = NULL;
 
167
  self->priv->dummycat.category.key = (char *) "";
 
168
  self->priv->dummycat.category.name = (char *) "";
177
169
 
178
170
  return self;
179
171
}
206
198
}
207
199
 
208
200
/**
209
 
 * set_category:
210
 
 * @scores: A scores object.
 
201
 * games_scores_set_category:
 
202
 * @self: A scores object.
211
203
 * @category: A string identifying the category to use (the key in
212
204
 *            the GamesScoresCategory structure).
213
205
 *
235
227
}
236
228
 
237
229
/**
238
 
 * add_score:
 
230
 * games_scores_add_score:
239
231
 * @self: A scores object.
240
 
 * @score: A GamesScoreValue - it is up to the caller to convert their
 
232
 * @score: A #GamesScore - it is up to the caller to convert their
241
233
 *         raw value to one of the supported types.
242
234
 *
243
235
 * Add a score to the set of scores. Retention of anything but the
247
239
 *
248
240
 **/
249
241
gint
250
 
games_scores_add_score (GamesScores * self, GamesScoreValue score)
 
242
games_scores_add_score (GamesScores * self, GamesScore *score)
251
243
{
252
244
  GamesScoresPrivate *priv = self->priv;
253
 
  GamesScore *fullscore;
254
245
  GamesScoresCategoryInternal *cat;
255
246
  gint place, n;
256
247
  GList *s, *scores_list;
257
248
 
258
249
  g_return_val_if_fail (self != NULL, 0);
259
250
 
260
 
  fullscore = games_score_new ();
261
 
  fullscore->value = score;
262
 
 
263
251
  cat = games_scores_get_current (self);
264
252
 
265
253
  scores_list = games_scores_backend_get_scores (cat->backend);
274
262
    n++;
275
263
 
276
264
    /* If beat someone in the list, add us there. */
277
 
    if (games_score_compare (priv->style, oldscore, fullscore) < 0) {
 
265
    if (games_score_compare (priv->style, oldscore, score) < 0) {
278
266
      scores_list = g_list_insert_before (scores_list, s,
279
 
                                          games_score_dup (fullscore));
 
267
                                          g_object_ref (score));
280
268
      place = n;
281
269
      break;
282
270
    }
289
277
   * This also handles the empty-file case. */
290
278
  if ((place == 0) && (n < GAMES_SCORES_SIGNIFICANT)) {
291
279
    place = n + 1;
292
 
    scores_list = g_list_append (scores_list, games_score_dup (fullscore));
 
280
    scores_list = g_list_append (scores_list, g_object_ref (score));
293
281
  }
294
282
 
295
283
  if (g_list_length (scores_list) > GAMES_SCORES_SIGNIFICANT) {
296
284
    s = g_list_nth (scores_list, GAMES_SCORES_SIGNIFICANT - 1);
297
285
    /* Note that we are guaranteed to only need to remove one link
298
286
     * and it is also guaranteed not to be the first one. */
299
 
    games_score_destroy ((GamesScore *) (g_list_next (s)->data));
 
287
    g_object_unref (g_list_next (s)->data);
300
288
    g_list_free (g_list_next (s));
301
289
    s->next = NULL;
302
290
  }
306
294
 
307
295
  priv->last_score_significant = place > 0;
308
296
  priv->last_score_position = place;
309
 
  priv->last_score_value = score;
 
297
  g_object_unref (priv->last_score);
 
298
  priv->last_score = g_object_ref (score);
310
299
 
311
300
  return place;
312
301
}
313
302
 
 
303
gint
 
304
games_scores_add_plain_score (GamesScores * self, guint32 value)
 
305
{
 
306
  return games_scores_add_score (self, games_score_new_plain (value));
 
307
}
 
308
 
 
309
gint
 
310
games_scores_add_time_score (GamesScores * self, gdouble value)
 
311
{
 
312
  return games_scores_add_score (self, games_score_new_time (value));
 
313
}
 
314
 
314
315
/**
315
316
 * games_scores_update_score_name:
316
317
 * @self: A scores object.
317
318
 * @new_name: The new name to use.
 
319
 * @old_name: (allow-none):
318
320
 *
319
321
 * By default add_score uses the current user name. This routine updates
320
322
 * that name. There are a few wrinkles: the score may have moved since we
330
332
  GList *s, *scores_list;
331
333
  gint n, place;
332
334
  GamesScore *sc;
333
 
  GamesScoreValue score;
334
335
 
335
336
  g_return_if_fail (self != NULL);
336
337
 
337
338
  place = priv->last_score_position;
338
 
  score = priv->last_score_value;
339
339
 
340
340
  if (place == 0)
341
341
    return;
360
360
 
361
361
  while ((n >= place) && (s != NULL)) {
362
362
    sc = (GamesScore *) (s->data);
363
 
    if ((games_score_compare_values (priv->style, sc->value, score) ==
364
 
         0) && (g_utf8_collate (old_name, sc->name) == 0)) {
365
 
      g_free (sc->name);
366
 
      sc->name = g_strdup (new_name);
 
363
    if ((games_score_compare (priv->style, sc, priv->last_score) ==
 
364
         0) && (g_utf8_collate (old_name, games_score_get_name (sc)) == 0)) {
 
365
      games_score_set_name (sc, new_name);
367
366
    }
368
367
 
369
368
    s = g_list_previous (s);
393
392
}
394
393
 
395
394
/**
396
 
 * get:
 
395
 * games_scores_get:
397
396
 * @self: A scores object.
398
397
 *
399
398
 * Get a list of GamesScore objects for the current category. The list
400
399
 * is still owned by the GamesScores object and is not guaranteed to
401
400
 * be the either the same or accurate after any games_scores call
402
401
 * except games_scores_get. Do not alter the data either.
 
402
 *
 
403
 * Returns: (element-type GnomeGamesSupport.Score) (transfer none): A list of GamesScore objects.
403
404
 **/
404
405
GList *
405
406
games_scores_get (GamesScores * self)
446
447
}
447
448
 
448
449
/**
449
 
 * get_style:
 
450
 * games_scores_get_style:
450
451
 * @self: A scores object.
451
452
 *
452
453
 * Returns the style of the scores.
463
464
}
464
465
 
465
466
/**
466
 
 * get_category:
 
467
 * games_scores_get_category:
467
468
 * @self: A scores object.
468
469
 *
469
470
 * Returns the current category key. It is owned by the GamesScores object and
492
493
 
493
494
  priv->last_score_significant = FALSE;
494
495
  priv->last_score_position = 0;
495
 
  priv->last_score_value.plain = 0;
 
496
  priv->last_score = games_score_new ();
 
497
}
 
498
 
 
499
static void
 
500
games_scores_finalize (GObject * object)
 
501
{
 
502
  GamesScores *scores = GAMES_SCORES (object);
 
503
 
 
504
  g_hash_table_unref (scores->priv->categories);
 
505
  g_free (scores->priv->catsordered);
 
506
  g_free (scores->priv->currentcat);
 
507
  g_free (scores->priv->defcat);
 
508
  g_free (scores->priv->basename);
 
509
  g_object_unref (scores->priv->last_score);
 
510
 
 
511
  G_OBJECT_CLASS (games_scores_parent_class)->finalize (object);
496
512
}
497
513
 
498
514
static void
499
515
games_scores_class_init (GamesScoresClass * klass)
500
516
{
 
517
  GObjectClass *object_class = (GObjectClass *) klass;  
 
518
  object_class->finalize = games_scores_finalize;
501
519
  g_type_class_add_private (klass, sizeof (GamesScoresPrivate));
502
520
}