1 /*************************************************************************/
2 /*  bindings_generator.h                                                 */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #ifndef BINDINGS_GENERATOR_H
32 #define BINDINGS_GENERATOR_H
33 
34 #include "core/class_db.h"
35 #include "core/string_builder.h"
36 #include "editor/doc/doc_data.h"
37 #include "editor/editor_help.h"
38 
39 #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED)
40 
41 #include "core/ustring.h"
42 
43 class BindingsGenerator {
44 
45 	struct ConstantInterface {
46 		String name;
47 		String proxy_name;
48 		int value;
49 		const DocData::ConstantDoc *const_doc;
50 
ConstantInterfaceConstantInterface51 		ConstantInterface() {}
52 
ConstantInterfaceConstantInterface53 		ConstantInterface(const String &p_name, const String &p_proxy_name, int p_value) {
54 			name = p_name;
55 			proxy_name = p_proxy_name;
56 			value = p_value;
57 		}
58 	};
59 
60 	struct EnumInterface {
61 		StringName cname;
62 		List<ConstantInterface> constants;
63 
64 		_FORCE_INLINE_ bool operator==(const EnumInterface &p_ienum) const {
65 			return p_ienum.cname == cname;
66 		}
67 
EnumInterfaceEnumInterface68 		EnumInterface() {}
69 
EnumInterfaceEnumInterface70 		EnumInterface(const StringName &p_cname) {
71 			cname = p_cname;
72 		}
73 	};
74 
75 	struct PropertyInterface {
76 		StringName cname;
77 		String proxy_name;
78 		int index;
79 
80 		StringName setter;
81 		StringName getter;
82 
83 		const DocData::PropertyDoc *prop_doc;
84 	};
85 
86 	struct TypeReference {
87 		StringName cname;
88 		bool is_enum;
89 
TypeReferenceTypeReference90 		TypeReference() :
91 				is_enum(false) {
92 		}
93 
TypeReferenceTypeReference94 		TypeReference(const StringName &p_cname) :
95 				cname(p_cname),
96 				is_enum(false) {
97 		}
98 	};
99 
100 	struct ArgumentInterface {
101 		enum DefaultParamMode {
102 			CONSTANT,
103 			NULLABLE_VAL,
104 			NULLABLE_REF
105 		};
106 
107 		TypeReference type;
108 
109 		String name;
110 		String default_argument;
111 		DefaultParamMode def_param_mode;
112 
ArgumentInterfaceArgumentInterface113 		ArgumentInterface() {
114 			def_param_mode = CONSTANT;
115 		}
116 	};
117 
118 	struct MethodInterface {
119 		String name;
120 		StringName cname;
121 
122 		/**
123 		 * Name of the C# method
124 		 */
125 		String proxy_name;
126 
127 		/**
128 		 * [TypeInterface::name] of the return type
129 		 */
130 		TypeReference return_type;
131 
132 		/**
133 		 * Determines if the method has a variable number of arguments (VarArg)
134 		 */
135 		bool is_vararg;
136 
137 		/**
138 		 * Virtual methods ("virtual" as defined by the Godot API) are methods that by default do nothing,
139 		 * but can be overridden by the user to add custom functionality.
140 		 * e.g.: _ready, _process, etc.
141 		 */
142 		bool is_virtual;
143 
144 		/**
145 		 * Determines if the call should fallback to Godot's object.Call(string, params) in C#.
146 		 */
147 		bool requires_object_call;
148 
149 		/**
150 		 * Determines if the method visibility is 'internal' (visible only to files in the same assembly).
151 		 * Currently, we only use this for methods that are not meant to be exposed,
152 		 * but are required by properties as getters or setters.
153 		 * Methods that are not meant to be exposed are those that begin with underscore and are not virtual.
154 		 */
155 		bool is_internal;
156 
157 		List<ArgumentInterface> arguments;
158 
159 		const DocData::MethodDoc *method_doc;
160 
161 		bool is_deprecated;
162 		String deprecation_message;
163 
add_argumentMethodInterface164 		void add_argument(const ArgumentInterface &argument) {
165 			arguments.push_back(argument);
166 		}
167 
MethodInterfaceMethodInterface168 		MethodInterface() {
169 			is_vararg = false;
170 			is_virtual = false;
171 			requires_object_call = false;
172 			is_internal = false;
173 			method_doc = NULL;
174 			is_deprecated = false;
175 		}
176 	};
177 
178 	struct TypeInterface {
179 		/**
180 		 * Identifier name for this type.
181 		 * Also used to format [c_out].
182 		 */
183 		String name;
184 		StringName cname;
185 
186 		/**
187 		 * Identifier name of the base class.
188 		 */
189 		StringName base_name;
190 
191 		/**
192 		 * Name of the C# class
193 		 */
194 		String proxy_name;
195 
196 		ClassDB::APIType api_type;
197 
198 		bool is_enum;
199 		bool is_object_type;
200 		bool is_singleton;
201 		bool is_reference;
202 
203 		/**
204 		 * Used only by Object-derived types.
205 		 * Determines if this type is not abstract (incomplete).
206 		 * e.g.: CanvasItem cannot be instantiated.
207 		 */
208 		bool is_instantiable;
209 
210 		/**
211 		 * Used only by Object-derived types.
212 		 * Determines if the C# class owns the native handle and must free it somehow when disposed.
213 		 * e.g.: Reference types must notify when the C# instance is disposed, for proper refcounting.
214 		 */
215 		bool memory_own;
216 
217 		/**
218 		 * This must be set to true for any struct bigger than 32-bits. Those cannot be passed/returned by value
219 		 * with internal calls, so we must use pointers instead. Returns must be replace with out parameters.
220 		 * In this case, [c_out] and [cs_out] must have a different format, explained below.
221 		 * The Mono IL interpreter icall trampolines don't support passing structs bigger than 32-bits by value (at least not on WASM).
222 		 */
223 		bool ret_as_byref_arg;
224 
225 		// !! The comments of the following fields make reference to other fields via square brackets, e.g.: [field_name]
226 		// !! When renaming those fields, make sure to rename their references in the comments
227 
228 		// --- C INTERFACE ---
229 
230 		static const char *DEFAULT_VARARG_C_IN;
231 
232 		/**
233 		 * One or more statements that manipulate the parameter before being passed as argument of a ptrcall.
234 		 * If the statement adds a local that must be passed as the argument instead of the parameter,
235 		 * the name of that local must be specified with [c_arg_in].
236 		 * For variadic methods, this field is required and, if empty, [DEFAULT_VARARG_C_IN] is used instead.
237 		 * Formatting elements:
238 		 * %0: [c_type] of the parameter
239 		 * %1: name of the parameter
240 		 */
241 		String c_in;
242 
243 		/**
244 		 * Determines the expression that will be passed as argument to ptrcall.
245 		 * By default the value equals the name of the parameter,
246 		 * this varies for types that require special manipulation via [c_in].
247 		 * Formatting elements:
248 		 * %0 or %s: name of the parameter
249 		 */
250 		String c_arg_in;
251 
252 		/**
253 		 * One or more statements that determine how a variable of this type is returned from a function.
254 		 * It must contain the return statement(s).
255 		 * Formatting elements:
256 		 * %0: [c_type_out] of the return type
257 		 * %1: name of the variable to be returned
258 		 * %2: [name] of the return type
259 		 * ---------------------------------------
260 		 * If [ret_as_byref_arg] is true, the format is different. Instead of using a return statement,
261 		 * the value must be assigned to a parameter. This type of this parameter is a pointer to [c_type_out].
262 		 * Formatting elements:
263 		 * %0: [c_type_out] of the return type
264 		 * %1: name of the variable to be returned
265 		 * %2: [name] of the return type
266 		 * %3: name of the parameter that must be assigned the return value
267 		 */
268 		String c_out;
269 
270 		/**
271 		 * The actual expected type, as seen (in most cases) in Variant copy constructors
272 		 * Used for the type of the return variable and to format [c_in].
273 		 * The value must be the following depending of the type:
274 		 * Object-derived types: Object*
275 		 * Other types: [name]
276 		 * -- Exceptions --
277 		 * VarArg (fictitious type to represent variable arguments): Array
278 		 * float: double (because ptrcall only supports double)
279 		 * int: int64_t (because ptrcall only supports int64_t and uint64_t)
280 		 * Reference types override this for the type of the return variable: Ref<Reference>
281 		 */
282 		String c_type;
283 
284 		/**
285 		 * Determines the type used for parameters in function signatures.
286 		 */
287 		String c_type_in;
288 
289 		/**
290 		 * Determines the return type used for function signatures.
291 		 * Also used to construct a default value to return in case of errors,
292 		 * and to format [c_out].
293 		 */
294 		String c_type_out;
295 
296 		// --- C# INTERFACE ---
297 
298 		/**
299 		 * An expression that overrides the way the parameter is passed to the internal call.
300 		 * If empty, the parameter is passed as is.
301 		 * Formatting elements:
302 		 * %0 or %s: name of the parameter
303 		 */
304 		String cs_in;
305 
306 		/**
307 		 * One or more statements that determine how a variable of this type is returned from a method.
308 		 * It must contain the return statement(s).
309 		 * Formatting elements:
310 		 * %0: internal method name
311 		 * %1: internal method call arguments without surrounding parenthesis
312 		 * %2: [cs_type] of the return type
313 		 * %3: [im_type_out] of the return type
314 		 */
315 		String cs_out;
316 
317 		/**
318 		 * Type used for method signatures, both for parameters and the return type.
319 		 * Same as [proxy_name] except for variable arguments (VarArg) and collections (which include the namespace).
320 		 */
321 		String cs_type;
322 
323 		/**
324 		 * Type used for parameters of internal call methods.
325 		 */
326 		String im_type_in;
327 
328 		/**
329 		 * Type used for the return type of internal call methods.
330 		 */
331 		String im_type_out;
332 
333 		const DocData::ClassDoc *class_doc;
334 
335 		List<ConstantInterface> constants;
336 		List<EnumInterface> enums;
337 		List<PropertyInterface> properties;
338 		List<MethodInterface> methods;
339 
find_method_by_nameTypeInterface340 		const MethodInterface *find_method_by_name(const StringName &p_cname) const {
341 			for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) {
342 				if (E->get().cname == p_cname)
343 					return &E->get();
344 			}
345 
346 			return NULL;
347 		}
348 
find_property_by_nameTypeInterface349 		const PropertyInterface *find_property_by_name(const StringName &p_cname) const {
350 			for (const List<PropertyInterface>::Element *E = properties.front(); E; E = E->next()) {
351 				if (E->get().cname == p_cname)
352 					return &E->get();
353 			}
354 
355 			return NULL;
356 		}
357 
find_property_by_proxy_nameTypeInterface358 		const PropertyInterface *find_property_by_proxy_name(const String &p_proxy_name) const {
359 			for (const List<PropertyInterface>::Element *E = properties.front(); E; E = E->next()) {
360 				if (E->get().proxy_name == p_proxy_name)
361 					return &E->get();
362 			}
363 
364 			return NULL;
365 		}
366 
367 	private:
_init_value_typeTypeInterface368 		static void _init_value_type(TypeInterface &itype) {
369 			itype.proxy_name = itype.name;
370 
371 			itype.c_type = itype.name;
372 			itype.cs_type = itype.proxy_name;
373 			itype.im_type_in = "ref " + itype.proxy_name;
374 			itype.im_type_out = itype.proxy_name;
375 			itype.class_doc = &EditorHelp::get_doc_data()->class_list[itype.proxy_name];
376 		}
377 
378 	public:
create_value_typeTypeInterface379 		static TypeInterface create_value_type(const String &p_name) {
380 			TypeInterface itype;
381 			itype.name = p_name;
382 			itype.cname = StringName(p_name);
383 			_init_value_type(itype);
384 			return itype;
385 		}
386 
create_value_typeTypeInterface387 		static TypeInterface create_value_type(const StringName &p_name) {
388 			TypeInterface itype;
389 			itype.name = p_name.operator String();
390 			itype.cname = p_name;
391 			_init_value_type(itype);
392 			return itype;
393 		}
394 
create_object_typeTypeInterface395 		static TypeInterface create_object_type(const StringName &p_cname, ClassDB::APIType p_api_type) {
396 			TypeInterface itype;
397 
398 			itype.name = p_cname;
399 			itype.cname = p_cname;
400 			itype.proxy_name = itype.name.begins_with("_") ? itype.name.substr(1, itype.name.length()) : itype.name;
401 			itype.api_type = p_api_type;
402 			itype.is_object_type = true;
403 			itype.class_doc = &EditorHelp::get_doc_data()->class_list[itype.proxy_name];
404 
405 			return itype;
406 		}
407 
create_placeholder_typeTypeInterface408 		static void create_placeholder_type(TypeInterface &r_itype, const StringName &p_cname) {
409 			r_itype.name = p_cname;
410 			r_itype.cname = p_cname;
411 			r_itype.proxy_name = r_itype.name;
412 
413 			r_itype.c_type = r_itype.name;
414 			r_itype.c_type_in = "MonoObject*";
415 			r_itype.c_type_out = "MonoObject*";
416 			r_itype.cs_type = r_itype.proxy_name;
417 			r_itype.im_type_in = r_itype.proxy_name;
418 			r_itype.im_type_out = r_itype.proxy_name;
419 		}
420 
postsetup_enum_typeTypeInterface421 		static void postsetup_enum_type(TypeInterface &r_enum_itype) {
422 			// C interface for enums is the same as that of 'uint32_t'. Remember to apply
423 			// any of the changes done here to the 'uint32_t' type interface as well.
424 
425 			r_enum_itype.c_arg_in = "&%s_in";
426 			{
427 				// The expected types for parameters and return value in ptrcall are 'int64_t' or 'uint64_t'.
428 				r_enum_itype.c_in = "\t%0 %1_in = (%0)%1;\n";
429 				r_enum_itype.c_out = "\treturn (%0)%1;\n";
430 				r_enum_itype.c_type = "int64_t";
431 			}
432 			r_enum_itype.c_type_in = "int32_t";
433 			r_enum_itype.c_type_out = r_enum_itype.c_type_in;
434 
435 			r_enum_itype.cs_type = r_enum_itype.proxy_name;
436 			r_enum_itype.cs_in = "(int)%s";
437 			r_enum_itype.cs_out = "return (%2)%0(%1);";
438 			r_enum_itype.im_type_in = "int";
439 			r_enum_itype.im_type_out = "int";
440 			r_enum_itype.class_doc = &EditorHelp::get_doc_data()->class_list[r_enum_itype.proxy_name];
441 		}
442 
TypeInterfaceTypeInterface443 		TypeInterface() {
444 
445 			api_type = ClassDB::API_NONE;
446 
447 			is_enum = false;
448 			is_object_type = false;
449 			is_singleton = false;
450 			is_reference = false;
451 			is_instantiable = false;
452 
453 			memory_own = false;
454 
455 			ret_as_byref_arg = false;
456 
457 			c_arg_in = "%s";
458 
459 			class_doc = NULL;
460 		}
461 	};
462 
463 	struct InternalCall {
464 		String name;
465 		String im_type_out; // Return type for the C# method declaration. Also used as companion of [unique_siq]
466 		String im_sig; // Signature for the C# method declaration
467 		String unique_sig; // Unique signature to avoid duplicates in containers
468 		bool editor_only;
469 
InternalCallInternalCall470 		InternalCall() {}
471 
472 		InternalCall(const String &p_name, const String &p_im_type_out, const String &p_im_sig = String(), const String &p_unique_sig = String()) {
473 			name = p_name;
474 			im_type_out = p_im_type_out;
475 			im_sig = p_im_sig;
476 			unique_sig = p_unique_sig;
477 			editor_only = false;
478 		}
479 
480 		InternalCall(ClassDB::APIType api_type, const String &p_name, const String &p_im_type_out, const String &p_im_sig = String(), const String &p_unique_sig = String()) {
481 			name = p_name;
482 			im_type_out = p_im_type_out;
483 			im_sig = p_im_sig;
484 			unique_sig = p_unique_sig;
485 			editor_only = api_type == ClassDB::API_EDITOR;
486 		}
487 
488 		inline bool operator==(const InternalCall &p_a) const {
489 			return p_a.unique_sig == unique_sig;
490 		}
491 	};
492 
493 	bool log_print_enabled;
494 	bool initialized;
495 
496 	OrderedHashMap<StringName, TypeInterface> obj_types;
497 
498 	Map<StringName, TypeInterface> placeholder_types;
499 	Map<StringName, TypeInterface> builtin_types;
500 	Map<StringName, TypeInterface> enum_types;
501 
502 	List<EnumInterface> global_enums;
503 	List<ConstantInterface> global_constants;
504 
505 	List<InternalCall> method_icalls;
506 	Map<const MethodInterface *, const InternalCall *> method_icalls_map;
507 
508 	List<const InternalCall *> generated_icall_funcs;
509 
510 	List<InternalCall> core_custom_icalls;
511 	List<InternalCall> editor_custom_icalls;
512 
513 	Map<StringName, List<StringName> > blacklisted_methods;
514 
515 	void _initialize_blacklisted_methods();
516 
517 	struct NameCache {
518 		StringName type_void;
519 		StringName type_Array;
520 		StringName type_Dictionary;
521 		StringName type_Variant;
522 		StringName type_VarArg;
523 		StringName type_Object;
524 		StringName type_Reference;
525 		StringName type_RID;
526 		StringName type_String;
527 		StringName type_at_GlobalScope;
528 		StringName enum_Error;
529 
530 		StringName type_sbyte;
531 		StringName type_short;
532 		StringName type_int;
533 		StringName type_long;
534 		StringName type_byte;
535 		StringName type_ushort;
536 		StringName type_uint;
537 		StringName type_ulong;
538 		StringName type_float;
539 		StringName type_double;
540 
NameCacheNameCache541 		NameCache() {
542 			type_void = StaticCString::create("void");
543 			type_Array = StaticCString::create("Array");
544 			type_Dictionary = StaticCString::create("Dictionary");
545 			type_Variant = StaticCString::create("Variant");
546 			type_VarArg = StaticCString::create("VarArg");
547 			type_Object = StaticCString::create("Object");
548 			type_Reference = StaticCString::create("Reference");
549 			type_RID = StaticCString::create("RID");
550 			type_String = StaticCString::create("String");
551 			type_at_GlobalScope = StaticCString::create("@GlobalScope");
552 			enum_Error = StaticCString::create("Error");
553 
554 			type_sbyte = StaticCString::create("sbyte");
555 			type_short = StaticCString::create("short");
556 			type_int = StaticCString::create("int");
557 			type_long = StaticCString::create("long");
558 			type_byte = StaticCString::create("byte");
559 			type_ushort = StaticCString::create("ushort");
560 			type_uint = StaticCString::create("uint");
561 			type_ulong = StaticCString::create("ulong");
562 			type_float = StaticCString::create("float");
563 			type_double = StaticCString::create("double");
564 		}
565 
566 	private:
567 		NameCache(const NameCache &);
568 		NameCache &operator=(const NameCache &);
569 	};
570 
571 	NameCache name_cache;
572 
find_icall_by_name(const String & p_name,const List<InternalCall> & p_list)573 	const List<InternalCall>::Element *find_icall_by_name(const String &p_name, const List<InternalCall> &p_list) {
574 		const List<InternalCall>::Element *it = p_list.front();
575 		while (it) {
576 			if (it->get().name == p_name) return it;
577 			it = it->next();
578 		}
579 		return NULL;
580 	}
581 
find_constant_by_name(const String & p_name,const List<ConstantInterface> & p_constants)582 	const ConstantInterface *find_constant_by_name(const String &p_name, const List<ConstantInterface> &p_constants) const {
583 		for (const List<ConstantInterface>::Element *E = p_constants.front(); E; E = E->next()) {
584 			if (E->get().name == p_name)
585 				return &E->get();
586 		}
587 
588 		return NULL;
589 	}
590 
get_unique_sig(const TypeInterface & p_type)591 	inline String get_unique_sig(const TypeInterface &p_type) {
592 		if (p_type.is_reference)
593 			return "Ref";
594 		else if (p_type.is_object_type)
595 			return "Obj";
596 		else if (p_type.is_enum)
597 			return "int";
598 
599 		return p_type.name;
600 	}
601 
602 	String bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype);
603 
604 	int _determine_enum_prefix(const EnumInterface &p_ienum);
605 	void _apply_prefix_to_enum_constants(EnumInterface &p_ienum, int p_prefix_length);
606 
607 	void _generate_method_icalls(const TypeInterface &p_itype);
608 
609 	const TypeInterface *_get_type_or_null(const TypeReference &p_typeref);
610 	const TypeInterface *_get_type_or_placeholder(const TypeReference &p_typeref);
611 
612 	StringName _get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
613 	StringName _get_float_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
614 
615 	bool _arg_default_value_from_variant(const Variant &p_val, ArgumentInterface &r_iarg);
616 
617 	bool _populate_object_type_interfaces();
618 	void _populate_builtin_type_interfaces();
619 
620 	void _populate_global_constants();
621 
622 	Error _generate_cs_type(const TypeInterface &itype, const String &p_output_file);
623 
624 	Error _generate_cs_property(const TypeInterface &p_itype, const PropertyInterface &p_iprop, StringBuilder &p_output);
625 	Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output);
626 
627 	void _generate_global_constants(StringBuilder &p_output);
628 
629 	Error _generate_glue_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, StringBuilder &p_output);
630 
631 	Error _save_file(const String &p_path, const StringBuilder &p_content);
632 
633 	void _log(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
634 
635 	void _initialize();
636 
637 public:
638 	Error generate_cs_core_project(const String &p_proj_dir);
639 	Error generate_cs_editor_project(const String &p_proj_dir);
640 	Error generate_cs_api(const String &p_output_dir);
641 	Error generate_glue(const String &p_output_dir);
642 
is_log_print_enabled()643 	_FORCE_INLINE_ bool is_log_print_enabled() { return log_print_enabled; }
set_log_print_enabled(bool p_enabled)644 	_FORCE_INLINE_ void set_log_print_enabled(bool p_enabled) { log_print_enabled = p_enabled; }
645 
is_initialized()646 	_FORCE_INLINE_ bool is_initialized() { return initialized; }
647 
648 	static uint32_t get_version();
649 
650 	static void handle_cmdline_args(const List<String> &p_cmdline_args);
651 
BindingsGenerator()652 	BindingsGenerator() :
653 			log_print_enabled(true),
654 			initialized(false) {
655 		_initialize();
656 	}
657 };
658 
659 #endif
660 
661 #endif // BINDINGS_GENERATOR_H
662