mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-09-27 17:52:58 +02:00
Simplify/fix state logic in GAction, test it.
This commit is contained in:
@@ -67,9 +67,8 @@ struct _GActionPrivate
|
|||||||
{
|
{
|
||||||
gchar *name;
|
gchar *name;
|
||||||
GVariantType *parameter_type;
|
GVariantType *parameter_type;
|
||||||
gboolean enabled;
|
guint enabled : 1;
|
||||||
|
guint state_set : 1;
|
||||||
GVariantType *state_type;
|
|
||||||
GVariant *state;
|
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));
|
g_action_set_enabled (action, g_value_get_boolean (value));
|
||||||
break;
|
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:
|
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));
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -193,8 +207,6 @@ g_action_finalize (GObject *object)
|
|||||||
g_free (action->priv->name);
|
g_free (action->priv->name);
|
||||||
if (action->priv->parameter_type)
|
if (action->priv->parameter_type)
|
||||||
g_variant_type_free (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)
|
if (action->priv->state)
|
||||||
g_variant_unref (action->priv->state);
|
g_variant_unref (action->priv->state);
|
||||||
|
|
||||||
@@ -310,8 +322,7 @@ g_action_class_init (GActionClass *class)
|
|||||||
P_("State Type"),
|
P_("State Type"),
|
||||||
P_("The type of the state kept by the action"),
|
P_("The type of the state kept by the action"),
|
||||||
G_TYPE_VARIANT_TYPE,
|
G_TYPE_VARIANT_TYPE,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_CONSTRUCT_ONLY |
|
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -354,9 +365,13 @@ void
|
|||||||
g_action_set_state (GAction *action,
|
g_action_set_state (GAction *action,
|
||||||
GVariant *value)
|
GVariant *value)
|
||||||
{
|
{
|
||||||
|
const GVariantType *state_type;
|
||||||
|
|
||||||
g_return_if_fail (G_IS_ACTION (action));
|
g_return_if_fail (G_IS_ACTION (action));
|
||||||
g_return_if_fail ((action->priv->state_type == NULL && value == NULL) ||
|
g_return_if_fail (value != NULL);
|
||||||
g_variant_is_of_type (value, action->priv->state_type));
|
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);
|
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
|
* action is stateful then the type of the return value is the type
|
||||||
* given by g_action_get_state_type().
|
* given by g_action_get_state_type().
|
||||||
*
|
*
|
||||||
* The return value (if non-%NULL) should be freed with
|
* Returns: (allow-none) (transfer none): the current state of the action
|
||||||
* g_variant_unref() when it is no longer required.
|
|
||||||
*
|
|
||||||
* Returns: (allow-none): the current state of the action
|
|
||||||
*
|
*
|
||||||
* Since: 2.26
|
* Since: 2.26
|
||||||
**/
|
**/
|
||||||
@@ -461,7 +473,10 @@ g_action_get_state_type (GAction *action)
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (G_IS_ACTION (action), NULL);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -96,6 +96,40 @@ test_simple_group (void)
|
|||||||
g_assert (!a.did_run);
|
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
|
int
|
||||||
main (int argc, char **argv)
|
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/basic", test_basic);
|
||||||
g_test_add_func ("/actions/simplegroup", test_simple_group);
|
g_test_add_func ("/actions/simplegroup", test_simple_group);
|
||||||
|
g_test_add_func ("/actions/stateful", test_stateful);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user