1/* valaclassregisterfunction.vala 2 * 3 * Copyright (C) 2006-2008 Jürg Billeter 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 * Author: 20 * Jürg Billeter <j@bitron.ch> 21 */ 22 23using GLib; 24 25/** 26 * C function to register a class at runtime. 27 */ 28public class Vala.ClassRegisterFunction : TypeRegisterFunction { 29 /** 30 * Specifies the class to be registered. 31 */ 32 public weak Class class_reference { get; set; } 33 34 /** 35 * Creates a new C function to register the specified class at runtime. 36 * 37 * @param cl a class 38 * @return newly created class register function 39 */ 40 public ClassRegisterFunction (Class cl) { 41 class_reference = cl; 42 } 43 44 public override TypeSymbol get_type_declaration () { 45 return class_reference; 46 } 47 48 public override string get_type_struct_name () { 49 return get_ccode_type_name (class_reference); 50 } 51 52 public override string get_base_init_func_name () { 53 if (class_reference.class_constructor != null) { 54 return "%s_base_init".printf (get_ccode_lower_case_name (class_reference, null)); 55 } else { 56 return "NULL"; 57 } 58 } 59 60 public override string get_class_finalize_func_name () { 61 if (class_reference.static_destructor != null) { 62 return "%s_class_finalize".printf (get_ccode_lower_case_name (class_reference, null)); 63 } else { 64 return "NULL"; 65 } 66 } 67 68 public override string get_base_finalize_func_name () { 69 if (class_reference.class_destructor != null) { 70 return "%s_base_finalize".printf (get_ccode_lower_case_name (class_reference, null)); 71 } else { 72 return "NULL"; 73 } 74 } 75 76 public override string get_class_init_func_name () { 77 return "%s_class_init".printf (get_ccode_lower_case_name (class_reference, null)); 78 } 79 80 public override string get_instance_struct_size () { 81 return "sizeof (%s)".printf (get_ccode_name (class_reference)); 82 } 83 84 public override string get_instance_init_func_name () { 85 return "%s_instance_init".printf (get_ccode_lower_case_name (class_reference, null)); 86 } 87 88 public override string get_parent_type_name () { 89 return get_ccode_type_id (class_reference.base_class); 90 } 91 92 public override string get_type_flags () { 93 if (class_reference.is_abstract) { 94 return "G_TYPE_FLAG_ABSTRACT"; 95 } else { 96 return "0"; 97 } 98 } 99 100 public override SymbolAccessibility get_accessibility () { 101 return class_reference.access; 102 } 103 104 public override string? get_gtype_value_table_init_function_name () { 105 bool is_fundamental = !class_reference.is_compact && class_reference.base_class == null; 106 if ( is_fundamental ) 107 return "%s_init".printf (get_ccode_lower_case_name (class_reference, "value_")); 108 109 return null; 110 } 111 112 public override string? get_gtype_value_table_free_function_name () { 113 bool is_fundamental = !class_reference.is_compact && class_reference.base_class == null; 114 if ( is_fundamental ) 115 return "%s_free_value".printf (get_ccode_lower_case_name (class_reference, "value_")); 116 117 return null; 118 } 119 120 public override string? get_gtype_value_table_copy_function_name () { 121 bool is_fundamental = !class_reference.is_compact && class_reference.base_class == null; 122 if ( is_fundamental ) 123 return "%s_copy_value".printf (get_ccode_lower_case_name (class_reference, "value_")); 124 125 return null; 126 } 127 128 public override string? get_gtype_value_table_peek_pointer_function_name () { 129 bool is_fundamental = !class_reference.is_compact && class_reference.base_class == null; 130 if ( is_fundamental ) 131 return "%s_peek_pointer".printf (get_ccode_lower_case_name (class_reference, "value_")); 132 133 return null; 134 } 135 136 public override string? get_gtype_value_table_collect_value_function_name () { 137 bool is_fundamental = !class_reference.is_compact && class_reference.base_class == null; 138 if ( is_fundamental ) 139 return "%s_collect_value".printf (get_ccode_lower_case_name (class_reference, "value_")); 140 141 return null; 142 } 143 144 public override string? get_gtype_value_table_lcopy_value_function_name () { 145 bool is_fundamental = !class_reference.is_compact && class_reference.base_class == null; 146 if ( is_fundamental ) 147 return "%s_lcopy_value".printf (get_ccode_lower_case_name (class_reference, "value_")); 148 149 return null; 150 } 151 152 public override CCodeFragment get_type_interface_init_declaration () { 153 var frag = new CCodeFragment (); 154 155 foreach (DataType base_type in class_reference.get_base_types ()) { 156 if (!(base_type.type_symbol is Interface)) { 157 continue; 158 } 159 160 unowned Interface iface = (Interface) base_type.type_symbol; 161 162 var iface_info_name = "%s_info".printf (get_ccode_lower_case_name (iface, null)); 163 164 var ctypedecl = new CCodeDeclaration ("const GInterfaceInfo"); 165 ctypedecl.modifiers = CCodeModifiers.STATIC; 166 ctypedecl.add_declarator (new CCodeVariableDeclarator (iface_info_name, new CCodeConstant ("{ (GInterfaceInitFunc) %s_%s_interface_init, (GInterfaceFinalizeFunc) NULL, NULL}".printf (get_ccode_lower_case_name (class_reference), get_ccode_lower_case_name (iface))))); 167 frag.append (ctypedecl); 168 } 169 170 return frag; 171 } 172 173 public override void get_type_interface_init_statements (CodeContext context, CCodeBlock block, bool plugin) { 174 foreach (DataType base_type in class_reference.get_base_types ()) { 175 if (!(base_type.type_symbol is Interface)) { 176 continue; 177 } 178 179 unowned Interface iface = (Interface) base_type.type_symbol; 180 181 var iface_info_name = "%s_info".printf (get_ccode_lower_case_name (iface, null)); 182 if (!plugin) { 183 var reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_add_interface_static")); 184 reg_call.add_argument (new CCodeIdentifier ("%s_type_id".printf (get_ccode_lower_case_name (class_reference, null)))); 185 reg_call.add_argument (new CCodeIdentifier (get_ccode_type_id (iface))); 186 reg_call.add_argument (new CCodeIdentifier ("&%s".printf (iface_info_name))); 187 block.add_statement (new CCodeExpressionStatement (reg_call)); 188 } else { 189 var reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_module_add_interface")); 190 reg_call.add_argument (new CCodeIdentifier ("module")); 191 reg_call.add_argument (new CCodeIdentifier ("%s_type_id".printf (get_ccode_lower_case_name (class_reference, null)))); 192 reg_call.add_argument (new CCodeIdentifier (get_ccode_type_id (iface))); 193 reg_call.add_argument (new CCodeIdentifier ("&%s".printf (iface_info_name))); 194 block.add_statement (new CCodeExpressionStatement (reg_call)); 195 } 196 } 197 198 ((CCodeBaseModule) context.codegen).register_dbus_info (block, class_reference); 199 } 200} 201