void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {

	Object *obj = ObjectDB::get_instance(p_id);
	if (!obj)
		return;

	typedef Pair<PropertyInfo, Variant> PropertyDesc;
	List<PropertyDesc> properties;

	if (ScriptInstance *si = obj->get_script_instance()) {
		if (!si->get_script().is_null()) {

			typedef Map<const Script *, Set<StringName> > ScriptMemberMap;
			typedef Map<const Script *, Map<StringName, Variant> > ScriptConstantsMap;

			ScriptMemberMap members;
			members[si->get_script().ptr()] = Set<StringName>();
			si->get_script()->get_members(&(members[si->get_script().ptr()]));

			ScriptConstantsMap constants;
			constants[si->get_script().ptr()] = Map<StringName, Variant>();
			si->get_script()->get_constants(&(constants[si->get_script().ptr()]));

			Ref<Script> base = si->get_script()->get_base_script();
			while (base.is_valid()) {

				members[base.ptr()] = Set<StringName>();
				base->get_members(&(members[base.ptr()]));

				constants[base.ptr()] = Map<StringName, Variant>();
				base->get_constants(&(constants[base.ptr()]));

				base = base->get_base_script();
			}

			for (ScriptMemberMap::Element *sm = members.front(); sm; sm = sm->next()) {
				for (Set<StringName>::Element *E = sm->get().front(); E; E = E->next()) {
					Variant m;
					if (si->get(E->get(), m)) {
						String script_path = sm->key() == si->get_script().ptr() ? "" : sm->key()->get_path().get_file() + "/";
						PropertyInfo pi(m.get_type(), "Members/" + script_path + E->get());
						properties.push_back(PropertyDesc(pi, m));
					}
				}
			}

			for (ScriptConstantsMap::Element *sc = constants.front(); sc; sc = sc->next()) {
				for (Map<StringName, Variant>::Element *E = sc->get().front(); E; E = E->next()) {
					String script_path = sc->key() == si->get_script().ptr() ? "" : sc->key()->get_path().get_file() + "/";
					if (E->value().get_type() == Variant::OBJECT) {
						Variant id = ((Object *)E->value())->get_instance_id();
						PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object");
						properties.push_back(PropertyDesc(pi, id));
					} else {
						PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + 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()) {
				if (E->value().get_type() == Variant::OBJECT) {
					Variant id = ((Object *)E->value())->get_instance_id();
					PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object");
					properties.push_front(PropertyDesc(pi, E->value()));
				} else {
					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)));
		}
	}

	Array send_props;
	for (int i = 0; i < properties.size(); i++) {
		const PropertyInfo &pi = properties[i].first;
		Variant &var = properties[i].second;

		WeakRef *ref = Object::cast_to<WeakRef>(var);
		if (ref) {
			var = ref->get_ref();
		}

		RES res = var;

		Array prop;
		prop.push_back(pi.name);
		prop.push_back(pi.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
			prop.push_back(PROPERTY_HINT_OBJECT_TOO_BIG);
			prop.push_back("");
			prop.push_back(pi.usage);
			prop.push_back(Variant());
		} else {
			prop.push_back(pi.hint);
			prop.push_back(pi.hint_string);
			prop.push_back(pi.usage);

			if (!res.is_null()) {
				var = res->get_path();
			}

			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);
}
Example #2
0
void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {

	Object *obj = ObjectDB::get_instance(p_id);
	if (!obj)
		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;
	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)));
		}
	}

	Array send_props;
	for (int i = 0; i < properties.size(); i++) {
		const PropertyInfo &pi = properties[i].first;
		Variant &var = properties[i].second;

		WeakRef *ref = Object::cast_to<WeakRef>(var);
		if (ref) {
			var = ref->get_ref();
		}

		RES res = var;

		Array prop;
		prop.push_back(pi.name);
		prop.push_back(pi.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
			prop.push_back(PROPERTY_HINT_OBJECT_TOO_BIG);
			prop.push_back("");
			prop.push_back(pi.usage);
			prop.push_back(Variant());
		} else {
			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);
}