this might be of help too, at least gvalue_to_neko is used in the
mashaller code i sent you:
#define error(msg,...) \
raise_exception( msg, __FILE__, __LINE__, __VA_ARGS__ );
DEFINE_KIND(k_GObject);
void raise_exception( const char *msg, const char *file, int line, ... )
{
buffer b = alloc_buffer("");
buffer_append(b,msg);
_neko_failure( buffer_to_string(b), file, line );
}
/* --------------------------------------------------
Helper
-------------------------------------------------- */
GObject *val_gobject( value obj ) {
if( !val_is_abstract(obj) || !val_is_kind( obj, k_GObject ) ) {
error("not a GObject",obj);
return NULL;
}
GObject *o = (GObject*)val_data(obj);
if( !o ) {
error("GObject is null",obj);
return NULL;
}
return o;
}
value alloc_gobject( GObject * o ) {
return alloc_abstract( k_GObject, o );
}
/* get string from value (even if it is a HaXe String) */
const char *haxe_string( value s ) {
if( val_is_string(s) ) {
return val_string(s);
} else if( val_is_object(s) ) {
value v = val_field(s,val_id("__s"));
return haxe_string(v);
} else {
error("not a string",s);
return NULL;
}
}
/* convert GValue to neko value */
value gvalue_to_neko( const GValue *gv ) {
switch( G_VALUE_TYPE(gv) ) {
case G_TYPE_STRING:
return alloc_string( g_value_get_string(gv) );
case G_TYPE_BOOLEAN:
return alloc_bool( g_value_get_boolean(gv) );
case G_TYPE_INT:
return alloc_int( g_value_get_int(gv) );
case G_TYPE_FLOAT:
return alloc_float( g_value_get_float(gv) );
default:
if( g_type_is_a( G_VALUE_TYPE(gv), G_TYPE_OBJECT ) ) {
return alloc_gobject( g_value_get_object(gv) );
} else {
//error("cannot convert GValue to neko
value.",val_null);
// printf("WARNING: cannot convert GValue (type %s) to
neko.\n", g_type_name( G_VALUE_TYPE(gv) ) );
return val_null;
}
}
}
/* convert neko value to GValue*/
void neko_to_gvalue( value v, GValue *gv ) {
value s;
if( val_is_null(v) ) {
g_value_init( gv, G_TYPE_INT );
g_value_set_int( gv, 0 );
} else if( val_is_int(v) ) {
g_value_init( gv, G_TYPE_INT );
g_value_set_int( gv, val_number(v) );
} else if( val_is_float(v) ) {
g_value_init( gv, G_TYPE_FLOAT );
g_value_set_float( gv, val_number(v) );
} else if( val_is_bool(v) ) {
g_value_init( gv, G_TYPE_BOOLEAN );
g_value_set_boolean( gv, val_bool(v) );
} else if( val_is_string(v) ) {
g_value_init( gv, G_TYPE_STRING );
g_value_set_string( gv, val_string(v) );
} else if( val_is_object(v) ) {
/* see if its a haxe String */
s = val_field(v,val_id("__s"));
if( s == val_null || !val_is_string(s) ) {
error("cannot convert neko object to GValue",v);
return;
}
g_value_init( gv, G_TYPE_STRING );
g_value_set_string( gv, val_string(s) );
/*
} else if( val_is_array(v) ) {
printf("array : size %d",val_array_size(v));
} else if( val_is_function(v) ) {
printf("function : %d args",val_fun_nargs(v));
} else if( val_is_object(v) ) {
printf("object");
} else if( val_is_abstract(v) ) {
printf("abstract of kind %X",val_kind(v));
*/
} else {
error("cannot convert neko value to GValue", v );
}
return;
}
/* --------------------------------------------------
GObject
-------------------------------------------------- */
/* object_get */
value object_get( value obj, value prop ) {
GObject *o = val_gobject( obj );
if( !o ) return val_null;
const char *name = haxe_string(prop);
GParamSpec *spec = g_object_class_find_property(
G_OBJECT_GET_CLASS(o), name );
if( !spec ) {
error("property not found", prop, obj );
return val_null;
}
GValue gv;
memset( &gv, 0, sizeof( gv ) );
g_value_init( &gv, G_PARAM_SPEC_VALUE_TYPE(spec) );
g_object_get_property( o, haxe_string( prop ), &gv );
value result = gvalue_to_neko( &gv );
return result;
}
DEFINE_PRIM(object_get,2);
/* object_set */
value object_set( value obj, value prop, value val ) {
GObject *o = val_gobject( obj );
if( !o ) return val_null;
GValue gv;
memset( &gv, 0, sizeof( gv ) );
neko_to_gvalue( val, &gv );
g_object_set_property( o, haxe_string( prop ), &gv );
return;
}
DEFINE_PRIM(object_set,3);
--
Neko : One VM to run them all
(http://nekovm.org)