mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	Send script members, contants and globals to debugger
Remove remote inspector panel
This commit is contained in:
		
							parent
							
								
									475cee9c0f
								
							
						
					
					
						commit
						ccf76798d5
					
				
					 3 changed files with 218 additions and 121 deletions
				
			
		|  | @ -35,6 +35,8 @@ | ||||||
| #include "os/input.h" | #include "os/input.h" | ||||||
| #include "os/os.h" | #include "os/os.h" | ||||||
| #include "project_settings.h" | #include "project_settings.h" | ||||||
|  | #include "scene/main/node.h" | ||||||
|  | 
 | ||||||
| void ScriptDebuggerRemote::_send_video_memory() { | void ScriptDebuggerRemote::_send_video_memory() { | ||||||
| 
 | 
 | ||||||
| 	List<ResourceUsage> usage; | 	List<ResourceUsage> usage; | ||||||
|  | @ -201,20 +203,39 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue) | ||||||
| 
 | 
 | ||||||
| 				List<String> members; | 				List<String> members; | ||||||
| 				List<Variant> member_vals; | 				List<Variant> member_vals; | ||||||
| 
 | 				if (ScriptInstance *inst = p_script->debug_get_stack_level_instance(lv)) { | ||||||
|  | 					members.push_back("self"); | ||||||
|  | 					member_vals.push_back(inst->get_owner()); | ||||||
|  | 				} | ||||||
| 				p_script->debug_get_stack_level_members(lv, &members, &member_vals); | 				p_script->debug_get_stack_level_members(lv, &members, &member_vals); | ||||||
| 
 |  | ||||||
| 				ERR_CONTINUE(members.size() != member_vals.size()); | 				ERR_CONTINUE(members.size() != member_vals.size()); | ||||||
| 
 | 
 | ||||||
| 				List<String> locals; | 				List<String> locals; | ||||||
| 				List<Variant> local_vals; | 				List<Variant> local_vals; | ||||||
| 
 |  | ||||||
| 				p_script->debug_get_stack_level_locals(lv, &locals, &local_vals); | 				p_script->debug_get_stack_level_locals(lv, &locals, &local_vals); | ||||||
| 
 |  | ||||||
| 				ERR_CONTINUE(locals.size() != local_vals.size()); | 				ERR_CONTINUE(locals.size() != local_vals.size()); | ||||||
| 
 | 
 | ||||||
|  | 				List<String> globals; | ||||||
|  | 				List<Variant> globals_vals; | ||||||
|  | 				p_script->debug_get_globals(&globals, &globals_vals); | ||||||
|  | 				ERR_CONTINUE(globals.size() != globals_vals.size()); | ||||||
|  | 
 | ||||||
| 				packet_peer_stream->put_var("stack_frame_vars"); | 				packet_peer_stream->put_var("stack_frame_vars"); | ||||||
| 				packet_peer_stream->put_var(2 + locals.size() * 2 + members.size() * 2); | 				packet_peer_stream->put_var(3 + (locals.size() + members.size() + globals.size()) * 2); | ||||||
|  | 
 | ||||||
|  | 				{ //locals
 | ||||||
|  | 					packet_peer_stream->put_var(locals.size()); | ||||||
|  | 
 | ||||||
|  | 					List<String>::Element *E = locals.front(); | ||||||
|  | 					List<Variant>::Element *F = local_vals.front(); | ||||||
|  | 
 | ||||||
|  | 					while (E) { | ||||||
|  | 						_put_variable(E->get(), F->get()); | ||||||
|  | 
 | ||||||
|  | 						E = E->next(); | ||||||
|  | 						F = F->next(); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
| 
 | 
 | ||||||
| 				{ //members
 | 				{ //members
 | ||||||
| 					packet_peer_stream->put_var(members.size()); | 					packet_peer_stream->put_var(members.size()); | ||||||
|  | @ -231,11 +252,11 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				{ //locals
 | 				{ //globals
 | ||||||
| 					packet_peer_stream->put_var(locals.size()); | 					packet_peer_stream->put_var(globals.size()); | ||||||
| 
 | 
 | ||||||
| 					List<String>::Element *E = locals.front(); | 					List<String>::Element *E = globals.front(); | ||||||
| 					List<Variant>::Element *F = local_vals.front(); | 					List<Variant>::Element *F = globals_vals.front(); | ||||||
| 
 | 
 | ||||||
| 					while (E) { | 					while (E) { | ||||||
| 						_put_variable(E->get(), F->get()); | 						_put_variable(E->get(), F->get()); | ||||||
|  | @ -532,56 +553,77 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) { | ||||||
| 	if (!obj) | 	if (!obj) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | 	typedef Pair<PropertyInfo, Variant> PropertyDesc; | ||||||
|  | 	List<PropertyDesc> properties; | ||||||
|  | 
 | ||||||
|  | 	if (ScriptInstance *si = obj->get_script_instance()) { | ||||||
|  | 		if (!si->get_script().is_null()) { | ||||||
|  | 
 | ||||||
|  | 			Set<StringName> members; | ||||||
|  | 			si->get_script()->get_members(&members); | ||||||
|  | 			for (Set<StringName>::Element *E = members.front(); E; E = E->next()) { | ||||||
|  | 
 | ||||||
|  | 				Variant m; | ||||||
|  | 				if (si->get(E->get(), m)) { | ||||||
|  | 					PropertyInfo pi(m.get_type(), String("Members/") + E->get()); | ||||||
|  | 					properties.push_back(PropertyDesc(pi, m)); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			Map<StringName, Variant> constants; | ||||||
|  | 			si->get_script()->get_constants(&constants); | ||||||
|  | 			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { | ||||||
|  | 				PropertyInfo pi(E->value().get_type(), (String("Constants/") + E->key())); | ||||||
|  | 				properties.push_back(PropertyDesc(pi, E->value())); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if (Node *node = Object::cast_to<Node>(obj)) { | ||||||
|  | 		PropertyInfo pi(Variant::NODE_PATH, String("Node/path")); | ||||||
|  | 		properties.push_front(PropertyDesc(pi, node->get_path())); | ||||||
|  | 	} else if (Resource *res = Object::cast_to<Resource>(obj)) { | ||||||
|  | 		if (Script *s = Object::cast_to<Script>(res)) { | ||||||
|  | 			Map<StringName, Variant> constants; | ||||||
|  | 			s->get_constants(&constants); | ||||||
|  | 			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { | ||||||
|  | 				PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key()); | ||||||
|  | 				properties.push_front(PropertyDesc(pi, E->value())); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	List<PropertyInfo> pinfo; | 	List<PropertyInfo> pinfo; | ||||||
| 	obj->get_property_list(&pinfo, true); | 	obj->get_property_list(&pinfo, true); | ||||||
| 
 |  | ||||||
| 	int props_to_send = 0; |  | ||||||
| 	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { | 	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { | ||||||
| 
 |  | ||||||
| 		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { | 		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { | ||||||
| 			props_to_send++; | 			properties.push_back(PropertyDesc(E->get(), obj->get(E->get().name))); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	Array send_props; | ||||||
|  | 	for (int i = 0; i < properties.size(); i++) { | ||||||
|  | 		const PropertyInfo &pi = properties[i].first; | ||||||
|  | 		const Variant &var = properties[i].second; | ||||||
|  | 		RES res = var; | ||||||
|  | 
 | ||||||
|  | 		Array prop; | ||||||
|  | 		prop.push_back(pi.name); | ||||||
|  | 		prop.push_back(pi.type); | ||||||
|  | 		prop.push_back(pi.hint); | ||||||
|  | 		if (res.is_null()) | ||||||
|  | 			prop.push_back(pi.hint_string); | ||||||
|  | 		else | ||||||
|  | 			prop.push_back(String("RES:") + res->get_path()); | ||||||
|  | 		prop.push_back(pi.usage); | ||||||
|  | 		prop.push_back(var); | ||||||
|  | 		send_props.push_back(prop); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	packet_peer_stream->put_var("message:inspect_object"); | 	packet_peer_stream->put_var("message:inspect_object"); | ||||||
| 	packet_peer_stream->put_var(props_to_send * 5 + 4); | 	packet_peer_stream->put_var(3); | ||||||
| 	packet_peer_stream->put_var(p_id); | 	packet_peer_stream->put_var(p_id); | ||||||
| 	packet_peer_stream->put_var(obj->get_class()); | 	packet_peer_stream->put_var(obj->get_class()); | ||||||
| 	if (obj->is_class("Resource") || obj->is_class("Node")) | 	packet_peer_stream->put_var(send_props); | ||||||
| 		packet_peer_stream->put_var(obj->call("get_path")); |  | ||||||
| 	else |  | ||||||
| 		packet_peer_stream->put_var(""); |  | ||||||
| 
 |  | ||||||
| 	packet_peer_stream->put_var(props_to_send); |  | ||||||
| 
 |  | ||||||
| 	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { |  | ||||||
| 
 |  | ||||||
| 		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { |  | ||||||
| 
 |  | ||||||
| 			if (E->get().usage & PROPERTY_USAGE_CATEGORY) { |  | ||||||
| 				packet_peer_stream->put_var("*" + E->get().name); |  | ||||||
| 			} else { |  | ||||||
| 				packet_peer_stream->put_var(E->get().name); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			Variant var = obj->get(E->get().name); |  | ||||||
| 			packet_peer_stream->put_var(E->get().type); |  | ||||||
| 			//only send information that can be sent..
 |  | ||||||
| 
 |  | ||||||
| 			int len = 0; //test how big is this to encode
 |  | ||||||
| 			encode_variant(var, NULL, len); |  | ||||||
| 
 |  | ||||||
| 			if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size
 |  | ||||||
| 				packet_peer_stream->put_var(PROPERTY_HINT_OBJECT_TOO_BIG); |  | ||||||
| 				packet_peer_stream->put_var(""); |  | ||||||
| 				packet_peer_stream->put_var(Variant()); |  | ||||||
| 			} else { |  | ||||||
| 				packet_peer_stream->put_var(E->get().hint); |  | ||||||
| 				packet_peer_stream->put_var(E->get().hint_string); |  | ||||||
| 				packet_peer_stream->put_var(var); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ScriptDebuggerRemote::_set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value) { | void ScriptDebuggerRemote::_set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value) { | ||||||
|  | @ -590,7 +632,11 @@ void ScriptDebuggerRemote::_set_object_property(ObjectID p_id, const String &p_p | ||||||
| 	if (!obj) | 	if (!obj) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	obj->set(p_property, p_value); | 	String prop_name = p_property; | ||||||
|  | 	if (p_property.begins_with("Members/")) | ||||||
|  | 		prop_name = p_property.substr(8, p_property.length()); | ||||||
|  | 
 | ||||||
|  | 	obj->set(prop_name, p_value); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ScriptDebuggerRemote::_poll_events() { | void ScriptDebuggerRemote::_poll_events() { | ||||||
|  |  | ||||||
|  | @ -116,7 +116,7 @@ class ScriptEditorDebuggerInspectedObject : public Object { | ||||||
| protected: | protected: | ||||||
| 	bool _set(const StringName &p_name, const Variant &p_value) { | 	bool _set(const StringName &p_name, const Variant &p_value) { | ||||||
| 
 | 
 | ||||||
| 		if (!prop_values.has(p_name)) | 		if (!prop_values.has(p_name) || String(p_name).begins_with("Constants/")) | ||||||
| 			return false; | 			return false; | ||||||
| 
 | 
 | ||||||
| 		emit_signal("value_edited", p_name, p_value); | 		emit_signal("value_edited", p_name, p_value); | ||||||
|  | @ -132,6 +132,7 @@ protected: | ||||||
| 		r_ret = prop_values[p_name]; | 		r_ret = prop_values[p_name]; | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	void _get_property_list(List<PropertyInfo> *p_list) const { | 	void _get_property_list(List<PropertyInfo> *p_list) const { | ||||||
| 
 | 
 | ||||||
| 		p_list->clear(); //sorry, no want category
 | 		p_list->clear(); //sorry, no want category
 | ||||||
|  | @ -142,23 +143,52 @@ protected: | ||||||
| 
 | 
 | ||||||
| 	static void _bind_methods() { | 	static void _bind_methods() { | ||||||
| 
 | 
 | ||||||
|  | 		ClassDB::bind_method(D_METHOD("get_title"), &ScriptEditorDebuggerInspectedObject::get_title); | ||||||
|  | 		ClassDB::bind_method(D_METHOD("get_variant"), &ScriptEditorDebuggerInspectedObject::get_variant); | ||||||
|  | 		ClassDB::bind_method(D_METHOD("clear"), &ScriptEditorDebuggerInspectedObject::clear); | ||||||
|  | 		ClassDB::bind_method(D_METHOD("get_remote_object_id"), &ScriptEditorDebuggerInspectedObject::get_remote_object_id); | ||||||
|  | 
 | ||||||
| 		ADD_SIGNAL(MethodInfo("value_edited")); | 		ADD_SIGNAL(MethodInfo("value_edited")); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 	ObjectID last_edited_id; | 	String type_name; | ||||||
|  | 	ObjectID remote_object_id; | ||||||
| 	List<PropertyInfo> prop_list; | 	List<PropertyInfo> prop_list; | ||||||
| 	Map<StringName, Variant> prop_values; | 	Map<StringName, Variant> prop_values; | ||||||
| 
 | 
 | ||||||
|  | 	ObjectID get_remote_object_id() { | ||||||
|  | 		return remote_object_id; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	String get_title() { | ||||||
|  | 		if (remote_object_id) | ||||||
|  | 			return TTR("Remote ") + String(type_name) + ": " + itos(remote_object_id); | ||||||
|  | 		else | ||||||
|  | 			return "<null>"; | ||||||
|  | 	} | ||||||
|  | 	Variant get_variant(const StringName &p_name) { | ||||||
|  | 
 | ||||||
|  | 		Variant var; | ||||||
|  | 		_get(p_name, var); | ||||||
|  | 		return var; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void clear() { | ||||||
|  | 
 | ||||||
|  | 		prop_list.clear(); | ||||||
|  | 		prop_values.clear(); | ||||||
|  | 	} | ||||||
| 	void update() { | 	void update() { | ||||||
| 		_change_notify(); | 		_change_notify(); | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	void update_single(const char *p_prop) { | 	void update_single(const char *p_prop) { | ||||||
| 		_change_notify(p_prop); | 		_change_notify(p_prop); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ScriptEditorDebuggerInspectedObject() { last_edited_id = 0; } | 	ScriptEditorDebuggerInspectedObject() { | ||||||
|  | 		remote_object_id = 0; | ||||||
|  | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void ScriptEditorDebugger::debug_next() { | void ScriptEditorDebugger::debug_next() { | ||||||
|  | @ -297,7 +327,6 @@ Size2 ScriptEditorDebugger::get_minimum_size() const { | ||||||
| void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_data) { | void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_data) { | ||||||
| 
 | 
 | ||||||
| 	if (p_msg == "debug_enter") { | 	if (p_msg == "debug_enter") { | ||||||
| 
 |  | ||||||
| 		Array msg; | 		Array msg; | ||||||
| 		msg.push_back("get_stack_dump"); | 		msg.push_back("get_stack_dump"); | ||||||
| 		ppeer->put_var(msg); | 		ppeer->put_var(msg); | ||||||
|  | @ -315,12 +344,10 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da | ||||||
| 		if (error != "") { | 		if (error != "") { | ||||||
| 			tabs->set_current_tab(0); | 			tabs->set_current_tab(0); | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		profiler->set_enabled(false); | 		profiler->set_enabled(false); | ||||||
| 
 |  | ||||||
| 		EditorNode::get_singleton()->get_pause_button()->set_pressed(true); | 		EditorNode::get_singleton()->get_pause_button()->set_pressed(true); | ||||||
| 
 |  | ||||||
| 		EditorNode::get_singleton()->make_bottom_panel_item_visible(this); | 		EditorNode::get_singleton()->make_bottom_panel_item_visible(this); | ||||||
|  | 		_clear_remote_objects(); | ||||||
| 
 | 
 | ||||||
| 	} else if (p_msg == "debug_exit") { | 	} else if (p_msg == "debug_exit") { | ||||||
| 
 | 
 | ||||||
|  | @ -337,9 +364,8 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da | ||||||
| 		//tabs->set_current_tab(0);
 | 		//tabs->set_current_tab(0);
 | ||||||
| 		profiler->set_enabled(true); | 		profiler->set_enabled(true); | ||||||
| 		profiler->disable_seeking(); | 		profiler->disable_seeking(); | ||||||
| 
 | 		inspector->edit(NULL); | ||||||
| 		EditorNode::get_singleton()->get_pause_button()->set_pressed(false); | 		EditorNode::get_singleton()->get_pause_button()->set_pressed(false); | ||||||
| 
 |  | ||||||
| 	} else if (p_msg == "message:click_ctrl") { | 	} else if (p_msg == "message:click_ctrl") { | ||||||
| 
 | 
 | ||||||
| 		clicked_ctrl->set_text(p_data[0]); | 		clicked_ctrl->set_text(p_data[0]); | ||||||
|  | @ -399,55 +425,57 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da | ||||||
| 		le_set->set_disabled(false); | 		le_set->set_disabled(false); | ||||||
| 	} else if (p_msg == "message:inspect_object") { | 	} else if (p_msg == "message:inspect_object") { | ||||||
| 
 | 
 | ||||||
|  | 		ScriptEditorDebuggerInspectedObject *debugObj = NULL; | ||||||
|  | 
 | ||||||
| 		ObjectID id = p_data[0]; | 		ObjectID id = p_data[0]; | ||||||
| 		String type = p_data[1]; | 		String type = p_data[1]; | ||||||
| 		Variant path = p_data[2]; //what to do yet, i don't  know
 | 		Array properties = p_data[2]; | ||||||
| 		int prop_count = p_data[3]; |  | ||||||
| 
 | 
 | ||||||
| 		int idx = 4; | 		bool is_new_object = false; | ||||||
| 
 | 		if (remote_objects.has(id)) { | ||||||
| 		if (inspected_object->last_edited_id != id) { | 			debugObj = remote_objects[id]; | ||||||
| 			inspected_object->prop_list.clear(); | 		} else { | ||||||
| 			inspected_object->prop_values.clear(); | 			debugObj = memnew(ScriptEditorDebuggerInspectedObject); | ||||||
|  | 			debugObj->remote_object_id = id; | ||||||
|  | 			debugObj->type_name = type; | ||||||
|  | 			remote_objects[id] = debugObj; | ||||||
|  | 			is_new_object = true; | ||||||
|  | 			debugObj->connect("value_edited", this, "_scene_tree_property_value_edited"); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < prop_count; i++) { | 		for (int i = 0; i < properties.size(); i++) { | ||||||
|  | 
 | ||||||
|  | 			Array prop = properties[i]; | ||||||
|  | 			if (prop.size() != 6) | ||||||
|  | 				continue; | ||||||
| 
 | 
 | ||||||
| 			PropertyInfo pinfo; | 			PropertyInfo pinfo; | ||||||
| 			pinfo.name = p_data[idx++]; | 			pinfo.name = prop[0]; | ||||||
| 			pinfo.type = Variant::Type(int(p_data[idx++])); | 			pinfo.type = Variant::Type(int(prop[1])); | ||||||
| 			pinfo.hint = PropertyHint(int(p_data[idx++])); | 			pinfo.hint = PropertyHint(int(prop[2])); | ||||||
| 			pinfo.hint_string = p_data[idx++]; | 			pinfo.hint_string = prop[3]; | ||||||
| 			if (pinfo.name.begins_with("*")) { | 			pinfo.usage = PropertyUsageFlags(int(prop[4])); | ||||||
| 				pinfo.name = pinfo.name.substr(1, pinfo.name.length()); | 			Variant var = prop[5]; | ||||||
| 				pinfo.usage = PROPERTY_USAGE_CATEGORY; | 
 | ||||||
| 			} else { | 			String hint_string = pinfo.hint_string; | ||||||
| 				pinfo.usage = PROPERTY_USAGE_EDITOR; | 			if (hint_string.begins_with("RES:") && hint_string != "RES:") { | ||||||
|  | 				String path = hint_string.substr(4, hint_string.length()); | ||||||
|  | 				var = ResourceLoader::load(path); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (inspected_object->last_edited_id != id) { | 			if (is_new_object) { | ||||||
| 				//don't update.. it's the same, instead refresh
 | 				//don't update.. it's the same, instead refresh
 | ||||||
| 				inspected_object->prop_list.push_back(pinfo); | 				debugObj->prop_list.push_back(pinfo); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			inspected_object->prop_values[pinfo.name] = p_data[idx++]; | 			debugObj->prop_values[pinfo.name] = var; | ||||||
| 
 |  | ||||||
| 			if (inspected_object->last_edited_id == id) { |  | ||||||
| 				//same, just update value, don't rebuild
 |  | ||||||
| 				inspected_object->update_single(pinfo.name.ascii().get_data()); |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (inspected_object->last_edited_id != id) { | 		if (editor->get_editor_history()->get_current() != debugObj->get_instance_id()) { | ||||||
| 			//only if different
 | 			editor->push_item(debugObj, ""); | ||||||
| 			inspected_object->update(); | 		} else { | ||||||
|  | 			debugObj->update(); | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		inspected_object->last_edited_id = id; |  | ||||||
| 
 |  | ||||||
| 		tabs->set_current_tab(inspect_info->get_index()); |  | ||||||
| 		inspect_properties->edit(inspected_object); |  | ||||||
| 
 |  | ||||||
| 	} else if (p_msg == "message:video_mem") { | 	} else if (p_msg == "message:video_mem") { | ||||||
| 
 | 
 | ||||||
| 		vmem_tree->clear(); | 		vmem_tree->clear(); | ||||||
|  | @ -502,7 +530,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da | ||||||
| 
 | 
 | ||||||
| 		int ofs = 0; | 		int ofs = 0; | ||||||
| 		int mcount = p_data[ofs]; | 		int mcount = p_data[ofs]; | ||||||
| 
 |  | ||||||
| 		ofs++; | 		ofs++; | ||||||
| 		for (int i = 0; i < mcount; i++) { | 		for (int i = 0; i < mcount; i++) { | ||||||
| 
 | 
 | ||||||
|  | @ -521,12 +548,11 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da | ||||||
| 				v = s.get_slice(":", 1).to_int(); | 				v = s.get_slice(":", 1).to_int(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			variables->add_property("members/" + n, v, h, hs); | 			variables->add_property("Locals/" + n, v, h, hs); | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
| 		ofs += mcount * 2; | 		ofs += mcount * 2; | ||||||
| 
 |  | ||||||
| 		mcount = p_data[ofs]; | 		mcount = p_data[ofs]; | ||||||
| 
 |  | ||||||
| 		ofs++; | 		ofs++; | ||||||
| 		for (int i = 0; i < mcount; i++) { | 		for (int i = 0; i < mcount; i++) { | ||||||
| 
 | 
 | ||||||
|  | @ -545,7 +571,30 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da | ||||||
| 				v = s.get_slice(":", 1).to_int(); | 				v = s.get_slice(":", 1).to_int(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			variables->add_property("locals/" + n, v, h, hs); | 			variables->add_property("Members/" + n, v, h, hs); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ofs += mcount * 2; | ||||||
|  | 		mcount = p_data[ofs]; | ||||||
|  | 		ofs++; | ||||||
|  | 		for (int i = 0; i < mcount; i++) { | ||||||
|  | 
 | ||||||
|  | 			String n = p_data[ofs + i * 2 + 0]; | ||||||
|  | 			Variant v = p_data[ofs + i * 2 + 1]; | ||||||
|  | 			PropertyHint h = PROPERTY_HINT_NONE; | ||||||
|  | 			String hs = String(); | ||||||
|  | 
 | ||||||
|  | 			if (n.begins_with("*")) { | ||||||
|  | 
 | ||||||
|  | 				n = n.substr(1, n.length()); | ||||||
|  | 				h = PROPERTY_HINT_OBJECT_ID; | ||||||
|  | 				String s = v; | ||||||
|  | 				s = s.replace("[", ""); | ||||||
|  | 				hs = s.get_slice(":", 0); | ||||||
|  | 				v = s.get_slice(":", 1).to_int(); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			variables->add_property("Globals/" + n, v, h, hs); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		variables->update(); | 		variables->update(); | ||||||
|  | @ -1133,7 +1182,6 @@ void ScriptEditorDebugger::stop() { | ||||||
| 	le_set->set_disabled(true); | 	le_set->set_disabled(true); | ||||||
| 	profiler->set_enabled(true); | 	profiler->set_enabled(true); | ||||||
| 
 | 
 | ||||||
| 	inspect_properties->edit(NULL); |  | ||||||
| 	inspect_scene_tree->clear(); | 	inspect_scene_tree->clear(); | ||||||
| 
 | 
 | ||||||
| 	EditorNode::get_singleton()->get_pause_button()->set_pressed(false); | 	EditorNode::get_singleton()->get_pause_button()->set_pressed(false); | ||||||
|  | @ -1604,6 +1652,21 @@ void ScriptEditorDebugger::_paused() { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ScriptEditorDebugger::_set_remote_object(ObjectID p_id, ScriptEditorDebuggerInspectedObject *p_obj) { | ||||||
|  | 
 | ||||||
|  | 	if (remote_objects.has(p_id)) | ||||||
|  | 		memdelete(remote_objects[p_id]); | ||||||
|  | 	remote_objects[p_id] = p_obj; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ScriptEditorDebugger::_clear_remote_objects() { | ||||||
|  | 
 | ||||||
|  | 	for (Map<ObjectID, ScriptEditorDebuggerInspectedObject *>::Element *E = remote_objects.front(); E; E = E->next()) { | ||||||
|  | 		memdelete(E->value()); | ||||||
|  | 	} | ||||||
|  | 	remote_objects.clear(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ScriptEditorDebugger::_bind_methods() { | void ScriptEditorDebugger::_bind_methods() { | ||||||
| 
 | 
 | ||||||
| 	ClassDB::bind_method(D_METHOD("_stack_dump_frame_selected"), &ScriptEditorDebugger::_stack_dump_frame_selected); | 	ClassDB::bind_method(D_METHOD("_stack_dump_frame_selected"), &ScriptEditorDebugger::_stack_dump_frame_selected); | ||||||
|  | @ -1649,6 +1712,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { | ||||||
| 	ppeer = Ref<PacketPeerStream>(memnew(PacketPeerStream)); | 	ppeer = Ref<PacketPeerStream>(memnew(PacketPeerStream)); | ||||||
| 	ppeer->set_input_buffer_max_size(1024 * 1024 * 8); //8mb should be enough
 | 	ppeer->set_input_buffer_max_size(1024 * 1024 * 8); //8mb should be enough
 | ||||||
| 	editor = p_editor; | 	editor = p_editor; | ||||||
|  | 	editor->get_property_editor()->connect("object_id_selected", this, "_scene_tree_property_select_object"); | ||||||
| 
 | 
 | ||||||
| 	tabs = memnew(TabContainer); | 	tabs = memnew(TabContainer); | ||||||
| 	tabs->set_tab_align(TabContainer::ALIGN_LEFT); | 	tabs->set_tab_align(TabContainer::ALIGN_LEFT); | ||||||
|  | @ -1776,26 +1840,10 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { | ||||||
| 		inspect_scene_tree->connect("cell_selected", this, "_scene_tree_selected"); | 		inspect_scene_tree->connect("cell_selected", this, "_scene_tree_selected"); | ||||||
| 		inspect_scene_tree->connect("item_collapsed", this, "_scene_tree_folded"); | 		inspect_scene_tree->connect("item_collapsed", this, "_scene_tree_folded"); | ||||||
| 
 | 
 | ||||||
| 		//
 |  | ||||||
| 
 |  | ||||||
| 		VBoxContainer *info_right = memnew(VBoxContainer); |  | ||||||
| 		info_right->set_h_size_flags(SIZE_EXPAND_FILL); |  | ||||||
| 		inspect_info->add_child(info_right); |  | ||||||
| 
 |  | ||||||
| 		inspect_properties = memnew(PropertyEditor); |  | ||||||
| 		inspect_properties->hide_top_label(); |  | ||||||
| 		inspect_properties->set_show_categories(true); |  | ||||||
| 		inspect_properties->connect("object_id_selected", this, "_scene_tree_property_select_object"); |  | ||||||
| 
 |  | ||||||
| 		info_right->add_margin_child(TTR("Remote Object Properties: "), inspect_properties, true); |  | ||||||
| 
 |  | ||||||
| 		inspect_scene_tree_timeout = EDITOR_DEF("debugger/scene_tree_refresh_interval", 1.0); | 		inspect_scene_tree_timeout = EDITOR_DEF("debugger/scene_tree_refresh_interval", 1.0); | ||||||
| 		inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2); | 		inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2); | ||||||
| 		inspected_object_id = 0; | 		inspected_object_id = 0; | ||||||
| 		updating_scene_tree = false; | 		updating_scene_tree = false; | ||||||
| 
 |  | ||||||
| 		inspected_object = memnew(ScriptEditorDebuggerInspectedObject); |  | ||||||
| 		inspected_object->connect("value_edited", this, "_scene_tree_property_value_edited"); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	{ //profiler
 | 	{ //profiler
 | ||||||
|  | @ -1952,5 +2000,5 @@ ScriptEditorDebugger::~ScriptEditorDebugger() { | ||||||
| 	ppeer->set_stream_peer(Ref<StreamPeer>()); | 	ppeer->set_stream_peer(Ref<StreamPeer>()); | ||||||
| 
 | 
 | ||||||
| 	server->stop(); | 	server->stop(); | ||||||
| 	memdelete(inspected_object); | 	_clear_remote_objects(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -74,12 +74,13 @@ class ScriptEditorDebugger : public Control { | ||||||
| 
 | 
 | ||||||
| 	Tree *inspect_scene_tree; | 	Tree *inspect_scene_tree; | ||||||
| 	HSplitContainer *inspect_info; | 	HSplitContainer *inspect_info; | ||||||
| 	PropertyEditor *inspect_properties; | 
 | ||||||
|  | 	bool updating_scene_tree; | ||||||
| 	float inspect_scene_tree_timeout; | 	float inspect_scene_tree_timeout; | ||||||
| 	float inspect_edited_object_timeout; | 	float inspect_edited_object_timeout; | ||||||
| 	ObjectID inspected_object_id; | 	ObjectID inspected_object_id; | ||||||
| 	ScriptEditorDebuggerInspectedObject *inspected_object; | 	ScriptEditorDebuggerVariables *variables; | ||||||
| 	bool updating_scene_tree; | 	Map<ObjectID, ScriptEditorDebuggerInspectedObject *> remote_objects; | ||||||
| 	Set<ObjectID> unfold_cache; | 	Set<ObjectID> unfold_cache; | ||||||
| 
 | 
 | ||||||
| 	HSplitContainer *error_split; | 	HSplitContainer *error_split; | ||||||
|  | @ -96,7 +97,6 @@ class ScriptEditorDebugger : public Control { | ||||||
| 	TabContainer *tabs; | 	TabContainer *tabs; | ||||||
| 
 | 
 | ||||||
| 	Label *reason; | 	Label *reason; | ||||||
| 	ScriptEditorDebuggerVariables *variables; |  | ||||||
| 
 | 
 | ||||||
| 	Button *step; | 	Button *step; | ||||||
| 	Button *next; | 	Button *next; | ||||||
|  | @ -174,6 +174,9 @@ class ScriptEditorDebugger : public Control { | ||||||
| 
 | 
 | ||||||
| 	void _paused(); | 	void _paused(); | ||||||
| 
 | 
 | ||||||
|  | 	void _set_remote_object(ObjectID p_id, ScriptEditorDebuggerInspectedObject *p_obj); | ||||||
|  | 	void _clear_remote_objects(); | ||||||
|  | 
 | ||||||
| protected: | protected: | ||||||
| 	void _notification(int p_what); | 	void _notification(int p_what); | ||||||
| 	static void _bind_methods(); | 	static void _bind_methods(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 geequlim
						geequlim