mirror of
https://github.com/godotengine/godot
synced 2024-09-05 06:18:39 +00:00
Merge pull request #27886 from LeonardMeagher2/obj_to_string
Allow overriding how scripted objects are converted to strings
This commit is contained in:
commit
defd960276
|
@ -44,6 +44,7 @@ CoreStringNames::CoreStringNames() :
|
|||
_iter_next(StaticCString::create("_iter_next")),
|
||||
_iter_get(StaticCString::create("_iter_get")),
|
||||
get_rid(StaticCString::create("get_rid")),
|
||||
_to_string(StaticCString::create("_to_string")),
|
||||
#ifdef TOOLS_ENABLED
|
||||
_sections_unfolded(StaticCString::create("_sections_unfolded")),
|
||||
#endif
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
StringName _iter_next;
|
||||
StringName _iter_get;
|
||||
StringName get_rid;
|
||||
StringName _to_string;
|
||||
#ifdef TOOLS_ENABLED
|
||||
StringName _sections_unfolded;
|
||||
#endif
|
||||
|
|
|
@ -954,6 +954,16 @@ void Object::notification(int p_notification, bool p_reversed) {
|
|||
}
|
||||
}
|
||||
|
||||
String Object::to_string() {
|
||||
if (script_instance) {
|
||||
bool valid;
|
||||
String ret = script_instance->to_string(&valid);
|
||||
if (valid)
|
||||
return ret;
|
||||
}
|
||||
return "[" + get_class() + ":" + itos(get_instance_id()) + "]";
|
||||
}
|
||||
|
||||
void Object::_changed_callback(Object *p_changed, const char *p_prop) {
|
||||
}
|
||||
|
||||
|
@ -1687,6 +1697,7 @@ void Object::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_property_list"), &Object::_get_property_list_bind);
|
||||
ClassDB::bind_method(D_METHOD("get_method_list"), &Object::_get_method_list_bind);
|
||||
ClassDB::bind_method(D_METHOD("notification", "what", "reversed"), &Object::notification, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("to_string"), &Object::to_string);
|
||||
ClassDB::bind_method(D_METHOD("get_instance_id"), &Object::get_instance_id);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_script", "script"), &Object::set_script);
|
||||
|
@ -1774,6 +1785,7 @@ void Object::_bind_methods() {
|
|||
|
||||
#endif
|
||||
BIND_VMETHOD(MethodInfo("_init"));
|
||||
BIND_VMETHOD(MethodInfo(Variant::STRING, "_to_string"));
|
||||
|
||||
BIND_CONSTANT(NOTIFICATION_POSTINITIALIZE);
|
||||
BIND_CONSTANT(NOTIFICATION_PREDELETE);
|
||||
|
|
|
@ -659,6 +659,7 @@ public:
|
|||
void call_multilevel(const StringName &p_name, VARIANT_ARG_LIST); // C++ helper
|
||||
|
||||
void notification(int p_notification, bool p_reversed = false);
|
||||
String to_string();
|
||||
|
||||
//used mainly by script, get and set all INCLUDING string
|
||||
virtual Variant getvar(const Variant &p_key, bool *r_valid = NULL) const;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "script_language.h"
|
||||
|
||||
#include "core/core_string_names.h"
|
||||
#include "core/project_settings.h"
|
||||
|
||||
ScriptLanguage *ScriptServer::_languages[MAX_LANGUAGES];
|
||||
|
|
|
@ -173,6 +173,11 @@ public:
|
|||
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
|
||||
virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
|
||||
virtual void notification(int p_notification) = 0;
|
||||
virtual String to_string(bool *r_valid) {
|
||||
if (r_valid)
|
||||
*r_valid = false;
|
||||
return String();
|
||||
}
|
||||
|
||||
//this is used by script languages that keep a reference counter of their own
|
||||
//you can make make Ref<> not die when it reaches zero, so deleting the reference
|
||||
|
|
|
@ -1601,7 +1601,7 @@ String Variant::stringify(List<const void *> &stack) const {
|
|||
};
|
||||
};
|
||||
#endif
|
||||
return "[" + _get_obj().obj->get_class() + ":" + itos(_get_obj().obj->get_instance_id()) + "]";
|
||||
return _get_obj().obj->to_string();
|
||||
} else
|
||||
return "[Object:null]";
|
||||
|
||||
|
|
|
@ -57,6 +57,22 @@
|
|||
Sets a property. Returns [code]true[/code] if the [code]property[/code] exists.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_to_string" qualifiers="virtual">
|
||||
<return type="String">
|
||||
</return>
|
||||
<description>
|
||||
Returns a [String] representing the object. Default is [code]"[ClassName:RID]"[/code].
|
||||
Override this method to customize the [String] representation of the object when it's being converted to a string, for example: [code]print(obj)[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="to_string">
|
||||
<return type="String">
|
||||
</return>
|
||||
<description>
|
||||
Returns a [String] representing the object. Default is [code]"[ClassName:RID]"[/code].
|
||||
Override the method [method _to_string] to customize the [String] representation.
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_user_signal">
|
||||
<return type="void">
|
||||
</return>
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "gdnative/gdnative.h"
|
||||
|
||||
#include "core/core_string_names.h"
|
||||
#include "core/global_constants.h"
|
||||
#include "core/io/file_access_encrypted.h"
|
||||
#include "core/os/file_access.h"
|
||||
|
@ -771,6 +772,27 @@ void NativeScriptInstance::notification(int p_notification) {
|
|||
call_multilevel("_notification", args, 1);
|
||||
}
|
||||
|
||||
String NativeScriptInstance::to_string(bool *r_valid) {
|
||||
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
|
||||
Variant::CallError ce;
|
||||
Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce);
|
||||
if (ce.error == Variant::CallError::CALL_OK) {
|
||||
if (ret.get_type() != Variant::STRING) {
|
||||
if (r_valid)
|
||||
*r_valid = false;
|
||||
ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
|
||||
ERR_FAIL_V(String());
|
||||
}
|
||||
if (r_valid)
|
||||
*r_valid = true;
|
||||
return ret.operator String();
|
||||
}
|
||||
}
|
||||
if (r_valid)
|
||||
*r_valid = false;
|
||||
return String();
|
||||
}
|
||||
|
||||
void NativeScriptInstance::refcount_incremented() {
|
||||
Variant::CallError err;
|
||||
call("_refcount_incremented", NULL, 0, err);
|
||||
|
|
|
@ -208,6 +208,7 @@ public:
|
|||
virtual bool has_method(const StringName &p_method) const;
|
||||
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
|
||||
virtual void notification(int p_notification);
|
||||
String to_string(bool *r_valid);
|
||||
virtual Ref<Script> get_script() const;
|
||||
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
|
||||
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "gdscript.h"
|
||||
|
||||
#include "core/core_string_names.h"
|
||||
#include "core/engine.h"
|
||||
#include "core/global_constants.h"
|
||||
#include "core/io/file_access_encrypted.h"
|
||||
|
@ -1234,6 +1235,27 @@ void GDScriptInstance::notification(int p_notification) {
|
|||
}
|
||||
}
|
||||
|
||||
String GDScriptInstance::to_string(bool *r_valid) {
|
||||
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
|
||||
Variant::CallError ce;
|
||||
Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce);
|
||||
if (ce.error == Variant::CallError::CALL_OK) {
|
||||
if (ret.get_type() != Variant::STRING) {
|
||||
if (r_valid)
|
||||
*r_valid = false;
|
||||
ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
|
||||
ERR_FAIL_V(String());
|
||||
}
|
||||
if (r_valid)
|
||||
*r_valid = true;
|
||||
return ret.operator String();
|
||||
}
|
||||
}
|
||||
if (r_valid)
|
||||
*r_valid = false;
|
||||
return String();
|
||||
}
|
||||
|
||||
Ref<Script> GDScriptInstance::get_script() const {
|
||||
|
||||
return script;
|
||||
|
|
|
@ -251,6 +251,7 @@ public:
|
|||
Variant debug_get_member_by_index(int p_idx) const { return members[p_idx]; }
|
||||
|
||||
virtual void notification(int p_notification);
|
||||
String to_string(bool *r_valid);
|
||||
|
||||
virtual Ref<Script> get_script() const;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "visual_script.h"
|
||||
|
||||
#include "core/core_string_names.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/project_settings.h"
|
||||
#include "scene/main/node.h"
|
||||
|
@ -1976,6 +1977,27 @@ void VisualScriptInstance::notification(int p_notification) {
|
|||
call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); //do as call
|
||||
}
|
||||
|
||||
String VisualScriptInstance::to_string(bool *r_valid) {
|
||||
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
|
||||
Variant::CallError ce;
|
||||
Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce);
|
||||
if (ce.error == Variant::CallError::CALL_OK) {
|
||||
if (ret.get_type() != Variant::STRING) {
|
||||
if (r_valid)
|
||||
*r_valid = false;
|
||||
ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
|
||||
ERR_FAIL_V(String());
|
||||
}
|
||||
if (r_valid)
|
||||
*r_valid = true;
|
||||
return ret.operator String();
|
||||
}
|
||||
}
|
||||
if (r_valid)
|
||||
*r_valid = false;
|
||||
return String();
|
||||
}
|
||||
|
||||
Ref<Script> VisualScriptInstance::get_script() const {
|
||||
|
||||
return script;
|
||||
|
|
|
@ -405,6 +405,7 @@ public:
|
|||
virtual bool has_method(const StringName &p_method) const;
|
||||
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
|
||||
virtual void notification(int p_notification);
|
||||
String to_string(bool *r_valid);
|
||||
|
||||
bool set_variable(const StringName &p_variable, const Variant &p_value) {
|
||||
|
||||
|
|
Loading…
Reference in a new issue