class_db.cpp 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304
  1. /*************************************************************************/
  2. /* class_db.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 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. #include "class_db.h"
  30. #include "os/mutex.h"
  31. #ifdef NO_THREADS
  32. #define OBJTYPE_RLOCK
  33. #define OBJTYPE_WLOCK
  34. #else
  35. #define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock);
  36. #define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock);
  37. #endif
  38. #ifdef DEBUG_METHODS_ENABLED
  39. ParamDef::ParamDef(const Variant& p_variant) { used=true; val=p_variant; }
  40. MethodDefinition _MD(const char* p_name) {
  41. MethodDefinition md;
  42. md.name=StaticCString::create(p_name);
  43. return md;
  44. }
  45. MethodDefinition _MD(const char* p_name,const char *p_arg1) {
  46. MethodDefinition md;
  47. md.name=StaticCString::create(p_name);
  48. md.args.push_back(StaticCString::create(p_arg1));
  49. return md;
  50. }
  51. MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2) {
  52. MethodDefinition md;
  53. md.name=StaticCString::create(p_name);
  54. md.args.resize(2);
  55. md.args[0]=StaticCString::create(p_arg1);
  56. md.args[1]=StaticCString::create(p_arg2);
  57. return md;
  58. }
  59. MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3) {
  60. MethodDefinition md;
  61. md.name=StaticCString::create(p_name);
  62. md.args.resize(3);
  63. md.args[0]=StaticCString::create(p_arg1);
  64. md.args[1]=StaticCString::create(p_arg2);
  65. md.args[2]=StaticCString::create(p_arg3);
  66. return md;
  67. }
  68. MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,const char *p_arg3,const char *p_arg4) {
  69. MethodDefinition md;
  70. md.name=StaticCString::create(p_name);
  71. md.args.resize(4);
  72. md.args[0]=StaticCString::create(p_arg1);
  73. md.args[1]=StaticCString::create(p_arg2);
  74. md.args[2]=StaticCString::create(p_arg3);
  75. md.args[3]=StaticCString::create(p_arg4);
  76. return md;
  77. }
  78. 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) {
  79. MethodDefinition md;
  80. md.name=StaticCString::create(p_name);
  81. md.args.resize(5);
  82. md.args[0]=StaticCString::create(p_arg1);
  83. md.args[1]=StaticCString::create(p_arg2);
  84. md.args[2]=StaticCString::create(p_arg3);
  85. md.args[3]=StaticCString::create(p_arg4);
  86. md.args[4]=StaticCString::create(p_arg5);
  87. return md;
  88. }
  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;
  91. md.name=StaticCString::create(p_name);
  92. md.args.resize(6);
  93. md.args[0]=StaticCString::create(p_arg1);
  94. md.args[1]=StaticCString::create(p_arg2);
  95. md.args[2]=StaticCString::create(p_arg3);
  96. md.args[3]=StaticCString::create(p_arg4);
  97. md.args[4]=StaticCString::create(p_arg5);
  98. md.args[5]=StaticCString::create(p_arg6);
  99. return md;
  100. }
  101. 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) {
  102. MethodDefinition md;
  103. md.name=StaticCString::create(p_name);
  104. md.args.resize(7);
  105. md.args[0]=StaticCString::create(p_arg1);
  106. md.args[1]=StaticCString::create(p_arg2);
  107. md.args[2]=StaticCString::create(p_arg3);
  108. md.args[3]=StaticCString::create(p_arg4);
  109. md.args[4]=StaticCString::create(p_arg5);
  110. md.args[5]=StaticCString::create(p_arg6);
  111. md.args[6]=StaticCString::create(p_arg7);
  112. return md;
  113. }
  114. 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) {
  115. MethodDefinition md;
  116. md.name=StaticCString::create(p_name);
  117. md.args.resize(8);
  118. md.args[0]=StaticCString::create(p_arg1);
  119. md.args[1]=StaticCString::create(p_arg2);
  120. md.args[2]=StaticCString::create(p_arg3);
  121. md.args[3]=StaticCString::create(p_arg4);
  122. md.args[4]=StaticCString::create(p_arg5);
  123. md.args[5]=StaticCString::create(p_arg6);
  124. md.args[6]=StaticCString::create(p_arg7);
  125. md.args[7]=StaticCString::create(p_arg8);
  126. return md;
  127. }
  128. 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) {
  129. MethodDefinition md;
  130. md.name=StaticCString::create(p_name);
  131. md.args.resize(9);
  132. md.args[0]=StaticCString::create(p_arg1);
  133. md.args[1]=StaticCString::create(p_arg2);
  134. md.args[2]=StaticCString::create(p_arg3);
  135. md.args[3]=StaticCString::create(p_arg4);
  136. md.args[4]=StaticCString::create(p_arg5);
  137. md.args[5]=StaticCString::create(p_arg6);
  138. md.args[6]=StaticCString::create(p_arg7);
  139. md.args[7]=StaticCString::create(p_arg8);
  140. md.args[8]=StaticCString::create(p_arg9);
  141. return md;
  142. }
  143. 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) {
  144. MethodDefinition md;
  145. md.name=StaticCString::create(p_name);
  146. md.args.resize(10);
  147. md.args[0]=StaticCString::create(p_arg1);
  148. md.args[1]=StaticCString::create(p_arg2);
  149. md.args[2]=StaticCString::create(p_arg3);
  150. md.args[3]=StaticCString::create(p_arg4);
  151. md.args[4]=StaticCString::create(p_arg5);
  152. md.args[5]=StaticCString::create(p_arg6);
  153. md.args[6]=StaticCString::create(p_arg7);
  154. md.args[7]=StaticCString::create(p_arg8);
  155. md.args[8]=StaticCString::create(p_arg9);
  156. md.args[9]=StaticCString::create(p_arg10);
  157. return md;
  158. }
  159. #endif
  160. ClassDB::APIType ClassDB::current_api=API_CORE;
  161. void ClassDB::set_current_api(APIType p_api) {
  162. current_api=p_api;
  163. }
  164. HashMap<StringName,ClassDB::ClassInfo,StringNameHasher> ClassDB::classes;
  165. HashMap<StringName,StringName,StringNameHasher> ClassDB::resource_base_extensions;
  166. HashMap<StringName,StringName,StringNameHasher> ClassDB::compat_classes;
  167. ClassDB::ClassInfo::ClassInfo() {
  168. creation_func=NULL;
  169. inherits_ptr=NULL;
  170. disabled=false;
  171. }
  172. ClassDB::ClassInfo::~ClassInfo() {
  173. }
  174. bool ClassDB::is_parent_class(const StringName &p_class,const StringName& p_inherits) {
  175. OBJTYPE_RLOCK;
  176. StringName inherits=p_class;
  177. while (inherits.operator String().length()) {
  178. if (inherits==p_inherits)
  179. return true;
  180. inherits=get_parent_class(inherits);
  181. }
  182. return false;
  183. }
  184. void ClassDB::get_class_list( List<StringName> *p_classes) {
  185. OBJTYPE_RLOCK;
  186. const StringName *k=NULL;
  187. while((k=classes.next(k))) {
  188. p_classes->push_back(*k);
  189. }
  190. p_classes->sort();
  191. }
  192. void ClassDB::get_inheriters_from_class( const StringName& p_class,List<StringName> *p_classes) {
  193. OBJTYPE_RLOCK;
  194. const StringName *k=NULL;
  195. while((k=classes.next(k))) {
  196. if (*k!=p_class && is_parent_class(*k,p_class))
  197. p_classes->push_back(*k);
  198. }
  199. }
  200. StringName ClassDB::get_parent_class_nocheck(const StringName& p_class) {
  201. OBJTYPE_RLOCK;
  202. ClassInfo *ti = classes.getptr(p_class);
  203. if (!ti)
  204. return StringName();
  205. return ti->inherits;
  206. }
  207. StringName ClassDB::get_parent_class(const StringName& p_class) {
  208. OBJTYPE_RLOCK;
  209. ClassInfo *ti = classes.getptr(p_class);
  210. ERR_FAIL_COND_V(!ti,StringName());
  211. return ti->inherits;
  212. }
  213. ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) {
  214. OBJTYPE_RLOCK;
  215. ClassInfo *ti = classes.getptr(p_class);
  216. ERR_FAIL_COND_V(!ti,API_NONE);
  217. return ti->api;
  218. }
  219. uint64_t ClassDB::get_api_hash(APIType p_api) {
  220. OBJTYPE_RLOCK;
  221. #ifdef DEBUG_METHODS_ENABLED
  222. uint64_t hash = hash_djb2_one_64(HashMapHahserDefault::hash(VERSION_FULL_NAME));
  223. List<StringName> names;
  224. const StringName *k=NULL;
  225. while((k=classes.next(k))) {
  226. names.push_back(*k);
  227. }
  228. //must be alphabetically sorted for hash to compute
  229. names.sort_custom<StringName::AlphCompare>();
  230. for (List<StringName>::Element *E=names.front();E;E=E->next()) {
  231. ClassInfo *t = classes.getptr(E->get());
  232. ERR_FAIL_COND_V(!t,0);
  233. if (t->api!=p_api)
  234. continue;
  235. hash = hash_djb2_one_64(t->name.hash(),hash);
  236. hash = hash_djb2_one_64(t->inherits.hash(),hash);
  237. { //methods
  238. List<StringName> snames;
  239. k=NULL;
  240. while((k=t->method_map.next(k))) {
  241. snames.push_back(*k);
  242. }
  243. snames.sort_custom<StringName::AlphCompare>();
  244. for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
  245. MethodBind *mb = t->method_map[F->get()];
  246. hash = hash_djb2_one_64( mb->get_name().hash(), hash);
  247. hash = hash_djb2_one_64( mb->get_argument_count(), hash);
  248. hash = hash_djb2_one_64( mb->get_argument_type(-1), hash); //return
  249. for(int i=0;i<mb->get_argument_count();i++) {
  250. hash = hash_djb2_one_64( mb->get_argument_info(i).type, hash );
  251. hash = hash_djb2_one_64( mb->get_argument_info(i).name.hash(), hash );
  252. hash = hash_djb2_one_64( mb->get_argument_info(i).hint, hash );
  253. hash = hash_djb2_one_64( mb->get_argument_info(i).hint_string.hash(), hash );
  254. }
  255. hash = hash_djb2_one_64( mb->get_default_argument_count(), hash);
  256. for(int i=0;i<mb->get_default_argument_count();i++) {
  257. //hash should not change, i hope for tis
  258. Variant da = mb->get_default_argument(i);
  259. hash = hash_djb2_one_64( da.hash(), hash );
  260. }
  261. hash = hash_djb2_one_64( mb->get_hint_flags(), hash);
  262. }
  263. }
  264. { //constants
  265. List<StringName> snames;
  266. k=NULL;
  267. while((k=t->constant_map.next(k))) {
  268. snames.push_back(*k);
  269. }
  270. snames.sort_custom<StringName::AlphCompare>();
  271. for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
  272. hash = hash_djb2_one_64(F->get().hash(), hash);
  273. hash = hash_djb2_one_64( t->constant_map[F->get()], hash);
  274. }
  275. }
  276. { //signals
  277. List<StringName> snames;
  278. k=NULL;
  279. while((k=t->signal_map.next(k))) {
  280. snames.push_back(*k);
  281. }
  282. snames.sort_custom<StringName::AlphCompare>();
  283. for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
  284. MethodInfo &mi = t->signal_map[F->get()];
  285. hash = hash_djb2_one_64( F->get().hash(), hash);
  286. for(int i=0;i<mi.arguments.size();i++) {
  287. hash = hash_djb2_one_64( mi.arguments[i].type, hash);
  288. }
  289. }
  290. }
  291. { //properties
  292. List<StringName> snames;
  293. k=NULL;
  294. while((k=t->property_setget.next(k))) {
  295. snames.push_back(*k);
  296. }
  297. snames.sort_custom<StringName::AlphCompare>();
  298. for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
  299. PropertySetGet *psg=t->property_setget.getptr(F->get());
  300. hash = hash_djb2_one_64( F->get().hash(), hash);
  301. hash = hash_djb2_one_64( psg->setter.hash(), hash);
  302. hash = hash_djb2_one_64( psg->getter.hash(), hash);
  303. }
  304. }
  305. //property list
  306. for (List<PropertyInfo>::Element *F=t->property_list.front();F;F=F->next()) {
  307. hash = hash_djb2_one_64( F->get().name.hash(), hash);
  308. hash = hash_djb2_one_64( F->get().type, hash);
  309. hash = hash_djb2_one_64( F->get().hint, hash);
  310. hash = hash_djb2_one_64( F->get().hint_string.hash(), hash);
  311. hash = hash_djb2_one_64( F->get().usage, hash);
  312. }
  313. }
  314. return hash;
  315. #else
  316. return 0;
  317. #endif
  318. }
  319. bool ClassDB::class_exists(const StringName &p_class) {
  320. OBJTYPE_RLOCK;
  321. return classes.has(p_class);
  322. }
  323. void ClassDB::add_compatibility_class(const StringName& p_class,const StringName& p_fallback) {
  324. OBJTYPE_WLOCK;
  325. compat_classes[p_class]=p_fallback;
  326. }
  327. Object *ClassDB::instance(const StringName &p_class) {
  328. ClassInfo *ti;
  329. {
  330. OBJTYPE_RLOCK;
  331. ti=classes.getptr(p_class);
  332. if (!ti || ti->disabled || !ti->creation_func) {
  333. if (compat_classes.has(p_class)) {
  334. ti=classes.getptr(compat_classes[p_class]);
  335. }
  336. }
  337. ERR_FAIL_COND_V(!ti,NULL);
  338. ERR_FAIL_COND_V(ti->disabled,NULL);
  339. ERR_FAIL_COND_V(!ti->creation_func,NULL);
  340. }
  341. return ti->creation_func();
  342. }
  343. bool ClassDB::can_instance(const StringName &p_class) {
  344. OBJTYPE_RLOCK;
  345. ClassInfo *ti = classes.getptr(p_class);
  346. ERR_FAIL_COND_V(!ti,false);
  347. return (!ti->disabled && ti->creation_func!=NULL);
  348. }
  349. void ClassDB::_add_class2(const StringName& p_class, const StringName& p_inherits) {
  350. OBJTYPE_WLOCK;
  351. StringName name = p_class;
  352. ERR_FAIL_COND(classes.has(name));
  353. classes[name]=ClassInfo();
  354. ClassInfo &ti=classes[name];
  355. ti.name=name;
  356. ti.inherits=p_inherits;
  357. ti.api=current_api;
  358. if (ti.inherits) {
  359. ERR_FAIL_COND( !classes.has(ti.inherits) ); //it MUST be registered.
  360. ti.inherits_ptr = &classes[ti.inherits];
  361. } else {
  362. ti.inherits_ptr=NULL;
  363. }
  364. }
  365. void ClassDB::get_method_list(StringName p_class,List<MethodInfo> *p_methods,bool p_no_inheritance) {
  366. OBJTYPE_RLOCK;
  367. ClassInfo *type=classes.getptr(p_class);
  368. while(type) {
  369. if (type->disabled) {
  370. if (p_no_inheritance)
  371. break;
  372. type=type->inherits_ptr;
  373. continue;
  374. }
  375. #ifdef DEBUG_METHODS_ENABLED
  376. for( List<MethodInfo>::Element *E=type->virtual_methods.front();E;E=E->next()) {
  377. p_methods->push_back(E->get());
  378. }
  379. for( List<StringName>::Element *E=type->method_order.front();E;E=E->next()) {
  380. MethodBind *method=type->method_map.get(E->get());
  381. MethodInfo minfo;
  382. minfo.name=E->get();
  383. minfo.id=method->get_method_id();
  384. for (int i=0;i<method->get_argument_count();i++) {
  385. //Variant::Type t=method->get_argument_type(i);
  386. minfo.arguments.push_back(method->get_argument_info(i));
  387. }
  388. if (method->get_argument_type(-1)!=Variant::NIL) {
  389. minfo.return_val=method->get_argument_info(-1);
  390. }
  391. minfo.flags=method->get_hint_flags();
  392. p_methods->push_back(minfo);
  393. }
  394. #else
  395. const StringName *K=NULL;
  396. while((K=type->method_map.next(K))) {
  397. MethodBind*m = type->method_map[*K];
  398. MethodInfo mi;
  399. mi.name=m->get_name();
  400. p_methods->push_back(mi);
  401. }
  402. #endif
  403. if (p_no_inheritance)
  404. break;
  405. type=type->inherits_ptr;
  406. }
  407. }
  408. MethodBind *ClassDB::get_method(StringName p_class, StringName p_name) {
  409. OBJTYPE_RLOCK;
  410. ClassInfo *type=classes.getptr(p_class);
  411. while(type) {
  412. MethodBind **method=type->method_map.getptr(p_name);
  413. if (method && *method)
  414. return *method;
  415. type=type->inherits_ptr;
  416. }
  417. return NULL;
  418. }
  419. void ClassDB::bind_integer_constant(const StringName& p_class, const StringName &p_name, int p_constant) {
  420. OBJTYPE_WLOCK;
  421. ClassInfo *type=classes.getptr(p_class);
  422. if (!type) {
  423. ERR_FAIL_COND(!type);
  424. }
  425. if (type->constant_map.has(p_name)) {
  426. ERR_FAIL();
  427. }
  428. type->constant_map[p_name]=p_constant;
  429. #ifdef DEBUG_METHODS_ENABLED
  430. type->constant_order.push_back(p_name);
  431. #endif
  432. }
  433. void ClassDB::get_integer_constant_list(const StringName& p_class, List<String> *p_constants, bool p_no_inheritance) {
  434. OBJTYPE_RLOCK;
  435. ClassInfo *type=classes.getptr(p_class);
  436. while(type) {
  437. #ifdef DEBUG_METHODS_ENABLED
  438. for(List<StringName>::Element *E=type->constant_order.front();E;E=E->next())
  439. p_constants->push_back(E->get());
  440. #else
  441. const StringName *K=NULL;
  442. while((K=type->constant_map.next(K))) {
  443. p_constants->push_back(*K);
  444. }
  445. #endif
  446. if (p_no_inheritance)
  447. break;
  448. type=type->inherits_ptr;
  449. }
  450. }
  451. int ClassDB::get_integer_constant(const StringName& p_class, const StringName &p_name, bool *p_success) {
  452. OBJTYPE_RLOCK;
  453. ClassInfo *type=classes.getptr(p_class);
  454. while(type) {
  455. int *constant=type->constant_map.getptr(p_name);
  456. if (constant) {
  457. if (p_success)
  458. *p_success=true;
  459. return *constant;
  460. }
  461. type=type->inherits_ptr;
  462. }
  463. if (p_success)
  464. *p_success=false;
  465. return 0;
  466. }
  467. void ClassDB::add_signal(StringName p_class,const MethodInfo& p_signal) {
  468. OBJTYPE_WLOCK;
  469. ClassInfo *type=classes.getptr(p_class);
  470. ERR_FAIL_COND(!type);
  471. ClassInfo *check=type;
  472. StringName sname = p_signal.name;
  473. #ifdef DEBUG_METHODS_ENABLED
  474. while(check) {
  475. if (check->signal_map.has(sname)) {
  476. ERR_EXPLAIN("Type "+String(p_class)+" already has signal: "+String(sname));
  477. ERR_FAIL();
  478. }
  479. check=check->inherits_ptr;
  480. }
  481. #endif
  482. type->signal_map[sname]=p_signal;
  483. }
  484. void ClassDB::get_signal_list(StringName p_class,List<MethodInfo> *p_signals,bool p_no_inheritance) {
  485. OBJTYPE_RLOCK;
  486. ClassInfo *type=classes.getptr(p_class);
  487. ERR_FAIL_COND(!type);
  488. ClassInfo *check=type;
  489. while(check) {
  490. const StringName *S=NULL;
  491. while((S=check->signal_map.next(S))) {
  492. p_signals->push_back(check->signal_map[*S]);
  493. }
  494. if (p_no_inheritance)
  495. return;
  496. check=check->inherits_ptr;
  497. }
  498. }
  499. bool ClassDB::has_signal(StringName p_class,StringName p_signal) {
  500. OBJTYPE_RLOCK;
  501. ClassInfo *type=classes.getptr(p_class);
  502. ClassInfo *check=type;
  503. while(check) {
  504. if (check->signal_map.has(p_signal))
  505. return true;
  506. check=check->inherits_ptr;
  507. }
  508. return false;
  509. }
  510. bool ClassDB::get_signal(StringName p_class,StringName p_signal,MethodInfo *r_signal) {
  511. OBJTYPE_RLOCK;
  512. ClassInfo *type=classes.getptr(p_class);
  513. ClassInfo *check=type;
  514. while(check) {
  515. if (check->signal_map.has(p_signal)) {
  516. if (r_signal) {
  517. *r_signal=check->signal_map[p_signal];
  518. }
  519. return true;
  520. }
  521. check=check->inherits_ptr;
  522. }
  523. return false;
  524. }
  525. void ClassDB::add_property_group(StringName p_class,const String& p_name,const String& p_prefix) {
  526. OBJTYPE_WLOCK;
  527. ClassInfo *type=classes.getptr(p_class);
  528. ERR_FAIL_COND(!type);
  529. type->property_list.push_back(PropertyInfo(Variant::NIL,p_name,PROPERTY_HINT_NONE,p_prefix,PROPERTY_USAGE_GROUP));
  530. }
  531. void ClassDB::add_property(StringName p_class,const PropertyInfo& p_pinfo, const StringName& p_setter, const StringName& p_getter, int p_index) {
  532. #ifndef NO_THREADS
  533. lock->read_lock();
  534. #endif
  535. ClassInfo *type=classes.getptr(p_class);
  536. #ifndef NO_THREADS
  537. lock->read_unlock();
  538. #endif
  539. ERR_FAIL_COND(!type);
  540. MethodBind *mb_set=NULL;
  541. if (p_setter) {
  542. mb_set = get_method(p_class,p_setter);
  543. #ifdef DEBUG_METHODS_ENABLED
  544. if (!mb_set) {
  545. ERR_EXPLAIN("Invalid Setter: "+p_class+"::"+p_setter+" for property: "+p_pinfo.name);
  546. ERR_FAIL_COND(!mb_set);
  547. } else {
  548. int exp_args=1+(p_index>=0?1:0);
  549. if (mb_set->get_argument_count()!=exp_args) {
  550. ERR_EXPLAIN("Invalid Function for Setter: "+p_class+"::"+p_setter+" for property: "+p_pinfo.name);
  551. ERR_FAIL();
  552. }
  553. }
  554. #endif
  555. }
  556. MethodBind *mb_get=NULL;
  557. if (p_getter) {
  558. MethodBind *mb_get = get_method(p_class,p_getter);
  559. #ifdef DEBUG_METHODS_ENABLED
  560. if (!mb_get) {
  561. ERR_EXPLAIN("Invalid Getter: "+p_class+"::"+p_getter+" for property: "+p_pinfo.name);
  562. ERR_FAIL_COND(!mb_get);
  563. } else {
  564. int exp_args=0+(p_index>=0?1:0);
  565. if (mb_get->get_argument_count()!=exp_args) {
  566. ERR_EXPLAIN("Invalid Function for Getter: "+p_class+"::"+p_getter+" for property: "+p_pinfo.name);
  567. ERR_FAIL();
  568. }
  569. }
  570. #endif
  571. }
  572. #ifdef DEBUG_METHODS_ENABLED
  573. if (type->property_setget.has(p_pinfo.name)) {
  574. ERR_EXPLAIN("Object already has property: "+p_class);
  575. ERR_FAIL();
  576. }
  577. #endif
  578. OBJTYPE_WLOCK
  579. type->property_list.push_back(p_pinfo);
  580. PropertySetGet psg;
  581. psg.setter=p_setter;
  582. psg.getter=p_getter;
  583. psg._setptr=mb_set;
  584. psg._getptr=mb_get;
  585. psg.index=p_index;
  586. psg.type=p_pinfo.type;
  587. type->property_setget[p_pinfo.name]=psg;
  588. }
  589. void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance,const Object *p_validator) {
  590. OBJTYPE_RLOCK;
  591. ClassInfo *type=classes.getptr(p_class);
  592. ClassInfo *check=type;
  593. while(check) {
  594. for(List<PropertyInfo>::Element *E=check->property_list.front();E;E=E->next()) {
  595. if (p_validator) {
  596. PropertyInfo pi = E->get();
  597. p_validator->_validate_property(pi);
  598. p_list->push_back(pi);
  599. } else {
  600. p_list->push_back(E->get());
  601. }
  602. }
  603. if (p_no_inheritance)
  604. return ;
  605. check=check->inherits_ptr;
  606. }
  607. }
  608. bool ClassDB::set_property(Object* p_object,const StringName& p_property, const Variant& p_value,bool *r_valid) {
  609. ClassInfo *type=classes.getptr(p_object->get_class_name());
  610. ClassInfo *check=type;
  611. while(check) {
  612. const PropertySetGet *psg = check->property_setget.getptr(p_property);
  613. if (psg) {
  614. if (!psg->setter) {
  615. if (r_valid)
  616. *r_valid=false;
  617. return true; //return true but do nothing
  618. }
  619. Variant::CallError ce;
  620. if (psg->index>=0) {
  621. Variant index=psg->index;
  622. const Variant* arg[2]={&index,&p_value};
  623. //p_object->call(psg->setter,arg,2,ce);
  624. if (psg->_setptr) {
  625. psg->_setptr->call(p_object,arg,2,ce);
  626. } else {
  627. p_object->call(psg->setter,arg,2,ce);
  628. }
  629. } else {
  630. const Variant* arg[1]={&p_value};
  631. if (psg->_setptr) {
  632. psg->_setptr->call(p_object,arg,1,ce);
  633. } else {
  634. p_object->call(psg->setter,arg,1,ce);
  635. }
  636. }
  637. if (r_valid)
  638. *r_valid=ce.error==Variant::CallError::CALL_OK;
  639. return true;
  640. }
  641. check=check->inherits_ptr;
  642. }
  643. return false;
  644. }
  645. bool ClassDB::get_property(Object* p_object,const StringName& p_property, Variant& r_value) {
  646. ClassInfo *type=classes.getptr(p_object->get_class_name());
  647. ClassInfo *check=type;
  648. while(check) {
  649. const PropertySetGet *psg = check->property_setget.getptr(p_property);
  650. if (psg) {
  651. if (!psg->getter)
  652. return true; //return true but do nothing
  653. if (psg->index>=0) {
  654. Variant index=psg->index;
  655. const Variant* arg[1]={&index};
  656. Variant::CallError ce;
  657. r_value = p_object->call(psg->getter,arg,1,ce);
  658. } else {
  659. Variant::CallError ce;
  660. if (psg->_getptr) {
  661. r_value = psg->_getptr->call(p_object,NULL,0,ce);
  662. } else {
  663. r_value = p_object->call(psg->getter,NULL,0,ce);
  664. }
  665. }
  666. return true;
  667. }
  668. const int *c =check->constant_map.getptr(p_property);
  669. if (c) {
  670. r_value=*c;
  671. return true;
  672. }
  673. //if (check->constant_map.fin)
  674. check=check->inherits_ptr;
  675. }
  676. return false;
  677. }
  678. Variant::Type ClassDB::get_property_type(const StringName& p_class, const StringName& p_property,bool *r_is_valid) {
  679. ClassInfo *type=classes.getptr(p_class);
  680. ClassInfo *check=type;
  681. while(check) {
  682. const PropertySetGet *psg = check->property_setget.getptr(p_property);
  683. if (psg) {
  684. if (r_is_valid)
  685. *r_is_valid=true;
  686. return psg->type;
  687. }
  688. check=check->inherits_ptr;
  689. }
  690. if (r_is_valid)
  691. *r_is_valid=false;
  692. return Variant::NIL;
  693. }
  694. StringName ClassDB::get_property_setter(StringName p_class,const StringName p_property) {
  695. ClassInfo *type=classes.getptr(p_class);
  696. ClassInfo *check=type;
  697. while(check) {
  698. const PropertySetGet *psg = check->property_setget.getptr(p_property);
  699. if (psg) {
  700. return psg->setter;
  701. }
  702. check=check->inherits_ptr;
  703. }
  704. return StringName();
  705. }
  706. StringName ClassDB::get_property_getter(StringName p_class,const StringName p_property) {
  707. ClassInfo *type=classes.getptr(p_class);
  708. ClassInfo *check=type;
  709. while(check) {
  710. const PropertySetGet *psg = check->property_setget.getptr(p_property);
  711. if (psg) {
  712. return psg->getter;
  713. }
  714. check=check->inherits_ptr;
  715. }
  716. return StringName();
  717. }
  718. bool ClassDB::has_property(const StringName& p_class, const StringName& p_property, bool p_no_inheritance) {
  719. ClassInfo *type=classes.getptr(p_class);
  720. ClassInfo *check=type;
  721. while(check) {
  722. if (check->property_setget.has(p_property))
  723. return true;
  724. if (p_no_inheritance)
  725. break;
  726. check=check->inherits_ptr;
  727. }
  728. return false;
  729. }
  730. void ClassDB::set_method_flags(StringName p_class,StringName p_method,int p_flags) {
  731. OBJTYPE_WLOCK;
  732. ClassInfo *type=classes.getptr(p_class);
  733. ClassInfo *check=type;
  734. ERR_FAIL_COND(!check);
  735. ERR_FAIL_COND(!check->method_map.has(p_method));
  736. check->method_map[p_method]->set_hint_flags(p_flags);
  737. }
  738. bool ClassDB::has_method(StringName p_class,StringName p_method,bool p_no_inheritance) {
  739. ClassInfo *type=classes.getptr(p_class);
  740. ClassInfo *check=type;
  741. while(check) {
  742. if (check->method_map.has(p_method))
  743. return true;
  744. if (p_no_inheritance)
  745. return false;
  746. check=check->inherits_ptr;
  747. }
  748. return false;
  749. }
  750. bool ClassDB::get_setter_and_type_for_property(const StringName& p_class, const StringName& p_prop, StringName& r_class, StringName& r_setter) {
  751. ClassInfo *type=classes.getptr(p_class);
  752. ClassInfo *check=type;
  753. while(check) {
  754. if (check->property_setget.has(p_prop)) {
  755. r_class=check->name;
  756. r_setter=check->property_setget[p_prop].setter;
  757. return true;
  758. }
  759. check=check->inherits_ptr;
  760. }
  761. return false;
  762. }
  763. #ifdef DEBUG_METHODS_ENABLED
  764. MethodBind* ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) {
  765. StringName mdname=method_name.name;
  766. #else
  767. MethodBind* ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const char *method_name, const Variant **p_defs, int p_defcount) {
  768. StringName mdname=StaticCString::create(method_name);
  769. #endif
  770. StringName rettype;
  771. if (mdname.operator String().find(":")!=-1) {
  772. rettype = mdname.operator String().get_slice(":",1);
  773. mdname = mdname.operator String().get_slice(":",0);
  774. }
  775. OBJTYPE_WLOCK;
  776. ERR_FAIL_COND_V(!p_bind,NULL);
  777. p_bind->set_name(mdname);
  778. String instance_type=p_bind->get_instance_class();
  779. #ifdef DEBUG_ENABLED
  780. if (has_method(instance_type,mdname)) {
  781. ERR_EXPLAIN("Class "+String(instance_type)+" already has a method "+String(mdname));
  782. ERR_FAIL_V(NULL);
  783. }
  784. #endif
  785. ClassInfo *type=classes.getptr(instance_type);
  786. if (!type) {
  787. ERR_PRINTS("Couldn't bind method '"+mdname+"' for instance: "+instance_type);
  788. memdelete(p_bind);
  789. ERR_FAIL_COND_V(!type,NULL);
  790. }
  791. if (type->method_map.has(mdname)) {
  792. memdelete(p_bind);
  793. // overloading not supported
  794. ERR_EXPLAIN("Method already bound: "+instance_type+"::"+mdname);
  795. ERR_FAIL_V(NULL);
  796. }
  797. #ifdef DEBUG_METHODS_ENABLED
  798. p_bind->set_argument_names(method_name.args);
  799. p_bind->set_return_type(rettype);
  800. type->method_order.push_back(mdname);
  801. #endif
  802. type->method_map[mdname]=p_bind;
  803. Vector<Variant> defvals;
  804. defvals.resize(p_defcount);
  805. for(int i=0;i<p_defcount;i++) {
  806. defvals[i]=*p_defs[p_defcount-i-1];
  807. }
  808. p_bind->set_default_arguments(defvals);
  809. p_bind->set_hint_flags(p_flags);
  810. return p_bind;
  811. }
  812. void ClassDB::add_virtual_method(const StringName& p_class, const MethodInfo& p_method , bool p_virtual) {
  813. ERR_FAIL_COND(!classes.has(p_class));
  814. OBJTYPE_WLOCK;
  815. #ifdef DEBUG_METHODS_ENABLED
  816. MethodInfo mi=p_method;
  817. if (p_virtual)
  818. mi.flags|=METHOD_FLAG_VIRTUAL;
  819. classes[p_class].virtual_methods.push_back(mi);
  820. #endif
  821. }
  822. void ClassDB::get_virtual_methods(const StringName& p_class, List<MethodInfo> * p_methods , bool p_no_inheritance) {
  823. ERR_FAIL_COND(!classes.has(p_class));
  824. #ifdef DEBUG_METHODS_ENABLED
  825. ClassInfo *type=classes.getptr(p_class);
  826. ClassInfo *check=type;
  827. while(check) {
  828. for(List<MethodInfo>::Element *E=check->virtual_methods.front();E;E=E->next()) {
  829. p_methods->push_back(E->get());
  830. }
  831. if (p_no_inheritance)
  832. return;
  833. check=check->inherits_ptr;
  834. }
  835. #endif
  836. }
  837. void ClassDB::set_class_enabled(StringName p_class,bool p_enable) {
  838. OBJTYPE_WLOCK;
  839. ERR_FAIL_COND(!classes.has(p_class));
  840. classes[p_class].disabled=!p_enable;
  841. }
  842. bool ClassDB::is_class_enabled(StringName p_class) {
  843. OBJTYPE_RLOCK;
  844. ClassInfo *ti=classes.getptr(p_class);
  845. if (!ti || !ti->creation_func) {
  846. if (compat_classes.has(p_class)) {
  847. ti=classes.getptr(compat_classes[p_class]);
  848. }
  849. }
  850. ERR_FAIL_COND_V(!ti,false);
  851. return !ti->disabled;
  852. }
  853. StringName ClassDB::get_category(const StringName& p_node) {
  854. ERR_FAIL_COND_V(!classes.has(p_node),StringName());
  855. #ifdef DEBUG_ENABLED
  856. return classes[p_node].category;
  857. #else
  858. return StringName();
  859. #endif
  860. }
  861. void ClassDB::add_resource_base_extension(const StringName& p_extension,const StringName& p_class) {
  862. if (resource_base_extensions.has(p_extension))
  863. return;
  864. resource_base_extensions[p_extension]=p_class;
  865. }
  866. void ClassDB::get_resource_base_extensions(List<String> *p_extensions) {
  867. const StringName *K=NULL;
  868. while((K=resource_base_extensions.next(K))) {
  869. p_extensions->push_back(*K);
  870. }
  871. }
  872. void ClassDB::get_extensions_for_type(const StringName& p_class,List<String> *p_extensions) {
  873. const StringName *K=NULL;
  874. while((K=resource_base_extensions.next(K))) {
  875. StringName cmp = resource_base_extensions[*K];
  876. if (is_parent_class(cmp,p_class))
  877. p_extensions->push_back(*K);
  878. }
  879. }
  880. RWLock *ClassDB::lock=NULL;
  881. void ClassDB::init() {
  882. #ifndef NO_THREADS
  883. lock = RWLock::create();
  884. #endif
  885. }
  886. void ClassDB::cleanup() {
  887. //OBJTYPE_LOCK; hah not here
  888. const StringName *k=NULL;
  889. while((k=classes.next(k))) {
  890. ClassInfo &ti=classes[*k];
  891. const StringName *m=NULL;
  892. while((m=ti.method_map.next(m))) {
  893. memdelete( ti.method_map[*m] );
  894. }
  895. }
  896. classes.clear();
  897. resource_base_extensions.clear();
  898. compat_classes.clear();
  899. #ifndef NO_THREADS
  900. memdelete(lock);
  901. #endif
  902. }
  903. //