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); }
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); }