[aisleriot] guile: Load games from %load-path
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [aisleriot] guile: Load games from %load-path
- Date: Sat, 3 Dec 2011 16:50:20 +0000 (UTC)
commit 5a5d567cca4ad1d984b4fed83d74e7efac1f5e62
Author: Christian Persch <chpe gnome org>
Date: Sat Dec 3 00:20:25 2011 +0100
guile: Load games from %load-path
Instead of constructing the path directly, load the game with
scm_primitive_load_path().
Install the game files in a directory versioned with the effective
guile version.
Add a function to get the list of installed games, and use it in
the game chooser.
configure.ac | 2 +
games/Makefile.am | 13 ++---
games/athena.scm | 2 +-
games/aunt-mary.scm | 2 +-
games/bakers-game.scm | 2 +-
games/gold-mine.scm | 2 +-
games/peek.scm | 2 +-
games/saratoga.scm | 2 +-
games/spider-three-decks.scm | 2 +-
games/spiderette.scm | 2 +-
games/will-o-the-wisp.scm | 2 +-
src/ar-game-chooser.c | 29 ++++-------
src/game.c | 62 +++++++++++++++++++---
src/game.h | 2 +
src/window.c | 119 +++++++++++++++++++-----------------------
15 files changed, 135 insertions(+), 110 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 0b6da51..4586b5a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -570,6 +570,8 @@ PKG_CHECK_MODULES([GUILE],[$GUILE_PKGS])
AM_CONDITIONAL([HAVE_GUILE_2_X],[test "$with_guile" != "1.8"])
+AC_SUBST([GUILE_EFFECTIVE_VERSION],[$with_guile])
+
AC_ARG_VAR([GUILE_TOOLS])
AC_PATH_PROG([GUILE_TOOLS],[guile-tools],[false])
if test "$GUILE_TOOLS" = "false"; then
diff --git a/games/Makefile.am b/games/Makefile.am
index a536d35..4c424f5 100644
--- a/games/Makefile.am
+++ b/games/Makefile.am
@@ -1,14 +1,13 @@
NULL =
-guiledir = $(pkgdatadir)/aisleriot
+pkgguiledir = $(pkgdatadir)/guile/$(GUILE_EFFECTIVE_VERSION)
-guile_DATA = \
+moduledir = $(pkgguiledir)/aisleriot
+module_DATA = \
api.scm \
$(NULL)
-rulesdir = $(pkgdatadir)/games
-
-rules_DATA = \
+pkgguile_DATA = \
accordion.scm \
agnes.scm \
athena.scm \
@@ -100,8 +99,8 @@ rules_DATA = \
$(NULL)
EXTRA_DIST = \
- $(rules_DATA) \
- $(guile_DATA) \
+ $(pkgguile_DATA) \
+ $(module_DATA) \
template.scm \
Rules.HOWTO \
$(NULL)
diff --git a/games/athena.scm b/games/athena.scm
index f9ee71d..b988564 100644
--- a/games/athena.scm
+++ b/games/athena.scm
@@ -24,7 +24,7 @@
;; TODO rewrite in a way less redundant way and share code with Klondike
;; As seen in Pretty Good Solitaire 10 http://goodsol.com 2005.
-(load "klondike.scm")
+(primitive-load-path "klondike")
(define deal-one #t)
(define deal-three #f)
diff --git a/games/aunt-mary.scm b/games/aunt-mary.scm
index 5504f0b..a28883e 100644
--- a/games/aunt-mary.scm
+++ b/games/aunt-mary.scm
@@ -17,7 +17,7 @@
(use-modules (aisleriot interface) (aisleriot api))
-(load "klondike.scm")
+(primitive-load-path "klondike")
(define deal-one #t)
(define deal-three #f)
diff --git a/games/bakers-game.scm b/games/bakers-game.scm
index 19f0d60..5a9755f 100644
--- a/games/bakers-game.scm
+++ b/games/bakers-game.scm
@@ -16,7 +16,7 @@
(use-modules (aisleriot interface) (aisleriot api))
-(load "freecell.scm")
+(primitive-load-path "freecell")
(define (field-join? lower upper)
(and (eq? (get-suit lower) (get-suit upper))
diff --git a/games/gold-mine.scm b/games/gold-mine.scm
index 717fdc5..08e99fb 100644
--- a/games/gold-mine.scm
+++ b/games/gold-mine.scm
@@ -16,7 +16,7 @@
(use-modules (aisleriot interface) (aisleriot api))
-(load "klondike.scm")
+(primitive-load-path "klondike")
(define deal-one #f)
(define deal-three #t)
diff --git a/games/peek.scm b/games/peek.scm
index 3cd78c6..1482f58 100644
--- a/games/peek.scm
+++ b/games/peek.scm
@@ -16,7 +16,7 @@
(use-modules (aisleriot interface) (aisleriot api))
-(load "osmosis.scm")
+(primitive-load-path "osmosis")
(define (initial-deal)
(deal-cards-face-up 8 '(0 2 4 6 0 2 4 6 0 2 4 6 0 2 4 6 1))
diff --git a/games/saratoga.scm b/games/saratoga.scm
index c8ed305..26a2e50 100644
--- a/games/saratoga.scm
+++ b/games/saratoga.scm
@@ -25,7 +25,7 @@
(use-modules (aisleriot interface) (aisleriot api))
-(load "klondike.scm")
+(primitive-load-path "klondike")
(define deal-one #t)
(define deal-three #f)
diff --git a/games/spider-three-decks.scm b/games/spider-three-decks.scm
index 6039a59..d8fc943 100644
--- a/games/spider-three-decks.scm
+++ b/games/spider-three-decks.scm
@@ -16,7 +16,7 @@
(use-modules (aisleriot interface) (aisleriot api))
-(load "spider.scm")
+(primitive-load-path "spider")
(define tableau '(13 14 15 16 17 18 19 20 21 22 23 24))
(define foundation '(1 2 3 4 5 6 7 8 9 10 11 12))
diff --git a/games/spiderette.scm b/games/spiderette.scm
index e8a110c..52bab0d 100644
--- a/games/spiderette.scm
+++ b/games/spiderette.scm
@@ -16,7 +16,7 @@
(use-modules (aisleriot interface) (aisleriot api))
-(load "spider.scm")
+(primitive-load-path "spider")
(define stock 0)
(define foundation '(1 2 3 4))
diff --git a/games/will-o-the-wisp.scm b/games/will-o-the-wisp.scm
index ed857cd..7aa3f71 100644
--- a/games/will-o-the-wisp.scm
+++ b/games/will-o-the-wisp.scm
@@ -17,7 +17,7 @@
(use-modules (aisleriot interface) (aisleriot api))
-(load "spider.scm")
+(primitive-load-path "spider")
(define stock 0)
(define foundation '(1 2 3 4))
diff --git a/src/ar-game-chooser.c b/src/ar-game-chooser.c
index ded04e8..95c555c 100644
--- a/src/ar-game-chooser.c
+++ b/src/ar-game-chooser.c
@@ -129,8 +129,8 @@ ar_game_chooser_constructor (GType type,
GtkTreeIter current_iter;
gboolean current_iter_set = FALSE;
const char *current_game_module;
- const char *games_dir;
- GDir *dir;
+ char **games;
+ int i;
GtkWidget *content_area;
GtkDialog *dialog;
@@ -147,22 +147,14 @@ ar_game_chooser_constructor (GType type,
current_game_module = aisleriot_window_get_game_module (priv->window);
- games_dir = ar_runtime_get_directory (AR_RUNTIME_GAMES_DIRECTORY);
-
- dir = g_dir_open (games_dir, 0, NULL);
- if (dir != NULL) {
- const char *game_file;
-
- while ((game_file = g_dir_read_name (dir)) != NULL) {
- char *game_name, *game_module;
+ games = ar_get_game_modules ();
+ if (games != NULL) {
+ for (i = 0; games[i]; ++i) {
+ const char *game_module = games[i];
+ char *game_name;
GtkTreeIter iter;
- if (!g_str_has_suffix (game_file, ".scm") ||
- strcmp (game_file, "api.scm") == 0)
- continue;
-
- game_name = ar_filename_to_display_name (game_file);
- game_module = ar_filename_to_game_module (game_file);
+ game_name = ar_filename_to_display_name (game_module);
gtk_list_store_insert_with_values (GTK_LIST_STORE (list), &iter,
-1,
@@ -177,12 +169,11 @@ ar_game_chooser_constructor (GType type,
}
g_free (game_name);
- g_free (game_module);
}
-
- g_dir_close (dir);
}
+ g_strfreev (games);
+
/* Now construct the window contents */
gtk_window_set_title (window, _("Select Game"));
gtk_window_set_modal (window, TRUE);
diff --git a/src/game.c b/src/game.c
index e733481..87f2b48 100644
--- a/src/game.c
+++ b/src/game.c
@@ -47,6 +47,9 @@
#ifndef SCM_MAJOR_VERSION
#define SCM_MAJOR_VERSION 1
#endif
+#ifndef SCM_EFFECTIVE_VERSION
+#define SCM_EFFECTIVE_VERSION "1.8"
+#endif
struct _AisleriotGameClass
{
@@ -1288,7 +1291,7 @@ aisleriot_game_class_init (AisleriotGameClass *klass)
GType error_types[] = { G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE };
GType ptr_types[] = { G_TYPE_POINTER };
SCM variable;
- const char *path;
+ char *path;
gobject_class->constructor = aisleriot_game_constructor;
gobject_class->finalize = aisleriot_game_finalize;
@@ -1405,16 +1408,24 @@ aisleriot_game_class_init (AisleriotGameClass *klass)
scm_c_define_module ("aisleriot interface", cscm_init, NULL);
/* Append load-path */
- path = ar_runtime_get_directory (AR_RUNTIME_PKG_DATA_DIRECTORY);
+ path = g_build_filename (ar_runtime_get_directory (AR_RUNTIME_PKG_DATA_DIRECTORY),
+ "guile",
+ SCM_EFFECTIVE_VERSION,
+ NULL);
variable = scm_c_module_lookup (scm_the_root_module (), "%load-path");
scm_variable_set_x (variable, scm_append_x (scm_list_2 (scm_variable_ref (variable),
scm_list_1 (scm_from_locale_string (path)))));
+ g_free (path);
#if SCM_MAJOR_VERSION >= 2
- path = ar_runtime_get_directory (AR_RUNTIME_PKG_LIBRARY_DIRECTORY);
+ path = g_build_filename (ar_runtime_get_directory (AR_RUNTIME_PKG_LIBRARY_DIRECTORY),
+ "guile",
+ SCM_EFFECTIVE_VERSION,
+ NULL);
variable = scm_c_module_lookup (scm_the_root_module (), "%load-compiled-path");
scm_variable_set_x (variable, scm_append_x (scm_list_2 (scm_variable_ref (variable),
scm_list_1 (scm_from_locale_string (path)))));
+ g_free (path);
#endif
}
@@ -1697,16 +1708,11 @@ game_scm_load_game (void *user_data)
{
AisleriotGame *game = app_game;
const char *game_module = user_data;
- char *game_file, *path;
int i;
scm_dynwind_begin (0);
- game_file = g_strconcat (game_module, ".scm", NULL);
- scm_dynwind_unwind_handler (g_free, game_file, SCM_F_WIND_EXPLICITLY);
- path = ar_runtime_get_file (AR_RUNTIME_GAMES_DIRECTORY, game_file);
- scm_dynwind_unwind_handler (g_free, path, SCM_F_WIND_EXPLICITLY);
- scm_c_primitive_load (path);
+ scm_primitive_load_path (scm_from_locale_string (game_module));
for (i = 0; i <= LAST_MANDATORY_LAMBDA; ++i) {
if (scm_is_false (scm_procedure_p (game->lambdas[i]))) {
@@ -2622,3 +2628,41 @@ aisleriot_game_reset_old_cards (ArSlot *slot)
}
#endif /* HAVE_CLUTTER */
+
+/**
+ * ar_get_game_modules:
+ *
+ * Returns: (tranfer full): the list of available games
+ */
+char **
+ar_get_game_modules (void)
+{
+ char *path;
+ const char *filename;
+ GDir *dir;
+ GPtrArray *array;
+
+ path = g_build_filename (ar_runtime_get_directory (AR_RUNTIME_PKG_DATA_DIRECTORY),
+ "guile",
+ SCM_EFFECTIVE_VERSION,
+ NULL);
+ dir = g_dir_open (path, 0, NULL);
+ g_free (path);
+ if (dir == NULL)
+ return NULL;
+
+ array = g_ptr_array_new ();
+
+ while ((filename = g_dir_read_name (dir)) != NULL) {
+ if (!g_str_has_suffix (filename, ".scm") ||
+ strcmp (filename, "api.scm") == 0)
+ continue;
+
+ g_ptr_array_add (array, ar_filename_to_game_module (filename));
+ }
+
+ g_ptr_array_sort (array, (GCompareFunc) strcmp);
+ g_ptr_array_add (array, NULL);
+
+ return (char **) g_ptr_array_free (array, FALSE);
+}
diff --git a/src/game.h b/src/game.h
index 8143f9f..1d96a4f 100644
--- a/src/game.h
+++ b/src/game.h
@@ -243,6 +243,8 @@ void aisleriot_game_get_card_offset (ArSlot *slot,
void aisleriot_game_reset_old_cards (ArSlot *slot);
+char **ar_get_game_modules (void);
+
G_END_DECLS
#endif /* !AISLERIOT_GAME_H */
diff --git a/src/window.c b/src/window.c
index 0948848..c9bec1e 100644
--- a/src/window.c
+++ b/src/window.c
@@ -573,15 +573,16 @@ debug_exception_cb (GtkAction *action,
typedef struct {
AisleriotWindow *window;
- GList *games_list;
- GList *current_game;
+ char **games;
+ int n_games;
+ int current;
} DebugWindowData;
static void
debug_data_free (DebugWindowData *data)
{
- g_list_foreach (data->games_list, (GFunc) g_free, NULL);
- g_list_free (data->games_list);
+ g_strfreev (data->games);
+
g_slice_free (DebugWindowData, data);
}
@@ -590,37 +591,37 @@ debug_ensure_game_list (AisleriotWindow *window)
{
AisleriotWindowPrivate *priv = window->priv;
DebugWindowData *data;
- GDir *dir;
- GList *list = NULL;
- const char *games_dir;
+ char **games;
+ int n_games;
+ const char *current_game_module;
+ int i;
data = g_object_get_data (G_OBJECT (window), DEBUG_WINDOW_DATA_KEY);
if (data != NULL)
return data;
- games_dir = ar_runtime_get_directory (AR_RUNTIME_GAMES_DIRECTORY);
- dir = g_dir_open (games_dir, 0, NULL);
- if (dir != NULL) {
- const char *game_file;
-
- while ((game_file = g_dir_read_name (dir)) != NULL) {
- if (!g_str_has_suffix (game_file, ".scm") ||
- strcmp (game_file, "api.scm") == 0)
- continue;
-
- list = g_list_prepend (list, ar_filename_to_game_module (game_file));
- }
+ games = ar_get_game_modules ();
+ if (games == NULL)
+ return NULL;
- list = g_list_sort (list, (GCompareFunc) strcmp);
- g_dir_close (dir);
+ n_games = g_strv_length (games);
+ if (n_games == 0) {
+ g_strfreev (games);
+ return NULL;
}
- data = g_slice_new (DebugWindowData);
data->window = window;
- data->games_list = list;
- data->current_game = g_list_find_custom (data->games_list,
- aisleriot_game_get_game_module (priv->game),
- (GCompareFunc) strcmp);
+ data->games = games;
+ data->n_games = n_games;
+ data->current = -1;
+
+ current_game_module = aisleriot_game_get_game_module (priv->game);
+ for (i = 0; data->games[i]; ++i) {
+ if (strcmp (data->games[i], current_game_module) == 0) {
+ data->current = i;
+ break;
+ }
+ }
g_object_set_data_full (G_OBJECT (window), DEBUG_WINDOW_DATA_KEY,
data, (GDestroyNotify) debug_data_free);
@@ -629,35 +630,31 @@ debug_ensure_game_list (AisleriotWindow *window)
}
static gboolean
-debug_cycle_timeout_cb (AisleriotWindow *window)
+debug_cycle_timeout_cb (DebugWindowData *data)
{
- DebugWindowData *data;
- char *game_module;
+ if (data->current >= -1)
+ data->current++;
- data = debug_ensure_game_list (window);
- if (data->current_game != NULL) {
- data->current_game = data->current_game->next;
- /* We're done */
- if (!data->current_game)
- return FALSE;
- }
- if (!data->current_game) {
- data->current_game = data->games_list;
- }
- if (!data->current_game)
+ /* We're done */
+ if (data->current >= data->n_games)
return FALSE;
- game_module = data->current_game->data;
- aisleriot_window_set_game_module (data->window, game_module, NULL);
+ aisleriot_window_set_game_module (data->window, data->games[data->current], NULL);
- return TRUE;
+ return TRUE; /* run again */
}
static void
debug_cycle_cb (GtkAction *action,
AisleriotWindow *window)
{
- g_timeout_add (500, (GSourceFunc) debug_cycle_timeout_cb, window);
+ DebugWindowData *data;
+
+ data = debug_ensure_game_list (window);
+ if (data == NULL)
+ return;
+
+ g_timeout_add (500, (GSourceFunc) debug_cycle_timeout_cb, data);
}
static void
@@ -667,11 +664,11 @@ debug_game_first (GtkAction *action,
DebugWindowData *data;
data = debug_ensure_game_list (window);
- data->current_game = data->games_list;
- if (!data->current_game)
+ if (data == NULL)
return;
- aisleriot_window_set_game_module (data->window, (const char *) data->current_game->data, NULL);
+ data->current = 0;
+ aisleriot_window_set_game_module (data->window, data->games[data->current], NULL);
}
static void
@@ -681,11 +678,11 @@ debug_game_last (GtkAction *action,
DebugWindowData *data;
data = debug_ensure_game_list (window);
- data->current_game = g_list_last (data->games_list);
- if (!data->current_game)
+ if (data == NULL)
return;
- aisleriot_window_set_game_module (data->window, (const char *) data->current_game->data, NULL);
+ data->current = data->n_games - 1;
+ aisleriot_window_set_game_module (data->window, data->games[data->current], NULL);
}
static void
@@ -695,16 +692,11 @@ debug_game_next (GtkAction *action,
DebugWindowData *data;
data = debug_ensure_game_list (window);
- if (data->current_game) {
- data->current_game = data->current_game->next;
- }
- if (!data->current_game) {
- data->current_game = data->games_list;
- }
- if (!data->current_game)
+ if (data == NULL || data->current + 1 == data->n_games)
return;
- aisleriot_window_set_game_module (data->window, (const char *) data->current_game->data, NULL);
+ data->current++;
+ aisleriot_window_set_game_module (data->window, data->games[data->current], NULL);
}
static void
@@ -714,16 +706,11 @@ debug_game_prev (GtkAction *action,
DebugWindowData *data;
data = debug_ensure_game_list (window);
- if (data->current_game) {
- data->current_game = data->current_game->prev;
- }
- if (!data->current_game) {
- data->current_game = data->games_list;
- }
- if (!data->current_game)
+ if (data == NULL || data->current == 0)
return;
- aisleriot_window_set_game_module (data->window, (const char *) data->current_game->data, NULL);
+ data->current--;
+ aisleriot_window_set_game_module (data->window, data->games[data->current], NULL);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]