script: Allow resolving signals states added from code
Currently, defining states for object signals can only be done by defining a ClutterState inside the ClutterScript definition. We should allow creating a (named) ClutterState in code, and associating it to a ClutterScript instance — and have the Script resolve the "state" field of a signal definition correctly.
This commit is contained in:
parent
e745ce52e7
commit
29d7c5a297
@ -592,20 +592,11 @@ parse_signals (ClutterScript *script,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mandatory: "state" */
|
/* mandatory: "target-state" or "handler" */
|
||||||
if (json_object_has_member (object, "state"))
|
if (json_object_has_member (object, "target-state"))
|
||||||
{
|
{
|
||||||
const gchar *state;
|
const gchar *state = NULL;
|
||||||
const gchar *target;
|
const gchar *target = NULL;
|
||||||
|
|
||||||
state = json_object_get_string_member (object, "state");
|
|
||||||
if (state == NULL)
|
|
||||||
{
|
|
||||||
_clutter_script_warn_invalid_value (script,
|
|
||||||
"state", "string",
|
|
||||||
val);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
target = json_object_get_string_member (object, "target-state");
|
target = json_object_get_string_member (object, "target-state");
|
||||||
if (target == NULL)
|
if (target == NULL)
|
||||||
@ -616,10 +607,13 @@ parse_signals (ClutterScript *script,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (json_object_has_member (object, "state"))
|
||||||
|
state = json_object_get_string_member (object, "state");
|
||||||
|
|
||||||
CLUTTER_NOTE (SCRIPT,
|
CLUTTER_NOTE (SCRIPT,
|
||||||
"Added signal '%s' (state:%s, target:%s)",
|
"Added signal '%s' (state:%s, target:%s)",
|
||||||
name,
|
name,
|
||||||
state, target);
|
state != NULL ? state : "<default>", target);
|
||||||
|
|
||||||
sinfo = g_slice_new0 (SignalInfo);
|
sinfo = g_slice_new0 (SignalInfo);
|
||||||
sinfo->is_handler = FALSE;
|
sinfo->is_handler = FALSE;
|
||||||
@ -627,9 +621,7 @@ parse_signals (ClutterScript *script,
|
|||||||
sinfo->state = g_strdup (state);
|
sinfo->state = g_strdup (state);
|
||||||
sinfo->target = g_strdup (target);
|
sinfo->target = g_strdup (target);
|
||||||
}
|
}
|
||||||
|
else if (json_object_has_member (object, "handler"))
|
||||||
/* mandatory: "handler" */
|
|
||||||
if (json_object_has_member (object, "handler"))
|
|
||||||
{
|
{
|
||||||
const gchar *handler;
|
const gchar *handler;
|
||||||
const gchar *connect;
|
const gchar *connect;
|
||||||
@ -676,13 +668,12 @@ parse_signals (ClutterScript *script,
|
|||||||
sinfo->object = g_strdup (connect);
|
sinfo->object = g_strdup (connect);
|
||||||
sinfo->flags = flags;
|
sinfo->flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sinfo != NULL)
|
|
||||||
retval = g_list_prepend (retval, sinfo);
|
|
||||||
else
|
else
|
||||||
_clutter_script_warn_missing_attribute (script,
|
_clutter_script_warn_missing_attribute (script,
|
||||||
NULL,
|
NULL,
|
||||||
"handler or state");
|
"handler or state");
|
||||||
|
if (sinfo != NULL)
|
||||||
|
retval = g_list_prepend (retval, sinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -231,6 +231,8 @@ struct _ClutterScriptPrivate
|
|||||||
|
|
||||||
ClutterScriptParser *parser;
|
ClutterScriptParser *parser;
|
||||||
|
|
||||||
|
GHashTable *states;
|
||||||
|
|
||||||
gchar **search_paths;
|
gchar **search_paths;
|
||||||
|
|
||||||
gchar *filename;
|
gchar *filename;
|
||||||
@ -337,6 +339,7 @@ clutter_script_finalize (GObject *gobject)
|
|||||||
g_hash_table_destroy (priv->objects);
|
g_hash_table_destroy (priv->objects);
|
||||||
g_strfreev (priv->search_paths);
|
g_strfreev (priv->search_paths);
|
||||||
g_free (priv->filename);
|
g_free (priv->filename);
|
||||||
|
g_hash_table_destroy (priv->states);
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_script_parent_class)->finalize (gobject);
|
G_OBJECT_CLASS (clutter_script_parent_class)->finalize (gobject);
|
||||||
}
|
}
|
||||||
@ -427,6 +430,9 @@ clutter_script_init (ClutterScript *script)
|
|||||||
priv->objects = g_hash_table_new_full (g_str_hash, g_str_equal,
|
priv->objects = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
NULL,
|
NULL,
|
||||||
object_info_free);
|
object_info_free);
|
||||||
|
priv->states = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
g_free,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -987,14 +993,22 @@ connect_each_object (gpointer key,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GObject *state_object;
|
GObject *state_object = NULL;
|
||||||
const gchar *signal_name, *signal_detail;
|
const gchar *signal_name, *signal_detail;
|
||||||
gchar **components;
|
gchar **components;
|
||||||
GQuark signal_quark;
|
GQuark signal_quark;
|
||||||
guint signal_id;
|
guint signal_id;
|
||||||
HookData *hook_data;
|
HookData *hook_data;
|
||||||
|
|
||||||
state_object = clutter_script_get_object (script, sinfo->state);
|
if (sinfo->state == NULL)
|
||||||
|
state_object = (GObject *) clutter_script_get_state (script, NULL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state_object = clutter_script_get_object (script, sinfo->state);
|
||||||
|
if (state_object == NULL)
|
||||||
|
state_object = (GObject *) clutter_script_get_state (script, sinfo->state);
|
||||||
|
}
|
||||||
|
|
||||||
if (state_object == NULL)
|
if (state_object == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1254,6 +1268,66 @@ clutter_script_list_objects (ClutterScript *script)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_script_add_state:
|
||||||
|
* @script: a #ClutterScript
|
||||||
|
* @state_name: (allow-none): a name for the @state, or %NULL to
|
||||||
|
* set the default #ClutterState
|
||||||
|
*
|
||||||
|
* Adds a #ClutterState using the given name to the #ClutterScript instance.
|
||||||
|
*
|
||||||
|
* The #ClutterScript instance will use @state to resolve target states when
|
||||||
|
* connecting signal handlers.
|
||||||
|
*
|
||||||
|
* The #ClutterScript instance will take a reference on the #ClutterState
|
||||||
|
* passed to this function.
|
||||||
|
*
|
||||||
|
* Since: 1.8
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_script_add_state (ClutterScript *script,
|
||||||
|
const gchar *state_name,
|
||||||
|
ClutterState *state)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_SCRIPT (script));
|
||||||
|
g_return_if_fail (CLUTTER_IS_STATE (state));
|
||||||
|
|
||||||
|
if (state_name == NULL || *state_name == '\0')
|
||||||
|
state_name = "__clutter_script_default_state";
|
||||||
|
|
||||||
|
g_hash_table_replace (script->priv->states,
|
||||||
|
g_strdup (state_name),
|
||||||
|
g_object_ref (state));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_script_get_state:
|
||||||
|
* @script: a #ClutterScript
|
||||||
|
* @state_name: (allow-none): the name of the #ClutterState, or %NULL
|
||||||
|
*
|
||||||
|
* Retrieves the #ClutterState for the given @state_name.
|
||||||
|
*
|
||||||
|
* If @state_name is %NULL, this function will return the default
|
||||||
|
* #ClutterState instance.
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): a pointer to the #ClutterState for the
|
||||||
|
* given name. The #ClutterState is owned by the #ClutterScript instance
|
||||||
|
* and it should not be unreferenced
|
||||||
|
*
|
||||||
|
* Since: 1.8
|
||||||
|
*/
|
||||||
|
ClutterState *
|
||||||
|
clutter_script_get_state (ClutterScript *script,
|
||||||
|
const gchar *state_name)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), NULL);
|
||||||
|
|
||||||
|
if (state_name == NULL || *state_name == '\0')
|
||||||
|
state_name = "__clutter_script_default_state";
|
||||||
|
|
||||||
|
return g_hash_table_lookup (script->priv->states, state_name);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _clutter_script_generate_fake_id:
|
* _clutter_script_generate_fake_id:
|
||||||
* @script: a #ClutterScript
|
* @script: a #ClutterScript
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
#ifndef __CLUTTER_SCRIPT_H__
|
#ifndef __CLUTTER_SCRIPT_H__
|
||||||
#define __CLUTTER_SCRIPT_H__
|
#define __CLUTTER_SCRIPT_H__
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <clutter/clutter-types.h>
|
||||||
|
#include <clutter/clutter-state.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -143,44 +144,48 @@ struct _ClutterScriptClass
|
|||||||
void (*_clutter_reserved8) (void);
|
void (*_clutter_reserved8) (void);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_script_get_type (void) G_GNUC_CONST;
|
GType clutter_script_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
ClutterScript *clutter_script_new (void);
|
ClutterScript * clutter_script_new (void);
|
||||||
guint clutter_script_load_from_file (ClutterScript *script,
|
guint clutter_script_load_from_file (ClutterScript *script,
|
||||||
const gchar *filename,
|
const gchar *filename,
|
||||||
GError **error);
|
GError **error);
|
||||||
guint clutter_script_load_from_data (ClutterScript *script,
|
guint clutter_script_load_from_data (ClutterScript *script,
|
||||||
const gchar *data,
|
const gchar *data,
|
||||||
gssize length,
|
gssize length,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
GObject * clutter_script_get_object (ClutterScript *script,
|
GObject * clutter_script_get_object (ClutterScript *script,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
gint clutter_script_get_objects (ClutterScript *script,
|
gint clutter_script_get_objects (ClutterScript *script,
|
||||||
const gchar *first_name,
|
const gchar *first_name,
|
||||||
...) G_GNUC_NULL_TERMINATED;
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
GList * clutter_script_list_objects (ClutterScript *script);
|
GList * clutter_script_list_objects (ClutterScript *script);
|
||||||
|
void clutter_script_unmerge_objects (ClutterScript *script,
|
||||||
|
guint merge_id);
|
||||||
|
void clutter_script_ensure_objects (ClutterScript *script);
|
||||||
|
|
||||||
void clutter_script_unmerge_objects (ClutterScript *script,
|
void clutter_script_add_state (ClutterScript *script,
|
||||||
guint merge_id);
|
const gchar *state_name,
|
||||||
void clutter_script_ensure_objects (ClutterScript *script);
|
ClutterState *state);
|
||||||
|
ClutterState * clutter_script_get_state (ClutterScript *script,
|
||||||
|
const gchar *state_name);
|
||||||
|
|
||||||
GType clutter_script_get_type_from_name (ClutterScript *script,
|
void clutter_script_connect_signals (ClutterScript *script,
|
||||||
const gchar *type_name);
|
gpointer user_data);
|
||||||
|
void clutter_script_connect_signals_full (ClutterScript *script,
|
||||||
|
ClutterScriptConnectFunc func,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
const gchar * clutter_get_script_id (GObject *gobject);
|
void clutter_script_add_search_paths (ClutterScript *script,
|
||||||
|
const gchar * const paths[],
|
||||||
|
gsize n_paths);
|
||||||
|
gchar * clutter_script_lookup_filename (ClutterScript *script,
|
||||||
|
const gchar *filename) G_GNUC_MALLOC;
|
||||||
|
GType clutter_script_get_type_from_name (ClutterScript *script,
|
||||||
|
const gchar *type_name);
|
||||||
|
|
||||||
void clutter_script_connect_signals (ClutterScript *script,
|
const gchar * clutter_get_script_id (GObject *gobject);
|
||||||
gpointer user_data);
|
|
||||||
void clutter_script_connect_signals_full (ClutterScript *script,
|
|
||||||
ClutterScriptConnectFunc func,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
void clutter_script_add_search_paths (ClutterScript *script,
|
|
||||||
const gchar * const paths[],
|
|
||||||
gsize n_paths);
|
|
||||||
gchar * clutter_script_lookup_filename (ClutterScript *script,
|
|
||||||
const gchar *filename) G_GNUC_MALLOC;
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user