| 
									
										
										
										
											2023-01-10 15:26:54 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  class_db.cpp                                                          */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining  */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the        */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including    */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,    */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to     */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to  */ | 
					
						
							|  |  |  | /* the following conditions:                                              */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be         */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.        */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-16 08:04:19 +01:00
										 |  |  | #include "class_db.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/engine.h"
 | 
					
						
							|  |  |  | #include "core/os/mutex.h"
 | 
					
						
							|  |  |  | #include "core/version.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | #define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock);
 | 
					
						
							|  |  |  | #define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(const char *p_name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(const char *p_name, const char *p_arg1) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	md.args.push_back(StaticCString::create(p_arg1)); | 
					
						
							|  |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	md.args.resize(2); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	md.args.resize(3); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	md.args.resize(4); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	md.args.resize(5); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(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) { | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	md.args.resize(6); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							|  |  |  | 	md.args.write[5] = StaticCString::create(p_arg6); | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(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) { | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-09-17 12:24:38 -03:00
										 |  |  | 	md.args.resize(7); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							|  |  |  | 	md.args.write[5] = StaticCString::create(p_arg6); | 
					
						
							|  |  |  | 	md.args.write[6] = StaticCString::create(p_arg7); | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(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) { | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-09-17 12:21:50 -03:00
										 |  |  | 	md.args.resize(8); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							|  |  |  | 	md.args.write[5] = StaticCString::create(p_arg6); | 
					
						
							|  |  |  | 	md.args.write[6] = StaticCString::create(p_arg7); | 
					
						
							|  |  |  | 	md.args.write[7] = StaticCString::create(p_arg8); | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(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) { | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-09-17 12:21:50 -03:00
										 |  |  | 	md.args.resize(9); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							|  |  |  | 	md.args.write[5] = StaticCString::create(p_arg6); | 
					
						
							|  |  |  | 	md.args.write[6] = StaticCString::create(p_arg7); | 
					
						
							|  |  |  | 	md.args.write[7] = StaticCString::create(p_arg8); | 
					
						
							|  |  |  | 	md.args.write[8] = StaticCString::create(p_arg9); | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodDefinition D_METHOD(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) { | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	MethodDefinition md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							| 
									
										
										
										
											2014-09-17 12:21:50 -03:00
										 |  |  | 	md.args.resize(10); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							|  |  |  | 	md.args.write[5] = StaticCString::create(p_arg6); | 
					
						
							|  |  |  | 	md.args.write[6] = StaticCString::create(p_arg7); | 
					
						
							|  |  |  | 	md.args.write[7] = StaticCString::create(p_arg8); | 
					
						
							|  |  |  | 	md.args.write[8] = StaticCString::create(p_arg9); | 
					
						
							|  |  |  | 	md.args.write[9] = StaticCString::create(p_arg10); | 
					
						
							| 
									
										
										
										
											2014-09-17 11:53:29 -03:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-20 00:24:49 +02:00
										 |  |  | MethodDefinition D_METHOD(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, const char *p_arg11) { | 
					
						
							|  |  |  | 	MethodDefinition md; | 
					
						
							|  |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							|  |  |  | 	md.args.resize(11); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							|  |  |  | 	md.args.write[5] = StaticCString::create(p_arg6); | 
					
						
							|  |  |  | 	md.args.write[6] = StaticCString::create(p_arg7); | 
					
						
							|  |  |  | 	md.args.write[7] = StaticCString::create(p_arg8); | 
					
						
							|  |  |  | 	md.args.write[8] = StaticCString::create(p_arg9); | 
					
						
							|  |  |  | 	md.args.write[9] = StaticCString::create(p_arg10); | 
					
						
							|  |  |  | 	md.args.write[10] = StaticCString::create(p_arg11); | 
					
						
							| 
									
										
										
										
											2017-10-20 00:24:49 +02:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Added all missing VisualServer bindings
- Added bindings for multimesh, immediate, skeleton, light, reflection probe, gi probe, lightmap, particles, camera, environment, scenario, instance
- Removed draw and sync, were duplicates of force_* equivalents
- Bumped binders max arguments from 11 to 13
- Wrote some wrappers as not all methods were variant-friendly
											
										 
											2018-01-20 16:18:51 +01:00
										 |  |  | MethodDefinition D_METHOD(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, const char *p_arg11, const char *p_arg12) { | 
					
						
							|  |  |  | 	MethodDefinition md; | 
					
						
							|  |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							|  |  |  | 	md.args.resize(12); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							|  |  |  | 	md.args.write[5] = StaticCString::create(p_arg6); | 
					
						
							|  |  |  | 	md.args.write[6] = StaticCString::create(p_arg7); | 
					
						
							|  |  |  | 	md.args.write[7] = StaticCString::create(p_arg8); | 
					
						
							|  |  |  | 	md.args.write[8] = StaticCString::create(p_arg9); | 
					
						
							|  |  |  | 	md.args.write[9] = StaticCString::create(p_arg10); | 
					
						
							|  |  |  | 	md.args.write[10] = StaticCString::create(p_arg11); | 
					
						
							|  |  |  | 	md.args.write[11] = StaticCString::create(p_arg12); | 
					
						
							| 
									
										
										
											
												Added all missing VisualServer bindings
- Added bindings for multimesh, immediate, skeleton, light, reflection probe, gi probe, lightmap, particles, camera, environment, scenario, instance
- Removed draw and sync, were duplicates of force_* equivalents
- Bumped binders max arguments from 11 to 13
- Wrote some wrappers as not all methods were variant-friendly
											
										 
											2018-01-20 16:18:51 +01:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MethodDefinition D_METHOD(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, const char *p_arg11, const char *p_arg12, const char *p_arg13) { | 
					
						
							|  |  |  | 	MethodDefinition md; | 
					
						
							|  |  |  | 	md.name = StaticCString::create(p_name); | 
					
						
							|  |  |  | 	md.args.resize(13); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	md.args.write[0] = StaticCString::create(p_arg1); | 
					
						
							|  |  |  | 	md.args.write[1] = StaticCString::create(p_arg2); | 
					
						
							|  |  |  | 	md.args.write[2] = StaticCString::create(p_arg3); | 
					
						
							|  |  |  | 	md.args.write[3] = StaticCString::create(p_arg4); | 
					
						
							|  |  |  | 	md.args.write[4] = StaticCString::create(p_arg5); | 
					
						
							|  |  |  | 	md.args.write[5] = StaticCString::create(p_arg6); | 
					
						
							|  |  |  | 	md.args.write[6] = StaticCString::create(p_arg7); | 
					
						
							|  |  |  | 	md.args.write[7] = StaticCString::create(p_arg8); | 
					
						
							|  |  |  | 	md.args.write[8] = StaticCString::create(p_arg9); | 
					
						
							|  |  |  | 	md.args.write[9] = StaticCString::create(p_arg10); | 
					
						
							|  |  |  | 	md.args.write[10] = StaticCString::create(p_arg11); | 
					
						
							|  |  |  | 	md.args.write[11] = StaticCString::create(p_arg12); | 
					
						
							|  |  |  | 	md.args.write[12] = StaticCString::create(p_arg13); | 
					
						
							| 
									
										
										
											
												Added all missing VisualServer bindings
- Added bindings for multimesh, immediate, skeleton, light, reflection probe, gi probe, lightmap, particles, camera, environment, scenario, instance
- Removed draw and sync, were duplicates of force_* equivalents
- Bumped binders max arguments from 11 to 13
- Wrote some wrappers as not all methods were variant-friendly
											
										 
											2018-01-20 16:18:51 +01:00
										 |  |  | 	return md; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | ClassDB::APIType ClassDB::current_api = API_CORE; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | void ClassDB::set_current_api(APIType p_api) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	current_api = p_api; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-06 16:12:59 +02:00
										 |  |  | ClassDB::APIType ClassDB::get_current_api() { | 
					
						
							|  |  |  | 	return current_api; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes; | 
					
						
							|  |  |  | HashMap<StringName, StringName> ClassDB::resource_base_extensions; | 
					
						
							|  |  |  | HashMap<StringName, StringName> ClassDB::compat_classes; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | ClassDB::ClassInfo::ClassInfo() { | 
					
						
							| 
									
										
										
										
											2018-04-19 13:04:41 +02:00
										 |  |  | 	api = API_NONE; | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	creation_func = nullptr; | 
					
						
							|  |  |  | 	inherits_ptr = nullptr; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	disabled = false; | 
					
						
							| 
									
										
										
										
											2017-10-09 23:49:17 +02:00
										 |  |  | 	exposed = false; | 
					
						
							| 
									
										
										
										
											2021-10-10 17:49:50 +02:00
										 |  |  | 	class_ptr = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-04-19 13:04:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | ClassDB::ClassInfo::~ClassInfo() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-01 00:44:15 -07:00
										 |  |  | bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_inherits) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	StringName inherits = p_class; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	while (inherits.operator String().length()) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (inherits == p_inherits) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-01 00:44:15 -07:00
										 |  |  | 		inherits = _get_parent_class(inherits); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-11-01 00:44:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) { | 
					
						
							|  |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return _is_parent_class(p_class, p_inherits); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::get_class_list(List<StringName> *p_classes) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	const StringName *k = nullptr; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while ((k = classes.next(k))) { | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 		p_classes->push_back(*k); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	p_classes->sort(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	const StringName *k = nullptr; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while ((k = classes.next(k))) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (*k != p_class && _is_parent_class(*k, p_class)) { | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 			p_classes->push_back(*k); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-08 19:18:03 -03:00
										 |  |  | void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) { | 
					
						
							|  |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	const StringName *k = nullptr; | 
					
						
							| 
									
										
										
										
											2019-04-08 19:18:03 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while ((k = classes.next(k))) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (*k != p_class && _get_parent_class(*k) == p_class) { | 
					
						
							| 
									
										
										
										
											2019-04-08 19:18:03 -03:00
										 |  |  | 			p_classes->push_back(*k); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-08 19:18:03 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) { | 
					
						
							| 
									
										
										
										
											2017-01-11 18:29:59 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassInfo *ti = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (!ti) { | 
					
						
							| 
									
										
										
										
											2017-01-11 18:29:59 -03:00
										 |  |  | 		return StringName(); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-11 18:29:59 -03:00
										 |  |  | 	return ti->inherits; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-01 00:44:15 -07:00
										 |  |  | StringName ClassDB::_get_parent_class(const StringName &p_class) { | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	ClassInfo *ti = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!ti, StringName(), "Cannot get class '" + String(p_class) + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return ti->inherits; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-01 00:44:15 -07:00
										 |  |  | StringName ClassDB::get_parent_class(const StringName &p_class) { | 
					
						
							|  |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return _get_parent_class(p_class); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	ClassInfo *ti = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2017-01-11 18:29:59 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!ti, API_NONE, "Cannot get class '" + String(p_class) + "'."); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 	return ti->api; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | uint64_t ClassDB::get_api_hash(APIType p_api) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Refactor version macros and fix related bugs
The previous logic with VERSION_MKSTRING was a bit unwieldy, so there were
several places hardcoding their own variant of the version string, potentially
with bugs (e.g. forgetting the patch number when defined).
The new logic defines:
- VERSION_BRANCH, the main 'major.minor' version (e.g. 3.1)
- VERSION_NUMBER, which can be 'major.minor' or 'major.minor.patch',
  depending on whether the latter is defined (e.g. 3.1.4)
- VERSION_FULL_CONFIG, which contains the version status (e.g. stable)
  and the module-specific suffix (e.g. mono)
- VERSION_FULL_BUILD, same as above but with build/reference name
  (e.g. official, custom_build, mageia, etc.)
  Note: Slight change here, as the previous format had the build name
  *before* the module-specific suffix; now it's after
- VERSION_FULL_NAME, same as before, so VERSION_FULL_BUILD prefixed
  with "Godot v" for readability
Bugs fixed thanks to that:
- Export templates version matching now properly takes VERSION_PATCH
  into account by relying on VERSION_FULL_CONFIG.
- ClassDB hash no longer takes the build name into account, but limits
  itself to VERSION_FULL_CONFIG (build name is cosmetic, not relevant
  for the API hash).
- Docs XML no longer hardcode the VERSION_STATUS, this was annoying.
- Small cleanup in Windows .rc file thanks to new macros.
											
										 
											2018-02-23 19:48:49 +01:00
										 |  |  | 	uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	List<StringName> names; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	const StringName *k = nullptr; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while ((k = classes.next(k))) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 		names.push_back(*k); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	//must be alphabetically sorted for hash to compute
 | 
					
						
							|  |  |  | 	names.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (List<StringName>::Element *E = names.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 		ClassInfo *t = classes.getptr(E->get()); | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 		ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E->get()) + "'."); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (t->api != p_api || !t->exposed) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		hash = hash_djb2_one_64(t->name.hash(), hash); | 
					
						
							|  |  |  | 		hash = hash_djb2_one_64(t->inherits.hash(), hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		{ //methods
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			List<StringName> snames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			k = nullptr; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			while ((k = t->method_map.next(k))) { | 
					
						
							| 
									
										
										
										
											2020-01-07 00:08:46 +01:00
										 |  |  | 				String name = k->operator String(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				ERR_CONTINUE(name.empty()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 				if (name[0] == '_') { | 
					
						
							| 
									
										
										
										
											2020-01-07 00:08:46 +01:00
										 |  |  | 					continue; // Ignore non-virtual methods that start with an underscore
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-01-07 00:08:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				snames.push_back(*k); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			snames.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				MethodBind *mb = t->method_map[F->get()]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				hash = hash_djb2_one_64(mb->get_name().hash(), hash); | 
					
						
							|  |  |  | 				hash = hash_djb2_one_64(mb->get_argument_count(), hash); | 
					
						
							|  |  |  | 				hash = hash_djb2_one_64(mb->get_argument_type(-1), hash); //return
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				for (int i = 0; i < mb->get_argument_count(); i++) { | 
					
						
							| 
									
										
										
										
											2017-12-16 15:47:36 +01:00
										 |  |  | 					const PropertyInfo info = mb->get_argument_info(i); | 
					
						
							|  |  |  | 					hash = hash_djb2_one_64(info.type, hash); | 
					
						
							|  |  |  | 					hash = hash_djb2_one_64(info.name.hash(), hash); | 
					
						
							|  |  |  | 					hash = hash_djb2_one_64(info.hint, hash); | 
					
						
							|  |  |  | 					hash = hash_djb2_one_64(info.hint_string.hash(), hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				hash = hash_djb2_one_64(mb->get_default_argument_count(), hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				for (int i = 0; i < mb->get_default_argument_count(); i++) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 					//hash should not change, i hope for tis
 | 
					
						
							|  |  |  | 					Variant da = mb->get_default_argument(i); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					hash = hash_djb2_one_64(da.hash(), hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				hash = hash_djb2_one_64(mb->get_hint_flags(), hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ //constants
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			List<StringName> snames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			k = nullptr; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			while ((k = t->constant_map.next(k))) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				snames.push_back(*k); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			snames.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				hash = hash_djb2_one_64(F->get().hash(), hash); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				hash = hash_djb2_one_64(t->constant_map[F->get()], hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ //signals
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			List<StringName> snames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			k = nullptr; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			while ((k = t->signal_map.next(k))) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				snames.push_back(*k); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			snames.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				MethodInfo &mi = t->signal_map[F->get()]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				hash = hash_djb2_one_64(F->get().hash(), hash); | 
					
						
							|  |  |  | 				for (int i = 0; i < mi.arguments.size(); i++) { | 
					
						
							|  |  |  | 					hash = hash_djb2_one_64(mi.arguments[i].type, hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ //properties
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			List<StringName> snames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			k = nullptr; | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			while ((k = t->property_setget.next(k))) { | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 				snames.push_back(*k); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			snames.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { | 
					
						
							|  |  |  | 				PropertySetGet *psg = t->property_setget.getptr(F->get()); | 
					
						
							| 
									
										
										
										
											2019-07-23 09:14:31 +02:00
										 |  |  | 				ERR_FAIL_COND_V(!psg, 0); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				hash = hash_djb2_one_64(F->get().hash(), hash); | 
					
						
							|  |  |  | 				hash = hash_djb2_one_64(psg->setter.hash(), hash); | 
					
						
							|  |  |  | 				hash = hash_djb2_one_64(psg->getter.hash(), hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		//property list
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (List<PropertyInfo>::Element *F = t->property_list.front(); F; F = F->next()) { | 
					
						
							|  |  |  | 			hash = hash_djb2_one_64(F->get().name.hash(), hash); | 
					
						
							|  |  |  | 			hash = hash_djb2_one_64(F->get().type, hash); | 
					
						
							|  |  |  | 			hash = hash_djb2_one_64(F->get().hint, hash); | 
					
						
							|  |  |  | 			hash = hash_djb2_one_64(F->get().hint_string.hash(), hash); | 
					
						
							|  |  |  | 			hash = hash_djb2_one_64(F->get().usage, hash); | 
					
						
							| 
									
										
										
										
											2016-09-14 19:37:37 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return hash; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | bool ClassDB::class_exists(const StringName &p_class) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	return classes.has(p_class); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::add_compatibility_class(const StringName &p_class, const StringName &p_fallback) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	compat_classes[p_class] = p_fallback; | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | Object *ClassDB::instance(const StringName &p_class) { | 
					
						
							|  |  |  | 	ClassInfo *ti; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 		OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ti = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | 		if (!ti || ti->disabled || !ti->creation_func) { | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 			if (compat_classes.has(p_class)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ti = classes.getptr(compat_classes[p_class]); | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		ERR_FAIL_COND_V_MSG(!ti, nullptr, "Cannot get class '" + String(p_class) + "'."); | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, "Class '" + String(p_class) + "' is disabled."); | 
					
						
							| 
									
										
										
										
											2021-10-05 08:09:09 -04:00
										 |  |  | 		ERR_FAIL_COND_V_MSG(!ti->creation_func, nullptr, "Class '" + String(p_class) + "' or its base class cannot be instantiated."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-06 21:07:46 -03:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							|  |  |  | 	if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) { | 
					
						
							| 
									
										
										
										
											2021-06-16 11:56:25 +01:00
										 |  |  | 		ERR_PRINT("Class '" + String(p_class) + "' can only be instantiated by editor."); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2018-09-06 21:07:46 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return ti->creation_func(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | bool ClassDB::can_instance(const StringName &p_class) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	ClassInfo *ti = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'."); | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							|  |  |  | 	if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	return (!ti->disabled && ti->creation_func != nullptr); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	const StringName &name = p_class; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(classes.has(name), "Class '" + String(p_class) + "' already exists."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	classes[name] = ClassInfo(); | 
					
						
							|  |  |  | 	ClassInfo &ti = classes[name]; | 
					
						
							|  |  |  | 	ti.name = name; | 
					
						
							|  |  |  | 	ti.inherits = p_inherits; | 
					
						
							|  |  |  | 	ti.api = current_api; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ti.inherits) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ERR_FAIL_COND(!classes.has(ti.inherits)); //it MUST be registered.
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 		ti.inherits_ptr = &classes[ti.inherits]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		ti.inherits_ptr = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 10:24:20 -03:00
										 |  |  | static MethodInfo info_from_bind(MethodBind *p_method) { | 
					
						
							|  |  |  | 	MethodInfo minfo; | 
					
						
							|  |  |  | 	minfo.name = p_method->get_name(); | 
					
						
							|  |  |  | 	minfo.id = p_method->get_method_id(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < p_method->get_argument_count(); i++) { | 
					
						
							|  |  |  | 		minfo.arguments.push_back(p_method->get_argument_info(i)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	minfo.return_val = p_method->get_return_info(); | 
					
						
							|  |  |  | 	minfo.flags = p_method->get_hint_flags(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < p_method->get_argument_count(); i++) { | 
					
						
							|  |  |  | 		if (p_method->has_default_argument(i)) { | 
					
						
							|  |  |  | 			minfo.default_arguments.push_back(p_method->get_default_argument(i)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return minfo; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-23 15:10:46 -03:00
										 |  |  | void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (type) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (type->disabled) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			type = type->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (List<MethodInfo>::Element *E = type->virtual_methods.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			p_methods->push_back(E->get()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (List<StringName>::Element *E = type->method_order.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2022-04-01 10:24:20 -03:00
										 |  |  | 			if (p_exclude_from_properties && type->methods_in_properties.has(E->get())) { | 
					
						
							| 
									
										
										
										
											2017-06-23 15:10:46 -03:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-06-23 15:10:46 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 10:24:20 -03:00
										 |  |  | 			MethodBind *method = type->method_map.get(E->get()); | 
					
						
							|  |  |  | 			MethodInfo minfo = info_from_bind(method); | 
					
						
							| 
									
										
										
										
											2017-08-29 18:11:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			p_methods->push_back(minfo); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 10:24:20 -03:00
										 |  |  | 		const StringName *K = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		while ((K = type->method_map.next(K))) { | 
					
						
							|  |  |  | 			MethodBind *m = type->method_map[*K]; | 
					
						
							| 
									
										
										
										
											2022-04-01 10:24:20 -03:00
										 |  |  | 			MethodInfo minfo = info_from_bind(m); | 
					
						
							|  |  |  | 			p_methods->push_back(minfo); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		type = type->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | MethodBind *ClassDB::get_method(StringName p_class, StringName p_name) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (type) { | 
					
						
							|  |  |  | 		MethodBind **method = type->method_map.getptr(p_name); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (method && *method) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return *method; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		type = type->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	return nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | void ClassDB::bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 16:59:48 +02:00
										 |  |  | 	ERR_FAIL_COND(!type); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (type->constant_map.has(p_name)) { | 
					
						
							|  |  |  | 		ERR_FAIL(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	type->constant_map[p_name] = p_constant; | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 00:06:56 -03:00
										 |  |  | 	String enum_name = p_enum; | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:32 +02:00
										 |  |  | 	if (enum_name != String()) { | 
					
						
							|  |  |  | 		if (enum_name.find(".") != -1) { | 
					
						
							|  |  |  | 			enum_name = enum_name.get_slicec('.', 1); | 
					
						
							| 
									
										
										
										
											2017-08-24 00:06:56 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		List<StringName> *constants_list = type->enum_map.getptr(enum_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (constants_list) { | 
					
						
							|  |  |  | 			constants_list->push_back(p_name); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			List<StringName> new_list; | 
					
						
							|  |  |  | 			new_list.push_back(p_name); | 
					
						
							|  |  |  | 			type->enum_map[enum_name] = new_list; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-30 16:20:24 +02:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	type->constant_order.push_back(p_name); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (type) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		for (List<StringName>::Element *E = type->constant_order.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			p_constants->push_back(E->get()); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		const StringName *K = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		while ((K = type->constant_map.next(K))) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			p_constants->push_back(*K); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		type = type->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | int ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (type) { | 
					
						
							|  |  |  | 		int *constant = type->constant_map.getptr(p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (constant) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (p_success) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				*p_success = true; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return *constant; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		type = type->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (p_success) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		*p_success = false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { | 
					
						
							|  |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (type) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		const StringName *k = nullptr; | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 		while ((k = type->enum_map.next(k))) { | 
					
						
							|  |  |  | 			List<StringName> &constants_list = type->enum_map.get(*k); | 
					
						
							|  |  |  | 			const List<StringName>::Element *found = constants_list.find(p_name); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (found) { | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 				return *k; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		type = type->inherits_ptr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return StringName(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClassDB::get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance) { | 
					
						
							|  |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (type) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		const StringName *k = nullptr; | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 		while ((k = type->enum_map.next(k))) { | 
					
						
							|  |  |  | 			p_enums->push_back(*k); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		type = type->inherits_ptr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance) { | 
					
						
							|  |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (type) { | 
					
						
							|  |  |  | 		const List<StringName> *constants = type->enum_map.getptr(p_enum); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (constants) { | 
					
						
							|  |  |  | 			for (const List<StringName>::Element *E = constants->front(); E; E = E->next()) { | 
					
						
							|  |  |  | 				p_constants->push_back(E->get()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		type = type->inherits_ptr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-11 20:33:29 +08:00
										 |  |  | bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { | 
					
						
							|  |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (type) { | 
					
						
							|  |  |  | 		if (type->enum_map.has(p_name)) { | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (p_no_inheritance) { | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		type = type->inherits_ptr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	ERR_FAIL_COND(!type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	StringName sname = p_signal.name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 16:13:34 +02:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 		ERR_FAIL_COND_MSG(check->signal_map.has(sname), "Class '" + String(p_class) + "' already has signal '" + String(sname) + "'."); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	type->signal_map[sname] = p_signal; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	ERR_FAIL_COND(!type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *check = type; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		const StringName *S = nullptr; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		while ((S = check->signal_map.next(S))) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			p_signals->push_back(check->signal_map[*S]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool ClassDB::has_signal(StringName p_class, StringName p_signal) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (check->signal_map.has(p_signal)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool ClassDB::get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2016-08-07 19:22:33 -03:00
										 |  |  | 		if (check->signal_map.has(p_signal)) { | 
					
						
							|  |  |  | 			if (r_signal) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				*r_signal = check->signal_map[p_signal]; | 
					
						
							| 
									
										
										
										
											2016-08-07 19:22:33 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2016-08-07 19:22:33 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::add_property_group(StringName p_class, const String &p_name, const String &p_prefix) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2017-01-03 00:38:16 -03:00
										 |  |  | 	ERR_FAIL_COND(!type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	type->property_list.push_back(PropertyInfo(Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_GROUP)); | 
					
						
							| 
									
										
										
										
											2017-01-03 00:38:16 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) { | 
					
						
							| 
									
										
										
										
											2021-01-25 19:48:38 +01:00
										 |  |  | 	lock.read_lock(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2021-01-25 19:48:38 +01:00
										 |  |  | 	lock.read_unlock(); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	ERR_FAIL_COND(!type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	MethodBind *mb_set = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (p_setter) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		mb_set = get_method(p_class, p_setter); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 		ERR_FAIL_COND_MSG(!mb_set, "Invalid setter '" + p_class + "::" + p_setter + "' for property '" + p_pinfo.name + "'."); | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		int exp_args = 1 + (p_index >= 0 ? 1 : 0); | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 		ERR_FAIL_COND_MSG(mb_set->get_argument_count() != exp_args, "Invalid function for setter '" + p_class + "::" + p_setter + " for property '" + p_pinfo.name + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	MethodBind *mb_get = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (p_getter) { | 
					
						
							| 
									
										
										
										
											2017-08-28 00:03:34 -03:00
										 |  |  | 		mb_get = get_method(p_class, p_getter); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 		ERR_FAIL_COND_MSG(!mb_get, "Invalid getter '" + p_class + "::" + p_getter + "' for property '" + p_pinfo.name + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 		int exp_args = 0 + (p_index >= 0 ? 1 : 0); | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 		ERR_FAIL_COND_MSG(mb_get->get_argument_count() != exp_args, "Invalid function for getter '" + p_class + "::" + p_getter + "' for property: '" + p_pinfo.name + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(type->property_setget.has(p_pinfo.name), "Object '" + p_class + "' already has property '" + p_pinfo.name + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	OBJTYPE_WLOCK | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	type->property_list.push_back(p_pinfo); | 
					
						
							| 
									
										
										
										
											2017-06-23 15:10:46 -03:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							|  |  |  | 	if (mb_get) { | 
					
						
							|  |  |  | 		type->methods_in_properties.insert(p_getter); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (mb_set) { | 
					
						
							|  |  |  | 		type->methods_in_properties.insert(p_setter); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	PropertySetGet psg; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	psg.setter = p_setter; | 
					
						
							|  |  |  | 	psg.getter = p_getter; | 
					
						
							|  |  |  | 	psg._setptr = mb_set; | 
					
						
							|  |  |  | 	psg._getptr = mb_get; | 
					
						
							|  |  |  | 	psg.index = p_index; | 
					
						
							|  |  |  | 	psg.type = p_pinfo.type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	type->property_setget[p_pinfo.name] = psg; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | void ClassDB::set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default) { | 
					
						
							|  |  |  | 	if (!default_values.has(p_class)) { | 
					
						
							|  |  |  | 		default_values[p_class] = HashMap<StringName, Variant>(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	default_values[p_class][p_name] = p_default; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							|  |  |  | 		for (List<PropertyInfo>::Element *E = check->property_list.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2016-05-14 23:48:23 -03:00
										 |  |  | 			if (p_validator) { | 
					
						
							|  |  |  | 				PropertyInfo pi = E->get(); | 
					
						
							|  |  |  | 				p_validator->_validate_property(pi); | 
					
						
							|  |  |  | 				p_list->push_back(pi); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				p_list->push_back(E->get()); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid) { | 
					
						
							| 
									
										
										
										
											2021-04-02 20:05:01 +02:00
										 |  |  | 	ERR_FAIL_NULL_V(p_object, false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_object->get_class_name()); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		const PropertySetGet *psg = check->property_setget.getptr(p_property); | 
					
						
							|  |  |  | 		if (psg) { | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 			if (!psg->setter) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 				if (r_valid) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					*r_valid = false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				return true; //return true but do nothing
 | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Variant::CallError ce; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (psg->index >= 0) { | 
					
						
							|  |  |  | 				Variant index = psg->index; | 
					
						
							|  |  |  | 				const Variant *arg[2] = { &index, &p_value }; | 
					
						
							| 
									
										
										
										
											2017-01-14 12:26:56 +01:00
										 |  |  | 				//p_object->call(psg->setter,arg,2,ce);
 | 
					
						
							| 
									
										
										
										
											2015-06-29 00:29:49 -03:00
										 |  |  | 				if (psg->_setptr) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					psg->_setptr->call(p_object, arg, 2, ce); | 
					
						
							| 
									
										
										
										
											2015-06-29 00:29:49 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					p_object->call(psg->setter, arg, 2, ce); | 
					
						
							| 
									
										
										
										
											2015-06-29 00:29:49 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				const Variant *arg[1] = { &p_value }; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				if (psg->_setptr) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					psg->_setptr->call(p_object, arg, 1, ce); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					p_object->call(psg->setter, arg, 1, ce); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (r_valid) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				*r_valid = ce.error == Variant::CallError::CALL_OK; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool ClassDB::get_property(Object *p_object, const StringName &p_property, Variant &r_value) { | 
					
						
							| 
									
										
										
										
											2021-04-02 20:05:01 +02:00
										 |  |  | 	ERR_FAIL_NULL_V(p_object, false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_object->get_class_name()); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		const PropertySetGet *psg = check->property_setget.getptr(p_property); | 
					
						
							|  |  |  | 		if (psg) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (!psg->getter) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				return true; //return true but do nothing
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (psg->index >= 0) { | 
					
						
							|  |  |  | 				Variant index = psg->index; | 
					
						
							|  |  |  | 				const Variant *arg[1] = { &index }; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				Variant::CallError ce; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				r_value = p_object->call(psg->getter, arg, 1, ce); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				Variant::CallError ce; | 
					
						
							|  |  |  | 				if (psg->_getptr) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 					r_value = psg->_getptr->call(p_object, nullptr, 0, ce); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 					r_value = p_object->call(psg->getter, nullptr, 0, ce); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		const int *c = check->constant_map.getptr(p_property); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (c) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			r_value = *c; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-06 02:04:10 +02:00
										 |  |  | int ClassDB::get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid) { | 
					
						
							|  |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							|  |  |  | 		const PropertySetGet *psg = check->property_setget.getptr(p_property); | 
					
						
							|  |  |  | 		if (psg) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (r_is_valid) { | 
					
						
							| 
									
										
										
										
											2017-08-06 02:04:10 +02:00
										 |  |  | 				*r_is_valid = true; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-08-06 02:04:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return psg->index; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		check = check->inherits_ptr; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (r_is_valid) { | 
					
						
							| 
									
										
										
										
											2017-08-06 02:04:10 +02:00
										 |  |  | 		*r_is_valid = false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-06 02:04:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Variant::Type ClassDB::get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid) { | 
					
						
							|  |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 		const PropertySetGet *psg = check->property_setget.getptr(p_property); | 
					
						
							|  |  |  | 		if (psg) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (r_is_valid) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				*r_is_valid = true; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return psg->type; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (r_is_valid) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		*r_is_valid = false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return Variant::NIL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-10 11:54:12 +02:00
										 |  |  | StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_property) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 		const PropertySetGet *psg = check->property_setget.getptr(p_property); | 
					
						
							|  |  |  | 		if (psg) { | 
					
						
							|  |  |  | 			return psg->setter; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return StringName(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-10 11:54:12 +02:00
										 |  |  | StringName ClassDB::get_property_getter(StringName p_class, const StringName &p_property) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 		const PropertySetGet *psg = check->property_setget.getptr(p_property); | 
					
						
							|  |  |  | 		if (psg) { | 
					
						
							|  |  |  | 			return psg->getter; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return StringName(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool ClassDB::has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance) { | 
					
						
							|  |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (check->property_setget.has(p_property)) { | 
					
						
							| 
									
										
										
										
											2017-01-04 17:37:45 -03:00
										 |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-04 17:37:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2017-01-04 17:37:45 -03:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2017-01-04 17:37:45 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::set_method_flags(StringName p_class, StringName p_method, int p_flags) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	ERR_FAIL_COND(!check); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!check->method_map.has(p_method)); | 
					
						
							|  |  |  | 	check->method_map[p_method]->set_hint_flags(p_flags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inheritance) { | 
					
						
							|  |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (check->method_map.has(p_method)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) { | 
					
						
							|  |  |  | 	StringName mdname = method_name.name; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount) { | 
					
						
							|  |  |  | 	StringName mdname = StaticCString::create(method_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	ERR_FAIL_COND_V(!p_bind, nullptr); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	p_bind->set_name(mdname); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	String instance_type = p_bind->get_instance_class(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 11:07:57 -03:00
										 |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(has_method(instance_type, mdname), nullptr, "Class " + String(instance_type) + " already has a method " + String(mdname) + "."); | 
					
						
							| 
									
										
										
										
											2017-01-14 11:07:57 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(instance_type); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (!type) { | 
					
						
							|  |  |  | 		memdelete(p_bind); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		ERR_FAIL_V_MSG(nullptr, "Couldn't bind method '" + mdname + "' for instance '" + instance_type + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (type->method_map.has(mdname)) { | 
					
						
							|  |  |  | 		memdelete(p_bind); | 
					
						
							|  |  |  | 		// overloading not supported
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		ERR_FAIL_V_MSG(nullptr, "Method already bound '" + instance_type + "::" + mdname + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-09 11:54:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-08-09 11:54:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (method_name.args.size() > p_bind->get_argument_count()) { | 
					
						
							|  |  |  | 		memdelete(p_bind); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		ERR_FAIL_V_MSG(nullptr, "Method definition provides more arguments than the method actually has '" + instance_type + "::" + mdname + "'."); | 
					
						
							| 
									
										
										
										
											2017-08-09 11:54:27 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	p_bind->set_argument_names(method_name.args); | 
					
						
							| 
									
										
										
										
											2017-08-09 11:54:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	type->method_order.push_back(mdname); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-08-09 11:54:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	type->method_map[mdname] = p_bind; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Vector<Variant> defvals; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defvals.resize(p_defcount); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < p_defcount; i++) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		defvals.write[i] = *p_defs[p_defcount - i - 1]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p_bind->set_default_arguments(defvals); | 
					
						
							|  |  |  | 	p_bind->set_hint_flags(p_flags); | 
					
						
							|  |  |  | 	return p_bind; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual) { | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	MethodInfo mi = p_method; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (p_virtual) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		mi.flags |= METHOD_FLAG_VIRTUAL; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	classes[p_class].virtual_methods.push_back(mi); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2014-12-18 00:56:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *type = classes.getptr(p_class); | 
					
						
							|  |  |  | 	ClassInfo *check = type; | 
					
						
							|  |  |  | 	while (check) { | 
					
						
							|  |  |  | 		for (List<MethodInfo>::Element *E = check->virtual_methods.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2014-12-18 00:56:33 -03:00
										 |  |  | 			p_methods->push_back(E->get()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_no_inheritance) { | 
					
						
							| 
									
										
										
										
											2014-12-18 00:56:33 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		check = check->inherits_ptr; | 
					
						
							| 
									
										
										
										
											2014-12-18 00:56:33 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::set_class_enabled(StringName p_class, bool p_enable) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_WLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'."); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	classes[p_class].disabled = !p_enable; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | bool ClassDB::is_class_enabled(StringName p_class) { | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassInfo *ti = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2015-01-13 11:22:56 -03:00
										 |  |  | 	if (!ti || !ti->creation_func) { | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 		if (compat_classes.has(p_class)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			ti = classes.getptr(compat_classes[p_class]); | 
					
						
							| 
									
										
										
										
											2015-01-13 11:22:56 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'."); | 
					
						
							| 
									
										
										
										
											2015-01-13 11:22:56 -03:00
										 |  |  | 	return !ti->disabled; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 23:49:17 +02:00
										 |  |  | bool ClassDB::is_class_exposed(StringName p_class) { | 
					
						
							|  |  |  | 	OBJTYPE_RLOCK; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassInfo *ti = classes.getptr(p_class); | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'."); | 
					
						
							| 
									
										
										
										
											2017-10-09 23:49:17 +02:00
										 |  |  | 	return ti->exposed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | StringName ClassDB::get_category(const StringName &p_node) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!classes.has(p_node), StringName()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	return classes[p_node].category; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	return StringName(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::add_resource_base_extension(const StringName &p_extension, const StringName &p_class) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (resource_base_extensions.has(p_extension)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	resource_base_extensions[p_extension] = p_class; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | void ClassDB::get_resource_base_extensions(List<String> *p_extensions) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	const StringName *K = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while ((K = resource_base_extensions.next(K))) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		p_extensions->push_back(*K); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p_extensions) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	const StringName *K = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while ((K = resource_base_extensions.next(K))) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		StringName cmp = resource_base_extensions[*K]; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (is_parent_class(p_class, cmp) || is_parent_class(cmp, p_class)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			p_extensions->push_back(*K); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 14:20:36 +02:00
										 |  |  | HashMap<StringName, HashMap<StringName, Variant>> ClassDB::default_values; | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | Set<StringName> ClassDB::default_values_cached; | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 15:51:33 +03:00
										 |  |  | Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid) { | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 	if (!default_values_cached.has(p_class)) { | 
					
						
							|  |  |  | 		if (!default_values.has(p_class)) { | 
					
						
							|  |  |  | 			default_values[p_class] = HashMap<StringName, Variant>(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		Object *c = nullptr; | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 		bool cleanup_c = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (Engine::get_singleton()->has_singleton(p_class)) { | 
					
						
							|  |  |  | 			c = Engine::get_singleton()->get_singleton_object(p_class); | 
					
						
							|  |  |  | 			cleanup_c = false; | 
					
						
							|  |  |  | 		} else if (ClassDB::can_instance(p_class)) { | 
					
						
							|  |  |  | 			c = ClassDB::instance(p_class); | 
					
						
							|  |  |  | 			cleanup_c = true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (c) { | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 			List<PropertyInfo> plist; | 
					
						
							|  |  |  | 			c->get_property_list(&plist); | 
					
						
							|  |  |  | 			for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 				if (E->get().usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) { | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 					if (!default_values[p_class].has(E->get().name)) { | 
					
						
							|  |  |  | 						Variant v = c->get(E->get().name); | 
					
						
							|  |  |  | 						default_values[p_class][E->get().name] = v; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (cleanup_c) { | 
					
						
							|  |  |  | 				memdelete(c); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		default_values_cached.insert(p_class); | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!default_values.has(p_class)) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (r_valid != nullptr) { | 
					
						
							| 
									
										
										
										
											2021-05-04 14:28:27 +02:00
										 |  |  | 			*r_valid = false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 		return Variant(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!default_values[p_class].has(p_property)) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (r_valid != nullptr) { | 
					
						
							| 
									
										
										
										
											2021-05-04 14:28:27 +02:00
										 |  |  | 			*r_valid = false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 		return Variant(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (r_valid != nullptr) { | 
					
						
							| 
									
										
										
										
											2021-05-04 14:28:27 +02:00
										 |  |  | 		*r_valid = true; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-08 11:30:02 -03:00
										 |  |  | 	return default_values[p_class][p_property]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 19:48:38 +01:00
										 |  |  | RWLock ClassDB::lock; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | void ClassDB::cleanup_defaults() { | 
					
						
							|  |  |  | 	default_values.clear(); | 
					
						
							|  |  |  | 	default_values_cached.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | void ClassDB::cleanup() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	//OBJTYPE_LOCK; hah not here
 | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	const StringName *k = nullptr; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while ((k = classes.next(k))) { | 
					
						
							|  |  |  | 		ClassInfo &ti = classes[*k]; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		const StringName *m = nullptr; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		while ((m = ti.method_map.next(m))) { | 
					
						
							|  |  |  | 			memdelete(ti.method_map[*m]); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	classes.clear(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	resource_base_extensions.clear(); | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	compat_classes.clear(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //
 |