summaryrefslogtreecommitdiff
path: root/core/object
diff options
context:
space:
mode:
Diffstat (limited to 'core/object')
-rw-r--r--core/object/callable_method_pointer.h2
-rw-r--r--core/object/class_db.cpp27
-rw-r--r--core/object/class_db.h105
-rw-r--r--core/object/make_virtuals.py2
-rw-r--r--core/object/message_queue.h4
-rw-r--r--core/object/method_bind.cpp6
-rw-r--r--core/object/method_bind.h325
-rw-r--r--core/object/object.cpp109
-rw-r--r--core/object/object.h33
-rw-r--r--core/object/ref_counted.h2
-rw-r--r--core/object/script_language.cpp2
-rw-r--r--core/object/script_language.h142
-rw-r--r--core/object/script_language_extension.cpp180
-rw-r--r--core/object/script_language_extension.h835
-rw-r--r--core/object/undo_redo.cpp18
-rw-r--r--core/object/undo_redo.h4
16 files changed, 1505 insertions, 291 deletions
diff --git a/core/object/callable_method_pointer.h b/core/object/callable_method_pointer.h
index 3cd9ad3819..577d4b9fbd 100644
--- a/core/object/callable_method_pointer.h
+++ b/core/object/callable_method_pointer.h
@@ -38,7 +38,7 @@
#include "core/variant/callable.h"
class CallableCustomMethodPointerBase : public CallableCustom {
- uint32_t *comp_ptr;
+ uint32_t *comp_ptr = nullptr;
uint32_t comp_size;
uint32_t h;
#ifdef DEBUG_METHODS_ENABLED
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index e09c6cb97c..61ce965bc3 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -37,6 +37,8 @@
#define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock);
#define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock);
+#ifdef DEBUG_METHODS_ENABLED
+
MethodDefinition D_METHOD(const char *p_name) {
MethodDefinition md;
md.name = StaticCString::create(p_name);
@@ -224,6 +226,8 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
return md;
}
+#endif
+
ClassDB::APIType ClassDB::current_api = API_CORE;
void ClassDB::set_current_api(APIType p_api) {
@@ -1420,8 +1424,13 @@ void ClassDB::bind_method_custom(const StringName &p_class, MethodBind *p_method
type->method_map[p_method->get_name()] = p_method;
}
+#ifdef DEBUG_METHODS_ENABLED
MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) {
StringName mdname = method_name.name;
+#else
+MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount) {
+ StringName mdname = StaticCString::create(method_name);
+#endif
OBJTYPE_WLOCK;
ERR_FAIL_COND_V(!p_bind, nullptr);
@@ -1485,9 +1494,10 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
if (p_object_core) {
mi.flags |= METHOD_FLAG_OBJECT_CORE;
}
- if (p_arg_names.size()) {
+
+ if (!p_object_core) {
if (p_arg_names.size() != mi.arguments.size()) {
- WARN_PRINT("Mismatch argument name count for virtual function: " + String(p_class) + "::" + p_method.name);
+ WARN_PRINT("Mismatch argument name count for virtual method: " + String(p_class) + "::" + p_method.name);
} else {
for (int i = 0; i < p_arg_names.size(); i++) {
mi.arguments[i].name = p_arg_names[i];
@@ -1495,6 +1505,10 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
}
}
+ if (classes[p_class].virtual_methods_map.has(p_method.name)) {
+ // overloading not supported
+ ERR_FAIL_MSG("Virtual method already bound '" + String(p_class) + "::" + p_method.name + "'.");
+ }
classes[p_class].virtual_methods.push_back(mi);
classes[p_class].virtual_methods_map[p_method.name] = mi;
@@ -1551,15 +1565,6 @@ bool ClassDB::is_class_exposed(const StringName &p_class) {
return ti->exposed;
}
-StringName ClassDB::get_category(const StringName &p_node) {
- ERR_FAIL_COND_V(!classes.has(p_node), StringName());
-#ifdef DEBUG_ENABLED
- return classes[p_node].category;
-#else
- return StringName();
-#endif
-}
-
void ClassDB::add_resource_base_extension(const StringName &p_extension, const StringName &p_class) {
if (resource_base_extensions.has(p_extension)) {
return;
diff --git a/core/object/class_db.h b/core/object/class_db.h
index 32e4bf7644..333a3307e2 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -45,6 +45,8 @@
#define DEFVAL(m_defval) (m_defval)
+#ifdef DEBUG_METHODS_ENABLED
+
struct MethodDefinition {
StringName name;
Vector<StringName> args;
@@ -70,6 +72,14 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13);
+#else
+
+// When DEBUG_METHODS_ENABLED is set this will let the engine know
+// the argument names for easier debugging.
+#define D_METHOD(m_c, ...) m_c
+
+#endif
+
class ClassDB {
public:
enum APIType {
@@ -85,8 +95,8 @@ public:
int index;
StringName setter;
StringName getter;
- MethodBind *_setptr;
- MethodBind *_getptr;
+ MethodBind *_setptr = nullptr;
+ MethodBind *_getptr = nullptr;
Variant::Type type;
};
@@ -109,7 +119,6 @@ public:
Set<StringName> methods_in_properties;
List<MethodInfo> virtual_methods;
Map<StringName, MethodInfo> virtual_methods_map;
- StringName category;
Map<StringName, Vector<Error>> method_error_values;
#endif
HashMap<StringName, PropertySetGet> property_setget;
@@ -135,7 +144,11 @@ public:
static HashMap<StringName, StringName> resource_base_extensions;
static HashMap<StringName, StringName> compat_classes;
+#ifdef DEBUG_METHODS_ENABLED
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
+#else
+ static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount);
+#endif
static APIType current_api;
@@ -227,75 +240,27 @@ public:
static uint64_t get_api_hash(APIType p_api);
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method) {
- MethodBind *bind = create_method_bind(p_method);
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, nullptr, 0); //use static function, much smaller binary usage
- }
-
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1) {
- MethodBind *bind = create_method_bind(p_method);
- const Variant *ptr[1] = { &p_def1 };
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 1);
- }
-
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2) {
- MethodBind *bind = create_method_bind(p_method);
- const Variant *ptr[2] = { &p_def1, &p_def2 };
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 2);
- }
-
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3) {
- MethodBind *bind = create_method_bind(p_method);
- const Variant *ptr[3] = { &p_def1, &p_def2, &p_def3 };
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 3);
- }
-
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4) {
- MethodBind *bind = create_method_bind(p_method);
- const Variant *ptr[4] = { &p_def1, &p_def2, &p_def3, &p_def4 };
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 4);
- }
-
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5) {
- MethodBind *bind = create_method_bind(p_method);
- const Variant *ptr[5] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5 };
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 5);
- }
-
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6) {
+ template <class N, class M, typename... VarArgs>
+ static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args) {
+ Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
+ const Variant *argptrs[sizeof...(p_args) + 1];
+ for (uint32_t i = 0; i < sizeof...(p_args); i++) {
+ argptrs[i] = &args[i];
+ }
MethodBind *bind = create_method_bind(p_method);
- const Variant *ptr[6] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6 };
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 6);
+ return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7) {
- MethodBind *bind = create_method_bind(p_method);
- const Variant *ptr[7] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7 };
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 7);
- }
-
- template <class N, class M>
- static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7, const Variant &p_def8) {
- MethodBind *bind = create_method_bind(p_method);
- const Variant *ptr[8] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7, &p_def8 };
-
- return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 8);
+ template <class N, class M, typename... VarArgs>
+ static MethodBind *bind_static_method(const StringName &p_class, N p_method_name, M p_method, VarArgs... p_args) {
+ Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
+ const Variant *argptrs[sizeof...(p_args) + 1];
+ for (uint32_t i = 0; i < sizeof...(p_args); i++) {
+ argptrs[i] = &args[i];
+ }
+ MethodBind *bind = create_static_method_bind(p_method);
+ bind->set_instance_class(p_class);
+ return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
template <class M>
@@ -379,8 +344,6 @@ public:
static Vector<Error> get_method_error_return_values(const StringName &p_class, const StringName &p_method);
static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid = nullptr);
- static StringName get_category(const StringName &p_node);
-
static void set_class_enabled(const StringName &p_class, bool p_enable);
static bool is_class_enabled(const StringName &p_class);
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index 64ee5940b0..c18d70d9f6 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -28,7 +28,7 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
}\\
\\
if (required) {\\
- ERR_PRINT_ONCE("Required virtual method: "+get_class()+"::" + #m_name + " must be overriden before calling.");\\
+ ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");\\
$RVOID\\
}\\
\\
diff --git a/core/object/message_queue.h b/core/object/message_queue.h
index eaab01d0aa..2219cdb8f6 100644
--- a/core/object/message_queue.h
+++ b/core/object/message_queue.h
@@ -62,10 +62,10 @@ class MessageQueue {
};
};
- uint8_t *buffer;
+ uint8_t *buffer = nullptr;
uint32_t buffer_end = 0;
uint32_t buffer_max_used = 0;
- uint32_t buffer_size;
+ uint32_t buffer_size = 0;
void _call_function(const Callable &p_callable, const Variant *p_args, int p_argcount, bool p_show_error);
diff --git a/core/object/method_bind.cpp b/core/object/method_bind.cpp
index 32269b5f19..a208c1a2b2 100644
--- a/core/object/method_bind.cpp
+++ b/core/object/method_bind.cpp
@@ -69,8 +69,6 @@ PropertyInfo MethodBind::get_argument_info(int p_argument) const {
PropertyInfo info = _gen_argument_type_info(p_argument);
#ifdef DEBUG_METHODS_ENABLED
info.name = p_argument < arg_names.size() ? String(arg_names[p_argument]) : String("arg" + itos(p_argument));
-#else
- info.name = String("arg" + itos(p_argument));
#endif
return info;
}
@@ -83,6 +81,10 @@ void MethodBind::_set_const(bool p_const) {
_const = p_const;
}
+void MethodBind::_set_static(bool p_static) {
+ _static = p_static;
+}
+
void MethodBind::_set_returns(bool p_returns) {
_returns = p_returns;
}
diff --git a/core/object/method_bind.h b/core/object/method_bind.h
index 02b73fa273..2870195911 100644
--- a/core/object/method_bind.h
+++ b/core/object/method_bind.h
@@ -60,6 +60,7 @@ class MethodBind {
int default_argument_count = 0;
int argument_count = 0;
+ bool _static = false;
bool _const = false;
bool _returns = false;
@@ -69,6 +70,7 @@ protected:
Vector<StringName> arg_names;
#endif
void _set_const(bool p_const);
+ void _set_static(bool p_static);
void _set_returns(bool p_returns);
virtual Variant::Type _gen_argument_type(int p_arg) const = 0;
virtual PropertyInfo _gen_argument_type_info(int p_arg) const = 0;
@@ -116,7 +118,7 @@ public:
#endif
void set_hint_flags(uint32_t p_hint) { hint_flags = p_hint; }
- uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0); }
+ uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0) | (is_static() ? METHOD_FLAG_STATIC : 0); }
_FORCE_INLINE_ StringName get_instance_class() const { return instance_class; }
_FORCE_INLINE_ void set_instance_class(const StringName &p_class) { instance_class = p_class; }
@@ -129,6 +131,7 @@ public:
void set_name(const StringName &p_name);
_FORCE_INLINE_ int get_method_id() const { return method_id; }
_FORCE_INLINE_ bool is_const() const { return _const; }
+ _FORCE_INLINE_ bool is_static() const { return _static; }
_FORCE_INLINE_ bool has_return() const { return _returns; }
virtual bool is_vararg() const { return false; }
@@ -140,54 +143,60 @@ public:
virtual ~MethodBind();
};
-template <class T>
-class MethodBindVarArg : public MethodBind {
-public:
- typedef Variant (T::*NativeCall)(const Variant **, int, Callable::CallError &);
-
+// MethodBindVarArg base CRTP
+template <class Derived, class T, class R, bool should_returns>
+class MethodBindVarArgBase : public MethodBind {
protected:
- NativeCall call_method = nullptr;
- MethodInfo arguments;
+ R(T::*method)
+ (const Variant **, int, Callable::CallError &);
+ MethodInfo method_info;
public:
- virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+ virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
if (p_arg < 0) {
- return arguments.return_val;
- } else if (p_arg < arguments.arguments.size()) {
- return arguments.arguments[p_arg];
+ return _gen_return_type_info();
+ } else if (p_arg < method_info.arguments.size()) {
+ return method_info.arguments[p_arg];
} else {
return PropertyInfo(Variant::NIL, "arg_" + itos(p_arg), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
}
}
- virtual Variant::Type _gen_argument_type(int p_arg) const {
+ virtual Variant::Type _gen_argument_type(int p_arg) const override {
return _gen_argument_type_info(p_arg).type;
}
#ifdef DEBUG_METHODS_ENABLED
- virtual GodotTypeInfo::Metadata get_argument_meta(int) const {
+ virtual GodotTypeInfo::Metadata get_argument_meta(int) const override {
return GodotTypeInfo::METADATA_NONE;
}
#endif
- virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
- T *instance = static_cast<T *>(p_object);
- return (instance->*call_method)(p_args, p_arg_count, r_error);
+ virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override {
+ ERR_FAIL(); // Can't call.
}
- void set_method_info(const MethodInfo &p_info, bool p_return_nil_is_variant) {
- set_argument_count(p_info.arguments.size());
- Variant::Type *at = memnew_arr(Variant::Type, p_info.arguments.size() + 1);
- at[0] = p_info.return_val.type;
- if (p_info.arguments.size()) {
+ virtual bool is_const() const { return false; }
+
+ virtual bool is_vararg() const override { return true; }
+
+ MethodBindVarArgBase(
+ R (T::*p_method)(const Variant **, int, Callable::CallError &),
+ const MethodInfo &p_method_info,
+ bool p_return_nil_is_variant) :
+ method(p_method), method_info(p_method_info) {
+ set_argument_count(method_info.arguments.size());
+ Variant::Type *at = memnew_arr(Variant::Type, method_info.arguments.size() + 1);
+ at[0] = _gen_return_type_info().type;
+ if (method_info.arguments.size()) {
#ifdef DEBUG_METHODS_ENABLED
Vector<StringName> names;
- names.resize(p_info.arguments.size());
+ names.resize(method_info.arguments.size());
#endif
- for (int i = 0; i < p_info.arguments.size(); i++) {
- at[i + 1] = p_info.arguments[i].type;
+ for (int i = 0; i < method_info.arguments.size(); i++) {
+ at[i + 1] = method_info.arguments[i].type;
#ifdef DEBUG_METHODS_ENABLED
- names.write[i] = p_info.arguments[i].name;
+ names.write[i] = method_info.arguments[i].name;
#endif
}
@@ -196,31 +205,76 @@ public:
#endif
}
argument_types = at;
- arguments = p_info;
if (p_return_nil_is_variant) {
- arguments.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
}
+
+ _set_returns(should_returns);
}
- virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
- ERR_FAIL(); // Can't call.
+private:
+ PropertyInfo _gen_return_type_info() const {
+ return Derived::_gen_return_type_info_impl();
}
+};
- void set_method(NativeCall p_method) { call_method = p_method; }
- virtual bool is_const() const { return false; }
+// variadic, no return
+template <class T>
+class MethodBindVarArgT : public MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false> {
+ friend class MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>;
+
+public:
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override {
+ (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>::method)(p_args, p_arg_count, r_error);
+ return {};
+ }
- virtual bool is_vararg() const { return true; }
+ MethodBindVarArgT(
+ void (T::*p_method)(const Variant **, int, Callable::CallError &),
+ const MethodInfo &p_method_info,
+ bool p_return_nil_is_variant) :
+ MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>(p_method, p_method_info, p_return_nil_is_variant) {
+ }
- MethodBindVarArg() {
- _set_returns(true);
+private:
+ static PropertyInfo _gen_return_type_info_impl() {
+ return {};
}
};
template <class T>
-MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
- MethodBindVarArg<T> *a = memnew((MethodBindVarArg<T>));
- a->set_method(p_method);
- a->set_method_info(p_info, p_return_nil_is_variant);
+MethodBind *create_vararg_method_bind(void (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
+ MethodBind *a = memnew((MethodBindVarArgT<T>)(p_method, p_info, p_return_nil_is_variant));
+ a->set_instance_class(T::get_class_static());
+ return a;
+}
+
+// variadic, return
+template <class T, class R>
+class MethodBindVarArgTR : public MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true> {
+ friend class MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>;
+
+public:
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override {
+ return (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>::method)(p_args, p_arg_count, r_error);
+ }
+
+ MethodBindVarArgTR(
+ R (T::*p_method)(const Variant **, int, Callable::CallError &),
+ const MethodInfo &p_info,
+ bool p_return_nil_is_variant) :
+ MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>(p_method, p_info, p_return_nil_is_variant) {
+ }
+
+private:
+ static PropertyInfo _gen_return_type_info_impl() {
+ return GetTypeInfo<R>::get_class_info();
+ }
+};
+
+template <class T, class R>
+MethodBind *create_vararg_method_bind(R (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
+ MethodBind *a = memnew((MethodBindVarArgTR<T, R>)(p_method, p_info, p_return_nil_is_variant));
a->set_instance_class(T::get_class_static());
return a;
}
@@ -249,7 +303,7 @@ protected:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
#endif
- virtual Variant::Type _gen_argument_type(int p_arg) const {
+ virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
} else {
@@ -260,7 +314,7 @@ protected:
#pragma GCC diagnostic pop
#endif
- virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+ virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
PropertyInfo pi;
call_get_argument_type_info<P...>(p_arg, pi);
return pi;
@@ -268,25 +322,25 @@ protected:
public:
#ifdef DEBUG_METHODS_ENABLED
- virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
return call_get_argument_metadata<P...>(p_arg);
}
#endif
- virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override {
#ifdef TYPED_METHOD_BIND
call_with_variant_args_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
#else
- call_with_variant_args_dv((MB_T *)(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
+ call_with_variant_args_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
#endif
return Variant();
}
- virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
+ virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override {
#ifdef TYPED_METHOD_BIND
call_with_ptr_args<T, P...>(static_cast<T *>(p_object), method, p_args);
#else
- call_with_ptr_args<MB_T, P...>((MB_T *)(p_object), method, p_args);
+ call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args);
#endif
}
@@ -308,7 +362,7 @@ MethodBind *create_method_bind(void (T::*p_method)(P...)) {
return a;
}
-// no return, not const
+// no return, const
#ifdef TYPED_METHOD_BIND
template <class T, class... P>
@@ -324,7 +378,7 @@ protected:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
#endif
- virtual Variant::Type _gen_argument_type(int p_arg) const {
+ virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
} else {
@@ -335,7 +389,7 @@ protected:
#pragma GCC diagnostic pop
#endif
- virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+ virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
PropertyInfo pi;
call_get_argument_type_info<P...>(p_arg, pi);
return pi;
@@ -343,25 +397,25 @@ protected:
public:
#ifdef DEBUG_METHODS_ENABLED
- virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
return call_get_argument_metadata<P...>(p_arg);
}
#endif
- virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override {
#ifdef TYPED_METHOD_BIND
call_with_variant_argsc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
#else
- call_with_variant_argsc_dv((MB_T *)(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
+ call_with_variant_argsc_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
#endif
return Variant();
}
- virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
+ virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override {
#ifdef TYPED_METHOD_BIND
call_with_ptr_argsc<T, P...>(static_cast<T *>(p_object), method, p_args);
#else
- call_with_ptr_argsc<MB_T, P...>((MB_T *)(p_object), method, p_args);
+ call_with_ptr_argsc<MB_T, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args);
#endif
}
@@ -401,7 +455,7 @@ protected:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
#endif
- virtual Variant::Type _gen_argument_type(int p_arg) const {
+ virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
} else {
@@ -409,7 +463,7 @@ protected:
}
}
- virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+ virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
PropertyInfo pi;
call_get_argument_type_info<P...>(p_arg, pi);
@@ -424,7 +478,7 @@ protected:
public:
#ifdef DEBUG_METHODS_ENABLED
- virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
if (p_arg >= 0) {
return call_get_argument_metadata<P...>(p_arg);
} else {
@@ -433,21 +487,21 @@ public:
}
#endif
- virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override {
Variant ret;
#ifdef TYPED_METHOD_BIND
call_with_variant_args_ret_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
#else
- call_with_variant_args_ret_dv((MB_T *)p_object, method, p_args, p_arg_count, ret, r_error, get_default_arguments());
+ call_with_variant_args_ret_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
#endif
return ret;
}
- virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
+ virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override {
#ifdef TYPED_METHOD_BIND
call_with_ptr_args_ret<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
#else
- call_with_ptr_args_ret<MB_T, R, P...>((MB_T *)(p_object), method, p_args, r_ret);
+ call_with_ptr_args_ret<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
#endif
}
@@ -488,7 +542,7 @@ protected:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
#endif
- virtual Variant::Type _gen_argument_type(int p_arg) const {
+ virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
} else {
@@ -496,7 +550,7 @@ protected:
}
}
- virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+ virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
PropertyInfo pi;
call_get_argument_type_info<P...>(p_arg, pi);
@@ -511,7 +565,7 @@ protected:
public:
#ifdef DEBUG_METHODS_ENABLED
- virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
if (p_arg >= 0) {
return call_get_argument_metadata<P...>(p_arg);
} else {
@@ -520,21 +574,21 @@ public:
}
#endif
- virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override {
Variant ret;
#ifdef TYPED_METHOD_BIND
call_with_variant_args_retc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
#else
- call_with_variant_args_retc_dv((MB_T *)(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
+ call_with_variant_args_retc_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
#endif
return ret;
}
- virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
+ virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override {
#ifdef TYPED_METHOD_BIND
call_with_ptr_args_retc<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
#else
- call_with_ptr_args_retc<MB_T, R, P...>((MB_T *)(p_object), method, p_args, r_ret);
+ call_with_ptr_args_retc<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
#endif
}
@@ -558,4 +612,139 @@ MethodBind *create_method_bind(R (T::*p_method)(P...) const) {
return a;
}
+/* STATIC BINDS */
+
+// no return
+
+template <class... P>
+class MethodBindTS : public MethodBind {
+ void (*function)(P...);
+
+protected:
+// GCC raises warnings in the case P = {} as the comparison is always false...
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+ virtual Variant::Type _gen_argument_type(int p_arg) const override {
+ if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+ return call_get_argument_type<P...>(p_arg);
+ } else {
+ return Variant::NIL;
+ }
+ }
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+ virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
+ PropertyInfo pi;
+ call_get_argument_type_info<P...>(p_arg, pi);
+ return pi;
+ }
+
+public:
+#ifdef DEBUG_METHODS_ENABLED
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
+ return call_get_argument_metadata<P...>(p_arg);
+ }
+
+#endif
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override {
+ (void)p_object; // unused
+ call_with_variant_args_static_dv(function, p_args, p_arg_count, r_error, get_default_arguments());
+ return Variant();
+ }
+
+ virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override {
+ (void)p_object;
+ (void)r_ret;
+ call_with_ptr_args_static_method(function, p_args);
+ }
+
+ MethodBindTS(void (*p_function)(P...)) {
+ function = p_function;
+ _generate_argument_types(sizeof...(P));
+ set_argument_count(sizeof...(P));
+ _set_static(true);
+ }
+};
+
+template <class... P>
+MethodBind *create_static_method_bind(void (*p_method)(P...)) {
+ MethodBind *a = memnew((MethodBindTS<P...>)(p_method));
+ return a;
+}
+
+// return
+
+template <class R, class... P>
+class MethodBindTRS : public MethodBind {
+ R(*function)
+ (P...);
+
+protected:
+// GCC raises warnings in the case P = {} as the comparison is always false...
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+ virtual Variant::Type _gen_argument_type(int p_arg) const override {
+ if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+ return call_get_argument_type<P...>(p_arg);
+ } else {
+ return GetTypeInfo<R>::VARIANT_TYPE;
+ }
+ }
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+ virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
+ if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+ PropertyInfo pi;
+ call_get_argument_type_info<P...>(p_arg, pi);
+ return pi;
+ } else {
+ return GetTypeInfo<R>::get_class_info();
+ }
+ }
+
+public:
+#ifdef DEBUG_METHODS_ENABLED
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
+ if (p_arg >= 0) {
+ return call_get_argument_metadata<P...>(p_arg);
+ } else {
+ return GetTypeInfo<R>::METADATA;
+ }
+ }
+
+#endif
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override {
+ Variant ret;
+ call_with_variant_args_static_ret_dv(function, p_args, p_arg_count, ret, r_error, get_default_arguments());
+ return ret;
+ }
+
+ virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override {
+ (void)p_object;
+ call_with_ptr_args_static_method_ret(function, p_args, r_ret);
+ }
+
+ MethodBindTRS(R (*p_function)(P...)) {
+ function = p_function;
+ _generate_argument_types(sizeof...(P));
+ set_argument_count(sizeof...(P));
+ _set_static(true);
+ _set_returns(true);
+ }
+};
+
+template <class R, class... P>
+MethodBind *create_static_method_bind(R (*p_method)(P...)) {
+ MethodBind *a = memnew((MethodBindTRS<R, P...>)(p_method));
+ return a;
+}
+
#endif // METHOD_BIND_H
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 096edd4e60..897b5d18de 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -416,12 +416,22 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
}
return;
- } else if (p_name == CoreStringNames::get_singleton()->_meta) {
- metadata = p_value.duplicate();
- if (r_valid) {
- *r_valid = true;
+ } else {
+ OrderedHashMap<StringName, Variant>::Element *E = metadata_properties.getptr(p_name);
+ if (E) {
+ E->get() = p_value;
+ if (r_valid) {
+ *r_valid = true;
+ }
+ return;
+ } else if (p_name.operator String().begins_with("metadata/")) {
+ // Must exist, otherwise duplicate() will not work.
+ set_meta(p_name.operator String().replace_first("metadata/", ""), p_value);
+ if (r_valid) {
+ *r_valid = true;
+ }
+ return;
}
- return;
}
// Something inside the object... :|
@@ -496,9 +506,12 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
*r_valid = true;
}
return ret;
+ }
+
+ const OrderedHashMap<StringName, Variant>::Element *E = metadata_properties.getptr(p_name);
- } else if (p_name == CoreStringNames::get_singleton()->_meta) {
- ret = metadata;
+ if (E) {
+ ret = E->get();
if (r_valid) {
*r_valid = true;
}
@@ -648,13 +661,20 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
if (!is_class("Script")) { // can still be set, but this is for user-friendliness
p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT));
}
- if (!metadata.is_empty()) {
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
- }
+
if (script_instance && !p_reversed) {
p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
script_instance->get_property_list(p_list);
}
+
+ for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) {
+ PropertyInfo pi = PropertyInfo(K.value().get_type(), "metadata/" + K.key().operator String());
+ if (K.value().get_type() == Variant::OBJECT) {
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "Resource";
+ }
+ p_list->push_back(pi);
+ }
}
void Object::_validate_property(PropertyInfo &property) const {
@@ -845,7 +865,9 @@ String Object::to_string() {
}
}
if (_extension && _extension->to_string) {
- return _extension->to_string(_extension_instance);
+ String ret;
+ _extension->to_string(_extension_instance, &ret);
+ return ret;
}
return "[" + get_class() + ":" + itos(get_instance_id()) + "]";
}
@@ -915,20 +937,38 @@ bool Object::has_meta(const StringName &p_name) const {
void Object::set_meta(const StringName &p_name, const Variant &p_value) {
if (p_value.get_type() == Variant::NIL) {
- metadata.erase(p_name);
+ if (metadata.has(p_name)) {
+ metadata.erase(p_name);
+ metadata_properties.erase("metadata/" + p_name.operator String());
+ notify_property_list_changed();
+ }
return;
}
- metadata[p_name] = p_value;
+ OrderedHashMap<StringName, Variant>::Element E = metadata.find(p_name);
+ if (E) {
+ E.value() = p_value;
+ } else {
+ ERR_FAIL_COND(!p_name.operator String().is_valid_identifier());
+ E = metadata.insert(p_name, p_value);
+ metadata_properties["metadata/" + p_name.operator String()] = E;
+ notify_property_list_changed();
+ }
}
-Variant Object::get_meta(const StringName &p_name) const {
- ERR_FAIL_COND_V_MSG(!metadata.has(p_name), Variant(), "The object does not have any 'meta' values with the key '" + p_name + "'.");
+Variant Object::get_meta(const StringName &p_name, const Variant &p_default) const {
+ if (!metadata.has(p_name)) {
+ if (p_default != Variant()) {
+ return p_default;
+ } else {
+ ERR_FAIL_V_MSG(Variant(), "The object does not have any 'meta' values with the key '" + p_name + "'.");
+ }
+ }
return metadata[p_name];
}
void Object::remove_meta(const StringName &p_name) {
- metadata.erase(p_name);
+ set_meta(p_name, Variant());
}
Array Object::_get_property_list_bind() const {
@@ -954,20 +994,16 @@ Array Object::_get_method_list_bind() const {
Vector<StringName> Object::_get_meta_list_bind() const {
Vector<StringName> _metaret;
- List<Variant> keys;
- metadata.get_key_list(&keys);
- for (const Variant &E : keys) {
- _metaret.push_back(E);
+ for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) {
+ _metaret.push_back(K.key());
}
return _metaret;
}
void Object::get_meta_list(List<StringName> *p_list) const {
- List<Variant> keys;
- metadata.get_key_list(&keys);
- for (const Variant &E : keys) {
- p_list->push_back(E);
+ for (OrderedHashMap<StringName, Variant>::ConstElement K = metadata.front(); K; K = K.next()) {
+ p_list->push_back(K.key());
}
}
@@ -992,15 +1028,15 @@ struct _ObjectSignalDisconnectData {
Callable callable;
};
-Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+Error Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
- ERR_FAIL_COND_V(p_argcount < 1, Variant());
+ ERR_FAIL_COND_V(p_argcount < 1, Error::ERR_INVALID_PARAMETER);
if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING_NAME;
- ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING, Variant());
+ ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING, Error::ERR_INVALID_PARAMETER);
}
r_error.error = Callable::CallError::CALL_OK;
@@ -1014,9 +1050,7 @@ Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::C
args = &p_args[1];
}
- emit_signalp(signal, args, argc);
-
- return Variant();
+ return emit_signalp(signal, args, argc);
}
Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount) {
@@ -1529,7 +1563,7 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_meta", "name", "value"), &Object::set_meta);
ClassDB::bind_method(D_METHOD("remove_meta", "name"), &Object::remove_meta);
- ClassDB::bind_method(D_METHOD("get_meta", "name"), &Object::get_meta);
+ ClassDB::bind_method(D_METHOD("get_meta", "name", "default"), &Object::get_meta, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("has_meta", "name"), &Object::has_meta);
ClassDB::bind_method(D_METHOD("get_meta_list"), &Object::_get_meta_list_bind);
@@ -1814,6 +1848,13 @@ Object::Object() {
_construct_object(false);
}
+void Object::detach_from_objectdb() {
+ if (_instance_id != ObjectID()) {
+ ObjectDB::remove_instance(this);
+ _instance_id = ObjectID();
+ }
+}
+
Object::~Object() {
if (script_instance) {
memdelete(script_instance);
@@ -1853,8 +1894,10 @@ Object::~Object() {
c.signal.get_object()->_disconnect(c.signal.get_name(), c.callable, true);
}
- ObjectDB::remove_instance(this);
- _instance_id = ObjectID();
+ if (_instance_id != ObjectID()) {
+ ObjectDB::remove_instance(this);
+ _instance_id = ObjectID();
+ }
_predelete_ok = 2;
if (_instance_bindings != nullptr) {
diff --git a/core/object/object.h b/core/object/object.h
index 6b4f1c81e6..c3e3c68b59 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -39,6 +39,7 @@
#include "core/templates/hash_map.h"
#include "core/templates/list.h"
#include "core/templates/map.h"
+#include "core/templates/ordered_hash_map.h"
#include "core/templates/safe_refcount.h"
#include "core/templates/set.h"
#include "core/templates/vmap.h"
@@ -343,16 +344,6 @@ public:
m_inherits::get_inheritance_list_static(p_inheritance_list); \
p_inheritance_list->push_back(String(#m_class)); \
} \
- static String get_category_static() { \
- String category = m_inherits::get_category_static(); \
- if (_get_category != m_inherits::_get_category) { \
- if (!category.is_empty()) { \
- category += "/"; \
- } \
- category += _get_category(); \
- } \
- return category; \
- } \
virtual bool is_class(const String &p_class) const override { \
if (_get_extension() && _get_extension()->is_class(p_class)) { \
return true; \
@@ -453,12 +444,6 @@ protected:
\
private:
-#define OBJ_CATEGORY(m_category) \
-protected: \
- _FORCE_INLINE_ static String _get_category() { return m_category; } \
- \
-private:
-
#define OBJ_SAVE_TYPE(m_class) \
public: \
virtual String get_save_class() const override { return #m_class; } \
@@ -530,13 +515,14 @@ private:
#endif
ScriptInstance *script_instance = nullptr;
Variant script; // Reference does not exist yet, store it in a Variant.
- Dictionary metadata;
+ OrderedHashMap<StringName, Variant> metadata;
+ HashMap<StringName, OrderedHashMap<StringName, Variant>::Element> metadata_properties;
mutable StringName _class_name;
mutable const StringName *_class_ptr = nullptr;
void _add_user_signal(const String &p_name, const Array &p_args = Array());
bool _has_user_signal(const StringName &p_name) const;
- Variant _emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
+ Error _emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
Array _get_signal_list() const;
Array _get_signal_connection_list(const String &p_signal) const;
Array _get_incoming_connections() const;
@@ -552,8 +538,8 @@ private:
std::mutex _instance_binding_mutex;
struct InstanceBinding {
- void *binding;
- void *token;
+ void *binding = nullptr;
+ void *token = nullptr;
GDNativeInstanceBindingFreeCallback free_callback = nullptr;
GDNativeInstanceBindingReferenceCallback reference_callback = nullptr;
};
@@ -588,7 +574,6 @@ protected:
virtual void _get_property_listv(List<PropertyInfo> *p_list, bool p_reversed) const {};
virtual void _notificationv(int p_notification, bool p_reversed) {}
- static String _get_category() { return ""; }
static void _bind_methods();
bool _set(const StringName &p_name, const Variant &p_property) { return false; };
bool _get(const StringName &p_name, Variant &r_property) const { return false; };
@@ -648,6 +633,7 @@ public:
bool _is_gpl_reversed() const { return false; }
+ void detach_from_objectdb();
_FORCE_INLINE_ ObjectID get_instance_id() const { return _instance_id; }
template <class T>
@@ -692,7 +678,6 @@ public:
static String get_class_static() { return "Object"; }
static String get_parent_class_static() { return String(); }
- static String get_category_static() { return String(); }
virtual String get_class() const {
if (_extension) {
@@ -761,7 +746,7 @@ public:
bool has_meta(const StringName &p_name) const;
void set_meta(const StringName &p_name, const Variant &p_value);
void remove_meta(const StringName &p_name);
- Variant get_meta(const StringName &p_name) const;
+ Variant get_meta(const StringName &p_name, const Variant &p_default = Variant()) const;
void get_meta_list(List<StringName> *p_list) const;
#ifdef TOOLS_ENABLED
@@ -865,7 +850,7 @@ class ObjectDB {
uint64_t validator : OBJECTDB_VALIDATOR_BITS;
uint64_t next_free : OBJECTDB_SLOT_MAX_COUNT_BITS;
uint64_t is_ref_counted : 1;
- Object *object;
+ Object *object = nullptr;
};
static SpinLock spin_lock;
diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h
index 8eb1c97cce..dcacf19890 100644
--- a/core/object/ref_counted.h
+++ b/core/object/ref_counted.h
@@ -261,7 +261,7 @@ struct PtrToArg<Ref<T>> {
typedef Ref<T> EncodeT;
_FORCE_INLINE_ static void encode(Ref<T> p_val, const void *p_ptr) {
- *(Ref<RefCounted> *)p_ptr = p_val;
+ *(const_cast<Ref<RefCounted> *>(reinterpret_cast<const Ref<RefCounted> *>(p_ptr))) = p_val;
}
};
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index 11440c37fe..a5d25bf533 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -144,7 +144,7 @@ void ScriptServer::register_language(ScriptLanguage *p_language) {
_languages[_language_count++] = p_language;
}
-void ScriptServer::unregister_language(ScriptLanguage *p_language) {
+void ScriptServer::unregister_language(const ScriptLanguage *p_language) {
for (int i = 0; i < _language_count; i++) {
if (_languages[i] == p_language) {
_language_count--;
diff --git a/core/object/script_language.h b/core/object/script_language.h
index 2122f785b6..69002c81f4 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -68,7 +68,7 @@ public:
_FORCE_INLINE_ static int get_language_count() { return _language_count; }
static ScriptLanguage *get_language(int p_idx);
static void register_language(ScriptLanguage *p_language);
- static void unregister_language(ScriptLanguage *p_language);
+ static void unregister_language(const ScriptLanguage *p_language);
static void set_reload_scripts_on_save(bool p_enable);
static bool is_reload_scripts_on_save_enabled();
@@ -132,7 +132,7 @@ public:
virtual Error reload(bool p_keep_state = false) = 0;
#ifdef TOOLS_ENABLED
- virtual const Vector<DocData::ClassDoc> &get_documentation() const = 0;
+ virtual Vector<DocData::ClassDoc> get_documentation() const = 0;
#endif // TOOLS_ENABLED
virtual bool has_method(const StringName &p_method) const = 0;
@@ -212,44 +212,12 @@ public:
virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid);
virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid);
- virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const = 0;
+ virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const { return get_script()->get_rpc_methods(); }
virtual ScriptLanguage *get_language() = 0;
virtual ~ScriptInstance();
};
-struct ScriptCodeCompletionOption {
- /* Keep enum in Sync with: */
- /* /scene/gui/code_edit.h - CodeEdit::CodeCompletionKind */
- enum Kind {
- KIND_CLASS,
- KIND_FUNCTION,
- KIND_SIGNAL,
- KIND_VARIABLE,
- KIND_MEMBER,
- KIND_ENUM,
- KIND_CONSTANT,
- KIND_NODE_PATH,
- KIND_FILE_PATH,
- KIND_PLAIN_TEXT,
- };
- Kind kind = KIND_PLAIN_TEXT;
- String display;
- String insert_text;
- Color font_color;
- RES icon;
- Variant default_value;
- Vector<Pair<int, int>> matches;
-
- ScriptCodeCompletionOption() {}
-
- ScriptCodeCompletionOption(const String &p_text, Kind p_kind) {
- display = p_text;
- insert_text = p_text;
- kind = p_kind;
- }
-};
-
class ScriptCodeCompletionCache {
static ScriptCodeCompletionCache *singleton;
@@ -261,7 +229,8 @@ public:
virtual ~ScriptCodeCompletionCache() {}
};
-class ScriptLanguage {
+class ScriptLanguage : public Object {
+ GDCLASS(ScriptLanguage, Object)
public:
virtual String get_name() const = 0;
@@ -326,19 +295,64 @@ public:
virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; }
virtual bool overrides_external_editor() { return false; }
- virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; }
+ /* Keep enum in Sync with: */
+ /* /scene/gui/code_edit.h - CodeEdit::CodeCompletionKind */
+ enum CodeCompletionKind {
+ CODE_COMPLETION_KIND_CLASS,
+ CODE_COMPLETION_KIND_FUNCTION,
+ CODE_COMPLETION_KIND_SIGNAL,
+ CODE_COMPLETION_KIND_VARIABLE,
+ CODE_COMPLETION_KIND_MEMBER,
+ CODE_COMPLETION_KIND_ENUM,
+ CODE_COMPLETION_KIND_CONSTANT,
+ CODE_COMPLETION_KIND_NODE_PATH,
+ CODE_COMPLETION_KIND_FILE_PATH,
+ CODE_COMPLETION_KIND_PLAIN_TEXT,
+ CODE_COMPLETION_KIND_MAX
+ };
+
+ enum CodeCompletionLocation {
+ LOCATION_LOCAL = 0,
+ LOCATION_PARENT_MASK = 1 << 8,
+ LOCATION_OTHER_USER_CODE = 1 << 9,
+ LOCATION_OTHER = 1 << 10,
+ };
+
+ struct CodeCompletionOption {
+ CodeCompletionKind kind = CODE_COMPLETION_KIND_PLAIN_TEXT;
+ String display;
+ String insert_text;
+ Color font_color;
+ RES icon;
+ Variant default_value;
+ Vector<Pair<int, int>> matches;
+ int location = LOCATION_OTHER;
+
+ CodeCompletionOption() {}
+
+ CodeCompletionOption(const String &p_text, CodeCompletionKind p_kind, int p_location = LOCATION_OTHER) {
+ display = p_text;
+ insert_text = p_text;
+ kind = p_kind;
+ location = p_location;
+ }
+ };
+
+ virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<CodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; }
+
+ enum LookupResultType {
+ LOOKUP_RESULT_SCRIPT_LOCATION,
+ LOOKUP_RESULT_CLASS,
+ LOOKUP_RESULT_CLASS_CONSTANT,
+ LOOKUP_RESULT_CLASS_PROPERTY,
+ LOOKUP_RESULT_CLASS_METHOD,
+ LOOKUP_RESULT_CLASS_ENUM,
+ LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE,
+ LOOKUP_RESULT_MAX
+ };
struct LookupResult {
- enum Type {
- RESULT_SCRIPT_LOCATION,
- RESULT_CLASS,
- RESULT_CLASS_CONSTANT,
- RESULT_CLASS_PROPERTY,
- RESULT_CLASS_METHOD,
- RESULT_CLASS_ENUM,
- RESULT_CLASS_TBD_GLOBALSCOPE
- };
- Type type;
+ LookupResultType type;
Ref<Script> script;
String class_name;
String class_member;
@@ -416,42 +430,42 @@ public:
extern uint8_t script_encryption_key[32];
class PlaceHolderScriptInstance : public ScriptInstance {
- Object *owner;
+ Object *owner = nullptr;
List<PropertyInfo> properties;
Map<StringName, Variant> values;
Map<StringName, Variant> constants;
- ScriptLanguage *language;
+ ScriptLanguage *language = nullptr;
Ref<Script> script;
public:
- virtual bool set(const StringName &p_name, const Variant &p_value);
- virtual bool get(const StringName &p_name, Variant &r_ret) const;
- virtual void get_property_list(List<PropertyInfo> *p_properties) const;
- virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const;
+ virtual bool set(const StringName &p_name, const Variant &p_value) override;
+ virtual bool get(const StringName &p_name, Variant &r_ret) const override;
+ virtual void get_property_list(List<PropertyInfo> *p_properties) const override;
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const override;
- virtual void get_method_list(List<MethodInfo> *p_list) const;
- virtual bool has_method(const StringName &p_method) const;
+ virtual void get_method_list(List<MethodInfo> *p_list) const override;
+ virtual bool has_method(const StringName &p_method) const override;
- virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+ virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
- virtual void notification(int p_notification) {}
+ virtual void notification(int p_notification) override {}
- virtual Ref<Script> get_script() const { return script; }
+ virtual Ref<Script> get_script() const override { return script; }
- virtual ScriptLanguage *get_language() { return language; }
+ virtual ScriptLanguage *get_language() override { return language; }
- Object *get_owner() { return owner; }
+ Object *get_owner() override { return owner; }
void update(const List<PropertyInfo> &p_properties, const Map<StringName, Variant> &p_values); //likely changed in editor
- virtual bool is_placeholder() const { return true; }
+ virtual bool is_placeholder() const override { return true; }
- virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid = nullptr);
- virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid = nullptr);
+ virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid = nullptr) override;
+ virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid = nullptr) override;
- virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const { return Vector<Multiplayer::RPCConfig>(); }
+ virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override { return Vector<Multiplayer::RPCConfig>(); }
PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner);
~PlaceHolderScriptInstance();
diff --git a/core/object/script_language_extension.cpp b/core/object/script_language_extension.cpp
new file mode 100644
index 0000000000..21d7685674
--- /dev/null
+++ b/core/object/script_language_extension.cpp
@@ -0,0 +1,180 @@
+/*************************************************************************/
+/* script_language_extension.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "script_language_extension.h"
+
+void ScriptExtension::_bind_methods() {
+ GDVIRTUAL_BIND(_editor_can_reload_from_file);
+ GDVIRTUAL_BIND(_placeholder_erased, "placeholder");
+
+ GDVIRTUAL_BIND(_can_instantiate);
+ GDVIRTUAL_BIND(_get_base_script);
+ GDVIRTUAL_BIND(_inherits_script, "script");
+
+ GDVIRTUAL_BIND(_get_instance_base_type);
+ GDVIRTUAL_BIND(_instance_create, "for_object");
+ GDVIRTUAL_BIND(_placeholder_instance_create, "for_object");
+
+ GDVIRTUAL_BIND(_instance_has, "object");
+
+ GDVIRTUAL_BIND(_has_source_code);
+ GDVIRTUAL_BIND(_get_source_code);
+
+ GDVIRTUAL_BIND(_set_source_code, "code");
+ GDVIRTUAL_BIND(_reload, "keep_state");
+
+ GDVIRTUAL_BIND(_get_documentation);
+
+ GDVIRTUAL_BIND(_has_method, "method");
+ GDVIRTUAL_BIND(_get_method_info, "method");
+
+ GDVIRTUAL_BIND(_is_tool);
+ GDVIRTUAL_BIND(_is_valid);
+ GDVIRTUAL_BIND(_get_language);
+
+ GDVIRTUAL_BIND(_has_script_signal, "signal");
+ GDVIRTUAL_BIND(_get_script_signal_list);
+
+ GDVIRTUAL_BIND(_get_property_default_value, "property");
+
+ GDVIRTUAL_BIND(_update_exports);
+ GDVIRTUAL_BIND(_get_script_method_list);
+ GDVIRTUAL_BIND(_get_script_property_list);
+
+ GDVIRTUAL_BIND(_get_member_line, "member");
+
+ GDVIRTUAL_BIND(_get_constants);
+ GDVIRTUAL_BIND(_get_members);
+ GDVIRTUAL_BIND(_is_placeholder_fallback_enabled);
+
+ GDVIRTUAL_BIND(_get_rpc_methods);
+}
+
+void ScriptLanguageExtension::_bind_methods() {
+ GDVIRTUAL_BIND(_get_name);
+ GDVIRTUAL_BIND(_init);
+ GDVIRTUAL_BIND(_get_type);
+ GDVIRTUAL_BIND(_get_extension);
+ GDVIRTUAL_BIND(_execute_file, "path");
+ GDVIRTUAL_BIND(_finish);
+
+ GDVIRTUAL_BIND(_get_reserved_words);
+ GDVIRTUAL_BIND(_is_control_flow_keyword, "keyword");
+ GDVIRTUAL_BIND(_get_comment_delimiters);
+ GDVIRTUAL_BIND(_get_string_delimiters);
+ GDVIRTUAL_BIND(_make_template, "template", "class_name", "base_class_name");
+ GDVIRTUAL_BIND(_get_built_in_templates, "object");
+ GDVIRTUAL_BIND(_is_using_templates);
+ GDVIRTUAL_BIND(_validate, "script", "path", "validate_functions", "validate_errors", "validate_warnings", "validate_safe_lines");
+
+ GDVIRTUAL_BIND(_validate_path, "path");
+ GDVIRTUAL_BIND(_create_script);
+ GDVIRTUAL_BIND(_has_named_classes);
+ GDVIRTUAL_BIND(_supports_builtin_mode);
+ GDVIRTUAL_BIND(_supports_documentation);
+ GDVIRTUAL_BIND(_can_inherit_from_file);
+ GDVIRTUAL_BIND(_find_function, "class_name", "function_name");
+ GDVIRTUAL_BIND(_make_function, "class_name", "function_name", "function_args");
+ GDVIRTUAL_BIND(_open_in_external_editor, "script", "line", "column");
+ GDVIRTUAL_BIND(_overrides_external_editor);
+
+ GDVIRTUAL_BIND(_complete_code, "code", "path", "owner");
+ GDVIRTUAL_BIND(_lookup_code, "code", "symbol", "path", "owner");
+ GDVIRTUAL_BIND(_auto_indent_code, "code", "from_line", "to_line");
+
+ GDVIRTUAL_BIND(_add_global_constant, "name", "value");
+ GDVIRTUAL_BIND(_add_named_global_constant, "name", "value");
+ GDVIRTUAL_BIND(_remove_named_global_constant, "name");
+
+ GDVIRTUAL_BIND(_thread_enter);
+ GDVIRTUAL_BIND(_thread_exit);
+ GDVIRTUAL_BIND(_debug_get_error);
+ GDVIRTUAL_BIND(_debug_get_stack_level_count);
+
+ GDVIRTUAL_BIND(_debug_get_stack_level_line, "level");
+ GDVIRTUAL_BIND(_debug_get_stack_level_function, "level");
+ GDVIRTUAL_BIND(_debug_get_stack_level_locals, "level", "max_subitems", "max_depth");
+ GDVIRTUAL_BIND(_debug_get_stack_level_members, "level", "max_subitems", "max_depth");
+ GDVIRTUAL_BIND(_debug_get_stack_level_instance, "level");
+ GDVIRTUAL_BIND(_debug_get_globals, "max_subitems", "max_depth");
+ GDVIRTUAL_BIND(_debug_parse_stack_level_expression, "level", "expression", "max_subitems", "max_depth");
+
+ GDVIRTUAL_BIND(_debug_get_current_stack_info);
+
+ GDVIRTUAL_BIND(_reload_all_scripts);
+ GDVIRTUAL_BIND(_reload_tool_script, "script", "soft_reload");
+
+ GDVIRTUAL_BIND(_get_recognized_extensions);
+ GDVIRTUAL_BIND(_get_public_functions);
+ GDVIRTUAL_BIND(_get_public_constants);
+
+ GDVIRTUAL_BIND(_profiling_start);
+ GDVIRTUAL_BIND(_profiling_stop);
+
+ GDVIRTUAL_BIND(_profiling_get_accumulated_data, "info_array", "info_max");
+ GDVIRTUAL_BIND(_profiling_get_frame_data, "info_array", "info_max");
+
+ GDVIRTUAL_BIND(_alloc_instance_binding_data, "object");
+ GDVIRTUAL_BIND(_free_instance_binding_data, "data");
+
+ GDVIRTUAL_BIND(_refcount_incremented_instance_binding, "object");
+ GDVIRTUAL_BIND(_refcount_decremented_instance_binding, "object");
+
+ GDVIRTUAL_BIND(_frame);
+
+ GDVIRTUAL_BIND(_handles_global_class_type, "type");
+ GDVIRTUAL_BIND(_get_global_class_name, "path");
+
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_SCRIPT_LOCATION);
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS);
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_CONSTANT);
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_PROPERTY);
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_METHOD);
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ENUM);
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE);
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_MAX);
+
+ BIND_ENUM_CONSTANT(LOCATION_LOCAL);
+ BIND_ENUM_CONSTANT(LOCATION_PARENT_MASK);
+ BIND_ENUM_CONSTANT(LOCATION_OTHER_USER_CODE);
+ BIND_ENUM_CONSTANT(LOCATION_OTHER);
+
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_CLASS);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_FUNCTION);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_SIGNAL);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_VARIABLE);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_MEMBER);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_ENUM);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_CONSTANT);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_NODE_PATH);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_FILE_PATH);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_PLAIN_TEXT);
+ BIND_ENUM_CONSTANT(CODE_COMPLETION_KIND_MAX);
+}
diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h
new file mode 100644
index 0000000000..40f18ab30d
--- /dev/null
+++ b/core/object/script_language_extension.h
@@ -0,0 +1,835 @@
+/*************************************************************************/
+/* script_language_extension.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SCRIPT_LANGUAGE_EXTENSION_H
+#define SCRIPT_LANGUAGE_EXTENSION_H
+
+#include "core/extension/ext_wrappers.gen.inc"
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
+#include "core/variant/native_ptr.h"
+#include "core/variant/typed_array.h"
+
+class ScriptExtension : public Script {
+ GDCLASS(ScriptExtension, Script)
+
+protected:
+ EXBIND0R(bool, editor_can_reload_from_file)
+
+ GDVIRTUAL1(_placeholder_erased, GDNativePtr<void>)
+ virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override {
+ GDVIRTUAL_CALL(_placeholder_erased, p_placeholder);
+ }
+
+ static void _bind_methods();
+
+public:
+ EXBIND0RC(bool, can_instantiate)
+ EXBIND0RC(Ref<Script>, get_base_script)
+ EXBIND1RC(bool, inherits_script, const Ref<Script> &)
+ EXBIND0RC(StringName, get_instance_base_type)
+
+ GDVIRTUAL1RC(GDNativePtr<void>, _instance_create, Object *)
+ virtual ScriptInstance *instance_create(Object *p_this) override {
+ GDNativePtr<void> ret = nullptr;
+ GDVIRTUAL_REQUIRED_CALL(_instance_create, p_this, ret);
+ return reinterpret_cast<ScriptInstance *>(ret.operator void *());
+ }
+ GDVIRTUAL1RC(GDNativePtr<void>, _placeholder_instance_create, Object *)
+ PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override {
+ GDNativePtr<void> ret = nullptr;
+ GDVIRTUAL_REQUIRED_CALL(_placeholder_instance_create, p_this, ret);
+ return reinterpret_cast<PlaceHolderScriptInstance *>(ret.operator void *());
+ }
+
+ EXBIND1RC(bool, instance_has, const Object *)
+ EXBIND0RC(bool, has_source_code)
+ EXBIND0RC(String, get_source_code)
+ EXBIND1(set_source_code, const String &)
+ EXBIND1R(Error, reload, bool)
+
+ GDVIRTUAL0RC(TypedArray<Dictionary>, _get_documentation)
+#ifdef TOOLS_ENABLED
+ virtual Vector<DocData::ClassDoc> get_documentation() const override {
+ TypedArray<Dictionary> doc;
+ GDVIRTUAL_REQUIRED_CALL(_get_documentation, doc);
+
+ Vector<DocData::ClassDoc> class_doc;
+#ifndef _MSC_VER
+#warning missing conversion from documentation to ClassDoc
+#endif
+ return class_doc;
+ }
+#endif // TOOLS_ENABLED
+
+ EXBIND1RC(bool, has_method, const StringName &)
+
+ GDVIRTUAL1RC(Dictionary, _get_method_info, const StringName &)
+ virtual MethodInfo get_method_info(const StringName &p_method) const override {
+ Dictionary mi;
+ GDVIRTUAL_REQUIRED_CALL(_get_method_info, p_method, mi);
+ return MethodInfo::from_dict(mi);
+ }
+
+ EXBIND0RC(bool, is_tool)
+ EXBIND0RC(bool, is_valid)
+
+ EXBIND0RC(ScriptLanguage *, get_language)
+ EXBIND1RC(bool, has_script_signal, const StringName &)
+
+ GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_signal_list)
+
+ virtual void get_script_signal_list(List<MethodInfo> *r_signals) const override {
+ TypedArray<Dictionary> sl;
+ GDVIRTUAL_REQUIRED_CALL(_get_script_signal_list, sl);
+ for (int i = 0; i < sl.size(); i++) {
+ r_signals->push_back(MethodInfo::from_dict(sl[i]));
+ }
+ }
+
+ GDVIRTUAL1RC(bool, _has_property_default_value, const StringName &)
+ GDVIRTUAL1RC(Variant, _get_property_default_value, const StringName &)
+
+ virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const override {
+ bool has_dv = false;
+ if (!GDVIRTUAL_REQUIRED_CALL(_has_property_default_value, p_property, has_dv) || !has_dv) {
+ return false;
+ }
+ Variant ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_property_default_value, p_property, ret);
+ return ret;
+ }
+
+ EXBIND0(update_exports)
+
+ GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_method_list)
+
+ virtual void get_script_method_list(List<MethodInfo> *r_methods) const override {
+ TypedArray<Dictionary> sl;
+ GDVIRTUAL_REQUIRED_CALL(_get_script_method_list, sl);
+ for (int i = 0; i < sl.size(); i++) {
+ r_methods->push_back(MethodInfo::from_dict(sl[i]));
+ }
+ }
+
+ GDVIRTUAL0RC(TypedArray<Dictionary>, _get_script_property_list)
+
+ virtual void get_script_property_list(List<PropertyInfo> *r_propertys) const override {
+ TypedArray<Dictionary> sl;
+ GDVIRTUAL_REQUIRED_CALL(_get_script_property_list, sl);
+ for (int i = 0; i < sl.size(); i++) {
+ r_propertys->push_back(PropertyInfo::from_dict(sl[i]));
+ }
+ }
+
+ EXBIND1RC(int, get_member_line, const StringName &)
+
+ GDVIRTUAL0RC(Dictionary, _get_constants)
+
+ virtual void get_constants(Map<StringName, Variant> *p_constants) override {
+ Dictionary constants;
+ GDVIRTUAL_REQUIRED_CALL(_get_constants, constants);
+ List<Variant> keys;
+ constants.get_key_list(&keys);
+ for (const Variant &K : keys) {
+ p_constants->insert(K, constants[K]);
+ }
+ }
+ GDVIRTUAL0RC(TypedArray<StringName>, _get_members)
+ virtual void get_members(Set<StringName> *p_members) override {
+ TypedArray<StringName> members;
+ GDVIRTUAL_REQUIRED_CALL(_get_members, members);
+ for (int i = 0; i < members.size(); i++) {
+ p_members->insert(members[i]);
+ }
+ }
+
+ EXBIND0RC(bool, is_placeholder_fallback_enabled)
+
+ GDVIRTUAL0RC(TypedArray<Dictionary>, _get_rpc_methods)
+
+ virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override {
+ TypedArray<Dictionary> ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_rpc_methods, ret);
+ Vector<Multiplayer::RPCConfig> rpcret;
+ for (int i = 0; i < ret.size(); i++) {
+ Dictionary d = ret[i];
+ Multiplayer::RPCConfig rpc;
+ ERR_CONTINUE(!d.has("name"));
+ rpc.name = d["name"];
+ ERR_CONTINUE(!d.has("rpc_mode"));
+ rpc.rpc_mode = Multiplayer::RPCMode(int(d["rpc_mode"]));
+ ERR_CONTINUE(!d.has("call_local"));
+ rpc.call_local = d["call_local"];
+ ERR_CONTINUE(!d.has("transfer_mode"));
+ rpc.transfer_mode = Multiplayer::TransferMode(int(d["transfer_mode"]));
+ ERR_CONTINUE(!d.has("channel"));
+ rpc.channel = d["channel"];
+ rpcret.push_back(rpc);
+ }
+ return rpcret;
+ }
+
+ ScriptExtension() {}
+};
+
+typedef ScriptLanguage::ProfilingInfo ScriptLanguageExtensionProfilingInfo;
+
+GDVIRTUAL_NATIVE_PTR(ScriptLanguageExtensionProfilingInfo)
+
+class ScriptLanguageExtension : public ScriptLanguage {
+ GDCLASS(ScriptLanguageExtension, ScriptLanguage)
+protected:
+ static void _bind_methods();
+
+public:
+ EXBIND0RC(String, get_name)
+
+ EXBIND0(init)
+ EXBIND0RC(String, get_type)
+ EXBIND0RC(String, get_extension)
+ EXBIND1R(Error, execute_file, const String &)
+ EXBIND0(finish)
+
+ /* EDITOR FUNCTIONS */
+
+ GDVIRTUAL0RC(Vector<String>, _get_reserved_words)
+
+ virtual void get_reserved_words(List<String> *p_words) const override {
+ Vector<String> ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_reserved_words, ret);
+ for (int i = 0; i < ret.size(); i++) {
+ p_words->push_back(ret[i]);
+ }
+ }
+ EXBIND1RC(bool, is_control_flow_keyword, String)
+
+ GDVIRTUAL0RC(Vector<String>, _get_comment_delimiters)
+
+ virtual void get_comment_delimiters(List<String> *p_words) const override {
+ Vector<String> ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_comment_delimiters, ret);
+ for (int i = 0; i < ret.size(); i++) {
+ p_words->push_back(ret[i]);
+ }
+ }
+
+ GDVIRTUAL0RC(Vector<String>, _get_string_delimiters)
+
+ virtual void get_string_delimiters(List<String> *p_words) const override {
+ Vector<String> ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_string_delimiters, ret);
+ for (int i = 0; i < ret.size(); i++) {
+ p_words->push_back(ret[i]);
+ }
+ }
+
+ EXBIND3RC(Ref<Script>, make_template, const String &, const String &, const String &)
+
+ GDVIRTUAL1RC(TypedArray<Dictionary>, _get_built_in_templates, StringName)
+
+ virtual Vector<ScriptTemplate> get_built_in_templates(StringName p_object) override {
+ TypedArray<Dictionary> ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_built_in_templates, p_object, ret);
+ Vector<ScriptTemplate> stret;
+ for (int i = 0; i < ret.size(); i++) {
+ Dictionary d = ret[i];
+ ScriptTemplate st;
+ ERR_CONTINUE(!d.has("inherit"));
+ st.inherit = d["inherit"];
+ ERR_CONTINUE(!d.has("name"));
+ st.name = d["name"];
+ ERR_CONTINUE(!d.has("description"));
+ st.description = d["description"];
+ ERR_CONTINUE(!d.has("content"));
+ st.content = d["content"];
+ ERR_CONTINUE(!d.has("id"));
+ st.id = d["id"];
+ ERR_CONTINUE(!d.has("origin"));
+ st.origin = TemplateLocation(int(d["origin"]));
+ stret.push_back(st);
+ }
+ return stret;
+ }
+
+ EXBIND0R(bool, is_using_templates)
+
+ GDVIRTUAL6RC(Dictionary, _validate, const String &, const String &, bool, bool, bool, bool)
+ virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptError> *r_errors = nullptr, List<Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override {
+ Dictionary ret;
+ GDVIRTUAL_REQUIRED_CALL(_validate, p_script, p_path, r_functions != nullptr, r_errors != nullptr, r_warnings != nullptr, r_safe_lines != nullptr, ret);
+ if (!ret.has("valid")) {
+ return false;
+ }
+ if (r_functions != nullptr && ret.has("functions")) {
+ Vector<String> functions = ret["functions"];
+ for (int i = 0; i < functions.size(); i++) {
+ r_functions->push_back(functions[i]);
+ }
+ }
+ if (r_errors != nullptr && ret.has("errors")) {
+ Array errors = ret["errors"];
+ for (int i = 0; i < errors.size(); i++) {
+ Dictionary err = errors[i];
+ ERR_CONTINUE(!err.has("line"));
+ ERR_CONTINUE(!err.has("column"));
+ ERR_CONTINUE(!err.has("message"));
+
+ ScriptError serr;
+ serr.line = err["line"];
+ serr.column = err["column"];
+ serr.message = err["message"];
+
+ r_errors->push_back(serr);
+ }
+ }
+ if (r_warnings != nullptr && ret.has("warnings")) {
+ ERR_FAIL_COND_V(!ret.has("warnings"), false);
+ Array warnings = ret["warnings"];
+ for (int i = 0; i < warnings.size(); i++) {
+ Dictionary warn = warnings[i];
+ ERR_CONTINUE(!warn.has("start_line"));
+ ERR_CONTINUE(!warn.has("end_line"));
+ ERR_CONTINUE(!warn.has("leftmost_column"));
+ ERR_CONTINUE(!warn.has("rightmost_column"));
+ ERR_CONTINUE(!warn.has("code"));
+ ERR_CONTINUE(!warn.has("string_code"));
+ ERR_CONTINUE(!warn.has("message"));
+
+ Warning swarn;
+ swarn.start_line = warn["start_line"];
+ swarn.end_line = warn["end_line"];
+ swarn.leftmost_column = warn["leftmost_column"];
+ swarn.rightmost_column = warn["rightmost_column"];
+ swarn.code = warn["code"];
+ swarn.string_code = warn["string_code"];
+ swarn.message = warn["message"];
+
+ r_warnings->push_back(swarn);
+ }
+ }
+ if (r_safe_lines != nullptr && ret.has("safe_lines")) {
+ PackedInt32Array safe_lines = ret["safe_lines"];
+ for (int i = 0; i < safe_lines.size(); i++) {
+ r_safe_lines->insert(safe_lines[i]);
+ }
+ }
+ return ret["valid"];
+ }
+
+ EXBIND1RC(String, validate_path, const String &)
+ GDVIRTUAL0RC(Object *, _create_script)
+ Script *create_script() const override {
+ Object *ret = nullptr;
+ GDVIRTUAL_REQUIRED_CALL(_create_script, ret);
+ return Object::cast_to<Script>(ret);
+ }
+ EXBIND0RC(bool, has_named_classes)
+ EXBIND0RC(bool, supports_builtin_mode)
+ EXBIND0RC(bool, supports_documentation)
+ EXBIND0RC(bool, can_inherit_from_file)
+
+ EXBIND2RC(int, find_function, const String &, const String &)
+ EXBIND3RC(String, make_function, const String &, const String &, const PackedStringArray &)
+ EXBIND3R(Error, open_in_external_editor, const Ref<Script> &, int, int)
+ EXBIND0R(bool, overrides_external_editor)
+
+ GDVIRTUAL3RC(Dictionary, _complete_code, const String &, const String &, Object *)
+
+ virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<CodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) override {
+ Dictionary ret;
+ GDVIRTUAL_REQUIRED_CALL(_complete_code, p_code, p_path, p_owner, ret);
+ if (!ret.has("result")) {
+ return ERR_UNAVAILABLE;
+ }
+
+ if (r_options != nullptr && ret.has("options")) {
+ Array options = ret["options"];
+ for (int i = 0; i < options.size(); i++) {
+ Dictionary op = options[i];
+ CodeCompletionOption option;
+ ERR_CONTINUE(!op.has("kind"));
+ option.kind = CodeCompletionKind(int(op["kind"]));
+ ERR_CONTINUE(!op.has("display"));
+ option.display = op["display"];
+ ERR_CONTINUE(!op.has("insert_text"));
+ option.insert_text = op["insert_text"];
+ ERR_CONTINUE(!op.has("font_color"));
+ option.font_color = op["font_color"];
+ ERR_CONTINUE(!op.has("icon"));
+ option.icon = op["icon"];
+ ERR_CONTINUE(!op.has("default_value"));
+ option.default_value = op["default_value"];
+ ERR_CONTINUE(!op.has("location"));
+ option.location = op["location"];
+ if (op.has("matches")) {
+ PackedInt32Array matches = op["matches"];
+ ERR_CONTINUE(matches.size() & 1);
+ for (int j = 0; j < matches.size(); j += 2) {
+ option.matches.push_back(Pair<int, int>(matches[j], matches[j + 1]));
+ }
+ }
+ r_options->push_back(option);
+ }
+ }
+
+ ERR_FAIL_COND_V(!ret.has("force"), ERR_UNAVAILABLE);
+ r_force = ret["force"];
+ ERR_FAIL_COND_V(!ret.has("call_hint"), ERR_UNAVAILABLE);
+ r_call_hint = ret["call_hint"];
+ ERR_FAIL_COND_V(!ret.has("result"), ERR_UNAVAILABLE);
+ Error result = Error(int(ret["result"]));
+
+ return result;
+ }
+
+ GDVIRTUAL4RC(Dictionary, _lookup_code, const String &, const String &, const String &, Object *)
+
+ virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) override {
+ Dictionary ret;
+ GDVIRTUAL_REQUIRED_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret);
+ if (!ret.has("result")) {
+ return ERR_UNAVAILABLE;
+ }
+
+ ERR_FAIL_COND_V(!ret.has("type"), ERR_UNAVAILABLE);
+ r_result.type = LookupResultType(int(ret["type"]));
+ ERR_FAIL_COND_V(!ret.has("script"), ERR_UNAVAILABLE);
+ r_result.script = ret["script"];
+ ERR_FAIL_COND_V(!ret.has("class_name"), ERR_UNAVAILABLE);
+ r_result.class_name = ret["class_name"];
+ ERR_FAIL_COND_V(!ret.has("class_path"), ERR_UNAVAILABLE);
+ r_result.class_path = ret["class_path"];
+ ERR_FAIL_COND_V(!ret.has("location"), ERR_UNAVAILABLE);
+ r_result.location = ret["location"];
+
+ Error result = Error(int(ret["result"]));
+
+ return result;
+ }
+
+ GDVIRTUAL3RC(String, _auto_indent_code, const String &, int, int)
+ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override {
+ String ret;
+ GDVIRTUAL_REQUIRED_CALL(_auto_indent_code, p_code, p_from_line, p_to_line, ret);
+ p_code = ret;
+ }
+ EXBIND2(add_global_constant, const StringName &, const Variant &)
+ EXBIND2(add_named_global_constant, const StringName &, const Variant &)
+ EXBIND1(remove_named_global_constant, const StringName &)
+
+ /* MULTITHREAD FUNCTIONS */
+
+ //some VMs need to be notified of thread creation/exiting to allocate a stack
+ EXBIND0(thread_enter)
+ EXBIND0(thread_exit)
+
+ EXBIND0RC(String, debug_get_error)
+ EXBIND0RC(int, debug_get_stack_level_count)
+ EXBIND1RC(int, debug_get_stack_level_line, int)
+ EXBIND1RC(String, debug_get_stack_level_function, int)
+ EXBIND1RC(String, debug_get_stack_level_source, int)
+
+ GDVIRTUAL3R(Dictionary, _debug_get_stack_level_locals, int, int, int)
+ virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
+ Dictionary ret;
+ GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_locals, p_level, p_max_subitems, p_max_depth, ret);
+ if (ret.size() == 0) {
+ return;
+ }
+ if (p_locals != nullptr && ret.has("locals")) {
+ PackedStringArray strings = ret["locals"];
+ for (int i = 0; i < strings.size(); i++) {
+ p_locals->push_back(strings[i]);
+ }
+ }
+ if (p_values != nullptr && ret.has("values")) {
+ Array values = ret["values"];
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+ }
+ GDVIRTUAL3R(Dictionary, _debug_get_stack_level_members, int, int, int)
+ virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
+ Dictionary ret;
+ GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_members, p_level, p_max_subitems, p_max_depth, ret);
+ if (ret.size() == 0) {
+ return;
+ }
+ if (p_members != nullptr && ret.has("members")) {
+ PackedStringArray strings = ret["members"];
+ for (int i = 0; i < strings.size(); i++) {
+ p_members->push_back(strings[i]);
+ }
+ }
+ if (p_values != nullptr && ret.has("values")) {
+ Array values = ret["values"];
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+ }
+ GDVIRTUAL1R(GDNativePtr<void>, _debug_get_stack_level_instance, int)
+
+ virtual ScriptInstance *debug_get_stack_level_instance(int p_level) override {
+ GDNativePtr<void> ret = nullptr;
+ GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_instance, p_level, ret);
+ return reinterpret_cast<ScriptInstance *>(ret.operator void *());
+ }
+ GDVIRTUAL2R(Dictionary, _debug_get_globals, int, int)
+ virtual void debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override {
+ Dictionary ret;
+ GDVIRTUAL_REQUIRED_CALL(_debug_get_globals, p_max_subitems, p_max_depth, ret);
+ if (ret.size() == 0) {
+ return;
+ }
+ if (p_globals != nullptr && ret.has("globals")) {
+ PackedStringArray strings = ret["globals"];
+ for (int i = 0; i < strings.size(); i++) {
+ p_globals->push_back(strings[i]);
+ }
+ }
+ if (p_values != nullptr && ret.has("values")) {
+ Array values = ret["values"];
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+ }
+
+ EXBIND4R(String, debug_parse_stack_level_expression, int, const String &, int, int)
+
+ GDVIRTUAL0R(TypedArray<Dictionary>, _debug_get_current_stack_info)
+ virtual Vector<StackInfo> debug_get_current_stack_info() override {
+ TypedArray<Dictionary> ret;
+ GDVIRTUAL_REQUIRED_CALL(_debug_get_current_stack_info, ret);
+ Vector<StackInfo> sret;
+ for (int i = 0; i < ret.size(); i++) {
+ StackInfo si;
+ Dictionary d = ret[i];
+ ERR_CONTINUE(!d.has("file"));
+ ERR_CONTINUE(!d.has("func"));
+ ERR_CONTINUE(!d.has("line"));
+ si.file = d["file"];
+ si.func = d["func"];
+ si.line = d["line"];
+ sret.push_back(si);
+ }
+ return sret;
+ }
+
+ EXBIND0(reload_all_scripts)
+ EXBIND2(reload_tool_script, const Ref<Script> &, bool)
+ /* LOADER FUNCTIONS */
+
+ GDVIRTUAL0RC(PackedStringArray, _get_recognized_extensions)
+
+ virtual void get_recognized_extensions(List<String> *p_extensions) const override {
+ PackedStringArray ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_recognized_extensions, ret);
+ for (int i = 0; i < ret.size(); i++) {
+ p_extensions->push_back(ret[i]);
+ }
+ }
+
+ GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_functions)
+ virtual void get_public_functions(List<MethodInfo> *p_functions) const override {
+ TypedArray<Dictionary> ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_public_functions, ret);
+ for (int i = 0; i < ret.size(); i++) {
+ MethodInfo mi = MethodInfo::from_dict(ret[i]);
+ p_functions->push_back(mi);
+ }
+ }
+ GDVIRTUAL0RC(Dictionary, _get_public_constants)
+ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override {
+ Dictionary ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_public_constants, ret);
+ for (int i = 0; i < ret.size(); i++) {
+ Dictionary d = ret[i];
+ ERR_CONTINUE(!d.has("name"));
+ ERR_CONTINUE(!d.has("value"));
+ p_constants->push_back(Pair<String, Variant>(d["name"], d["value"]));
+ }
+ }
+
+ EXBIND0(profiling_start)
+ EXBIND0(profiling_stop)
+
+ GDVIRTUAL2R(int, _profiling_get_accumulated_data, GDNativePtr<ScriptLanguageExtensionProfilingInfo>, int)
+
+ virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override {
+ int ret = 0;
+ GDVIRTUAL_REQUIRED_CALL(_profiling_get_accumulated_data, p_info_arr, p_info_max, ret);
+ return ret;
+ }
+
+ GDVIRTUAL2R(int, _profiling_get_frame_data, GDNativePtr<ScriptLanguageExtensionProfilingInfo>, int)
+
+ virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override {
+ int ret = 0;
+ GDVIRTUAL_REQUIRED_CALL(_profiling_get_accumulated_data, p_info_arr, p_info_max, ret);
+ return ret;
+ }
+
+ GDVIRTUAL1R(GDNativePtr<void>, _alloc_instance_binding_data, Object *)
+
+ virtual void *alloc_instance_binding_data(Object *p_object) override {
+ GDNativePtr<void> ret = nullptr;
+ GDVIRTUAL_REQUIRED_CALL(_alloc_instance_binding_data, p_object, ret);
+ return ret.operator void *();
+ }
+
+ GDVIRTUAL1(_free_instance_binding_data, GDNativePtr<void>)
+
+ virtual void free_instance_binding_data(void *p_data) override {
+ GDVIRTUAL_REQUIRED_CALL(_free_instance_binding_data, p_data);
+ }
+
+ EXBIND1(refcount_incremented_instance_binding, Object *)
+ EXBIND1R(bool, refcount_decremented_instance_binding, Object *)
+
+ EXBIND0(frame)
+
+ EXBIND1RC(bool, handles_global_class_type, const String &)
+
+ GDVIRTUAL1RC(Dictionary, _get_global_class_name, const String &)
+
+ virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const override {
+ Dictionary ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_global_class_name, p_path, ret);
+ if (!ret.has("name")) {
+ return String();
+ }
+ if (r_base_type != nullptr && ret.has("base_type")) {
+ *r_base_type = ret["base_type"];
+ }
+ if (r_icon_path != nullptr && ret.has("icon_path")) {
+ *r_icon_path = ret["icon_path"];
+ }
+ return ret["name"];
+ }
+};
+
+VARIANT_ENUM_CAST(ScriptLanguageExtension::LookupResultType)
+VARIANT_ENUM_CAST(ScriptLanguageExtension::CodeCompletionKind)
+VARIANT_ENUM_CAST(ScriptLanguageExtension::CodeCompletionLocation)
+
+class ScriptInstanceExtension : public ScriptInstance {
+public:
+ const GDNativeExtensionScriptInstanceInfo *native_info;
+ GDNativeExtensionScriptInstanceDataPtr instance = nullptr;
+
+// There should not be warnings on explicit casts.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#endif
+
+ virtual bool set(const StringName &p_name, const Variant &p_value) override {
+ if (native_info->set_func) {
+ return native_info->set_func(instance, (const GDNativeStringNamePtr)&p_name, (const GDNativeVariantPtr)&p_value);
+ }
+ return false;
+ }
+ virtual bool get(const StringName &p_name, Variant &r_ret) const override {
+ if (native_info->get_func) {
+ return native_info->get_func(instance, (const GDNativeStringNamePtr)&p_name, (GDNativeVariantPtr)&r_ret);
+ }
+ return false;
+ }
+ virtual void get_property_list(List<PropertyInfo> *p_list) const override {
+ if (native_info->get_property_list_func) {
+ uint32_t pcount;
+ const GDNativePropertyInfo *pinfo = native_info->get_property_list_func(instance, &pcount);
+ for (uint32_t i = 0; i < pcount; i++) {
+ p_list->push_back(PropertyInfo(Variant::Type(pinfo[i].type), pinfo[i].class_name, PropertyHint(pinfo[i].hint), pinfo[i].hint_string, pinfo[i].usage, pinfo[i].class_name));
+ }
+ if (native_info->free_property_list_func) {
+ native_info->free_property_list_func(instance, pinfo);
+ }
+ }
+ }
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const override {
+ if (native_info->get_property_type_func) {
+ GDNativeBool is_valid = 0;
+ GDNativeVariantType type = native_info->get_property_type_func(instance, (const GDNativeStringNamePtr)&p_name, &is_valid);
+ if (r_is_valid) {
+ *r_is_valid = is_valid != 0;
+ }
+
+ return Variant::Type(type);
+ }
+ return Variant::NIL;
+ }
+
+ virtual Object *get_owner() override {
+ if (native_info->get_owner_func) {
+ return (Object *)native_info->get_owner_func(instance);
+ }
+ return nullptr;
+ }
+ static void _add_property_with_state(const GDNativeStringNamePtr p_name, const GDNativeVariantPtr p_value, void *p_userdata) {
+ List<Pair<StringName, Variant>> *state = (List<Pair<StringName, Variant>> *)p_userdata;
+ state->push_back(Pair<StringName, Variant>(*(const StringName *)p_name, *(const Variant *)p_value));
+ }
+ virtual void get_property_state(List<Pair<StringName, Variant>> &state) override {
+ if (native_info->get_property_state_func) {
+ native_info->get_property_state_func(instance, _add_property_with_state, &state);
+ }
+ }
+
+ virtual void get_method_list(List<MethodInfo> *p_list) const override {
+ if (native_info->get_method_list_func) {
+ uint32_t mcount;
+ const GDNativeMethodInfo *minfo = native_info->get_method_list_func(instance, &mcount);
+ for (uint32_t i = 0; i < mcount; i++) {
+ MethodInfo m;
+ m.name = minfo[i].name;
+ m.flags = minfo[i].flags;
+ m.id = minfo[i].id;
+ m.return_val = PropertyInfo(Variant::Type(minfo[i].return_value.type), minfo[i].return_value.class_name, PropertyHint(minfo[i].return_value.hint), minfo[i].return_value.hint_string, minfo[i].return_value.usage, minfo[i].return_value.class_name);
+ for (uint32_t j = 0; j < minfo[i].argument_count; j++) {
+ m.arguments.push_back(PropertyInfo(Variant::Type(minfo[i].arguments[j].type), minfo[i].arguments[j].class_name, PropertyHint(minfo[i].arguments[j].hint), minfo[i].arguments[j].hint_string, minfo[i].arguments[j].usage, minfo[i].arguments[j].class_name));
+ }
+ const Variant *def_values = (const Variant *)minfo[i].default_arguments;
+ for (uint32_t j = 0; j < minfo[i].default_argument_count; j++) {
+ m.default_arguments.push_back(def_values[j]);
+ }
+ p_list->push_back(m);
+ }
+ if (native_info->free_method_list_func) {
+ native_info->free_method_list_func(instance, minfo);
+ }
+ }
+ }
+ virtual bool has_method(const StringName &p_method) const override {
+ if (native_info->has_method_func) {
+ return native_info->has_method_func(instance, (GDNativeStringNamePtr)&p_method);
+ }
+ return false;
+ }
+
+ virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
+ Variant ret;
+ if (native_info->call_func) {
+ GDNativeCallError ce;
+ native_info->call_func(instance, (const GDNativeStringNamePtr)&p_method, (const GDNativeVariantPtr *)p_args, p_argcount, (GDNativeVariantPtr)&ret, &ce);
+ r_error.error = Callable::CallError::Error(ce.error);
+ r_error.argument = ce.argument;
+ r_error.expected = ce.expected;
+ }
+ return ret;
+ }
+
+ virtual void notification(int p_notification) override {
+ if (native_info->notification_func) {
+ native_info->notification_func(instance, p_notification);
+ }
+ }
+ virtual String to_string(bool *r_valid) override {
+ if (native_info->to_string_func) {
+ GDNativeBool valid;
+ String ret = native_info->to_string_func(instance, &valid);
+ if (r_valid) {
+ *r_valid = valid != 0;
+ }
+ return ret;
+ }
+ return String();
+ }
+
+ virtual void refcount_incremented() override {
+ if (native_info->refcount_incremented_func) {
+ native_info->refcount_incremented_func(instance);
+ }
+ }
+ virtual bool refcount_decremented() override {
+ if (native_info->refcount_decremented_func) {
+ return native_info->refcount_decremented_func(instance);
+ }
+ return false;
+ }
+
+ virtual Ref<Script> get_script() const override {
+ if (native_info->get_script_func) {
+ GDNativeObjectPtr script = native_info->get_script_func(instance);
+ return Ref<Script>(reinterpret_cast<Script *>(script));
+ }
+ return Ref<Script>();
+ }
+
+ virtual bool is_placeholder() const override {
+ if (native_info->is_placeholder_func) {
+ return native_info->is_placeholder_func(instance);
+ }
+ return false;
+ }
+
+ virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid) override {
+ if (native_info->set_fallback_func) {
+ bool ret = native_info->set_fallback_func(instance, (const GDNativeStringNamePtr)&p_name, (const GDNativeVariantPtr)&p_value);
+ if (r_valid) {
+ *r_valid = ret;
+ }
+ }
+ }
+ virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid) override {
+ Variant ret;
+ if (native_info->get_fallback_func) {
+ bool valid = native_info->get_fallback_func(instance, (const GDNativeStringNamePtr)&p_name, (GDNativeVariantPtr)&ret);
+ if (r_valid) {
+ *r_valid = valid;
+ }
+ }
+ return ret;
+ }
+
+ virtual ScriptLanguage *get_language() override {
+ if (native_info->get_language_func) {
+ GDNativeExtensionScriptLanguagePtr lang = native_info->get_language_func(instance);
+ return reinterpret_cast<ScriptLanguage *>(lang);
+ }
+ return nullptr;
+ ;
+ }
+ virtual ~ScriptInstanceExtension() {
+ if (native_info->free_func) {
+ native_info->free_func(instance);
+ }
+ }
+
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+};
+
+#endif // SCRIPT_LANGUAGE_EXTENSION_H
diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp
index ee8eb97a93..d3c48853f1 100644
--- a/core/object/undo_redo.cpp
+++ b/core/object/undo_redo.cpp
@@ -444,25 +444,25 @@ UndoRedo::~UndoRedo() {
clear_history();
}
-Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+void UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
- return Variant();
+ return;
}
if (p_args[0]->get_type() != Variant::OBJECT) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
- return Variant();
+ return;
}
if (p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING_NAME;
- return Variant();
+ return;
}
r_error.error = Callable::CallError::CALL_OK;
@@ -471,28 +471,27 @@ Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callabl
StringName method = *p_args[1];
add_do_methodp(object, method, p_args + 2, p_argcount - 2);
- return Variant();
}
-Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+void UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
- return Variant();
+ return;
}
if (p_args[0]->get_type() != Variant::OBJECT) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
- return Variant();
+ return;
}
if (p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING_NAME;
- return Variant();
+ return;
}
r_error.error = Callable::CallError::CALL_OK;
@@ -501,7 +500,6 @@ Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Calla
StringName method = *p_args[1];
add_undo_methodp(object, method, p_args + 2, p_argcount - 2);
- return Variant();
}
void UndoRedo::_bind_methods() {
diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h
index ecd7a21167..63cf3e5cbe 100644
--- a/core/object/undo_redo.h
+++ b/core/object/undo_redo.h
@@ -46,8 +46,8 @@ public:
};
typedef void (*CommitNotifyCallback)(void *p_ud, const String &p_name);
- Variant _add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
- Variant _add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
+ void _add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
+ void _add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
typedef void (*MethodNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount);
typedef void (*PropertyNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value);