| 
									
										
										
										
											2023-01-05 13:25:55 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  class_db_api_json.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.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "class_db_api_json.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 14:26:46 +02:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/config/project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2021-06-11 14:51:48 +02:00
										 |  |  | #include "core/io/file_access.h"
 | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | #include "core/io/json.h"
 | 
					
						
							|  |  |  | #include "core/version.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { | 
					
						
							|  |  |  | 	Dictionary classes_dict; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 10:09:19 +02:00
										 |  |  | 	List<StringName> class_list; | 
					
						
							|  |  |  | 	ClassDB::get_class_list(&class_list); | 
					
						
							|  |  |  | 	// Must be alphabetically sorted for hash to compute.
 | 
					
						
							|  |  |  | 	class_list.sort_custom<StringName::AlphCompare>(); | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 10:09:19 +02:00
										 |  |  | 	for (const StringName &E : class_list) { | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 		ClassDB::ClassInfo *t = ClassDB::classes.getptr(E); | 
					
						
							| 
									
										
										
										
											2023-09-09 17:40:07 +02:00
										 |  |  | 		ERR_FAIL_NULL(t); | 
					
						
							| 
									
										
										
										
											2020-07-05 19:19:36 +02:00
										 |  |  | 		if (t->api != p_api || !t->exposed) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-07-05 19:19:36 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Dictionary class_dict; | 
					
						
							|  |  |  | 		classes_dict[t->name] = class_dict; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		class_dict["inherits"] = t->inherits; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ //methods
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			List<StringName> snames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 10:09:19 +02:00
										 |  |  | 			for (const KeyValue<StringName, MethodBind *> &F : t->method_map) { | 
					
						
							|  |  |  | 				String name = F.key.operator String(); | 
					
						
							| 
									
										
										
										
											2020-01-19 20:02:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 				ERR_CONTINUE(name.is_empty()); | 
					
						
							| 
									
										
										
										
											2020-01-19 20:02:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 19:19:36 +02:00
										 |  |  | 				if (name[0] == '_') { | 
					
						
							| 
									
										
										
										
											2020-01-19 20:02:40 +01:00
										 |  |  | 					continue; // Ignore non-virtual methods that start with an underscore
 | 
					
						
							| 
									
										
										
										
											2020-07-05 19:19:36 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-01-19 20:02:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 10:09:19 +02:00
										 |  |  | 				snames.push_back(F.key); | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			snames.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Array methods; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 15:46:25 +02:00
										 |  |  | 			for (const StringName &F : snames) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				Dictionary method_dict; | 
					
						
							|  |  |  | 				methods.push_back(method_dict); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 				MethodBind *mb = t->method_map[F]; | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				method_dict["name"] = mb->get_name(); | 
					
						
							|  |  |  | 				method_dict["argument_count"] = mb->get_argument_count(); | 
					
						
							|  |  |  | 				method_dict["return_type"] = mb->get_argument_type(-1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Array arguments; | 
					
						
							|  |  |  | 				method_dict["arguments"] = arguments; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				for (int i = 0; i < mb->get_argument_count(); i++) { | 
					
						
							|  |  |  | 					Dictionary argument_dict; | 
					
						
							|  |  |  | 					arguments.push_back(argument_dict); | 
					
						
							|  |  |  | 					const PropertyInfo info = mb->get_argument_info(i); | 
					
						
							|  |  |  | 					argument_dict["type"] = info.type; | 
					
						
							|  |  |  | 					argument_dict["name"] = info.name; | 
					
						
							|  |  |  | 					argument_dict["hint"] = info.hint; | 
					
						
							|  |  |  | 					argument_dict["hint_string"] = info.hint_string; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				method_dict["default_argument_count"] = mb->get_default_argument_count(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Array default_arguments; | 
					
						
							|  |  |  | 				method_dict["default_arguments"] = default_arguments; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				for (int i = 0; i < mb->get_default_argument_count(); i++) { | 
					
						
							|  |  |  | 					Dictionary default_argument_dict; | 
					
						
							|  |  |  | 					default_arguments.push_back(default_argument_dict); | 
					
						
							|  |  |  | 					//hash should not change, i hope for tis
 | 
					
						
							|  |  |  | 					Variant da = mb->get_default_argument(i); | 
					
						
							|  |  |  | 					default_argument_dict["value"] = da; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				method_dict["hint_flags"] = mb->get_hint_flags(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 			if (!methods.is_empty()) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				class_dict["methods"] = methods; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ //constants
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			List<StringName> snames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-09 12:47:10 +03:00
										 |  |  | 			for (const KeyValue<StringName, int64_t> &F : t->constant_map) { | 
					
						
							| 
									
										
										
										
											2022-05-08 10:09:19 +02:00
										 |  |  | 				snames.push_back(F.key); | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			snames.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Array constants; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 15:46:25 +02:00
										 |  |  | 			for (const StringName &F : snames) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				Dictionary constant_dict; | 
					
						
							|  |  |  | 				constants.push_back(constant_dict); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 				constant_dict["name"] = F; | 
					
						
							|  |  |  | 				constant_dict["value"] = t->constant_map[F]; | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 			if (!constants.is_empty()) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				class_dict["constants"] = constants; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ //signals
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			List<StringName> snames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 10:09:19 +02:00
										 |  |  | 			for (const KeyValue<StringName, MethodInfo> &F : t->signal_map) { | 
					
						
							|  |  |  | 				snames.push_back(F.key); | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			snames.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Array signals; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 15:46:25 +02:00
										 |  |  | 			for (const StringName &F : snames) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				Dictionary signal_dict; | 
					
						
							|  |  |  | 				signals.push_back(signal_dict); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 				MethodInfo &mi = t->signal_map[F]; | 
					
						
							|  |  |  | 				signal_dict["name"] = F; | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				Array arguments; | 
					
						
							|  |  |  | 				signal_dict["arguments"] = arguments; | 
					
						
							|  |  |  | 				for (int i = 0; i < mi.arguments.size(); i++) { | 
					
						
							|  |  |  | 					Dictionary argument_dict; | 
					
						
							|  |  |  | 					arguments.push_back(argument_dict); | 
					
						
							|  |  |  | 					argument_dict["type"] = mi.arguments[i].type; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 			if (!signals.is_empty()) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				class_dict["signals"] = signals; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ //properties
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			List<StringName> snames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 10:09:19 +02:00
										 |  |  | 			for (const KeyValue<StringName, ClassDB::PropertySetGet> &F : t->property_setget) { | 
					
						
							|  |  |  | 				snames.push_back(F.key); | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			snames.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Array properties; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 15:46:25 +02:00
										 |  |  | 			for (const StringName &F : snames) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				Dictionary property_dict; | 
					
						
							|  |  |  | 				properties.push_back(property_dict); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 				ClassDB::PropertySetGet *psg = t->property_setget.getptr(F); | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 				property_dict["name"] = F; | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				property_dict["setter"] = psg->setter; | 
					
						
							|  |  |  | 				property_dict["getter"] = psg->getter; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 			if (!properties.is_empty()) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 				class_dict["property_setget"] = properties; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Array property_list; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		//property list
 | 
					
						
							| 
									
										
										
										
											2021-07-24 15:46:25 +02:00
										 |  |  | 		for (const PropertyInfo &F : t->property_list) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 			Dictionary property_dict; | 
					
						
							|  |  |  | 			property_list.push_back(property_dict); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 			property_dict["name"] = F.name; | 
					
						
							|  |  |  | 			property_dict["type"] = F.type; | 
					
						
							|  |  |  | 			property_dict["hint"] = F.hint; | 
					
						
							|  |  |  | 			property_dict["hint_string"] = F.hint_string; | 
					
						
							|  |  |  | 			property_dict["usage"] = F.usage; | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 		if (!property_list.is_empty()) { | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 			class_dict["property_list"] = property_list; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 11:08:58 +02:00
										 |  |  | 	Ref<FileAccess> f = FileAccess::open(p_output_file, FileAccess::WRITE); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_MSG(f.is_null(), "Cannot open file '" + p_output_file + "'."); | 
					
						
							| 
									
										
										
										
											2022-10-11 00:27:23 +02:00
										 |  |  | 	f->store_string(JSON::stringify(classes_dict, "\t")); | 
					
						
							| 
									
										
										
										
											2019-07-09 23:33:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	print_line(String() + "ClassDB API JSON written to: " + ProjectSettings::get_singleton()->globalize_path(p_output_file)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-07-20 14:26:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif // DEBUG_METHODS_ENABLED
 |