[glib] Simplify/fix state logic in GAction, test it.
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Simplify/fix state logic in GAction, test it.
- Date: Sat, 21 Aug 2010 21:35:46 +0000 (UTC)
commit 5b38bc5ad5181bb4900c1da898b2e4fcdcec1757
Author: Ryan Lortie <desrt desrt ca>
Date: Sat Aug 21 17:35:32 2010 -0400
Simplify/fix state logic in GAction, test it.
gio/gaction.c | 55 ++++++++++++++++++++++++++++++++------------------
gio/tests/actions.c | 35 ++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 20 deletions(-)
---
diff --git a/gio/gaction.c b/gio/gaction.c
index a01b2dd..a7ed5f4 100644
--- a/gio/gaction.c
+++ b/gio/gaction.c
@@ -67,9 +67,8 @@ struct _GActionPrivate
{
gchar *name;
GVariantType *parameter_type;
- gboolean enabled;
-
- GVariantType *state_type;
+ guint enabled : 1;
+ guint state_set : 1;
GVariant *state;
};
@@ -137,14 +136,29 @@ g_action_set_property (GObject *object, guint prop_id,
g_action_set_enabled (action, g_value_get_boolean (value));
break;
- case PROP_STATE_TYPE:
- g_assert (action->priv->state_type == NULL);
- action->priv->state_type = g_value_dup_boxed (value);
- break;
-
case PROP_STATE:
- if (g_value_get_variant (value))
+ /* PROP_STATE is marked as G_PARAM_CONSTRUCT so we always get a
+ * call during object construction, even if it is NULL. We treat
+ * that first call differently, for a number of reasons.
+ *
+ * First, we don't want the value to be rejected by the
+ * possibly-overridden .set_state() function. Second, we don't
+ * want to be tripped by the assertions in g_action_set_state()
+ * that would enforce the catch22 that we only provide a value of
+ * the same type as the existing value (when there is not yet an
+ * existing value).
+ */
+ if (action->priv->state_set)
g_action_set_state (action, g_value_get_variant (value));
+
+ else /* this is the special case */
+ {
+ /* only do it the first time. */
+ action->priv->state_set = TRUE;
+
+ /* blindly set it. */
+ action->priv->state = g_value_dup_variant (value);
+ }
break;
default:
@@ -193,8 +207,6 @@ g_action_finalize (GObject *object)
g_free (action->priv->name);
if (action->priv->parameter_type)
g_variant_type_free (action->priv->parameter_type);
- if (action->priv->state_type)
- g_variant_type_free (action->priv->state_type);
if (action->priv->state)
g_variant_unref (action->priv->state);
@@ -310,8 +322,7 @@ g_action_class_init (GActionClass *class)
P_("State Type"),
P_("The type of the state kept by the action"),
G_TYPE_VARIANT_TYPE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
@@ -354,9 +365,13 @@ void
g_action_set_state (GAction *action,
GVariant *value)
{
+ const GVariantType *state_type;
+
g_return_if_fail (G_IS_ACTION (action));
- g_return_if_fail ((action->priv->state_type == NULL && value == NULL) ||
- g_variant_is_of_type (value, action->priv->state_type));
+ g_return_if_fail (value != NULL);
+ state_type = g_action_get_state_type (action);
+ g_return_if_fail (state_type != NULL);
+ g_return_if_fail (g_variant_is_of_type (value, state_type));
g_variant_ref_sink (value);
@@ -377,10 +392,7 @@ g_action_set_state (GAction *action,
* action is stateful then the type of the return value is the type
* given by g_action_get_state_type().
*
- * The return value (if non-%NULL) should be freed with
- * g_variant_unref() when it is no longer required.
- *
- * Returns: (allow-none): the current state of the action
+ * Returns: (allow-none) (transfer none): the current state of the action
*
* Since: 2.26
**/
@@ -461,7 +473,10 @@ g_action_get_state_type (GAction *action)
{
g_return_val_if_fail (G_IS_ACTION (action), NULL);
- return action->priv->state_type;
+ if (action->priv->state != NULL)
+ return g_variant_get_type (action->priv->state);
+ else
+ return NULL;
}
/**
diff --git a/gio/tests/actions.c b/gio/tests/actions.c
index 9d24da0..d6baf63 100644
--- a/gio/tests/actions.c
+++ b/gio/tests/actions.c
@@ -96,6 +96,40 @@ test_simple_group (void)
g_assert (!a.did_run);
}
+static void
+test_stateful (void)
+{
+ GAction *action;
+
+ action = g_action_new_stateful ("foo", NULL, g_variant_new_string ("hihi"));
+ g_assert (g_variant_type_equal (g_action_get_state_type (action),
+ G_VARIANT_TYPE_STRING));
+ g_assert_cmpstr (g_variant_get_string (g_action_get_state (action), NULL),
+ ==, "hihi");
+
+ if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+ {
+ g_action_set_state (action, g_variant_new_int32 (123));
+ exit (0);
+ }
+ g_test_trap_assert_failed ();
+
+ g_action_set_state (action, g_variant_new_string ("hello"));
+ g_assert_cmpstr (g_variant_get_string (g_action_get_state (action), NULL),
+ ==, "hello");
+
+ g_object_unref (action);
+
+ action = g_action_new ("foo", NULL);
+ if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+ {
+ g_action_set_state (action, g_variant_new_int32 (123));
+ exit (0);
+ }
+ g_test_trap_assert_failed ();
+ g_object_unref (action);
+}
+
int
main (int argc, char **argv)
{
@@ -104,6 +138,7 @@ main (int argc, char **argv)
g_test_add_func ("/actions/basic", test_basic);
g_test_add_func ("/actions/simplegroup", test_simple_group);
+ g_test_add_func ("/actions/stateful", test_stateful);
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]