object_type_db.h
1 /*************************************************************************/
2 /* object_type_db.h */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* http://www.godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
9 /* */
10 /* Permission is hereby granted, free of charge, to any person obtaining */
11 /* a copy of this software and associated documentation files (the */
12 /* "Software"), to deal in the Software without restriction, including */
13 /* without limitation the rights to use, copy, modify, merge, publish, */
14 /* distribute, sublicense, and/or sell copies of the Software, and to */
15 /* permit persons to whom the Software is furnished to do so, subject to */
16 /* the following conditions: */
17 /* */
18 /* The above copyright notice and this permission notice shall be */
19 /* included in all copies or substantial portions of the Software. */
20 /* */
21 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
22 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
23 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
24 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
25 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
26 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
27 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
28 /*************************************************************************/
29 #ifndef OBJECT_TYPE_DB_H
30 #define OBJECT_TYPE_DB_H
31 
32 #include "object.h"
33 #include "method_bind.h"
34 #include "print_string.h"
39 struct ParamHint {
40 
41  String name;
42  PropertyHint hint;
43  String hint_text;
44  Variant default_val;
45 
46  ParamHint(const String& p_name="", PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="",Variant p_default_val=Variant()) {
47 
48  name=p_name;
49  hint=p_hint;
50  hint_text=p_hint_text;
51  default_val=p_default_val;
52  }
53 
54 };
55 
56 struct ParamDef {
57  bool used;
58  Variant val;
59  _FORCE_INLINE_ ParamDef() { used=false; }
60  ParamDef(const Variant& p_variant);
61 };
62 
63 //#define DEFVAL( m_defval ) ParamDef(m_defval)
64 #define DEFVAL( m_defval ) (m_defval)
65 
66 
67 //#define SIMPLE_METHODDEF
68 
69 #ifdef DEBUG_METHODS_ENABLED
70 
71 struct MethodDefinition {
72 
73 
74  StringName name;
75  Vector<StringName> args;
76  MethodDefinition() {}
77  MethodDefinition(const char *p_name) { name=p_name; }
78  MethodDefinition(const StringName& p_name) { name=p_name; }
79 };
80 
81 
82 
83 MethodDefinition _MD(const char* p_name);
84 MethodDefinition _MD(const char* p_name,const char *p_arg1);
85 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2);
86 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3);
87 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3,const char *p_arg4);
88 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3,const char *p_arg4,const char *p_arg5);
89 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3,const char *p_arg4,const char *p_arg5,const char *p_arg6);
90 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3,const char *p_arg4,const char *p_arg5,const char *p_arg6,const char *p_arg7);
91 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3,const char *p_arg4,const char *p_arg5,const char *p_arg6,const char *p_arg7,const char *p_arg8);
92 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3,const char *p_arg4,const char *p_arg5,const char *p_arg6,const char *p_arg7,const char *p_arg8,const char *p_arg9);
93 MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3,const char *p_arg4,const char *p_arg5,const char *p_arg6,const char *p_arg7,const char *p_arg8,const char *p_arg9,const char *p_arg10);
94 
95 #else
96 
97 //#define NO_VARIADIC_MACROS
98 
99 #ifdef NO_VARIADIC_MACROS
100 
101 static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name; }
102 
103 #else
104 
105 #define _MD(m_c, ...) m_c
106 
107 #endif
108 
109 #endif
110 
112 
113  struct PropertySetGet {
114 
115  int index;
116  StringName setter;
117  StringName getter;
118  MethodBind *_setptr;
119  MethodBind *_getptr;
120  Variant::Type type;
121  };
122 
123  struct TypeInfo {
124 
125  TypeInfo *inherits_ptr;
129  List<PropertyInfo> property_list;
130 #ifdef DEBUG_METHODS_ENABLED
131  List<StringName> constant_order;
132  List<StringName> method_order;
133  List<MethodInfo> virtual_methods;
134  StringName category;
135 #endif
137 
138 
139  StringName inherits;
140  StringName name;
141  bool disabled;
142  Object* (*creation_func)();
143  TypeInfo();
144  ~TypeInfo();
145  };
146 
147  template<class T>
148  static Object *creator() {
149  return memnew( T );
150  }
151 
152  static Mutex *lock;
154  static HashMap<StringName,StringName,StringNameHasher> resource_base_extensions;
156 
157 #ifdef DEBUG_METHODS_ENABLED
158  static MethodBind* bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
159 #else
160  static MethodBind* bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const char *method_name, const Variant **p_defs, int p_defcount);
161 #endif
162 
163 
164 
165  static void _add_type2(const StringName& p_type, const StringName& p_inherits);
166 public:
167 
168  // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
169  template<class T>
170  static void _add_type() {
171 
172  _add_type2(T::get_type_static(),T::get_parent_type_static());
173 #if 0
174  GLOBAL_LOCK_FUNCTION;
175 
176  StringName name = T::get_type_static();
177 
178  ERR_FAIL_COND(types.has(name));
179 
180  types[name]=TypeInfo();
181  TypeInfo &ti=types[name];
182  ti.name=name;
183  ti.inherits=T::get_parent_type_static();
184 
185  if (ti.inherits) {
186 
187  ERR_FAIL_COND( !types.has(ti.inherits) ); //it MUST be registered.
188  ti.inherits_ptr = &types[ti.inherits];
189 
190  } else {
191  ti.inherits_ptr=NULL;
192  }
193 #endif
194  }
195 
196  template<class T>
197  static void register_type() {
198 
199  GLOBAL_LOCK_FUNCTION;
200  T::initialize_type();
201  TypeInfo *t=types.getptr(T::get_type_static());
202  ERR_FAIL_COND(!t);
203  t->creation_func=&creator<T>;
204  T::register_custom_data_to_otdb();
205  }
206 
207  template<class T>
208  static void register_virtual_type() {
209 
210  GLOBAL_LOCK_FUNCTION;
211  T::initialize_type();
212  //nothing
213  }
214 
215  template<class T>
216  static Object* _create_ptr_func() {
217 
218  return T::create();
219  }
220 
221  template<class T>
222  static void register_create_type() {
223 
224  GLOBAL_LOCK_FUNCTION;
225  T::initialize_type();
226  TypeInfo *t=types.getptr(T::get_type_static());
227  ERR_FAIL_COND(!t);
228  t->creation_func=&_create_ptr_func<T>;
229  T::register_custom_data_to_otdb();
230  }
231 
232  static void get_type_list( List<StringName> *p_types);
233  static void get_inheriters_from( const StringName& p_type,List<StringName> *p_types);
234  static StringName type_inherits_from(const StringName& p_type);
235  static bool type_exists(const StringName &p_type);
236  static bool is_type(const StringName &p_type,const StringName& p_inherits);
237  static bool can_instance(const StringName &p_type);
238  static Object *instance(const StringName &p_type);
239 
240 #if 0
241  template<class N, class M>
242  static MethodBind* bind_method(N p_method_name, M p_method,
243  //default arguments
244  ParamDef d1=ParamDef(),
245  ParamDef d2=ParamDef(),
246  ParamDef d3=ParamDef(),
247  ParamDef d4=ParamDef(),
248  ParamDef d5=ParamDef()
249  ) {
250 
251  return bind_methodf(METHOD_FLAGS_DEFAULT,p_method_name, p_method, d1,d2,d3,d4,d5);
252  }
253 
254 
255 
256  template<class N, class M>
257  static MethodBind* bind_methodf(uint32_t p_flags, N p_method_name, M p_method,
258 
259 
260  //default arguments
261  const ParamDef &d1=ParamDef(),
262  const ParamDef &d2=ParamDef(),
263  const ParamDef &d3=ParamDef(),
264  const ParamDef &d4=ParamDef(),
265  const ParamDef &d5=ParamDef()
266  ) {
267 
268  GLOBAL_LOCK_FUNCTION;
269 
270  MethodDefinition method_name=p_method_name;
271 
272  MethodBind *bind = create_method_bind(p_method);
273  bind->set_name(method_name.name);
274  ERR_FAIL_COND_V(!bind,NULL);
275 
276  String instance_type=bind->get_instance_type();
277 
278  TypeInfo *type=types.getptr(instance_type);
279  if (!type) {
280  memdelete(bind);
281  ERR_FAIL_COND_V(!type,NULL);
282  }
283 
284  if (type->method_map.has(method_name.name)) {
285  memdelete(bind);
286  // overloading not supported
287  ERR_EXPLAIN("Method already bound: "+instance_type+"::"+method_name.name);
288  ERR_FAIL_V(NULL);
289  }
290  bind->set_argument_names(method_name.args);
291  type->method_map[method_name.name]=bind;
292 
293  Vector<Variant> defvals;
294 
295 #define PARSE_DEFVAL(m_defval)\
296  if (d##m_defval.used) defvals.insert(0,d##m_defval.val);\
297  else goto set_defvals;
298 
299 
300  PARSE_DEFVAL(1);
301  PARSE_DEFVAL(2);
302  PARSE_DEFVAL(3);
303  PARSE_DEFVAL(4);
304  PARSE_DEFVAL(5);
305  set_defvals:
306 
307  bind->set_default_arguments(defvals);
308  bind->set_hint_flags(p_flags);
309 
310  return bind;
311 #undef PARSE_DEFVAL
312  }
313 #else
314 
315 #if 0
316  template<class N, class M>
317  static MethodBind* bind_method(N p_method_name, M p_method,
318  //default arguments
319  const ParamDef &d1=ParamDef(),
320  const ParamDef &d2=ParamDef(),
321  const ParamDef &d3=ParamDef(),
322  const ParamDef &d4=ParamDef(),
323  const ParamDef &d5=ParamDef()
324  ) {
325 
326  MethodDefinition method_name=p_method_name;
327 
328  MethodBind *bind = create_method_bind(p_method);
329 
330  return bind_methodfi(METHOD_FLAGS_DEFAULT,bind,method_name,d1,d2,d3,d4,d5); //use static function, much smaller binary usage
331  }
332 #endif
333 
334  template<class N, class M>
335  static MethodBind* bind_method(N p_method_name, M p_method) {
336 
337  MethodBind *bind = create_method_bind(p_method);
338 
339  return bind_methodfi(METHOD_FLAGS_DEFAULT,bind,p_method_name,NULL,0); //use static function, much smaller binary usage
340  }
341 
342  template<class N, class M>
343  static MethodBind* bind_method(N p_method_name, M p_method,const Variant& p_def1) {
344 
345  MethodBind *bind = create_method_bind(p_method);
346  const Variant* ptr[1]={&p_def1};
347 
348  return bind_methodfi(METHOD_FLAGS_DEFAULT,bind,p_method_name,ptr,1);
349  }
350 
351 
352  template<class N, class M>
353  static MethodBind* bind_method(N p_method_name, M p_method,const Variant& p_def1,const Variant& p_def2) {
354 
355  MethodBind *bind = create_method_bind(p_method);
356  const Variant* ptr[2]={&p_def1,&p_def2};
357 
358  return bind_methodfi(METHOD_FLAGS_DEFAULT,bind,p_method_name,ptr,2);
359  }
360 
361  template<class N, class M>
362  static MethodBind* bind_method(N p_method_name, M p_method,const Variant& p_def1,const Variant& p_def2,const Variant& p_def3) {
363 
364  MethodBind *bind = create_method_bind(p_method);
365  const Variant* ptr[3]={&p_def1,&p_def2,&p_def3};
366 
367  return bind_methodfi(METHOD_FLAGS_DEFAULT,bind,p_method_name,ptr,3);
368  }
369 
370  template<class N, class M>
371  static MethodBind* bind_method(N p_method_name, M p_method,const Variant& p_def1,const Variant& p_def2,const Variant& p_def3,const Variant& p_def4) {
372 
373  MethodBind *bind = create_method_bind(p_method);
374  const Variant* ptr[4]={&p_def1,&p_def2,&p_def3,&p_def4};
375 
376  return bind_methodfi(METHOD_FLAGS_DEFAULT,bind,p_method_name,ptr,4);
377  }
378 
379  template<class N, class M>
380  static MethodBind* bind_method(N p_method_name, M p_method,const Variant& p_def1,const Variant& p_def2,const Variant& p_def3,const Variant& p_def4,const Variant& p_def5) {
381 
382  MethodBind *bind = create_method_bind(p_method);
383  const Variant* ptr[5]={&p_def1,&p_def2,&p_def3,&p_def4,&p_def5};
384 
385  return bind_methodfi(METHOD_FLAGS_DEFAULT,bind,p_method_name,ptr,5);
386  }
387 
388  template<class N, class M>
389  static MethodBind* bind_method(N p_method_name, M p_method,const Variant& p_def1,const Variant& p_def2,const Variant& p_def3,const Variant& p_def4,const Variant& p_def5,const Variant& p_def6) {
390 
391  MethodBind *bind = create_method_bind(p_method);
392  const Variant* ptr[6]={&p_def1,&p_def2,&p_def3,&p_def4,&p_def5,&p_def6};
393 
394  return bind_methodfi(METHOD_FLAGS_DEFAULT,bind,p_method_name,ptr,6);
395  }
396 
397 #if 0
398  template<class N, class M>
399  static MethodBind* bind_methodf(uint32_t p_flags, N p_method_name, M p_method,
400 
401  const ParamDef& d1=ParamDef(),
402  const ParamDef& d2=ParamDef(),
403  const ParamDef& d3=ParamDef(),
404  const ParamDef& d4=ParamDef(),
405  const ParamDef& d5=ParamDef()
406  ) {
407 
408  MethodDefinition method_name=p_method_name;
409 
410  MethodBind *bind = create_method_bind(p_method);
411 
412  return bind_methodfi(p_flags,bind,method_name,d1,d2,d3,d4,d5); //use static function, much smaller binary usage
413  }
414 #endif
415 
416 #endif
417  template<class M>
418  static MethodBind* bind_native_method(uint32_t p_flags, const StringName& p_name, M p_method,const MethodInfo& p_info=MethodInfo(),const Vector<Variant>& p_default_args=Vector<Variant>()) {
419 
420  GLOBAL_LOCK_FUNCTION;
421 
422 
423 
424  MethodBind *bind = create_native_method_bind(p_method,p_info);
425  ERR_FAIL_COND_V(!bind,NULL);
426  bind->set_name(p_name);
427  bind->set_default_arguments(p_default_args);
428 
429  String instance_type=bind->get_instance_type();
430 
431  TypeInfo *type=types.getptr(instance_type);
432  if (!type) {
433  memdelete(bind);
434  ERR_FAIL_COND_V(!type,NULL);
435  }
436 
437  if (type->method_map.has(p_name)) {
438  memdelete(bind);
439  // overloading not supported
440  ERR_EXPLAIN("Method already bound: "+instance_type+"::"+p_name);
441  ERR_FAIL_V(NULL);
442  }
443  type->method_map[p_name]=bind;
444 #ifdef DEBUG_METHODS_ENABLED
445  type->method_order.push_back(p_name);
446 #endif
447 
448 
449  return bind;
450 
451  }
452 
453 
454  static void add_signal(StringName p_type,const MethodInfo& p_signal);
455  static bool has_signal(StringName p_type,StringName p_signal);
456  static void get_signal_list(StringName p_type,List<MethodInfo> *p_signals,bool p_no_inheritance=false);
457 
458  static void add_property(StringName p_type,const PropertyInfo& p_pinfo, const StringName& p_setter, const StringName& p_getter, int p_index=-1);
459  static void get_property_list(StringName p_type,List<PropertyInfo> *p_list,bool p_no_inheritance=false);
460  static bool set_property(Object* p_object, const StringName& p_property, const Variant& p_value, bool *r_valid=NULL);
461  static bool get_property(Object* p_object,const StringName& p_property, Variant& r_value);
462  static Variant::Type get_property_type(const StringName& p_type, const StringName& p_property,bool *r_is_valid=NULL);
463 
464 
465 
466  static bool has_method(StringName p_type,StringName p_method,bool p_no_inheritance=false);
467  static void set_method_flags(StringName p_type,StringName p_method,int p_flags);
468 
469 
470  static void get_method_list(StringName p_type,List<MethodInfo> *p_methods,bool p_no_inheritance=false);
471  static MethodBind *get_method(StringName p_type, StringName p_name);
472 
473  static void add_virtual_method(const StringName& p_type,const MethodInfo& p_method,bool p_virtual=true );
474  static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods,bool p_no_inheritance=false );
475 
476  static void bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant);
477  static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false);
478  static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL);
479  static StringName get_category(const StringName& p_node);
480 
481  static bool get_setter_and_type_for_property(const StringName& p_class, const StringName& p_prop, StringName& r_class, StringName& r_setter);
482 
483  static void set_type_enabled(StringName p_type,bool p_enable);
484  static bool is_type_enabled(StringName p_type);
485 
486  static void add_resource_base_extension(const StringName& p_extension,const StringName& p_type);
487  static void get_resource_base_extensions(List<String> *p_extensions);
488  static void get_extensions_for_type(const StringName& p_type,List<String> *p_extensions);
489 
490  static void add_compatibility_type(const StringName& p_type,const StringName& p_fallback);
491  static void init();
492  static void cleanup();
493 };
494 
495 
496 #define BIND_CONSTANT(m_constant)\
497  ObjectTypeDB::bind_integer_constant( get_type_static() , #m_constant, m_constant);
498 
499 #ifdef TOOLS_ENABLED
500 
501 #define BIND_VMETHOD(m_method)\
502  ObjectTypeDB::add_virtual_method( get_type_static() , m_method );
503 
504 #else
505 
506 #define BIND_VMETHOD(m_method)
507 
508 #endif
509 
510 
511 
512 #endif
Definition: variant.h:74
Definition: object_type_db.h:56
Definition: object.h:104
Definition: mutex.h:45
Definition: string_db.h:48
Definition: object_type_db.h:39
Definition: object.h:127
_FORCE_INLINE_ TData * getptr(const TKey &p_key)
Definition: hash_map.h:341
Definition: ustring.h:64
Definition: object.h:317
Definition: method_bind.h:128
Definition: object_type_db.h:111