[gjs] param: Implement property lookup for ParamSpecs
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] param: Implement property lookup for ParamSpecs
- Date: Thu, 15 Dec 2011 22:17:27 +0000 (UTC)
commit 378ff475f1510192974c72709c2cdd9844de85e1
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Wed Nov 30 12:59:31 2011 -0500
param: Implement property lookup for ParamSpecs
https://bugzilla.gnome.org/show_bug.cgi?id=665432
gi/param.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 68 insertions(+), 15 deletions(-)
---
diff --git a/gi/param.c b/gi/param.c
index 5c8c58d..9b67140 100644
--- a/gi/param.c
+++ b/gi/param.c
@@ -26,6 +26,7 @@
#include <string.h>
#include "param.h"
+#include "arg.h"
#include "repo.h"
#include <gjs/gjs-module.h>
#include <gjs/compat.h>
@@ -42,6 +43,26 @@ static struct JSClass gjs_param_class;
GJS_DEFINE_DYNAMIC_PRIV_FROM_JS(Param, gjs_param_class)
+static GIFieldInfo *
+find_field_info(GIObjectInfo *info,
+ gchar *name)
+{
+ int i;
+ GIFieldInfo *field_info;
+
+ /* GParamSpecs aren't very big. We could optimize this so that it isn't
+ * O(N), but for the biggest GParamSpec, N=5, so it doesn't really matter. */
+ for (i = 0; i < g_object_info_get_n_fields((GIObjectInfo*)info); i++) {
+ field_info = g_object_info_get_field((GIObjectInfo*)info, i);
+ if (g_str_equal(name, g_base_info_get_name((GIBaseInfo*)field_info)))
+ return field_info;
+
+ g_base_info_unref((GIBaseInfo*)field_info);
+ }
+
+ return NULL;
+}
+
/* a hook on getting a property; set value_p to override property's value.
* Return value is JS_FALSE on OOM/exception.
*/
@@ -51,38 +72,70 @@ param_get_prop(JSContext *context,
jsid id,
jsval *value_p)
{
+ JSBool success;
Param *priv;
+ GParamSpec *pspec;
char *name;
- const char *value_str;
+ GType gtype;
+ GIObjectInfo *info, *parent_info;
+ GIFieldInfo *field_info = NULL;
+ GITypeInfo *type_info = NULL;
+ GIArgument arg;
if (!gjs_get_string_id(context, id, &name))
return JS_TRUE; /* not something we affect, but no error */
priv = priv_from_js(context, obj);
- gjs_debug_jsprop(GJS_DEBUG_GPARAM,
- "Get prop '%s' hook obj %p priv %p", name, obj, priv);
-
if (priv == NULL) {
g_free(name);
return JS_FALSE; /* wrong class */
}
- value_str = NULL;
- if (strcmp(name, "name") == 0)
- value_str = g_param_spec_get_name(priv->gparam);
- else if (strcmp(name, "nick") == 0)
- value_str = g_param_spec_get_nick(priv->gparam);
- else if (strcmp(name, "blurb") == 0)
- value_str = g_param_spec_get_blurb(priv->gparam);
+ success = JS_FALSE;
+ pspec = priv->gparam;
- g_free(name);
+ gtype = G_TYPE_FROM_INSTANCE(pspec);
+ info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), gtype);
+ parent_info = g_object_info_get_parent(info);
+
+ field_info = find_field_info(info, name);
- if (value_str != NULL) {
- *value_p = STRING_TO_JSVAL(JS_NewStringCopyZ(context, value_str));
+ if (field_info == NULL) {
+ /* Try it on the parent GParamSpec for generic GParamSpec properties. */
+ field_info = find_field_info(parent_info, name);
}
- return JS_TRUE;
+ if (field_info == NULL) {
+ *value_p = JSVAL_VOID;
+ success = JS_TRUE;
+ goto out;
+ }
+
+ type_info = g_field_info_get_type(field_info);
+
+ if (!g_field_info_get_field(field_info, priv->gparam, &arg)) {
+ gjs_throw(context, "Reading field %s.%s is not supported",
+ g_base_info_get_name(info),
+ g_base_info_get_name((GIBaseInfo*)field_info));
+ goto out;
+ }
+
+ if (!gjs_value_from_g_argument(context, value_p, type_info, &arg))
+ goto out;
+
+ success = JS_TRUE;
+
+ out:
+ if (field_info != NULL)
+ g_base_info_unref((GIBaseInfo*)field_info);
+ if (type_info != NULL)
+ g_base_info_unref((GIBaseInfo*)type_info);
+ g_base_info_unref((GIBaseInfo*)info);
+ g_base_info_unref((GIBaseInfo*)parent_info);
+ g_free(name);
+
+ return success;
}
GJS_NATIVE_CONSTRUCTOR_DECLARE(param)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]