summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/object/class_db.cpp40
-rw-r--r--core/object/class_db.h44
-rw-r--r--core/string/string_name.cpp72
-rw-r--r--core/string/string_name.h20
-rw-r--r--doc/classes/Camera2D.xml16
-rw-r--r--doc/classes/Camera3D.xml4
-rw-r--r--doc/classes/Viewport.xml11
-rw-r--r--editor/action_map_editor.cpp2
-rw-r--r--editor/debugger/script_editor_debugger.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.h2
-rw-r--r--editor/property_selector.cpp3
-rw-r--r--main/main.cpp4
-rw-r--r--modules/visual_script/visual_script_editor.cpp3
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp12
-rw-r--r--scene/2d/camera_2d.cpp42
-rw-r--r--scene/2d/camera_2d.h2
-rw-r--r--scene/3d/camera_3d.cpp20
-rw-r--r--scene/3d/cpu_particles_3d.cpp2
-rw-r--r--scene/3d/gpu_particles_collision_3d.cpp2
-rw-r--r--scene/gui/container.cpp6
-rw-r--r--scene/gui/control.cpp12
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/main/canvas_item.cpp8
-rw-r--r--scene/main/canvas_item.h2
-rw-r--r--scene/main/scene_tree.cpp12
-rw-r--r--scene/main/viewport.cpp96
-rw-r--r--scene/main/viewport.h19
-rw-r--r--scene/main/window.cpp4
29 files changed, 300 insertions, 166 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index a10405dfae..e2db5918e3 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -602,7 +602,7 @@ static MethodInfo info_from_bind(MethodBind *p_method) {
}
#endif
-void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) {
+void ClassDB::get_method_list(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -655,7 +655,7 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
}
}
-bool ClassDB::get_method_info(StringName p_class, StringName p_method, MethodInfo *r_info, bool p_no_inheritance, bool p_exclude_from_properties) {
+bool ClassDB::get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance, bool p_exclude_from_properties) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -706,7 +706,7 @@ bool ClassDB::get_method_info(StringName p_class, StringName p_method, MethodInf
return false;
}
-MethodBind *ClassDB::get_method(StringName p_class, StringName p_name) {
+MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_name) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -910,7 +910,7 @@ bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool
return false;
}
-void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
+void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -929,7 +929,7 @@ void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
type->signal_map[sname] = p_signal;
}
-void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance) {
+void ClassDB::get_signal_list(const StringName &p_class, List<MethodInfo> *p_signals, bool p_no_inheritance) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -951,7 +951,7 @@ void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, b
}
}
-bool ClassDB::has_signal(StringName p_class, StringName p_signal, bool p_no_inheritance) {
+bool ClassDB::has_signal(const StringName &p_class, const StringName &p_signal, bool p_no_inheritance) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
@@ -968,7 +968,7 @@ bool ClassDB::has_signal(StringName p_class, StringName p_signal, bool p_no_inhe
return false;
}
-bool ClassDB::get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal) {
+bool ClassDB::get_signal(const StringName &p_class, const StringName &p_signal, MethodInfo *r_signal) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
@@ -985,7 +985,7 @@ bool ClassDB::get_signal(StringName p_class, StringName p_signal, MethodInfo *r_
return false;
}
-void ClassDB::add_property_group(StringName p_class, const String &p_name, const String &p_prefix) {
+void ClassDB::add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix) {
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_COND(!type);
@@ -993,7 +993,7 @@ void ClassDB::add_property_group(StringName p_class, const String &p_name, const
type->property_list.push_back(PropertyInfo(Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_GROUP));
}
-void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix) {
+void ClassDB::add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix) {
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_COND(!type);
@@ -1002,7 +1002,7 @@ void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, co
}
// NOTE: For implementation simplicity reasons, this method doesn't allow setters to have optional arguments at the end.
-void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
+void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
lock.read_lock();
ClassInfo *type = classes.getptr(p_class);
lock.read_unlock();
@@ -1060,14 +1060,14 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
type->property_setget[p_pinfo.name] = psg;
}
-void ClassDB::set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default) {
+void ClassDB::set_property_default_value(const StringName &p_class, const StringName &p_name, const Variant &p_default) {
if (!default_values.has(p_class)) {
default_values[p_class] = HashMap<StringName, Variant>();
}
default_values[p_class][p_name] = p_default;
}
-void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) {
+void ClassDB::get_property_list(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -1090,7 +1090,7 @@ void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list,
}
}
-bool ClassDB::get_property_info(StringName p_class, StringName p_property, PropertyInfo *r_info, bool p_no_inheritance, const Object *p_validator) {
+bool ClassDB::get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, bool p_no_inheritance, const Object *p_validator) {
OBJTYPE_RLOCK;
ClassInfo *check = classes.getptr(p_class);
@@ -1258,7 +1258,7 @@ Variant::Type ClassDB::get_property_type(const StringName &p_class, const String
return Variant::NIL;
}
-StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_property) {
+StringName ClassDB::get_property_setter(const StringName &p_class, const StringName &p_property) {
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
@@ -1273,7 +1273,7 @@ StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_
return StringName();
}
-StringName ClassDB::get_property_getter(StringName p_class, const StringName &p_property) {
+StringName ClassDB::get_property_getter(const StringName &p_class, const StringName &p_property) {
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
@@ -1305,7 +1305,7 @@ bool ClassDB::has_property(const StringName &p_class, const StringName &p_proper
return false;
}
-void ClassDB::set_method_flags(StringName p_class, StringName p_method, int p_flags) {
+void ClassDB::set_method_flags(const StringName &p_class, const StringName &p_method, int p_flags) {
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
@@ -1314,7 +1314,7 @@ void ClassDB::set_method_flags(StringName p_class, StringName p_method, int p_fl
check->method_map[p_method]->set_hint_flags(p_flags);
}
-bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inheritance) {
+bool ClassDB::has_method(const StringName &p_class, const StringName &p_method, bool p_no_inheritance) {
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
@@ -1442,14 +1442,14 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p
#endif
}
-void ClassDB::set_class_enabled(StringName p_class, bool p_enable) {
+void ClassDB::set_class_enabled(const StringName &p_class, bool p_enable) {
OBJTYPE_WLOCK;
ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'.");
classes[p_class].disabled = !p_enable;
}
-bool ClassDB::is_class_enabled(StringName p_class) {
+bool ClassDB::is_class_enabled(const StringName &p_class) {
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
@@ -1463,7 +1463,7 @@ bool ClassDB::is_class_enabled(StringName p_class) {
return !ti->disabled;
}
-bool ClassDB::is_class_exposed(StringName p_class) {
+bool ClassDB::is_class_exposed(const StringName &p_class) {
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
diff --git a/core/object/class_db.h b/core/object/class_db.h
index e0cba1b8b5..fd574fd2d8 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -311,7 +311,7 @@ public:
}
template <class M>
- static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) {
+ static MethodBind *bind_vararg_method(uint32_t p_flags, const StringName &p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) {
GLOBAL_LOCK_FUNCTION;
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
@@ -345,31 +345,31 @@ public:
static void bind_method_custom(const StringName &p_class, MethodBind *p_method);
- static void add_signal(StringName p_class, const MethodInfo &p_signal);
- static bool has_signal(StringName p_class, StringName p_signal, bool p_no_inheritance = false);
- static bool get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal);
- static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false);
-
- static void add_property_group(StringName p_class, const String &p_name, const String &p_prefix = "");
- static void add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix = "");
- static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
- static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default);
- static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr);
- static bool get_property_info(StringName p_class, StringName p_property, PropertyInfo *r_info, bool p_no_inheritance = false, const Object *p_validator = nullptr);
+ static void add_signal(const StringName &p_class, const MethodInfo &p_signal);
+ static bool has_signal(const StringName &p_class, const StringName &p_signal, bool p_no_inheritance = false);
+ static bool get_signal(const StringName &p_class, const StringName &p_signal, MethodInfo *r_signal);
+ static void get_signal_list(const StringName &p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false);
+
+ static void add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix = "");
+ static void add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix = "");
+ static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
+ static void set_property_default_value(const StringName &p_class, const StringName &p_name, const Variant &p_default);
+ static void get_property_list(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr);
+ static bool get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, bool p_no_inheritance = false, const Object *p_validator = nullptr);
static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = nullptr);
static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value);
static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false);
static int get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid = nullptr);
static Variant::Type get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid = nullptr);
- static StringName get_property_setter(StringName p_class, const StringName &p_property);
- static StringName get_property_getter(StringName p_class, const StringName &p_property);
+ static StringName get_property_setter(const StringName &p_class, const StringName &p_property);
+ static StringName get_property_getter(const StringName &p_class, const StringName &p_property);
- static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false);
- static void set_method_flags(StringName p_class, StringName p_method, int p_flags);
+ static bool has_method(const StringName &p_class, const StringName &p_method, bool p_no_inheritance = false);
+ static void set_method_flags(const StringName &p_class, const StringName &p_method, int p_flags);
- static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
- static bool get_method_info(StringName p_class, StringName p_method, MethodInfo *r_info, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
- static MethodBind *get_method(StringName p_class, StringName p_name);
+ static void get_method_list(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
+ static bool get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
+ static MethodBind *get_method(const StringName &p_class, const StringName &p_name);
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true);
static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
@@ -388,10 +388,10 @@ public:
static StringName get_category(const StringName &p_node);
- static void set_class_enabled(StringName p_class, bool p_enable);
- static bool is_class_enabled(StringName p_class);
+ static void set_class_enabled(const StringName &p_class, bool p_enable);
+ static bool is_class_enabled(const StringName &p_class);
- static bool is_class_exposed(StringName p_class);
+ static bool is_class_exposed(const StringName &p_class);
static void add_resource_base_extension(const StringName &p_extension, const StringName &p_class);
static void get_resource_base_extensions(List<String> *p_extensions);
diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp
index 44ebafc643..9024f60dae 100644
--- a/core/string/string_name.cpp
+++ b/core/string/string_name.cpp
@@ -48,6 +48,10 @@ StringName _scs_create(const char *p_chr, bool p_static) {
bool StringName::configured = false;
Mutex StringName::mutex;
+#ifdef DEBUG_ENABLED
+bool StringName::debug_stringname = false;
+#endif
+
void StringName::setup() {
ERR_FAIL_COND(configured);
for (int i = 0; i < STRING_TABLE_LEN; i++) {
@@ -59,6 +63,23 @@ void StringName::setup() {
void StringName::cleanup() {
MutexLock lock(mutex);
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ Vector<_Data *> data;
+ for (int i = 0; i < STRING_TABLE_LEN; i++) {
+ _Data *d = _table[i];
+ while (d) {
+ data.push_back(d);
+ d = d->next;
+ }
+ }
+ print_line("\nStringName Reference Ranking:\n");
+ data.sort_custom<DebugSortReferences>();
+ for (int i = 0; i < MIN(100, data.size()); i++) {
+ print_line(itos(i + 1) + ": " + data[i]->get_name() + " - " + itos(data[i]->debug_references));
+ }
+ }
+#endif
int lost_strings = 0;
for (int i = 0; i < STRING_TABLE_LEN; i++) {
while (_table[i]) {
@@ -192,8 +213,14 @@ StringName::StringName(const char *p_name, bool p_static) {
if (p_static) {
_data->static_count.increment();
}
- return;
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ _data->debug_references++;
+ }
+#endif
}
+
+ return;
}
_data = memnew(_Data);
@@ -205,6 +232,13 @@ StringName::StringName(const char *p_name, bool p_static) {
_data->cname = nullptr;
_data->next = _table[idx];
_data->prev = nullptr;
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ // Keep in memory, force static.
+ _data->refcount.ref();
+ _data->static_count.increment();
+ }
+#endif
if (_table[idx]) {
_table[idx]->prev = _data;
}
@@ -240,6 +274,11 @@ StringName::StringName(const StaticCString &p_static_string, bool p_static) {
if (p_static) {
_data->static_count.increment();
}
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ _data->debug_references++;
+ }
+#endif
return;
}
}
@@ -253,6 +292,13 @@ StringName::StringName(const StaticCString &p_static_string, bool p_static) {
_data->cname = p_static_string.ptr;
_data->next = _table[idx];
_data->prev = nullptr;
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ // Keep in memory, force static.
+ _data->refcount.ref();
+ _data->static_count.increment();
+ }
+#endif
if (_table[idx]) {
_table[idx]->prev = _data;
}
@@ -288,6 +334,11 @@ StringName::StringName(const String &p_name, bool p_static) {
if (p_static) {
_data->static_count.increment();
}
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ _data->debug_references++;
+ }
+#endif
return;
}
}
@@ -301,6 +352,14 @@ StringName::StringName(const String &p_name, bool p_static) {
_data->cname = nullptr;
_data->next = _table[idx];
_data->prev = nullptr;
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ // Keep in memory, force static.
+ _data->refcount.ref();
+ _data->static_count.increment();
+ }
+#endif
+
if (_table[idx]) {
_table[idx]->prev = _data;
}
@@ -331,6 +390,12 @@ StringName StringName::search(const char *p_name) {
}
if (_data && _data->refcount.ref()) {
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ _data->debug_references++;
+ }
+#endif
+
return StringName(_data);
}
@@ -388,6 +453,11 @@ StringName StringName::search(const String &p_name) {
}
if (_data && _data->refcount.ref()) {
+#ifdef DEBUG_ENABLED
+ if (unlikely(debug_stringname)) {
+ _data->debug_references++;
+ }
+#endif
return StringName(_data);
}
diff --git a/core/string/string_name.h b/core/string/string_name.h
index ead321c5b0..ce7988744b 100644
--- a/core/string/string_name.h
+++ b/core/string/string_name.h
@@ -52,10 +52,11 @@ class StringName {
struct _Data {
SafeRefCount refcount;
SafeNumeric<uint32_t> static_count;
- SafeRefCount static_refcount;
const char *cname = nullptr;
String name;
-
+#ifdef DEBUG_ENABLED
+ uint32_t debug_references = 0;
+#endif
String get_name() const { return cname ? String(cname) : name; }
int idx = 0;
uint32_t hash = 0;
@@ -81,6 +82,15 @@ class StringName {
static void setup();
static void cleanup();
static bool configured;
+#ifdef DEBUG_ENABLED
+ struct DebugSortReferences {
+ bool operator()(const _Data *p_left, const _Data *p_right) const {
+ return p_left->debug_references > p_right->debug_references;
+ }
+ };
+
+ static bool debug_stringname;
+#endif
StringName(_Data *p_data) { _data = p_data; }
@@ -158,6 +168,10 @@ public:
unref();
}
}
+
+#ifdef DEBUG_ENABLED
+ static void set_debug_stringnames(bool p_enable) { debug_stringname = p_enable; }
+#endif
};
bool operator==(const String &p_name, const StringName &p_string_name);
@@ -167,6 +181,6 @@ bool operator!=(const char *p_name, const StringName &p_string_name);
StringName _scs_create(const char *p_chr, bool p_static = false);
-#define SNAME(m_arg) ([]() { static StringName sname = _scs_create(m_arg, true); return sname; })()
+#define SNAME(m_arg) ([]() -> const StringName & { static StringName sname = _scs_create(m_arg, true); return sname; })()
#endif // STRING_NAME_H
diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml
index 4620b3d93c..e8f4cb49b6 100644
--- a/doc/classes/Camera2D.xml
+++ b/doc/classes/Camera2D.xml
@@ -21,13 +21,6 @@
Aligns the camera to the tracked node.
</description>
</method>
- <method name="clear_current">
- <return type="void">
- </return>
- <description>
- Removes any [Camera2D] from the ancestor [Viewport]'s internal currently-assigned camera.
- </description>
- </method>
<method name="force_update_scroll">
<return type="void">
</return>
@@ -67,13 +60,6 @@
Returns the camera limit for the specified [enum Side]. See also [member limit_bottom], [member limit_top], [member limit_left], and [member limit_right].
</description>
</method>
- <method name="make_current">
- <return type="void">
- </return>
- <description>
- Make this the current 2D camera for the scene (viewport and layer), in case there are many cameras in the scene.
- </description>
- </method>
<method name="reset_smoothing">
<return type="void">
</return>
@@ -109,7 +95,7 @@
<member name="anchor_mode" type="int" setter="set_anchor_mode" getter="get_anchor_mode" enum="Camera2D.AnchorMode" default="1">
The Camera2D's anchor point. See [enum AnchorMode] constants.
</member>
- <member name="current" type="bool" setter="_set_current" getter="is_current" default="false">
+ <member name="current" type="bool" setter="set_current" getter="is_current" default="false">
If [code]true[/code], the camera is the active camera for the current scene. Only one camera can be current, so setting a different camera [code]current[/code] will disable this one.
</member>
<member name="custom_viewport" type="Node" setter="set_custom_viewport" getter="get_custom_viewport">
diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml
index afba478a20..0f0bfdc654 100644
--- a/doc/classes/Camera3D.xml
+++ b/doc/classes/Camera3D.xml
@@ -176,8 +176,8 @@
[codeblock]
# This code block is part of a script that inherits from Node3D.
# `control` is a reference to a node inheriting from Control.
- control.visible = not get_viewport().get_camera().is_position_behind(global_transform.origin)
- control.rect_position = get_viewport().get_camera().unproject_position(global_transform.origin)
+ control.visible = not get_viewport().get_camera_3d().is_position_behind(global_transform.origin)
+ control.rect_position = get_viewport().get_camera_3d().unproject_position(global_transform.origin)
[/codeblock]
</description>
</method>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 00827fe324..bf58dc4d8c 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -36,11 +36,18 @@
Returns the 3D world of the viewport, or if none the world of the parent viewport.
</description>
</method>
- <method name="get_camera" qualifiers="const">
+ <method name="get_camera_2d" qualifiers="const">
+ <return type="Camera2D">
+ </return>
+ <description>
+ Returns the currently active 2D camera. Returns null if there are no active cameras.
+ </description>
+ </method>
+ <method name="get_camera_3d" qualifiers="const">
<return type="Camera3D">
</return>
<description>
- Returns the active 3D camera.
+ Returns the currently active 3D camera.
</description>
</method>
<method name="get_final_transform" qualifiers="const">
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index d3f3ecba54..9126e0512e 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -1039,7 +1039,7 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info
// Third column - buttons
action_item->add_button(2, action_tree->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), BUTTON_ADD_EVENT, false, TTR("Add Event"));
- action_item->add_button(2, action_tree->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_ACTION, !action_info.editable, action_info.editable ? "Remove Action" : "Cannot Remove Action");
+ action_item->add_button(2, action_tree->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_ACTION, !action_info.editable, action_info.editable ? TTR("Remove Action") : TTR("Cannot Remove Action"));
action_item->set_custom_bg_color(0, action_tree->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
action_item->set_custom_bg_color(1, action_tree->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index e704609639..06b02cceb4 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -793,7 +793,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
} else if (camera_override >= CameraOverride::OVERRIDE_3D_1) {
int viewport_idx = camera_override - CameraOverride::OVERRIDE_3D_1;
Node3DEditorViewport *viewport = Node3DEditor::get_singleton()->get_editor_viewport(viewport_idx);
- Camera3D *const cam = viewport->get_camera();
+ Camera3D *const cam = viewport->get_camera_3d();
Array msg;
msg.push_back(cam->get_camera_transform());
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 0764a4c46c..a0884a81cd 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -2438,7 +2438,7 @@ void Node3DEditorViewport::_notification(int p_what) {
Node *scene_root = editor->get_scene_tree_dock()->get_editor_data()->get_edited_scene_root();
if (previewing_cinema && scene_root != nullptr) {
- Camera3D *cam = scene_root->get_viewport()->get_camera();
+ Camera3D *cam = scene_root->get_viewport()->get_camera_3d();
if (cam != nullptr && cam != previewing) {
//then switch the viewport's camera to the scene's viewport camera
if (previewing != nullptr) {
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index fa0f4e950f..cc65cb53ca 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -494,7 +494,7 @@ public:
AcceptDialog *p_accept);
SubViewport *get_viewport_node() { return viewport; }
- Camera3D *get_camera() { return camera; } // return the default camera object.
+ Camera3D *get_camera_3d() { return camera; } // return the default camera object.
Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index);
~Node3DEditorViewport();
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index e4e372a19c..d26fc6ad9d 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -137,6 +137,7 @@ void PropertySelector::_update_search() {
search_options->get_theme_icon(SNAME("Basis"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("Color"), SNAME("EditorIcons")),
+ search_options->get_theme_icon(SNAME("StringName"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("NodePath"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("RID"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("MiniObject"), SNAME("EditorIcons")),
@@ -146,7 +147,9 @@ void PropertySelector::_update_search() {
search_options->get_theme_icon(SNAME("Array"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("PackedByteArray"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("PackedInt32Array"), SNAME("EditorIcons")),
+ search_options->get_theme_icon(SNAME("PackedInt64Array"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("PackedFloat32Array"), SNAME("EditorIcons")),
+ search_options->get_theme_icon(SNAME("PackedFloat64Array"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("PackedStringArray"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("PackedVector2Array"), SNAME("EditorIcons")),
search_options->get_theme_icon(SNAME("PackedVector3Array"), SNAME("EditorIcons")),
diff --git a/main/main.cpp b/main/main.cpp
index 0651f4b93f..1e5445fd93 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -986,11 +986,13 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "-d" || I->get() == "--debug") {
debug_uri = "local://";
OS::get_singleton()->_debug_stdout = true;
-#if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED)
+#if defined(DEBUG_ENABLED)
} else if (I->get() == "--debug-collisions") {
debug_collisions = true;
} else if (I->get() == "--debug-navigation") {
debug_navigation = true;
+ } else if (I->get() == "--debug-stringnames") {
+ StringName::set_debug_stringnames(true);
#endif
} else if (I->get() == "--remote-debug") {
if (I->next()) {
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index b18d0fdb4b..2e0eb4757a 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -629,6 +629,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Control::get_theme_icon(SNAME("Basis"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("Color"), SNAME("EditorIcons")),
+ Control::get_theme_icon(SNAME("StringName"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("NodePath"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("RID"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("MiniObject"), SNAME("EditorIcons")),
@@ -638,7 +639,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Control::get_theme_icon(SNAME("Array"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("PackedByteArray"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("PackedInt32Array"), SNAME("EditorIcons")),
+ Control::get_theme_icon(SNAME("PackedInt64Array"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("PackedFloat32Array"), SNAME("EditorIcons")),
+ Control::get_theme_icon(SNAME("PackedFloat64Array"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("PackedStringArray"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("PackedVector2Array"), SNAME("EditorIcons")),
Control::get_theme_icon(SNAME("PackedVector3Array"), SNAME("EditorIcons")),
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index 005f54e595..ccb2e2df75 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -104,8 +104,11 @@ void VisualScriptPropertySelector::_update_search() {
vbc->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("String"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("Vector2i"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Rect2"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("Rect2i"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("Vector3i"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Transform2D"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Plane"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Quaternion"), SNAME("EditorIcons")),
@@ -113,15 +116,18 @@ void VisualScriptPropertySelector::_update_search() {
vbc->get_theme_icon(SNAME("Basis"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Color"), SNAME("EditorIcons")),
- vbc->get_theme_icon(SNAME("Path"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("StringName"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("NodePath"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("RID"), SNAME("EditorIcons")),
- vbc->get_theme_icon(SNAME("Object"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("MiniObject"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("Callable"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("Signal"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Dictionary"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("Array"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("PackedByteArray"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("PackedInt32Array"), SNAME("EditorIcons")),
- vbc->get_theme_icon(SNAME("PackedFloat32Array"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("PackedInt64Array"), SNAME("EditorIcons")),
+ vbc->get_theme_icon(SNAME("PackedFloat32Array"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("PackedFloat64Array"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("PackedStringArray"), SNAME("EditorIcons")),
vbc->get_theme_icon(SNAME("PackedVector2Array"), SNAME("EditorIcons")),
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index f293081987..0e55915957 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -241,6 +241,10 @@ void Camera2D::_notification(int p_what) {
viewport = get_viewport();
}
+ if (is_current()) {
+ viewport->_camera_2d_set(this);
+ }
+
canvas = get_canvas();
RID vp = viewport->get_viewport_rid();
@@ -259,6 +263,7 @@ void Camera2D::_notification(int p_what) {
if (is_current()) {
if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
viewport->set_canvas_transform(Transform2D());
+ clear_current();
}
}
remove_from_group(group_name);
@@ -392,18 +397,29 @@ Camera2D::Camera2DProcessCallback Camera2D::get_process_callback() const {
void Camera2D::_make_current(Object *p_which) {
if (p_which == this) {
current = true;
+ if (is_inside_tree()) {
+ get_viewport()->_camera_2d_set(this);
+ update();
+ }
} else {
current = false;
+ if (is_inside_tree()) {
+ if (get_viewport()->get_camera_2d() == this) {
+ get_viewport()->_camera_2d_set(nullptr);
+ }
+ update();
+ }
}
}
-void Camera2D::_set_current(bool p_current) {
+void Camera2D::set_current(bool p_current) {
if (p_current) {
make_current();
+ } else {
+ if (current) {
+ clear_current();
+ }
}
-
- current = p_current;
- update();
}
bool Camera2D::is_current() const {
@@ -411,18 +427,19 @@ bool Camera2D::is_current() const {
}
void Camera2D::make_current() {
- if (!is_inside_tree()) {
- current = true;
- } else {
+ if (is_inside_tree()) {
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", this);
+ } else {
+ current = true;
}
_update_scroll();
}
void Camera2D::clear_current() {
- current = false;
if (is_inside_tree()) {
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", (Object *)nullptr);
+ } else {
+ current = false;
}
}
@@ -659,17 +676,14 @@ void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_rotating", "rotating"), &Camera2D::set_rotating);
ClassDB::bind_method(D_METHOD("is_rotating"), &Camera2D::is_rotating);
- ClassDB::bind_method(D_METHOD("make_current"), &Camera2D::make_current);
- ClassDB::bind_method(D_METHOD("clear_current"), &Camera2D::clear_current);
- ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current);
-
ClassDB::bind_method(D_METHOD("_update_scroll"), &Camera2D::_update_scroll);
ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &Camera2D::set_process_callback);
ClassDB::bind_method(D_METHOD("get_process_callback"), &Camera2D::get_process_callback);
- ClassDB::bind_method(D_METHOD("_set_current", "current"), &Camera2D::_set_current);
+ ClassDB::bind_method(D_METHOD("set_current", "current"), &Camera2D::set_current);
ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current);
+ ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current);
ClassDB::bind_method(D_METHOD("set_limit", "margin", "limit"), &Camera2D::set_limit);
ClassDB::bind_method(D_METHOD("get_limit", "margin"), &Camera2D::get_limit);
@@ -725,7 +739,7 @@ void Camera2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed TopLeft,Drag Center"), "set_anchor_mode", "get_anchor_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotating"), "set_rotating", "is_rotating");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "_set_current", "is_current");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom"), "set_zoom", "get_zoom");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", PROPERTY_USAGE_NONE), "set_custom_viewport", "get_custom_viewport");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 7494e526cc..95b49cf076 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -83,7 +83,7 @@ protected:
void _update_scroll();
void _make_current(Object *p_which);
- void _set_current(bool p_current);
+ void set_current(bool p_current);
void _set_old_smoothing(real_t p_enable);
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 1ed8c0b4eb..0c38d85a6b 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -85,14 +85,14 @@ void Camera3D::_update_camera() {
// here goes listener stuff
/*
if (viewport_ptr && is_inside_scene() && is_current())
- get_viewport()->_camera_transform_changed_notify();
+ get_viewport()->_camera_3d_transform_changed_notify();
*/
if (get_tree()->is_node_being_edited(this) || !is_current()) {
return;
}
- get_viewport()->_camera_transform_changed_notify();
+ get_viewport()->_camera_3d_transform_changed_notify();
}
void Camera3D::_notification(int p_what) {
@@ -104,9 +104,9 @@ void Camera3D::_notification(int p_what) {
viewport = get_viewport();
ERR_FAIL_COND(!viewport);
- bool first_camera = viewport->_camera_add(this);
+ bool first_camera = viewport->_camera_3d_add(this);
if (current || first_camera) {
- viewport->_camera_set(this);
+ viewport->_camera_3d_set(this);
}
} break;
@@ -128,7 +128,7 @@ void Camera3D::_notification(int p_what) {
}
if (viewport) {
- viewport->_camera_remove(this);
+ viewport->_camera_3d_remove(this);
viewport = nullptr;
}
@@ -220,7 +220,7 @@ void Camera3D::make_current() {
return;
}
- get_viewport()->_camera_set(this);
+ get_viewport()->_camera_3d_set(this);
//get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,camera_group,"_camera_make_current",this);
}
@@ -231,11 +231,11 @@ void Camera3D::clear_current(bool p_enable_next) {
return;
}
- if (get_viewport()->get_camera() == this) {
- get_viewport()->_camera_set(nullptr);
+ if (get_viewport()->get_camera_3d() == this) {
+ get_viewport()->_camera_3d_set(nullptr);
if (p_enable_next) {
- get_viewport()->_camera_make_next_current(this);
+ get_viewport()->_camera_3d_make_next_current(this);
}
}
}
@@ -250,7 +250,7 @@ void Camera3D::set_current(bool p_current) {
bool Camera3D::is_current() const {
if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
- return get_viewport()->get_camera() == this;
+ return get_viewport()->get_camera_3d() == this;
} else {
return current;
}
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 178a269f17..9e0bc9f3a1 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -1003,7 +1003,7 @@ void CPUParticles3D::_update_particle_data_buffer() {
sorter.sort(order, pc);
} else if (draw_order == DRAW_ORDER_VIEW_DEPTH) {
ERR_FAIL_NULL(get_viewport());
- Camera3D *c = get_viewport()->get_camera();
+ Camera3D *c = get_viewport()->get_camera_3d();
if (c) {
Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close
diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp
index c1e71b9565..5b88a6ec9f 100644
--- a/scene/3d/gpu_particles_collision_3d.cpp
+++ b/scene/3d/gpu_particles_collision_3d.cpp
@@ -596,7 +596,7 @@ void GPUParticlesCollisionHeightField::_notification(int p_what) {
}
if (follow_camera_mode && get_viewport()) {
- Camera3D *cam = get_viewport()->get_camera();
+ Camera3D *cam = get_viewport()->get_camera_3d();
if (cam) {
Transform3D xform = get_global_transform();
Vector3 x_axis = xform.basis.get_axis(Vector3::AXIS_X).normalized();
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index dea69aae6b..c97434f69b 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -47,9 +47,9 @@ void Container::add_child_notify(Node *p_child) {
return;
}
- control->connect("size_flags_changed", callable_mp(this, &Container::queue_sort));
- control->connect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed));
- control->connect("visibility_changed", callable_mp(this, &Container::_child_minsize_changed));
+ control->connect(SNAME("size_flags_changed"), callable_mp(this, &Container::queue_sort));
+ control->connect(SNAME("minimum_size_changed"), callable_mp(this, &Container::_child_minsize_changed));
+ control->connect(SNAME("visibility_changed"), callable_mp(this, &Container::_child_minsize_changed));
minimum_size_changed();
queue_sort();
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 718e754514..032533d4a9 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -446,6 +446,10 @@ Control *Control::get_parent_control() const {
return data.parent;
}
+Window *Control::get_parent_window() const {
+ return data.parent_window;
+}
+
void Control::set_layout_direction(Control::LayoutDirection p_direction) {
ERR_FAIL_INDEX((int)p_direction, 4);
@@ -459,21 +463,21 @@ Control::LayoutDirection Control::get_layout_direction() const {
bool Control::is_layout_rtl() const {
if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) {
- Window *parent_window = Object::cast_to<Window>(get_parent());
+ Window *parent_window = get_parent_window();
Control *parent_control = get_parent_control();
if (parent_control) {
return parent_control->is_layout_rtl();
} else if (parent_window) {
return parent_window->is_layout_rtl();
} else {
- if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
+ if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
return true;
}
String locale = TranslationServer::get_singleton()->get_tool_locale();
return TS->is_locale_right_to_left(locale);
}
} else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) {
- if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
+ if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
return true;
}
String locale = TranslationServer::get_singleton()->get_tool_locale();
@@ -543,6 +547,7 @@ void Control::_notification(int p_notification) {
case NOTIFICATION_ENTER_CANVAS: {
data.parent = Object::cast_to<Control>(get_parent());
+ data.parent_window = Object::cast_to<Window>(get_parent());
Node *parent = this; //meh
Control *parent_control = nullptr;
@@ -607,6 +612,7 @@ void Control::_notification(int p_notification) {
data.parent = nullptr;
data.parent_canvas_item = nullptr;
+ data.parent_window = nullptr;
} break;
case NOTIFICATION_MOVED_IN_PARENT: {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index fb01295668..51b454b334 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -202,6 +202,7 @@ private:
Ref<Theme> theme;
Control *theme_owner = nullptr;
Window *theme_owner_window = nullptr;
+ Window *parent_window = nullptr;
StringName theme_type_variation;
String tooltip;
@@ -342,6 +343,7 @@ public:
Size2 get_custom_minimum_size() const;
Control *get_parent_control() const;
+ Window *get_parent_window() const;
void set_layout_direction(LayoutDirection p_direction);
LayoutDirection get_layout_direction() const;
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index c3fd62640a..5a12480577 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -523,7 +523,7 @@ void CanvasItem::_enter_canvas() {
get_viewport()->gui_reset_canvas_sort_index();
}
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, "_top_level_raise_self");
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, SNAME("_top_level_raise_self"));
} else {
CanvasItem *parent = get_parent_item();
@@ -542,7 +542,7 @@ void CanvasItem::_exit_canvas() {
notification(NOTIFICATION_EXIT_CANVAS, true); //reverse the notification
RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, RID());
canvas_layer = nullptr;
- group = "";
+ group = StringName();
}
void CanvasItem::_notification(int p_what) {
@@ -588,7 +588,7 @@ void CanvasItem::_notification(int p_what) {
break;
}
- if (group != "") {
+ if (group != StringName()) {
get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, "_top_level_raise_self");
} else {
CanvasItem *p = get_parent_item();
@@ -648,7 +648,7 @@ void CanvasItem::update() {
pending_update = true;
- MessageQueue::get_singleton()->push_call(this, "_update_callback");
+ MessageQueue::get_singleton()->push_call(this, SNAME("_update_callback"));
}
void CanvasItem::set_modulate(const Color &p_modulate) {
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index afdd18d76b..f264764870 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -187,7 +187,7 @@ private:
mutable SelfList<Node> xform_change;
RID canvas_item;
- String group;
+ StringName group;
CanvasLayer *canvas_layer = nullptr;
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index cc947560a2..2fe5d7aa78 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -408,9 +408,9 @@ bool SceneTree::physics_process(float p_time) {
emit_signal(SNAME("physics_frame"));
- _notify_group_pause("physics_process_internal", Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
- call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_process_picking");
- _notify_group_pause("physics_process", Node::NOTIFICATION_PHYSICS_PROCESS);
+ _notify_group_pause(SNAME("physics_process_internal"), Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
+ call_group_flags(GROUP_CALL_REALTIME, SNAME("_picking_viewports"), SNAME("_process_picking"));
+ _notify_group_pause(SNAME("physics_process"), Node::NOTIFICATION_PHYSICS_PROCESS);
_flush_ugc();
MessageQueue::get_singleton()->flush(); //small little hack
@@ -442,8 +442,8 @@ bool SceneTree::process(float p_time) {
flush_transform_notifications();
- _notify_group_pause("process_internal", Node::NOTIFICATION_INTERNAL_PROCESS);
- _notify_group_pause("process", Node::NOTIFICATION_PROCESS);
+ _notify_group_pause(SNAME("process_internal"), Node::NOTIFICATION_INTERNAL_PROCESS);
+ _notify_group_pause(SNAME("process"), Node::NOTIFICATION_PROCESS);
_flush_ugc();
MessageQueue::get_singleton()->flush(); //small little hack
@@ -490,7 +490,7 @@ bool SceneTree::process(float p_time) {
if (Engine::get_singleton()->is_editor_hint()) {
//simple hack to reload fallback environment if it changed from editor
- String env_path = ProjectSettings::get_singleton()->get("rendering/environment/defaults/default_environment");
+ String env_path = ProjectSettings::get_singleton()->get(SNAME("rendering/environment/defaults/default_environment"));
env_path = env_path.strip_edges(); //user may have added a space or two
String cpath;
Ref<Environment> fallback = get_root()->get_world_3d()->get_fallback_environment();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index b366f2d670..5a0a27520b 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -37,6 +37,7 @@
#include "core/os/os.h"
#include "core/string/translation.h"
+#include "scene/2d/camera_2d.h"
#include "scene/2d/collision_object_2d.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/collision_object_3d.h"
@@ -195,7 +196,7 @@ void Viewport::_collision_object_input_event(CollisionObject3D *p_object, Camera
return; //discarded
}
}
- p_object->_input_event(camera, p_input_event, p_pos, p_normal, p_shape);
+ p_object->_input_event(camera_3d, p_input_event, p_pos, p_normal, p_shape);
physics_last_object_transform = object_transform;
physics_last_camera_transform = camera_transform;
physics_last_id = id;
@@ -444,6 +445,7 @@ void Viewport::_notification(int p_what) {
RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh);
RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario());
//RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true);
+ set_physics_process_internal(true);
}
} break;
@@ -462,7 +464,7 @@ void Viewport::_notification(int p_what) {
}
}
- if (cameras.size() && !camera) {
+ if (cameras.size() && !camera_3d) {
//there are cameras but no current camera, pick first in tree and make it current
Camera3D *first = nullptr;
for (Set<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) {
@@ -477,10 +479,6 @@ void Viewport::_notification(int p_what) {
}
#endif
- // Enable processing for tooltips, collision debugging, physics object picking, etc.
- set_process_internal(true);
- set_physics_process_internal(true);
-
} break;
case NOTIFICATION_EXIT_TREE: {
_gui_cancel_tooltip();
@@ -500,6 +498,7 @@ void Viewport::_notification(int p_what) {
}
remove_from_group("_viewports");
+ set_physics_process_internal(false);
RS::get_singleton()->viewport_set_active(viewport, false);
RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID());
@@ -510,6 +509,7 @@ void Viewport::_notification(int p_what) {
gui.tooltip_timer -= get_process_delta_time();
if (gui.tooltip_timer < 0) {
_gui_show_tooltip();
+ set_process_internal(false);
}
}
@@ -743,8 +743,8 @@ void Viewport::_process_picking() {
if (physics_object_capture.is_valid()) {
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture));
- if (co && camera) {
- _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0);
+ if (co && camera_3d) {
+ _collision_object_input_event(co, camera_3d, ev, Vector3(), Vector3(), 0);
captured = true;
if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
physics_object_capture = ObjectID();
@@ -761,16 +761,16 @@ void Viewport::_process_picking() {
if (last_id.is_valid()) {
if (ObjectDB::get_instance(last_id) && last_object) {
//good, exists
- _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape);
+ _collision_object_input_event(last_object, camera_3d, ev, result.position, result.normal, result.shape);
if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
physics_object_capture = last_id;
}
}
}
} else {
- if (camera) {
- Vector3 from = camera->project_ray_origin(pos);
- Vector3 dir = camera->project_ray_normal(pos);
+ if (camera_3d) {
+ Vector3 from = camera_3d->project_ray_origin(pos);
+ Vector3 dir = camera_3d->project_ray_normal(pos);
PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space());
if (space) {
@@ -778,8 +778,8 @@ void Viewport::_process_picking() {
ObjectID new_collider;
if (col) {
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider);
- if (co && co->can_process()) {
- _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape);
+ if (co) {
+ _collision_object_input_event(co, camera_3d, ev, result.position, result.normal, result.shape);
last_object = co;
last_id = result.collider_id;
new_collider = last_id;
@@ -1033,64 +1033,68 @@ void Viewport::_listener_make_next_current(Listener3D *p_exclude) {
}
} else {
// Attempt to reset listener to the camera position
- if (camera != nullptr) {
+ if (camera_3d != nullptr) {
_update_listener();
- _camera_transform_changed_notify();
+ _camera_3d_transform_changed_notify();
}
}
}
#endif
-void Viewport::_camera_transform_changed_notify() {
+void Viewport::_camera_3d_transform_changed_notify() {
#ifndef _3D_DISABLED
#endif
}
-void Viewport::_camera_set(Camera3D *p_camera) {
+void Viewport::_camera_3d_set(Camera3D *p_camera) {
#ifndef _3D_DISABLED
- if (camera == p_camera) {
+ if (camera_3d == p_camera) {
return;
}
- if (camera) {
- camera->notification(Camera3D::NOTIFICATION_LOST_CURRENT);
+ if (camera_3d) {
+ camera_3d->notification(Camera3D::NOTIFICATION_LOST_CURRENT);
}
- camera = p_camera;
+ camera_3d = p_camera;
if (!camera_override) {
- if (camera) {
- RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
+ if (camera_3d) {
+ RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d->get_camera());
} else {
RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID());
}
}
- if (camera) {
- camera->notification(Camera3D::NOTIFICATION_BECAME_CURRENT);
+ if (camera_3d) {
+ camera_3d->notification(Camera3D::NOTIFICATION_BECAME_CURRENT);
}
_update_listener();
- _camera_transform_changed_notify();
+ _camera_3d_transform_changed_notify();
#endif
}
-bool Viewport::_camera_add(Camera3D *p_camera) {
+void Viewport::_camera_2d_set(Camera2D *p_camera_2d) {
+ camera_2d = p_camera_2d;
+}
+
+bool Viewport::_camera_3d_add(Camera3D *p_camera) {
cameras.insert(p_camera);
return cameras.size() == 1;
}
-void Viewport::_camera_remove(Camera3D *p_camera) {
+void Viewport::_camera_3d_remove(Camera3D *p_camera) {
cameras.erase(p_camera);
- if (camera == p_camera) {
- camera->notification(Camera3D::NOTIFICATION_LOST_CURRENT);
- camera = nullptr;
+ if (camera_3d == p_camera) {
+ camera_3d->notification(Camera3D::NOTIFICATION_LOST_CURRENT);
+ camera_3d = nullptr;
}
}
#ifndef _3D_DISABLED
-void Viewport::_camera_make_next_current(Camera3D *p_exclude) {
+void Viewport::_camera_3d_make_next_current(Camera3D *p_exclude) {
for (Set<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) {
if (p_exclude == E->get()) {
continue;
@@ -1098,7 +1102,7 @@ void Viewport::_camera_make_next_current(Camera3D *p_exclude) {
if (!E->get()->is_inside_tree()) {
continue;
}
- if (camera != nullptr) {
+ if (camera_3d != nullptr) {
return;
}
@@ -1287,8 +1291,12 @@ Listener3D *Viewport::get_listener() const {
return listener;
}
-Camera3D *Viewport::get_camera() const {
- return camera;
+Camera3D *Viewport::get_camera_3d() const {
+ return camera_3d;
+}
+
+Camera2D *Viewport::get_camera_2d() const {
+ return camera_2d;
}
void Viewport::enable_camera_override(bool p_enable) {
@@ -1306,8 +1314,8 @@ void Viewport::enable_camera_override(bool p_enable) {
if (p_enable) {
RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_override.rid);
- } else if (camera) {
- RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
+ } else if (camera_3d) {
+ RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d->get_camera());
} else {
RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID());
}
@@ -1482,6 +1490,7 @@ void Viewport::_gui_sort_roots() {
void Viewport::_gui_cancel_tooltip() {
gui.tooltip_control = nullptr;
gui.tooltip_timer = -1;
+ set_process_internal(false);
if (gui.tooltip_popup) {
gui.tooltip_popup->queue_delete();
gui.tooltip_popup = nullptr;
@@ -2133,6 +2142,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.tooltip_control = over;
gui.tooltip_pos = over->get_screen_transform().xform(pos);
gui.tooltip_timer = gui.tooltip_delay;
+ set_process_internal(true);
}
}
@@ -3172,8 +3182,13 @@ bool Viewport::is_using_own_world_3d() const {
void Viewport::set_physics_object_picking(bool p_enable) {
physics_object_picking = p_enable;
- if (!physics_object_picking) {
+ if (physics_object_picking) {
+ add_to_group("_picking_viewports");
+ } else {
physics_picking_events.clear();
+ if (is_in_group("_picking_viewports")) {
+ remove_from_group("_picking_viewports");
+ }
}
}
@@ -3542,7 +3557,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d);
ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d);
- ClassDB::bind_method(D_METHOD("get_camera"), &Viewport::get_camera);
+ ClassDB::bind_method(D_METHOD("get_camera_3d"), &Viewport::get_camera_3d);
+ ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d);
ClassDB::bind_method(D_METHOD("set_as_audio_listener", "enable"), &Viewport::set_as_audio_listener);
ClassDB::bind_method(D_METHOD("is_audio_listener"), &Viewport::is_audio_listener);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 59715ebd0e..7b7f1c3818 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -214,7 +214,8 @@ private:
}
} camera_override;
- Camera3D *camera = nullptr;
+ Camera3D *camera_3d = nullptr;
+ Camera2D *camera_2d = nullptr;
Set<Camera3D *> cameras;
Set<CanvasLayer *> canvas_layers;
@@ -450,11 +451,14 @@ private:
void _listener_make_next_current(Listener3D *p_exclude);
friend class Camera3D;
- void _camera_transform_changed_notify();
- void _camera_set(Camera3D *p_camera);
- bool _camera_add(Camera3D *p_camera); //true if first
- void _camera_remove(Camera3D *p_camera);
- void _camera_make_next_current(Camera3D *p_exclude);
+ void _camera_3d_transform_changed_notify();
+ void _camera_3d_set(Camera3D *p_camera);
+ bool _camera_3d_add(Camera3D *p_camera); //true if first
+ void _camera_3d_remove(Camera3D *p_camera);
+ void _camera_3d_make_next_current(Camera3D *p_exclude);
+
+ friend class Camera2D;
+ void _camera_2d_set(Camera2D *p_camera_2d);
friend class CanvasLayer;
void _canvas_layer_add(CanvasLayer *p_canvas_layer);
@@ -497,7 +501,8 @@ public:
uint64_t get_processed_events_count() const { return event_count; }
Listener3D *get_listener() const;
- Camera3D *get_camera() const;
+ Camera3D *get_camera_3d() const;
+ Camera2D *get_camera_2d() const;
void enable_camera_override(bool p_enable);
bool is_camera_override_enabled() const;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 7aa88fa766..bf7512e8eb 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1325,14 +1325,14 @@ bool Window::is_layout_rtl() const {
if (parent) {
return parent->is_layout_rtl();
} else {
- if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
+ if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
return true;
}
String locale = TranslationServer::get_singleton()->get_tool_locale();
return TS->is_locale_right_to_left(locale);
}
} else if (layout_dir == LAYOUT_DIRECTION_LOCALE) {
- if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
+ if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
return true;
}
String locale = TranslationServer::get_singleton()->get_tool_locale();