diff options
| author | geequlim <geequlim@gmail.com> | 2017-10-17 22:37:25 +0800 | 
|---|---|---|
| committer | Geequlim <geequlim@gmail.com> | 2017-11-17 09:20:32 +0800 | 
| commit | ccf76798d54c7ed70813346493b7f64264181f7c (patch) | |
| tree | a7ead8b82ae57af5f47e959d40c49b5144d227f4 | |
| parent | 475cee9c0fc7b1975de1c5380178763dc2c2df38 (diff) | |
Send script members, contants and globals to debugger
Remove remote inspector panel
| -rw-r--r-- | core/script_debugger_remote.cpp | 146 | ||||
| -rw-r--r-- | editor/script_editor_debugger.cpp | 180 | ||||
| -rw-r--r-- | editor/script_editor_debugger.h | 11 | 
3 files changed, 217 insertions, 120 deletions
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index f77fb116c7..14f0cddb9c 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -35,6 +35,8 @@  #include "os/input.h"  #include "os/os.h"  #include "project_settings.h" +#include "scene/main/node.h" +  void ScriptDebuggerRemote::_send_video_memory() {  	List<ResourceUsage> usage; @@ -201,20 +203,39 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)  				List<String> members;  				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); -  				ERR_CONTINUE(members.size() != member_vals.size());  				List<String> locals;  				List<Variant> local_vals; -  				p_script->debug_get_stack_level_locals(lv, &locals, &local_vals); -  				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(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  					packet_peer_stream->put_var(members.size()); @@ -231,11 +252,11 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)  					}  				} -				{ //locals -					packet_peer_stream->put_var(locals.size()); +				{ //globals +					packet_peer_stream->put_var(globals.size()); -					List<String>::Element *E = locals.front(); -					List<Variant>::Element *F = local_vals.front(); +					List<String>::Element *E = globals.front(); +					List<Variant>::Element *F = globals_vals.front();  					while (E) {  						_put_variable(E->get(), F->get()); @@ -532,56 +553,77 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {  	if (!obj)  		return; -	List<PropertyInfo> pinfo; -	obj->get_property_list(&pinfo, true); +	typedef Pair<PropertyInfo, Variant> PropertyDesc; +	List<PropertyDesc> properties; -	int props_to_send = 0; -	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { +	if (ScriptInstance *si = obj->get_script_instance()) { +		if (!si->get_script().is_null()) { -		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { -			props_to_send++; -		} -	} +			Set<StringName> members; +			si->get_script()->get_members(&members); +			for (Set<StringName>::Element *E = members.front(); E; E = E->next()) { -	packet_peer_stream->put_var("message:inspect_object"); -	packet_peer_stream->put_var(props_to_send * 5 + 4); -	packet_peer_stream->put_var(p_id); -	packet_peer_stream->put_var(obj->get_class()); -	if (obj->is_class("Resource") || obj->is_class("Node")) -		packet_peer_stream->put_var(obj->call("get_path")); -	else -		packet_peer_stream->put_var(""); +				Variant m; +				if (si->get(E->get(), m)) { +					PropertyInfo pi(m.get_type(), String("Members/") + E->get()); +					properties.push_back(PropertyDesc(pi, m)); +				} +			} -	packet_peer_stream->put_var(props_to_send); +			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; +	obj->get_property_list(&pinfo, true);  	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { -  		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { +			properties.push_back(PropertyDesc(E->get(), obj->get(E->get().name))); +		} +	} -			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); +	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; -			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); -			} -		} +		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(3); +	packet_peer_stream->put_var(p_id); +	packet_peer_stream->put_var(obj->get_class()); +	packet_peer_stream->put_var(send_props);  }  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)  		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() { diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index bc2423fffd..c2ef16571a 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -116,7 +116,7 @@ class ScriptEditorDebuggerInspectedObject : public Object {  protected:  	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;  		emit_signal("value_edited", p_name, p_value); @@ -132,6 +132,7 @@ protected:  		r_ret = prop_values[p_name];  		return true;  	} +  	void _get_property_list(List<PropertyInfo> *p_list) const {  		p_list->clear(); //sorry, no want category @@ -142,23 +143,52 @@ protected:  	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"));  	}  public: -	ObjectID last_edited_id; +	String type_name; +	ObjectID remote_object_id;  	List<PropertyInfo> prop_list;  	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() {  		_change_notify();  	} -  	void update_single(const char *p_prop) {  		_change_notify(p_prop);  	} -	ScriptEditorDebuggerInspectedObject() { last_edited_id = 0; } +	ScriptEditorDebuggerInspectedObject() { +		remote_object_id = 0; +	}  };  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) {  	if (p_msg == "debug_enter") { -  		Array msg;  		msg.push_back("get_stack_dump");  		ppeer->put_var(msg); @@ -315,12 +344,10 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da  		if (error != "") {  			tabs->set_current_tab(0);  		} -  		profiler->set_enabled(false); -  		EditorNode::get_singleton()->get_pause_button()->set_pressed(true); -  		EditorNode::get_singleton()->make_bottom_panel_item_visible(this); +		_clear_remote_objects();  	} 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);  		profiler->set_enabled(true);  		profiler->disable_seeking(); - +		inspector->edit(NULL);  		EditorNode::get_singleton()->get_pause_button()->set_pressed(false); -  	} else if (p_msg == "message:click_ctrl") {  		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);  	} else if (p_msg == "message:inspect_object") { +		ScriptEditorDebuggerInspectedObject *debugObj = NULL; +  		ObjectID id = p_data[0];  		String type = p_data[1]; -		Variant path = p_data[2]; //what to do yet, i don't  know -		int prop_count = p_data[3]; +		Array properties = p_data[2]; -		int idx = 4; - -		if (inspected_object->last_edited_id != id) { -			inspected_object->prop_list.clear(); -			inspected_object->prop_values.clear(); +		bool is_new_object = false; +		if (remote_objects.has(id)) { +			debugObj = remote_objects[id]; +		} else { +			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; -			pinfo.name = p_data[idx++]; -			pinfo.type = Variant::Type(int(p_data[idx++])); -			pinfo.hint = PropertyHint(int(p_data[idx++])); -			pinfo.hint_string = p_data[idx++]; -			if (pinfo.name.begins_with("*")) { -				pinfo.name = pinfo.name.substr(1, pinfo.name.length()); -				pinfo.usage = PROPERTY_USAGE_CATEGORY; -			} else { -				pinfo.usage = PROPERTY_USAGE_EDITOR; +			pinfo.name = prop[0]; +			pinfo.type = Variant::Type(int(prop[1])); +			pinfo.hint = PropertyHint(int(prop[2])); +			pinfo.hint_string = prop[3]; +			pinfo.usage = PropertyUsageFlags(int(prop[4])); +			Variant var = prop[5]; + +			String hint_string = pinfo.hint_string; +			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 -				inspected_object->prop_list.push_back(pinfo); +				debugObj->prop_list.push_back(pinfo);  			} -			inspected_object->prop_values[pinfo.name] = p_data[idx++]; - -			if (inspected_object->last_edited_id == id) { -				//same, just update value, don't rebuild -				inspected_object->update_single(pinfo.name.ascii().get_data()); -			} +			debugObj->prop_values[pinfo.name] = var;  		} -		if (inspected_object->last_edited_id != id) { -			//only if different -			inspected_object->update(); +		if (editor->get_editor_history()->get_current() != debugObj->get_instance_id()) { +			editor->push_item(debugObj, ""); +		} 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") {  		vmem_tree->clear(); @@ -502,7 +530,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da  		int ofs = 0;  		int mcount = p_data[ofs]; -  		ofs++;  		for (int i = 0; i < mcount; i++) { @@ -521,12 +548,34 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da  				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]; +		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("Members/" + n, v, h, hs); +		} +		ofs += mcount * 2; +		mcount = p_data[ofs];  		ofs++;  		for (int i = 0; i < mcount; i++) { @@ -545,7 +594,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da  				v = s.get_slice(":", 1).to_int();  			} -			variables->add_property("locals/" + n, v, h, hs); +			variables->add_property("Globals/" + n, v, h, hs);  		}  		variables->update(); @@ -1133,7 +1182,6 @@ void ScriptEditorDebugger::stop() {  	le_set->set_disabled(true);  	profiler->set_enabled(true); -	inspect_properties->edit(NULL);  	inspect_scene_tree->clear();  	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() {  	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->set_input_buffer_max_size(1024 * 1024 * 8); //8mb should be enough  	editor = p_editor; +	editor->get_property_editor()->connect("object_id_selected", this, "_scene_tree_property_select_object");  	tabs = memnew(TabContainer);  	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("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_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2);  		inspected_object_id = 0;  		updating_scene_tree = false; - -		inspected_object = memnew(ScriptEditorDebuggerInspectedObject); -		inspected_object->connect("value_edited", this, "_scene_tree_property_value_edited");  	}  	{ //profiler @@ -1952,5 +2000,5 @@ ScriptEditorDebugger::~ScriptEditorDebugger() {  	ppeer->set_stream_peer(Ref<StreamPeer>());  	server->stop(); -	memdelete(inspected_object); +	_clear_remote_objects();  } diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h index d18a625eef..d13048ce2b 100644 --- a/editor/script_editor_debugger.h +++ b/editor/script_editor_debugger.h @@ -74,12 +74,13 @@ class ScriptEditorDebugger : public Control {  	Tree *inspect_scene_tree;  	HSplitContainer *inspect_info; -	PropertyEditor *inspect_properties; + +	bool updating_scene_tree;  	float inspect_scene_tree_timeout;  	float inspect_edited_object_timeout;  	ObjectID inspected_object_id; -	ScriptEditorDebuggerInspectedObject *inspected_object; -	bool updating_scene_tree; +	ScriptEditorDebuggerVariables *variables; +	Map<ObjectID, ScriptEditorDebuggerInspectedObject *> remote_objects;  	Set<ObjectID> unfold_cache;  	HSplitContainer *error_split; @@ -96,7 +97,6 @@ class ScriptEditorDebugger : public Control {  	TabContainer *tabs;  	Label *reason; -	ScriptEditorDebuggerVariables *variables;  	Button *step;  	Button *next; @@ -174,6 +174,9 @@ class ScriptEditorDebugger : public Control {  	void _paused(); +	void _set_remote_object(ObjectID p_id, ScriptEditorDebuggerInspectedObject *p_obj); +	void _clear_remote_objects(); +  protected:  	void _notification(int p_what);  	static void _bind_methods();  |