update for 0.3.3 release
[vala-lang.git] / gobject / valatyperegisterfunction.vala
blob3e81a514603f3144c492cba7641dea6144cf7f4c
1 /* valatyperegisterfunction.vala
3 * Copyright (C) 2006-2007 Jürg Billeter
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.
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.
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
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
23 using GLib;
25 /**
26 * C function to register a type at runtime.
28 public abstract class Vala.TypeRegisterFunction : Object {
29 private CCodeFragment declaration_fragment = new CCodeFragment ();
31 private CCodeFragment definition_fragment = new CCodeFragment ();
33 /**
34 * Constructs the C function from the specified type.
36 public void init_from_type (bool plugin = false) {
37 bool fundamental = false;
38 Class cl = get_type_declaration () as Class;
39 if (cl != null && !cl.is_compact && cl.base_class == null) {
40 fundamental = true;
43 string type_id_name = "%s_type_id".printf (get_type_declaration ().get_lower_case_cname (null));
45 var type_block = new CCodeBlock ();
46 var cdecl = new CCodeDeclaration ("GType");
47 cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (type_id_name, new CCodeConstant ("0")));
48 cdecl.modifiers = CCodeModifiers.STATIC;
49 if (!plugin) {
50 type_block.add_statement (cdecl);
51 } else {
52 definition_fragment.append (cdecl);
55 CCodeFunction fun;
56 if (!plugin) {
57 fun = new CCodeFunction ("%s_get_type".printf (get_type_declaration ().get_lower_case_cname (null)), "GType");
58 /* Function will not be prototyped anyway */
59 if (get_accessibility () == SymbolAccessibility.PRIVATE) {
60 fun.modifiers = CCodeModifiers.STATIC;
62 } else {
63 fun = new CCodeFunction ("%s_register_type".printf (get_type_declaration ().get_lower_case_cname (null)), "GType");
64 fun.add_parameter (new CCodeFormalParameter ("module", "GTypeModule *"));
66 var get_fun = new CCodeFunction ("%s_get_type".printf (get_type_declaration ().get_lower_case_cname (null)), "GType");
67 if (get_accessibility () == SymbolAccessibility.PRIVATE) {
68 fun.modifiers = CCodeModifiers.STATIC;
71 declaration_fragment.append (get_fun.copy ());
73 get_fun.block = new CCodeBlock ();
74 get_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name)));
76 definition_fragment.append (get_fun);
79 var type_init = new CCodeBlock ();
80 var ctypedecl = new CCodeDeclaration ("const GTypeInfo");
81 ctypedecl.modifiers = CCodeModifiers.STATIC;
82 ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) NULL, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s }".printf (get_type_struct_name (), get_base_init_func_name (), get_class_init_func_name (), get_instance_struct_size (), get_instance_init_func_name ()))));
83 type_init.add_statement (ctypedecl);
84 if (fundamental) {
85 var ctypefundamentaldecl = new CCodeDeclaration ("const GTypeFundamentalInfo");
86 ctypefundamentaldecl.modifiers = CCodeModifiers.STATIC;
87 ctypefundamentaldecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_fundamental_info", new CCodeConstant ("{ (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }")));
88 type_init.add_statement (ctypefundamentaldecl);
91 type_init.add_statement (get_type_interface_init_declaration ());
93 CCodeFunctionCall reg_call;
94 if (fundamental) {
95 reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_register_fundamental"));
96 } else if (!plugin) {
97 reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_register_static"));
98 } else {
99 reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_module_register_type"));
100 reg_call.add_argument (new CCodeIdentifier ("module"));
102 if (fundamental) {
103 reg_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("g_type_fundamental_next")));
104 } else {
105 reg_call.add_argument (new CCodeIdentifier (get_parent_type_name ()));
107 reg_call.add_argument (new CCodeConstant ("\"%s\"".printf (get_type_declaration ().get_cname ())));
108 reg_call.add_argument (new CCodeIdentifier ("&g_define_type_info"));
109 if (fundamental) {
110 reg_call.add_argument (new CCodeIdentifier ("&g_define_type_fundamental_info"));
112 reg_call.add_argument (new CCodeConstant (get_type_flags ()));
113 type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call)));
115 type_init.add_statement (get_type_interface_init_statements ());
117 if (!plugin) {
118 var cond = new CCodeFunctionCall (new CCodeIdentifier ("G_UNLIKELY"));
119 cond.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier (type_id_name), new CCodeConstant ("0")));
120 var cif = new CCodeIfStatement (cond, type_init);
121 type_block.add_statement (cif);
122 } else {
123 type_block = type_init;
126 type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name)));
128 declaration_fragment.append (fun.copy ());
130 fun.block = type_block;
132 definition_fragment.append (fun);
136 * Returns the data type to be registered.
138 * @return type to be registered
140 public abstract TypeSymbol get_type_declaration ();
143 * Returns the name of the type struct in C code.
145 * @return C struct name
147 public abstract string get_type_struct_name ();
150 * Returns the name of the base_init function in C code.
152 * @return C function name
154 public abstract string get_base_init_func_name ();
157 * Returns the name of the class_init function in C code.
159 * @return C function name
161 public abstract string get_class_init_func_name ();
164 * Returns the size of the instance struct in C code.
166 * @return C instance struct size
168 public abstract string get_instance_struct_size ();
171 * Returns the name of the instance_init function in C code.
173 * @return C function name
175 public abstract string get_instance_init_func_name ();
178 * Returns the name of the parent type in C code.
180 * @return C parent type name
182 public abstract string get_parent_type_name ();
185 * Returns the set of type flags to be applied when registering.
187 * @return type flags
189 public virtual string get_type_flags () {
190 return "0";
194 * Returns additional C declarations to setup interfaces.
196 * @return C declarations
198 public virtual CCodeFragment get_type_interface_init_declaration () {
199 return new CCodeFragment ();
203 * Returns additional C initialization statements to setup interfaces.
205 * @return C statements
207 public abstract CCodeFragment get_type_interface_init_statements ();
210 * Returns the declaration for this type register function in C code.
212 * @return C function declaration fragment
214 public CCodeFragment get_declaration () {
215 return declaration_fragment;
219 * Returns the definition for this type register function in C code.
221 * @return C function definition fragment
223 public CCodeFragment get_definition () {
224 return definition_fragment;
228 * Returns the accessibility for this type.
230 public abstract SymbolAccessibility get_accessibility ();