From: Jürg Billeter Date: Sun, 21 Dec 2008 12:05:24 +0000 (+0000) Subject: Support boxed structs as GObject properties, based on patch by Étienne X-Git-Tag: VALA_0_5_4~56 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=095db049e0995551f07020cdacc537e999732eae;p=thirdparty%2Fvala.git Support boxed structs as GObject properties, based on patch by Étienne 2008-12-21 Jürg Billeter * vala/valastruct.vala: * gobject/valaccodebasemodule.vala: * gobject/valagobjectmodule.vala: * vapi/glib-2.0.vapi: Support boxed structs as GObject properties, based on patch by Étienne Bersac, fixes bug 520001 svn path=/trunk/; revision=2235 --- diff --git a/ChangeLog b/ChangeLog index 395cb9449..ff281151a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-12-21 Jürg Billeter + + * vala/valastruct.vala: + * gobject/valaccodebasemodule.vala: + * gobject/valagobjectmodule.vala: + * vapi/glib-2.0.vapi: + + Support boxed structs as GObject properties, + based on patch by Étienne Bersac, fixes bug 520001 + 2008-12-21 Jürg Billeter * gobject/valaccodebasemodule.vala: @@ -1219,7 +1229,7 @@ Convert ternary conditionals into if statements, fixes bug 543870 and bug 554594 -2008-11-28 Étienne BERSAC +2008-11-28 Étienne Bersac * vapi/gobject-2.0.vapi: diff --git a/gobject/valaccodebasemodule.vala b/gobject/valaccodebasemodule.vala index 61aa8988b..eb14d6451 100644 --- a/gobject/valaccodebasemodule.vala +++ b/gobject/valaccodebasemodule.vala @@ -1078,19 +1078,6 @@ public class Vala.CCodeBaseModule : CCodeModule { next_temp_var_id = old_next_temp_var_id; variable_name_map = old_variable_name_map; - - var cl = prop.parent_symbol as Class; - if (cl != null && cl.is_subtype_of (gobject_type) - && prop.binding == MemberBinding.INSTANCE) { - // GObject property - // FIXME: omit real struct types for now since they - // cannot be expressed as gobject property yet - // don't register private properties - if (!prop.property_type.is_real_struct_type () - && prop.access != SymbolAccessibility.PRIVATE) { - prop_enum.add_value (new CCodeEnumValue (prop.get_upper_case_cname ())); - } - } } public override void visit_property_accessor (PropertyAccessor acc) { diff --git a/gobject/valagobjectmodule.vala b/gobject/valagobjectmodule.vala index 3952bf238..c3e8de1b9 100644 --- a/gobject/valagobjectmodule.vala +++ b/gobject/valagobjectmodule.vala @@ -946,15 +946,16 @@ public class Vala.GObjectModule : GTypeModule { /* create properties */ var props = cl.get_properties (); foreach (Property prop in props) { - // FIXME: omit real struct types for now since they cannot be expressed as gobject property yet - if (prop.property_type.is_real_struct_type ()) { - continue; - } if (prop.access == SymbolAccessibility.PRIVATE) { // don't register private properties continue; } + var st = prop.property_type.data_type as Struct; + if (st != null && !st.has_type_id) { + continue; + } + if (prop.overrides || prop.base_interface_property != null) { var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_override_property")); cinst.add_argument (ccall); @@ -1252,12 +1253,15 @@ public class Vala.GObjectModule : GTypeModule { var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ())); cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall)); block.add_statement (cdecl); - + + cdecl = new CCodeDeclaration ("gpointer"); + cdecl.add_declarator (new CCodeVariableDeclarator ("boxed")); + block.add_statement (cdecl); + var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("property_id")); var props = cl.get_properties (); foreach (Property prop in props) { - // FIXME: omit real struct types for now since they cannot be expressed as gobject property yet - if (prop.get_accessor == null || prop.is_abstract || prop.property_type.is_real_struct_type ()) { + if (prop.get_accessor == null || prop.is_abstract) { continue; } if (prop.access == SymbolAccessibility.PRIVATE) { @@ -1265,6 +1269,11 @@ public class Vala.GObjectModule : GTypeModule { continue; } + var st = prop.property_type.data_type as Struct; + if (st != null && !st.has_type_id) { + continue; + } + string prefix = cl.get_lower_case_cname (null); CCodeExpression cself = new CCodeIdentifier ("self"); if (prop.base_property != null) { @@ -1278,13 +1287,27 @@ public class Vala.GObjectModule : GTypeModule { } cswitch.add_statement (new CCodeCaseStatement (new CCodeIdentifier (prop.get_upper_case_cname ()))); - ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (prefix, prop.name))); - ccall.add_argument (cself); - var csetcall = new CCodeFunctionCall (); - csetcall.call = head.get_value_setter_function (prop.property_type); - csetcall.add_argument (new CCodeIdentifier ("value")); - csetcall.add_argument (ccall); - cswitch.add_statement (new CCodeExpressionStatement (csetcall)); + if (prop.property_type.is_real_struct_type ()) { + var struct_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_new0")); + struct_creation.add_argument (new CCodeIdentifier (st.get_cname ())); + struct_creation.add_argument (new CCodeConstant ("1")); + cswitch.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("boxed"), struct_creation))); + ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (prefix, prop.name))); + ccall.add_argument (cself); + ccall.add_argument (new CCodeIdentifier ("boxed")); + var csetcall = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed")); + csetcall.add_argument (new CCodeIdentifier ("value")); + csetcall.add_argument (new CCodeIdentifier ("boxed")); + cswitch.add_statement (new CCodeExpressionStatement (csetcall)); + } else { + ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (prefix, prop.name))); + ccall.add_argument (cself); + var csetcall = new CCodeFunctionCall (); + csetcall.call = head.get_value_setter_function (prop.property_type); + csetcall.add_argument (new CCodeIdentifier ("value")); + csetcall.add_argument (ccall); + cswitch.add_statement (new CCodeExpressionStatement (csetcall)); + } cswitch.add_statement (new CCodeBreakStatement ()); } cswitch.add_statement (new CCodeLabel ("default")); @@ -1316,8 +1339,7 @@ public class Vala.GObjectModule : GTypeModule { var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("property_id")); var props = cl.get_properties (); foreach (Property prop in props) { - // FIXME: omit real struct types for now since they cannot be expressed as gobject property yet - if (prop.set_accessor == null || prop.is_abstract || prop.property_type.is_real_struct_type ()) { + if (prop.set_accessor == null || prop.is_abstract) { continue; } if (prop.access == SymbolAccessibility.PRIVATE) { @@ -1325,6 +1347,11 @@ public class Vala.GObjectModule : GTypeModule { continue; } + var st = prop.property_type.data_type as Struct; + if (st != null && !st.has_type_id) { + continue; + } + string prefix = cl.get_lower_case_cname (null); CCodeExpression cself = new CCodeIdentifier ("self"); if (prop.base_property != null) { @@ -1417,7 +1444,7 @@ public class Vala.GObjectModule : GTypeModule { if (param_spec_name == null) { cspec.call = new CCodeIdentifier ("g_param_spec_pointer"); } else { - cspec.call = new CCodeIdentifier ( param_spec_name ); + cspec.call = new CCodeIdentifier (param_spec_name); cspec.add_argument (new CCodeIdentifier (prop.property_type.data_type.get_type_id ())); } } else if (prop.property_type.data_type == string_type.data_type) { @@ -1556,7 +1583,8 @@ public class Vala.GObjectModule : GTypeModule { cspec.add_argument (new CCodeConstant ("G_TYPE_NONE")); } } else { - cspec.call = new CCodeIdentifier ("g_param_spec_pointer"); + cspec.call = new CCodeIdentifier ("g_param_spec_boxed"); + cspec.add_argument (new CCodeIdentifier (st.get_type_id ())); } } else { cspec.call = new CCodeIdentifier ("g_param_spec_pointer"); @@ -1873,5 +1901,20 @@ public class Vala.GObjectModule : GTypeModule { block.add_statement (new CCodeExpressionStatement (call)); } + + public override void visit_property (Property prop) { + base.visit_property (prop); + + var cl = prop.parent_symbol as Class; + if (cl != null && cl.is_subtype_of (gobject_type) + && prop.binding == MemberBinding.INSTANCE) { + // GObject property + var st = prop.property_type.data_type as Struct; + if (prop.access != SymbolAccessibility.PRIVATE + && (st == null || st.has_type_id)) { + prop_enum.add_value (new CCodeEnumValue (prop.get_upper_case_cname ())); + } + } + } } diff --git a/vala/valastruct.vala b/vala/valastruct.vala index e623124ff..48a99e713 100644 --- a/vala/valastruct.vala +++ b/vala/valastruct.vala @@ -54,7 +54,12 @@ public class Vala.Struct : TypeSymbol { * Specifies the default construction method. */ public Method default_construction_method { get; set; } - + + /** + * Specifies whether this struct has a registered GType. + */ + public bool has_type_id { get; set; default = true; } + /** * Creates a new struct. * @@ -316,6 +321,9 @@ public class Vala.Struct : TypeSymbol { add_cheader_filename (filename); } } + if (a.has_argument ("has_type_id")) { + has_type_id = a.get_bool ("has_type_id"); + } if (a.has_argument ("type_id")) { set_type_id (a.get_string ("type_id")); } @@ -429,6 +437,8 @@ public class Vala.Struct : TypeSymbol { if (is_simple_type ()) { Report.error (source_reference, "The value type `%s` doesn't declare a GValue get function".printf (get_full_name ())); return null; + } else if (has_type_id) { + return "g_value_get_boxed"; } else { return "g_value_get_pointer"; } @@ -448,6 +458,8 @@ public class Vala.Struct : TypeSymbol { if (is_simple_type ()) { Report.error (source_reference, "The value type `%s` doesn't declare a GValue set function".printf (get_full_name ())); return null; + } else if (has_type_id) { + return "g_value_set_boxed"; } else { return "g_value_set_pointer"; } diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi index de4ab0bdd..5b1123fc2 100644 --- a/vapi/glib-2.0.vapi +++ b/vapi/glib-2.0.vapi @@ -1577,7 +1577,8 @@ namespace GLib { } /* Date and Time Functions */ - + + [CCode (has_type_id = false)] public struct TimeVal { public long tv_sec; public long tv_usec; @@ -1694,7 +1695,7 @@ namespace GLib { public static bool valid_weekday (DateWeekday weekday); } - [CCode (cname = "struct tm", cheader_filename="time.h")] + [CCode (cname = "struct tm", cheader_filename = "time.h", has_type_id = false)] public struct Time { [CCode (cname = "tm_sec")] public int second;