summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/ProjectSettings.xml3
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp3
-rw-r--r--drivers/gles3/shaders/canvas.glsl2
-rw-r--r--drivers/gles3/shaders/canvas_uniforms_inc.glsl3
-rw-r--r--editor/editor_properties.cpp2
-rw-r--r--editor/event_listener_line_edit.cpp13
-rw-r--r--editor/event_listener_line_edit.h4
-rw-r--r--editor/input_event_configuration_dialog.cpp4
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp4
-rw-r--r--modules/gdscript/gdscript_warning.cpp5
-rw-r--r--modules/gdscript/gdscript_warning.h1
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.gd11
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.out7
13 files changed, 57 insertions, 5 deletions
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 4b2bb3b6e9..ff66affeab 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -413,6 +413,9 @@
<member name="debug/gdscript/warnings/standalone_ternary" type="int" setter="" getter="" default="1">
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when calling a ternary expression that has no effect on the surrounding code, such as writing [code]42 if active else 0[/code] as a statement.
</member>
+ <member name="debug/gdscript/warnings/static_called_on_instance" type="int" setter="" getter="" default="1">
+ When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when calling a static method from an instance of a class instead of from the class directly.
+ </member>
<member name="debug/gdscript/warnings/treat_warnings_as_errors" type="bool" setter="" getter="" default="false">
If [code]true[/code], all warnings will be reported as if they are errors.
</member>
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 65bb98d29e..2844c20193 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -130,7 +130,10 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
if (syncStatus == GL_UNSIGNALED) {
// If older than 2 frames, wait for sync OpenGL can have up to 3 frames in flight, any more and we need to sync anyway.
if (state.canvas_instance_data_buffers[state.current_buffer].last_frame_used < RSG::rasterizer->get_frame_number() - 2) {
+#ifndef WEB_ENABLED
+ // On web, we do nothing as the glSubBufferData will force a sync anyway and WebGL does not like waiting.
glClientWaitSync(state.canvas_instance_data_buffers[state.current_buffer].fence, 0, 100000000); // wait for up to 100ms
+#endif
} else {
// Used in last frame or frame before that. OpenGL can get up to two frames behind, so these buffers may still be in use
// Allocate a new buffer and use that.
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 22a11cdc29..23db41802e 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -211,7 +211,9 @@ void main() {
#include "canvas_uniforms_inc.glsl"
#include "stdlib_inc.glsl"
+#ifndef DISABLE_LIGHTING
uniform sampler2D atlas_texture; //texunit:-2
+#endif // DISABLE_LIGHTING
//uniform sampler2D shadow_atlas_texture; //texunit:-3
uniform sampler2D screen_texture; //texunit:-4
uniform sampler2D sdf_texture; //texunit:-5
diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
index 43d275205f..dd5ebecb1a 100644
--- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl
+++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
@@ -82,6 +82,7 @@ layout(std140) uniform CanvasData { //ubo:0
uint pad2;
};
+#ifndef DISABLE_LIGHTING
#define LIGHT_FLAGS_BLEND_MASK uint(3 << 16)
#define LIGHT_FLAGS_BLEND_MODE_ADD uint(0 << 16)
#define LIGHT_FLAGS_BLEND_MODE_SUB uint(1 << 16)
@@ -114,7 +115,7 @@ struct Light {
layout(std140) uniform LightData { //ubo:2
Light light_array[MAX_LIGHTS];
};
-
+#endif // DISABLE_LIGHTING
layout(std140) uniform DrawDataInstances { //ubo:3
DrawData draw_data[MAX_DRAW_DATA_INSTANCES];
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 332e47dc52..899fa69be1 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -90,7 +90,9 @@ void EditorPropertyText::update_property() {
String s = get_edited_object()->get(get_edited_property());
updating = true;
if (text->get_text() != s) {
+ int caret = text->get_caret_column();
text->set_text(s);
+ text->set_caret_column(caret);
}
text->set_editable(!is_read_only());
updating = false;
diff --git a/editor/event_listener_line_edit.cpp b/editor/event_listener_line_edit.cpp
index 14e482432a..e4c35a5b81 100644
--- a/editor/event_listener_line_edit.cpp
+++ b/editor/event_listener_line_edit.cpp
@@ -59,8 +59,9 @@ void EventListenerLineEdit::gui_input(const Ref<InputEvent> &p_event) {
// First event will be an event which is used to focus this control - i.e. a mouse click, or a tab press.
// Ignore the first one so that clicking into the LineEdit does not override the current event.
// Ignore is reset to true when the control is unfocused.
- if (ignore) {
- ignore = false;
+ // This class also specially handles grab_focus() calls.
+ if (ignore_next_event) {
+ ignore_next_event = false;
return;
}
@@ -85,7 +86,7 @@ void EventListenerLineEdit::_on_focus() {
}
void EventListenerLineEdit::_on_unfocus() {
- ignore = true;
+ ignore_next_event = true;
set_placeholder(TTR("Filter by event..."));
}
@@ -109,6 +110,12 @@ int EventListenerLineEdit::get_allowed_input_types() const {
return allowed_input_types;
}
+void EventListenerLineEdit::grab_focus() {
+ // If we grab focus through code, we don't need to ignore the first event!
+ ignore_next_event = false;
+ Control::grab_focus();
+}
+
void EventListenerLineEdit::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
diff --git a/editor/event_listener_line_edit.h b/editor/event_listener_line_edit.h
index 5b415e8a2d..c4cd5e4511 100644
--- a/editor/event_listener_line_edit.h
+++ b/editor/event_listener_line_edit.h
@@ -44,7 +44,7 @@ class EventListenerLineEdit : public LineEdit {
GDCLASS(EventListenerLineEdit, LineEdit)
int allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION;
- bool ignore = true;
+ bool ignore_next_event = true;
bool share_keycodes = false;
Ref<InputEvent> event;
@@ -67,6 +67,8 @@ public:
void set_allowed_input_types(int input_types);
int get_allowed_input_types() const;
+ void grab_focus();
+
public:
EventListenerLineEdit();
};
diff --git a/editor/input_event_configuration_dialog.cpp b/editor/input_event_configuration_dialog.cpp
index ed9a5898fb..c577c61db7 100644
--- a/editor/input_event_configuration_dialog.cpp
+++ b/editor/input_event_configuration_dialog.cpp
@@ -533,6 +533,10 @@ String InputEventConfigurationDialog::_get_device_string(int p_device) const {
void InputEventConfigurationDialog::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ event_listener->grab_focus();
+ } break;
+
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
input_list_search->set_right_icon(input_list_search->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index b3ca8ff00a..6fbdec863f 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -2552,6 +2552,10 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
if (p_is_root && return_type.kind != GDScriptParser::DataType::UNRESOLVED && return_type.builtin_type != Variant::NIL) {
parser->push_warning(p_call, GDScriptWarning::RETURN_VALUE_DISCARDED, p_call->function_name);
}
+
+ if (is_static && !base_type.is_meta_type && !(callee_type != GDScriptParser::Node::SUBSCRIPT && parser->current_function != nullptr && parser->current_function->is_static)) {
+ parser->push_warning(p_call, GDScriptWarning::STATIC_CALLED_ON_INSTANCE, p_call->function_name, base_type.to_string());
+ }
#endif // DEBUG_ENABLED
call_type = return_type;
diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp
index 1cae7bdfac..a0c107aa53 100644
--- a/modules/gdscript/gdscript_warning.cpp
+++ b/modules/gdscript/gdscript_warning.cpp
@@ -155,6 +155,10 @@ String GDScriptWarning::get_message() const {
case INT_ASSIGNED_TO_ENUM: {
return "Integer used when an enum value is expected. If this is intended cast the integer to the enum type.";
}
+ case STATIC_CALLED_ON_INSTANCE: {
+ CHECK_SYMBOLS(2);
+ return vformat(R"(The function '%s()' is a static function but was called from an instance. Instead, it should be directly called from the type: '%s.%s()'.)", symbols[0], symbols[1], symbols[0]);
+ }
case WARNING_MAX:
break; // Can't happen, but silences warning
}
@@ -215,6 +219,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
"EMPTY_FILE",
"SHADOWED_GLOBAL_IDENTIFIER",
"INT_ASSIGNED_TO_ENUM",
+ "STATIC_CALLED_ON_INSTANCE",
};
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h
index a639e7b44e..7e4e975510 100644
--- a/modules/gdscript/gdscript_warning.h
+++ b/modules/gdscript/gdscript_warning.h
@@ -78,6 +78,7 @@ public:
EMPTY_FILE, // A script file is empty.
SHADOWED_GLOBAL_IDENTIFIER, // A global class or function has the same name as variable.
INT_ASSIGNED_TO_ENUM, // An integer value was assigned to an enum-typed variable without casting.
+ STATIC_CALLED_ON_INSTANCE, // A static method was called on an instance of a class instead of on the class itself.
WARNING_MAX,
};
diff --git a/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.gd b/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.gd
new file mode 100644
index 0000000000..29d8501b78
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.gd
@@ -0,0 +1,11 @@
+class Player:
+ var x = 3
+
+func test():
+ # These should not emit a warning.
+ var _player = Player.new()
+ print(String.num_uint64(8589934592)) # 2 ^ 33
+
+ # This should emit a warning.
+ var some_string = String()
+ print(some_string.num_uint64(8589934592)) # 2 ^ 33
diff --git a/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.out b/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.out
new file mode 100644
index 0000000000..3933a35178
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.out
@@ -0,0 +1,7 @@
+GDTEST_OK
+>> WARNING
+>> Line: 11
+>> STATIC_CALLED_ON_INSTANCE
+>> The function 'num_uint64()' is a static function but was called from an instance. Instead, it should be directly called from the type: 'String.num_uint64()'.
+8589934592
+8589934592