[perl-Glib-Object-Introspection] Add support for calling functions on structs
- From: Torsten SchÃnfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib-Object-Introspection] Add support for calling functions on structs
- Date: Wed, 17 Aug 2011 21:50:33 +0000 (UTC)
commit 2019f43a13b4e8f5607d0b9aa9dafdb857671454
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date: Wed Aug 17 23:14:54 2011 +0200
Add support for calling functions on structs
GObjectIntrospection.xs | 54 +++++++++++++++++++++++++++++-----------------
t/structs.t | 27 +++++++++++++++++++++++
2 files changed, 61 insertions(+), 20 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index 59341a7..7bb2706 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -586,6 +586,7 @@ sv_to_struct (GITransfer transfer,
switch (transfer) {
case GI_TRANSFER_EVERYTHING:
field_transfer = GI_TRANSFER_EVERYTHING;
+ /* fall through */
case GI_TRANSFER_CONTAINER:
/* FIXME: What if there's a special allocator for the record?
* Like GSlice? */
@@ -1105,7 +1106,6 @@ sv_to_interface (GIArgInfo * arg_info,
{
GIBaseInfo *interface;
GIInfoType info_type;
- GITransfer transfer;
interface = g_type_info_get_interface (type_info);
if (!interface)
@@ -1115,8 +1115,6 @@ sv_to_interface (GIArgInfo * arg_info,
dwarn (" interface %p (%s) of type %d\n",
interface, g_base_info_get_name (interface), info_type);
- transfer = g_arg_info_get_ownership_transfer (arg_info);
-
switch (info_type) {
case GI_INFO_TYPE_OBJECT:
case GI_INFO_TYPE_INTERFACE:
@@ -1132,6 +1130,8 @@ sv_to_interface (GIArgInfo * arg_info,
GType type = g_registered_type_info_get_g_type (
(GIRegisteredTypeInfo *) interface);
if (!type || type == G_TYPE_NONE) {
+ GITransfer transfer =
+ g_arg_info_get_ownership_transfer (arg_info);
dwarn (" unboxed type\n");
arg->v_pointer = sv_to_struct (transfer,
interface,
@@ -1262,6 +1262,8 @@ instance_sv_to_pointer (GIFunctionInfo *function_info, SV *sv)
GIInfoType info_type = g_base_info_get_type (container);
gpointer pointer = NULL;
+ /* FIXME: Much of this code is duplicated in sv_to_interface. */
+
dwarn (" instance_sv_to_pointer: container name: %s, info type: %d\n",
g_base_info_get_name (container),
info_type);
@@ -1279,7 +1281,17 @@ instance_sv_to_pointer (GIFunctionInfo *function_info, SV *sv)
{
GType type = g_registered_type_info_get_g_type (
(GIRegisteredTypeInfo *) container);
- pointer = gperl_get_boxed_check (sv, type);
+ if (!type || type == G_TYPE_NONE) {
+ dwarn (" unboxed type\n");
+ pointer = sv_to_struct (GI_TRANSFER_NOTHING,
+ container,
+ info_type,
+ sv);
+ } else {
+ dwarn (" boxed type: %s (%d)\n",
+ g_type_name (type), type);
+ pointer = gperl_get_boxed_check (sv, type);
+ }
dwarn (" -> boxed pointer: %p\n", pointer);
break;
}
@@ -2296,6 +2308,8 @@ _register_types (class, namespace, package)
info_type = g_base_info_get_type (info);
name = g_base_info_get_name (info);
+ dwarn ("setting up %s.%s\n", namespace, name);
+
if (info_type == GI_INFO_TYPE_CONSTANT) {
av_push (constants, newSVpv (name, PL_na));
}
@@ -2316,22 +2330,6 @@ _register_types (class, namespace, package)
continue;
}
- type = g_registered_type_info_get_g_type (
- (GIRegisteredTypeInfo *) info);
- if (!type) {
- ccroak ("Could not find GType for type %s::%s",
- namespace, name);
- }
- if (type == G_TYPE_NONE) {
- g_base_info_unref ((GIBaseInfo *) info);
- continue;
- }
-
- full_package = g_strconcat (package, "::", name, NULL);
- dwarn ("registering %s, %d => %s\n",
- g_type_name (type), type,
- full_package);
-
if (info_type == GI_INFO_TYPE_OBJECT ||
info_type == GI_INFO_TYPE_INTERFACE ||
info_type == GI_INFO_TYPE_BOXED ||
@@ -2348,6 +2346,20 @@ _register_types (class, namespace, package)
store_fields (fields, info, info_type);
}
+ type = g_registered_type_info_get_g_type (
+ (GIRegisteredTypeInfo *) info);
+ if (!type) {
+ ccroak ("Could not find GType for type %s::%s",
+ namespace, name);
+ }
+ if (type == G_TYPE_NONE) {
+ g_base_info_unref ((GIBaseInfo *) info);
+ continue;
+ }
+
+ full_package = g_strconcat (package, "::", name, NULL);
+ dwarn (" registering as %s\n", full_package);
+
switch (info_type) {
case GI_INFO_TYPE_OBJECT:
case GI_INFO_TYPE_INTERFACE:
@@ -2552,6 +2564,8 @@ _invoke (class, basename, namespace, method, ...)
g_type_tag_to_string (g_type_info_get_tag (arg_type)),
iinfo.is_automatic_arg[i]);
+ /* FIXME: Check g_arg_info_is_caller_allocates. */
+
/* FIXME: Check that i+method_offset+stack_offset<items before
* calling ST, and generate a usage message otherwise. */
switch (g_arg_info_get_direction (arg_info)) {
diff --git a/t/structs.t b/t/structs.t
new file mode 100644
index 0000000..b865b1e
--- /dev/null
+++ b/t/structs.t
@@ -0,0 +1,27 @@
+#!/usr/bin/env perl
+
+BEGIN { require './t/inc/setup.pl' };
+
+use strict;
+use warnings;
+
+plan tests => 4;
+
+{
+ my $expected_struct = {long_ => 6, int8 => 7};
+ my $struct = GI::SimpleStruct::returnv ();
+ is_deeply ($struct, $expected_struct);
+ GI::SimpleStruct::inv ($struct);
+ GI::SimpleStruct::method ($struct);
+ undef $struct;
+ is_deeply (GI::SimpleStruct::returnv (), $expected_struct);
+}
+
+{
+ my $expected_struct = {long_ => 42};
+ my $struct = GI::PointerStruct::returnv ();
+ is_deeply ($struct, $expected_struct);
+ GI::PointerStruct::inv ($struct);
+ undef $struct;
+ is_deeply (GI::PointerStruct::returnv (), $expected_struct);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]