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
20 * Jürg Billeter <j@bitron.ch>
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 ();
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) {
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
;
50 type_block
.add_statement (cdecl
);
52 definition_fragment
.append (cdecl
);
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
;
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
);
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
;
95 reg_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_register_fundamental"));
97 reg_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_register_static"));
99 reg_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_module_register_type"));
100 reg_call
.add_argument (new
CCodeIdentifier ("module"));
103 reg_call
.add_argument (new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_fundamental_next")));
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"));
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 ());
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
);
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.
189 public virtual string get_type_flags () {
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 ();