gnome-games r8328 - trunk/aisleriot
- From: chpe svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-games r8328 - trunk/aisleriot
- Date: Sun, 23 Nov 2008 19:34:51 +0000 (UTC)
Author: chpe
Date: Sun Nov 23 19:34:51 2008
New Revision: 8328
URL: http://svn.gnome.org/viewvc/gnome-games?rev=8328&view=rev
Log:
Move option handling code from AisleriotWindow to AisleriotGame.
Now guile is only used from within game.c.
Modified:
trunk/aisleriot/game.c
trunk/aisleriot/game.h
trunk/aisleriot/window.c
Modified: trunk/aisleriot/game.c
==============================================================================
--- trunk/aisleriot/game.c (original)
+++ trunk/aisleriot/game.c Sun Nov 23 19:34:51 2008
@@ -1995,15 +1995,36 @@
}
/**
- * aisleriot_game_get_options_lambda:
+ * aisleriot_game_option_free:
+ * @option: a #AisleriotGameOption
+ *
+ * Frees @options.
+ */
+void
+aisleriot_game_option_free (AisleriotGameOption *option)
+{
+ g_return_if_fail (option != NULL);
+
+ g_free (option->display_name);
+ g_slice_free (AisleriotGameOption, option);
+}
+
+/**
+ * aisleriot_game_get_options:
* @game:
*
- * Returns: a #SCM containing the game options
+ * Returns: a newly allocated list containing newly allocated
+ * #AisleriotGameOption structs.
*/
-SCM
-aisleriot_game_get_options_lambda (AisleriotGame *game)
+GList *
+aisleriot_game_get_options (AisleriotGame *game)
{
CallData data = CALL_DATA_INIT;
+ SCM options_list;
+ int l, i;
+ guint32 bit = 1;
+ AisleriotGameOptionType type = AISLERIOT_GAME_OPTION_CHECK;
+ GList *options = NULL;
data.lambda = game->get_options_lambda;
data.n_args = 0;
@@ -2011,31 +2032,120 @@
cscmi_call_lambda, &data,
cscmi_catch_handler, NULL);
- return data.retval;
+ options_list = data.retval;
+ if (scm_is_false (scm_list_p (options_list)))
+ return NULL;
+
+ l = scm_to_int (scm_length (options_list));
+ bit = 1;
+ for (i = 0; i < l; i++) {
+ SCM entry;
+
+ /* Each entry in the options list is a list consisting of a name and
+ * a variable.
+ */
+ entry = scm_list_ref (options_list, scm_from_int (i));
+ if (!scm_is_false (scm_list_p (entry))) {
+ SCM entryname;
+ char *entrynamestr;
+ gboolean entrystate;
+ AisleriotGameOption *option;
+
+ entryname = scm_list_ref (entry, scm_from_uint (0));
+ if (!scm_is_string (entryname))
+ continue; /* Shouldn't happen */
+
+ entrynamestr = scm_to_locale_string (entryname);
+ if (!entrynamestr)
+ continue;
+
+ entrystate = SCM_NFALSEP (scm_list_ref (entry, scm_from_uint (1)));
+
+ option = g_slice_new (AisleriotGameOption);
+ option->display_name = g_strdup (entrynamestr);
+ option->type = type;
+ option->value = bit;
+ option->set = entrystate != FALSE;
+
+ options = g_list_prepend (options, option);
+
+ free (entrynamestr);
+
+ bit <<= 1;
+ } else {
+ /* If we encounter an atom, change the mode. What the atom is doesn't
+ * really matter. */
+ if (type == AISLERIOT_GAME_OPTION_CHECK) {
+ type = AISLERIOT_GAME_OPTION_RADIO;
+ } else {
+ type = AISLERIOT_GAME_OPTION_CHECK;
+ }
+ }
+ }
+
+ return g_list_reverse (options);
}
/**
* aisleriot_game_apply_options_lambda:
* @game:
- * @options:
+ * @changed_mask:
+ * @changed_value:
*
- * Applies @options.
+ * Applies options.
*
- * Returns: a #SCM with status information
+ * Returns: the new options value
*/
-SCM
-aisleriot_game_apply_options_lambda (AisleriotGame *game, SCM options)
+guint32
+aisleriot_game_change_options (AisleriotGame *game,
+ guint32 changed_mask,
+ guint32 changed_value)
{
CallData data = CALL_DATA_INIT;
+ CallData data2 = CALL_DATA_INIT;
+ SCM options_list;
+ guint32 bit, value;
+ int l, i;
- data.lambda = game->apply_options_lambda;
- data.n_args = 1;
- data.arg1 = options;
+ data.lambda = game->get_options_lambda;
+ data.n_args = 0;
scm_internal_stack_catch (SCM_BOOL_T,
cscmi_call_lambda, &data,
cscmi_catch_handler, NULL);
- return data.retval;
+ options_list = data.retval;
+ if (scm_is_false (scm_list_p (options_list)))
+ return 0;
+
+ value = 0;
+ bit = 1;
+ l = scm_to_int (scm_length (options_list));
+ for (i = 0; i < l; i++) {
+ SCM entry;
+
+ entry = scm_list_ref (options_list, scm_from_uint (i));
+ if (scm_is_false (scm_list_p (entry)))
+ continue;
+
+ if (changed_mask & bit)
+ scm_list_set_x (entry, scm_from_uint (1), (changed_value & bit) ? SCM_BOOL_T : SCM_BOOL_F);
+
+ if (SCM_NFALSEP (scm_list_ref (entry, scm_from_uint (1))))
+ value |= bit;
+
+ bit <<= 1;
+ }
+
+ data2.lambda = game->apply_options_lambda;
+ data2.n_args = 1;
+ data2.arg1 = options_list;
+ scm_internal_stack_catch (SCM_BOOL_T,
+ cscmi_call_lambda, &data2,
+ cscmi_catch_handler, NULL);
+
+ /* FIXMEchpe: check for exceptions? */
+
+ return value;
}
/**
Modified: trunk/aisleriot/game.h
==============================================================================
--- trunk/aisleriot/game.h (original)
+++ trunk/aisleriot/game.h Sun Nov 23 19:34:51 2008
@@ -19,8 +19,6 @@
#ifndef AISLERIOT_GAME_H
#define AISLERIOT_GAME_H
-#include <libguile.h>
-
#include <gdk/gdk.h>
#include <libgames-support/games-card.h>
@@ -94,6 +92,8 @@
#define AISLERIOT_GAME_ERROR (aisleriot_game_error_quark ())
+#define AISLERIOT_GAME_OPTIONS_MAX (0x7FFFFFFF) /* 31 bits, since we're using int not guint */
+
typedef struct _AisleriotGame AisleriotGame;
typedef GObjectClass AisleriotGameClass;
@@ -119,8 +119,22 @@
LAST_GAME_STATE
} AisleriotGameState;
+typedef enum {
+ AISLERIOT_GAME_OPTION_CHECK,
+ AISLERIOT_GAME_OPTION_RADIO
+} AisleriotGameOptionType;
+
+typedef struct {
+ char *display_name;
+ AisleriotGameOptionType type;
+ guint32 value; /* exactly 1 bit set */
+ gboolean set;
+} AisleriotGameOption;
+
GQuark aisleriot_game_error_quark (void);
+void aisleriot_game_option_free (AisleriotGameOption *option);
+
GType aisleriot_game_get_type (void);
AisleriotGame *aisleriot_game_new (void);
@@ -181,9 +195,11 @@
char *aisleriot_game_get_hint (AisleriotGame *game);
-SCM aisleriot_game_get_options_lambda (AisleriotGame * game);
+GList *aisleriot_game_get_options (AisleriotGame * game);
-SCM aisleriot_game_apply_options_lambda (AisleriotGame * game, SCM options);
+guint32 aisleriot_game_change_options (AisleriotGame *game,
+ guint32 changed_mask,
+ guint32 changed_value);
gboolean aisleriot_game_timeout_lambda (AisleriotGame * game);
Modified: trunk/aisleriot/window.c
==============================================================================
--- trunk/aisleriot/window.c (original)
+++ trunk/aisleriot/window.c Sun Nov 23 19:34:51 2008
@@ -25,12 +25,6 @@
#include <sys/types.h>
#include <errno.h>
-#include <libguile.h>
-
-#ifndef HAVE_GUILE_1_8
-#include "guile16-compat.h"
-#endif
-
#include <glib/gi18n.h>
#include <gdk/gdk.h>
@@ -1125,63 +1119,27 @@
aisleriot_game_deal_cards (priv->game);
}
-/* Make something that's easier to store in conf */
-static guint
-compress_options_to_int (SCM options_list)
-{
- int i;
- guint bits;
- SCM entry;
-
- bits = 0;
- for (i = scm_to_int (scm_length (options_list)) - 1; i >= 0; i--) {
- entry = scm_list_ref (options_list, scm_from_int (i));
- if (SCM_NFALSEP (scm_list_p (entry))) {
- bits <<= 1;
- bits |= SCM_NFALSEP (scm_list_ref (entry, scm_from_int (1))) ? 1 : 0;
- }
- }
-
- return bits;
-}
-
-/* Take the bit-string value and set the option list from it. */
-static void
-expand_options_from_int (SCM options_list, guint bits)
-{
- gint l, i;
- SCM entry;
-
- l = scm_to_int (scm_length (options_list));
- for (i = 0; i < l; i++) {
- entry = scm_list_ref (options_list, scm_from_int (i));
- if (SCM_NFALSEP (scm_list_p (entry))) {
- scm_list_set_x (entry, scm_from_int (1),
- bits & 1 ? SCM_BOOL_T : SCM_BOOL_F);
- bits >>= 1;
- }
- }
-}
-
/* The "Game Options" menu */
static void
-apply_option (SCM options_list,
- GtkToggleAction *action)
+apply_option (GtkToggleAction *action,
+ guint32 *changed_mask,
+ guint32 *changed_value)
{
- SCM entry;
gboolean active;
const char *action_name;
- guint n;
+ guint32 value;
active = gtk_toggle_action_get_active (action);
action_name = gtk_action_get_name (GTK_ACTION (action));
- n = g_ascii_strtoull (action_name + strlen ("Option"), NULL, 10);
+ value = g_ascii_strtoull (action_name + strlen ("Option"), NULL, 16);
- entry = scm_list_ref (options_list, scm_from_uint (n));
+ g_print ("option %s changed, value=%x set=%d\n", action_name, value, active);
- scm_list_set_x (entry, scm_from_uint (1), active ? SCM_BOOL_T : SCM_BOOL_F);
+ *changed_mask |= value;
+ if (active)
+ *changed_value |= value;
}
static void
@@ -1189,8 +1147,8 @@
AisleriotWindow *window)
{
AisleriotWindowPrivate *priv = window->priv;
- SCM options_list;
gboolean active;
+ guint32 changed_mask = 0, changed_value = 0, value;
/* Don't change the options if we're just installing the options menu */
if (priv->changing_game_type)
@@ -1208,8 +1166,6 @@
!active)
return;
- options_list = aisleriot_game_get_options_lambda (priv->game);
-
if (GTK_IS_RADIO_ACTION (action)) {
GSList *group, *l;
@@ -1220,16 +1176,15 @@
group = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
for (l = group; l; l = l->next) {
- apply_option (options_list, GTK_TOGGLE_ACTION (l->data));
+ apply_option (GTK_TOGGLE_ACTION (l->data), &changed_mask, &changed_value);
}
} else {
- apply_option (options_list, action);
+ apply_option (action, &changed_mask, &changed_value);
}
- aisleriot_conf_set_options (aisleriot_game_get_game_file (priv->game),
- compress_options_to_int (options_list));
+ value = aisleriot_game_change_options (priv->game, changed_mask, changed_value);
- aisleriot_game_apply_options_lambda (priv->game, options_list);
+ aisleriot_conf_set_options (aisleriot_game_get_game_file (priv->game), (int) value);
/* Now re-deal, so the option is applied */
aisleriot_game_new_game (priv->game, NULL);
@@ -1239,10 +1194,10 @@
install_options_menu (AisleriotWindow *window)
{
AisleriotWindowPrivate *priv = window->priv;
- SCM options_list;
- int l, i, options;
- gint mode = OPTION_CHECKMENU;
+ GList *options, *l;
+ int options_value = 0;
GSList *radiogroup = NULL;
+ int radion = 0;
if (priv->options_merge_id != 0) {
gtk_ui_manager_remove_ui (priv->ui_manager, priv->options_merge_id);
@@ -1257,99 +1212,74 @@
/* See gtk bug #424448 */
gtk_ui_manager_ensure_update (priv->ui_manager);
+ /* Only apply the options if they exist. Otherwise the options in the menu
+ * and the real game options are out of sync until first changed by the user.
+ */
+ if (aisleriot_conf_get_options (aisleriot_game_get_game_file (priv->game), &options_value)) {
+ aisleriot_game_change_options (priv->game, AISLERIOT_GAME_OPTIONS_MAX, options_value);
+ }
+
/* To get radio buttons in the menu insert an atom into the option list
* in your scheme code. To get back out of radio-button mode insert
* another atom. The exact value of the atoms is irrelevant - they merely
* trigger a toggle - but descriptive names like begin-exclusive and
* end-exclusive are probably a good idea.
*/
- options_list = aisleriot_game_get_options_lambda (priv->game);
-
- if (scm_is_false (scm_list_p (options_list)))
+ options = aisleriot_game_get_options (priv->game);
+ if (!options)
return;
-
+
priv->options_group = gtk_action_group_new ("Options");
gtk_ui_manager_insert_action_group (priv->ui_manager, priv->options_group, -1);
g_object_unref (priv->options_group);
priv->options_merge_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
- /* Only apply the options if they exist. Otherwise the options in the menu
- * and the real game options are out of sync until first changed by the user.
- */
- if (aisleriot_conf_get_options (aisleriot_game_get_game_file (priv->game), &options)) {
- expand_options_from_int (options_list, options);
- aisleriot_game_apply_options_lambda (priv->game, options_list);
- }
+ for (l = options; l != NULL; l = l->next) {
+ AisleriotGameOption *option = (AisleriotGameOption *) l->data;
+ GtkToggleAction *action;
+ gchar actionname[32];
+
+ g_print ("installing option value=%08x set=%d type=%d name='%s'\n",
+ option->value, option->set, option->type, option->display_name);
+
+ g_snprintf (actionname, sizeof (actionname), "Option%u", option->value);
+
+ if (option->type == AISLERIOT_GAME_OPTION_CHECK) {
+ action = gtk_toggle_action_new (actionname,
+ option->display_name,
+ NULL,
+ NULL /* tooltip */);
+ radiogroup = NULL; /* make sure to start a new radio group when the next RADIO option comes */
+ radion = 0;
+ } else {
+ action = GTK_TOGGLE_ACTION (gtk_radio_action_new (actionname,
+ option->display_name,
+ NULL,
+ NULL /* tooltip */,
+ radion++));
+ gtk_radio_action_set_group (GTK_RADIO_ACTION (action),
+ radiogroup);
+ radiogroup = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
+ }
- l = scm_to_int (scm_length (options_list));
- for (i = 0; i < l; i++) {
- SCM entry;
+ gtk_toggle_action_set_active (action, option->set);
+ g_signal_connect (action, "toggled",
+ G_CALLBACK (option_cb), window);
- /* Each entry in the options list is a list consisting of a name and
- * a variable.
- */
- entry = scm_list_ref (options_list, scm_from_int (i));
- if (!scm_is_false (scm_list_p (entry))) {
- SCM entryname;
- char *entrynamestr;
- gboolean entrystate;
- GtkToggleAction *action;
- gchar actionname[32];
-
- entryname = scm_list_ref (entry, scm_from_uint (0));
- if (!scm_is_string (entryname))
- continue; /* Shouldn't happen */
-
- entrynamestr = scm_to_locale_string (entryname);
- if (!entrynamestr)
- continue;
-
- entrystate = SCM_NFALSEP (scm_list_ref (entry, scm_from_uint (1)));
-
- g_snprintf (actionname, sizeof (actionname), "Option%d", i);
-
- if (mode == OPTION_CHECKMENU) {
- action = gtk_toggle_action_new (actionname,
- entrynamestr,
- NULL,
- NULL /* tooltip */);
- } else {
- action = GTK_TOGGLE_ACTION (gtk_radio_action_new (actionname,
- entrynamestr,
- NULL,
- NULL /* tooltip */,
- i));
- gtk_radio_action_set_group (GTK_RADIO_ACTION (action),
- radiogroup);
- radiogroup = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
- }
+ gtk_action_group_add_action (priv->options_group, GTK_ACTION (action));
+ g_object_unref (action);
- free (entrynamestr);
+ gtk_ui_manager_add_ui (priv->ui_manager,
+ priv->options_merge_id,
+ OPTIONS_MENU_PATH,
+ actionname, actionname,
+ GTK_UI_MANAGER_MENUITEM, FALSE);
- gtk_toggle_action_set_active (action, entrystate);
- g_signal_connect (action, "toggled",
- G_CALLBACK (option_cb), window);
-
- gtk_action_group_add_action (priv->options_group, GTK_ACTION (action));
- g_object_unref (action);
-
- gtk_ui_manager_add_ui (priv->ui_manager,
- priv->options_merge_id,
- OPTIONS_MENU_PATH,
- actionname, actionname,
- GTK_UI_MANAGER_MENUITEM, FALSE);
- } else {
- /* If we encounter an atom, change the mode. What the atom is doesn't
- * really matter. */
- if (mode == OPTION_CHECKMENU) {
- mode = OPTION_RADIOMENU;
- radiogroup = NULL; /* Start a new radio group. */
- } else {
- mode = OPTION_CHECKMENU;
- }
- }
+ aisleriot_game_option_free (option);
}
+
+ g_list_free (options);
}
/* The "Recent Games" menu */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]