summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CODEOWNERS1
-rw-r--r--.mailmap1
-rw-r--r--AUTHORS.md3
-rw-r--r--DONORS.md97
-rw-r--r--core/debugger/engine_debugger.cpp2
-rw-r--r--core/debugger/remote_debugger_peer.cpp2
-rw-r--r--core/io/resource_loader.cpp2
-rw-r--r--core/project_settings.cpp2
-rw-r--r--core/ustring.cpp26
-rw-r--r--core/ustring.h1
-rw-r--r--core/variant_call.cpp2
-rw-r--r--doc/classes/DisplayServer.xml12
-rw-r--r--doc/classes/EditorTranslationParserPlugin.xml2
-rw-r--r--doc/classes/ProjectSettings.xml3
-rw-r--r--doc/classes/RayCast2D.xml2
-rw-r--r--doc/classes/RayCast3D.xml2
-rw-r--r--doc/classes/String.xml20
-rw-r--r--doc/classes/TextEdit.xml6
-rw-r--r--doc/classes/Window.xml4
-rw-r--r--editor/animation_track_editor.cpp4
-rw-r--r--editor/create_dialog.cpp753
-rw-r--r--editor/create_dialog.h65
-rw-r--r--editor/editor_asset_installer.cpp2
-rw-r--r--editor/editor_feature_profile.cpp2
-rw-r--r--editor/editor_file_dialog.cpp6
-rw-r--r--editor/editor_file_system.cpp2
-rw-r--r--editor/editor_folding.cpp2
-rw-r--r--editor/editor_fonts.cpp2
-rw-r--r--editor/editor_inspector.cpp4
-rw-r--r--editor/editor_node.cpp4
-rw-r--r--editor/editor_run.cpp33
-rw-r--r--editor/filesystem_dock.cpp4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp30
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp48
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp1
-rw-r--r--editor/project_manager.cpp9
-rw-r--r--editor/project_settings_editor.cpp2
-rw-r--r--editor/script_create_dialog.cpp4
-rw-r--r--main/main.cpp4
-rw-r--r--main/tests/test_string.cpp5
-rw-r--r--modules/gdnative/gdnative/string.cpp7
-rw-r--r--modules/gdnative/gdnative_api.json8
-rw-r--r--modules/gdnative/include/gdnative/string.h1
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml38
-rw-r--r--modules/mono/class_db_api_json.cpp6
-rw-r--r--modules/mono/csharp_script.cpp313
-rw-r--r--modules/mono/csharp_script.h253
-rw-r--r--modules/mono/editor/bindings_generator.cpp2
-rw-r--r--modules/mono/editor/code_completion.cpp18
-rw-r--r--modules/mono/editor/csharp_project.cpp3
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp2
-rw-r--r--modules/mono/editor/godotsharp_export.cpp6
-rw-r--r--modules/mono/editor/script_class_parser.cpp51
-rw-r--r--modules/mono/editor/script_class_parser.h1
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs10
-rw-r--r--modules/mono/glue/arguments_vector.h4
-rw-r--r--modules/mono/glue/base_object_glue.cpp12
-rw-r--r--modules/mono/glue/base_object_glue.h73
-rw-r--r--modules/mono/glue/collections_glue.cpp5
-rw-r--r--modules/mono/glue/collections_glue.h124
-rw-r--r--modules/mono/glue/gd_glue.cpp16
-rw-r--r--modules/mono/glue/gd_glue.h86
-rw-r--r--modules/mono/glue/glue_header.h18
-rw-r--r--modules/mono/glue/nodepath_glue.cpp9
-rw-r--r--modules/mono/glue/nodepath_glue.h68
-rw-r--r--modules/mono/glue/rid_glue.cpp9
-rw-r--r--modules/mono/glue/rid_glue.h53
-rw-r--r--modules/mono/glue/scene_tree_glue.cpp14
-rw-r--r--modules/mono/glue/scene_tree_glue.h50
-rw-r--r--modules/mono/glue/string_glue.cpp4
-rw-r--r--modules/mono/glue/string_glue.h56
-rw-r--r--modules/mono/glue/string_name_glue.cpp7
-rw-r--r--modules/mono/glue/string_name_glue.h54
-rw-r--r--modules/mono/managed_callable.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp151
-rw-r--r--modules/mono/mono_gd/gd_mono.h27
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp63
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp2
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp69
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp12
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp5
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp9
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp313
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h10
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp18
-rw-r--r--modules/mono/mono_gd/gd_mono_property.cpp18
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp35
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h5
-rw-r--r--modules/mono/register_types.cpp6
-rw-r--r--modules/mono/signal_awaiter_utils.cpp18
-rw-r--r--modules/mono/utils/path_utils.cpp46
-rw-r--r--modules/mono/utils/path_utils.h2
-rw-r--r--modules/mono/utils/string_utils.cpp12
-rw-r--r--modules/websocket/websocket_client.cpp2
-rw-r--r--platform/android/export/export.cpp2
-rw-r--r--platform/linuxbsd/display_server_x11.cpp22
-rw-r--r--platform/osx/display_server_osx.h3
-rw-r--r--platform/osx/display_server_osx.mm466
-rw-r--r--platform/osx/os_osx.mm8
-rw-r--r--platform/windows/display_server_windows.cpp22
-rw-r--r--scene/2d/collision_shape_2d.cpp7
-rw-r--r--scene/gui/file_dialog.cpp4
-rw-r--r--scene/gui/graph_edit.cpp106
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/main/window.cpp1
-rw-r--r--scene/resources/default_theme/default_theme.cpp50
-rw-r--r--servers/display_server.cpp1
-rw-r--r--servers/display_server.h8
-rw-r--r--servers/physics_2d/area_2d_sw.cpp28
-rw-r--r--servers/physics_3d/area_3d_sw.cpp27
111 files changed, 1942 insertions, 2203 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 3bbe47af2a..33ec541bc7 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -35,6 +35,7 @@ doc_classes/* @godotengine/documentation
/modules/mbedtls/ @godotengine/network
/modules/mobile_vr/ @BastiaanOlij
/modules/mono/ @neikeq
+/modules/mono/glue/GodotSharp @aaronfranke
/modules/opensimplex/ @JFonS
/modules/regex/ @LeeZH
/modules/upnp/ @godotengine/network
diff --git a/.mailmap b/.mailmap
index 1ff1ffb0ee..4b427a8a5e 100644
--- a/.mailmap
+++ b/.mailmap
@@ -72,6 +72,7 @@ Leon Krause <lk@leonkrause.com> <eska014@users.noreply.github.com>
Manuel Strey <manuel.strey@gmx.de>
Marcelo Fernandez <marcelofg55@gmail.com>
Marcin Zawiejski <dragmz@gmail.com>
+Marcus Elg <marcusaccounts@yahoo.se>
Mariano Javier Suligoy <marianognu.easyrpg@gmail.com>
Mario Schlack <m4r10.5ch14ck@gmail.com>
marxin <mliska@suse.cz>
diff --git a/AUTHORS.md b/AUTHORS.md
index e8bb91d4bb..f1803c672c 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -110,10 +110,13 @@ name is available.
Leon Krause (eska014)
Lucien Menassol (Kanabenki)
m4nu3lf
+ Maganty Rushyendra (mrushyendra)
Marcel Admiraal (madmiraal)
Marcelo Fernandez (marcelofg55)
Marc Gilleron (Zylann)
Marcin Zawiejski (dragmz)
+ Marcus Brummer (mbrlabs)
+ Marcus (MCrafterzz)
Mariano Javier Suligoy (MarianoGnu)
Mario Schlack (hurikhan)
Martin Capitanio (capnm)
diff --git a/DONORS.md b/DONORS.md
index 2988cc94f4..16a30b9489 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -25,13 +25,14 @@ generous deed immortalized in the next stable release of Godot Engine.
AD Ford
Alan Beauchamp
albinaask
+ Alejandro Saucedo
Andrew Dunai
Brandon Lamb
Christian Baune
Christopher Montesano
- Darius Pranskus
Darkhan Baimyrza
Darrin Massena
+ Digital Grows
Dov Zimring
Edward Flick
Gamechuck
@@ -42,9 +43,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Jasper Brooks
Javary Co.
Jeffery Chiu
- John Benard (Linuxydable)
Justin Arnold
- Justo Delgado Baudí
Kyle Szklenski
Marcel Kräml
Matthieu Huvé
@@ -52,7 +51,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Mike King
Nathan Warden
Neal Gompa (Conan Kudo)
- Péter Magyar
Ronnie Cheng
Slobodan Milnovic
Stephan Lanfermann
@@ -64,46 +62,51 @@ generous deed immortalized in the next stable release of Godot Engine.
Bjarke
David Gehrig
- David Graham
David Snopek
Ed Morley
Florian Rämisch
Jakub Grzesik
- HardRound
Manuele Finocchiaro
Officine Pixel S.n.c.
+ Rami
Ronan Zeegers
Sofox
+ Spicylewd
Taylor Ritenour
Zaven Muradyan
+ Andreas Schüle
+ Andres Hernandez
Asher Glick
Austen McRae
Bernhard Werner
beVR
Carlo Cabanilla
+ Christopher Case
Daniel James
David Giardi
Default Name
eggs
Florian Breisch
+ Forge
Gamejunkey
Javier Roman
Jon Woodward
Karl Werf
- Keinan Powers
Klavdij Voncina
Lex Steers
Luke
Maciej Pendolski
Matthew Hillier
Mohamed Ikbel Boulabiar
+ Monster Vial
Rene
Retro Village
Rob Messick
Roland Fredenhagen
Ryan Badour
Sandro Jenny
+ Sarksus
Scott Wadden
Sergey
thechris
@@ -114,6 +117,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Alex Khayrullin
alice gambrell
+ Andrew Harris
Barugon
Chris Goddard
Chris Serino
@@ -121,28 +125,31 @@ generous deed immortalized in the next stable release of Godot Engine.
Conrad Curry
Craig Smith
Darrian Little
+ dragonage13
+ GiulianoB
Hoai Nam Tran
Horváth Péter
- Jamal Aboudrar
+ Jeff Nyte
Joan Fons
Joshua Flores
Leo Fidel R Liban
+ Michael Dürwald
+ Péter Magyar
Petr Malac
- Rami
Rob
Robert Willes
Ronnie Ashlock
SKison
Thomas Bjarnelöf
- Unseen Domains
Valryia
Vincent Henderson
+ Vojtěch
Wojciech Chojnacki
Xavier PATRICELLI
+ Zoran Kukulj
Adam Nakonieczny
Adam Neumann
- Adrian Demetrescu
Alexander J Maynard
Alexey Dyadchenko
Andreas Funke
@@ -152,20 +159,21 @@ generous deed immortalized in the next stable release of Godot Engine.
Carlos de Sousa Marques
Charlie Whitfield
Chase Taranto
+ Chelsea Hash
Chris Petrich
Christian Alexander Bjørklund Bøhler
Christian Leth Jeppesen
- Christoph Schröder
- Codee Leaf
Cody Parker
Craig Ostrin
curtis Kramer
D
+ Dev To be curious
+ Digital Denizen
Easypete
Edgar Sun
- Eric Monson
Eugenio Hugo Salgüero Jáñez
flesk
+ F S
Gary Hulst
gavlig
GGGames.org
@@ -174,24 +182,27 @@ generous deed immortalized in the next stable release of Godot Engine.
Hu Hund
Isaac Clausman
Jared White
- Jeff Nyte
Joe Flood
John G Gentzel
Jose Malheiro
+ Joseph Crane
Joshua Lesperance
Juan Velandia
Julian Todd
Juraj Móza
+ Justo Delgado Baudí
Kelteseth
kickmaniac
kinfox
Lain Ballard
+ luca duran
Marcelo Dornbusch Lopes
Marcelo Henrique Gonçalves
Markus Fehr
Markus Wiesner
Martin Eigel
Matt Eunson
+ Mikado069
m kaersten
MuffinManKen
Nick Abousselam
@@ -201,6 +212,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Paul Hocker
Paul Von Zimmerman
Pete Goodwin
+ PhaineOfCatz
pl
Ranoller
Rob McInroy
@@ -208,6 +220,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Ryan
Samuel Judd
Scott Pilet
+ Scott Ryan-Taylor
Sean Morgan
Sean Robertson
Sébastien
@@ -215,6 +228,7 @@ generous deed immortalized in the next stable release of Godot Engine.
SleepCircle
spilldata
Stoned Xander
+ Tahiti Bos
TheLevelOfDetail .
Thomas Kurz
Tobias Bocanegra
@@ -228,7 +242,9 @@ generous deed immortalized in the next stable release of Godot Engine.
## Silver donors
1D_Inc
+ Aaron
Aaron Winter
+ Abel Crunk
Abraham Haskins
Acheron
Adam
@@ -244,18 +260,15 @@ generous deed immortalized in the next stable release of Godot Engine.
Agustinus Arya
Aidan O'Flannagain
Aki Mimoto
- Alan Stice
Albin Jonasson Svärdsby
Alder Stefano
AleMax
Alessandro Senese
Alexander Erlemann
alex clavelle
- Alfred Reinold Baudisch
Allan Davis
Allen Schade
Andreas Krampitz
- Andres Hernandez
André Simões
andrew james morris
Andrew Mansuetti
@@ -267,12 +280,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Armin Preiml
Arseniy M
Arthur S. Muszynski
- Asger
Ashley Claymore
Ashton Scott Snapp
Aubrey Falconer
B A
Balázs Batári
+ Balázs Hasprai
Bartosz Bielecki
Benedikt
Ben Vercammen
@@ -299,21 +312,24 @@ generous deed immortalized in the next stable release of Godot Engine.
Christoph Woinke
Clay Heaton
Cole Johnson
+ Cuauhtemoc Moreno
Curt King
- Daniel Johnson
Daniel Kimblad
+ Daniel Johnson
+ DanielMaximiano
Daniel Tebbutt
+ Dave Walker
David May
David Woodard
Dimitri Stanojevic
- Dominic Cooney
+ Dmytro Korchynskyi
Dominik Wetzel
Donn Eddy
Dragontrapper
Dr Ewan Murray
+ Dr.Raccoon
Duobix
Duodecimal
- Dylan Todd
Eduardo Teixeira
Edward Herbert
Edward Swartz
@@ -331,11 +347,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Fancy Ants Studios
Fekinox
Felix Bohmann
- Felix Kollmann
Flaredown
+ Florian Richer
Forty Doubleu
- FuDiggity
Frank
+ FuDiggity
Gadzhi Kharkharov
gamedev by Celio
Gary Thomas
@@ -347,6 +363,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Guillaume Audirac
Guillaume Pham Ngoc
Guldoman
+ Gustavo Loureiro dos Reis
Hal A
Heribert Hirth
Hunter Jones
@@ -357,12 +374,14 @@ generous deed immortalized in the next stable release of Godot Engine.
Ivan Nikolaev
Jackson Harmer
Jacob
+ Jaguar
Jaiden Gerig
Jaime Ruiz-Borau Vizárraga
Jako Danar
James A F Manley
+ Jamiee H
+ Jamie Massey
Janders
- Jannik Gröger
JARKKO PARVIAINEN
Jean-Baptiste LEPESME
Jeff Hungerford
@@ -372,6 +391,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Joel Fivat
Joel Höglund
Joel Setterberg
+ Johannes Goslar
John Gabriel
John Walker
Jomei Jackson
@@ -385,7 +405,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Jon Sully
Jordy Goodridge
Jorge Antunes
- Jorge Caballero
Jose Aleman
Jose C. Rubio
Joseph Catrambone
@@ -396,6 +415,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Julian Murgia
June Little
JungleRobba
+ Justin Calleja
Justin Hamilton
Justin Spedding
KaDokta
@@ -405,6 +425,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Keith Bradner
Kent Jofur
Kevin McPhillips
+ Kevin Velasco
Kiri Jolly
Kjetil Haugland
Klagsam
@@ -412,10 +433,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Kuan Cheang
kycho
Kyle Appelgate
+ Kyuppin
Laurent Tréguier
- Leonard Meagher
Leonardo Dimano
- Levi Lindsey
Lin Chear
Linus Lind Lundgren
Lionel Gaillard
@@ -425,9 +445,14 @@ generous deed immortalized in the next stable release of Godot Engine.
Major Haul
Malcolm
Marco Lardelli
+ Mark Jad
+ Mark Krenz
Markus Michael Egger
+ Martin FIbik
Martin Holas
+ Martin Linklater
Martin Liška
+ Martin Trbola
Marvin
Mathieu
Matt Edwards
@@ -438,10 +463,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Megasploot
Melissa Mears
mewin
- mhilbrunner
- Michael Dürwald
Michael Haney
- Michael Labbe
Michał Skwarek
Mikael Olsson
Mikayla
@@ -470,6 +492,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Omar Delarosa
Oscar Norlander
Pan Ip
+ Parinya Teerakasemsuk
+ Patrick Dully
Patrick Nafarrete
Paul Gieske
Paul Mason
@@ -478,17 +502,20 @@ generous deed immortalized in the next stable release of Godot Engine.
Penguin
Peter
Philip Cohoe
+ Piotr Góral
Point08
pwab
Rad Cat
Rafa Laguna
+ Ram
Remi Rampin
Rémi Verschelde
+ Reneator
Ricardo Alcantara
Richard Diss
Richard Ivánek
Robert Farr (Larington)
- Robert Hernandez
+ Robert Larnach
Roger Smith
Roland Rząsa
Roman Tinkov
@@ -496,7 +523,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Ronan
Ronny Mühle
Ryan Groom
- Ryan Hentz
Sam Edson
Samuele Zolfanelli
Scott D. Yelich
@@ -534,6 +560,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Timothy B. MacDonald
Title Plinsut
Tobbun
+ Tobias Bradtke
Tom Glenn
Toni Duran
Torgeir Lilleskog
@@ -551,13 +578,15 @@ generous deed immortalized in the next stable release of Godot Engine.
Victor
Vigilant Watch
Vincent Cloutier
+ Vladimir Savin
waka nya
Wayne Haak
werner mendizabal
Wiley Thompson
Will
Wyatt Goodin
- Yegor
+ Yegor Smirnov
+ YiYin Gu
Yuri LaPointe
Yuri Sizov
Zgegnesh Hemomancer
diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp
index 5c9fb67de4..4bf31aa55f 100644
--- a/core/debugger/engine_debugger.cpp
+++ b/core/debugger/engine_debugger.cpp
@@ -169,7 +169,7 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
for (int i = 0; i < p_breakpoints.size(); i++) {
String bp = p_breakpoints[i];
- int sp = bp.find_last(":");
+ int sp = bp.rfind(":");
ERR_CONTINUE_MSG(sp == -1, "Invalid breakpoint: '" + bp + "', expected file:line format.");
singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp));
diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp
index faa3a75fda..0ce0042f50 100644
--- a/core/debugger/remote_debugger_peer.cpp
+++ b/core/debugger/remote_debugger_peer.cpp
@@ -225,7 +225,7 @@ RemoteDebuggerPeer *RemoteDebuggerPeerTCP::create(const String &p_uri) {
uint16_t debug_port = 6007;
if (debug_host.find(":") != -1) {
- int sep_pos = debug_host.find_last(":");
+ int sep_pos = debug_host.rfind(":");
debug_port = debug_host.substr(sep_pos + 1).to_int();
debug_host = debug_host.substr(0, sep_pos);
}
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index f9d2c9067c..534f3e44de 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -865,7 +865,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
bool near_match = false;
for (int i = 0; i < res_remaps.size(); i++) {
- int split = res_remaps[i].find_last(":");
+ int split = res_remaps[i].rfind(":");
if (split == -1) {
continue;
}
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 5247f6da40..7e96735d67 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -93,7 +93,7 @@ String ProjectSettings::localize_path(const String &p_path) const {
} else {
memdelete(dir);
- int sep = path.find_last("/");
+ int sep = path.rfind("/");
if (sep == -1) {
return "res://" + path;
}
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 0b44f0c056..5d3cf5f1a4 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -2280,18 +2280,6 @@ String String::substr(int p_from, int p_chars) const {
return s;
}
-int String::find_last(const String &p_str) const {
- int pos = -1;
- int findfrom = 0;
- int findres = -1;
- while ((findres = find(p_str, findfrom)) != -1) {
- pos = findres;
- findfrom = pos + 1;
- }
-
- return pos;
-}
-
int String::find(const String &p_str, int p_from) const {
if (p_from < 0) {
return -1;
@@ -2582,7 +2570,7 @@ int String::rfindn(const String &p_str, int p_from) const {
}
bool String::ends_with(const String &p_string) const {
- int pos = find_last(p_string);
+ int pos = rfind(p_string);
if (pos == -1) {
return false;
}
@@ -3831,7 +3819,7 @@ String String::get_base_dir() const {
}
}
- int sep = MAX(rs.find_last("/"), rs.find_last("\\"));
+ int sep = MAX(rs.rfind("/"), rs.rfind("\\"));
if (sep == -1) {
return base;
}
@@ -3840,7 +3828,7 @@ String String::get_base_dir() const {
}
String String::get_file() const {
- int sep = MAX(find_last("/"), find_last("\\"));
+ int sep = MAX(rfind("/"), rfind("\\"));
if (sep == -1) {
return *this;
}
@@ -3849,8 +3837,8 @@ String String::get_file() const {
}
String String::get_extension() const {
- int pos = find_last(".");
- if (pos < 0 || pos < MAX(find_last("/"), find_last("\\"))) {
+ int pos = rfind(".");
+ if (pos < 0 || pos < MAX(rfind("/"), rfind("\\"))) {
return "";
}
@@ -3938,8 +3926,8 @@ String String::property_name_encode() const {
}
String String::get_basename() const {
- int pos = find_last(".");
- if (pos < 0 || pos < MAX(find_last("/"), find_last("\\"))) {
+ int pos = rfind(".");
+ if (pos < 0 || pos < MAX(rfind("/"), rfind("\\"))) {
return *this;
}
diff --git a/core/ustring.h b/core/ustring.h
index a86849b932..e745475f11 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -202,7 +202,6 @@ public:
int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed
int find(const char *p_str, int p_from = 0) const; ///< return <0 if failed
int find_char(const CharType &p_char, int p_from = 0) const; ///< return <0 if failed
- int find_last(const String &p_str) const; ///< return <0 if failed
int findn(const String &p_str, int p_from = 0) const; ///< return <0 if failed, case insensitive
int rfind(const String &p_str, int p_from = -1) const; ///< return <0 if failed
int rfindn(const String &p_str, int p_from = -1) const; ///< return <0 if failed, case insensitive
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index a8beac1e44..308fa3c407 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -244,7 +244,6 @@ struct _VariantCall {
VCALL_LOCALMEM3R(String, countn);
VCALL_LOCALMEM2R(String, substr);
VCALL_LOCALMEM2R(String, find);
- VCALL_LOCALMEM1R(String, find_last);
VCALL_LOCALMEM2R(String, findn);
VCALL_LOCALMEM2R(String, rfind);
VCALL_LOCALMEM2R(String, rfindn);
@@ -1780,7 +1779,6 @@ void register_variant_methods() {
ADDFUNC3R(STRING, INT, String, count, STRING, "what", INT, "from", INT, "to", varray(0, 0));
ADDFUNC3R(STRING, INT, String, countn, STRING, "what", INT, "from", INT, "to", varray(0, 0));
- ADDFUNC1R(STRING, INT, String, find_last, STRING, "what", varray());
ADDFUNC2R(STRING, INT, String, findn, STRING, "what", INT, "from", varray(0));
ADDFUNC2R(STRING, INT, String, rfind, STRING, "what", INT, "from", varray(-1));
ADDFUNC2R(STRING, INT, String, rfindn, STRING, "what", INT, "from", varray(-1));
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 1fb1de2c12..d118cf8205 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -523,6 +523,15 @@
<description>
</description>
</method>
+ <method name="screen_get_max_scale" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ Return the greatest scale factor of all screens.
+ [b]Note:[/b] On macOS returned value is [code]2.0[/code] if there is at least one hiDPI (Retina) screen in the system, and [code]1.0[/code] in all other cases.
+ [b]Note:[/b] This method is implemented on macOS.
+ </description>
+ </method>
<method name="screen_get_orientation" qualifiers="const">
<return type="int" enum="DisplayServer.ScreenOrientation">
</return>
@@ -545,6 +554,9 @@
<argument index="0" name="screen" type="int" default="-1">
</argument>
<description>
+ Return the scale factor of the specified screen by index.
+ [b]Note:[/b] On macOS returned value is [code]2.0[/code] for hiDPI (Retina) screen, and [code]1.0[/code] for all other cases.
+ [b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="screen_get_size" qualifiers="const">
diff --git a/doc/classes/EditorTranslationParserPlugin.xml b/doc/classes/EditorTranslationParserPlugin.xml
index c7d796ec30..73098efd99 100644
--- a/doc/classes/EditorTranslationParserPlugin.xml
+++ b/doc/classes/EditorTranslationParserPlugin.xml
@@ -19,7 +19,7 @@
func get_recognized_extensions():
return ["csv"]
- [/codeblock]
+ [/codeblock]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 799c4d2e75..6a7a6b84f6 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -256,6 +256,9 @@
<member name="audio/output_latency" type="int" setter="" getter="" default="15">
Output latency in milliseconds for audio. Lower values will result in lower audio latency at the cost of increased CPU usage. Low values may result in audible cracking on slower hardware.
</member>
+ <member name="audio/output_latency.web" type="int" setter="" getter="" default="50">
+ Safer override for [member audio/output_latency] in the Web platform, to avoid audio issues especially on mobile devices.
+ </member>
<member name="audio/video_delay_compensation_ms" type="int" setter="" getter="" default="0">
Setting to hardcode audio delay when playing video. Best to leave this untouched unless you know what you are doing.
</member>
diff --git a/doc/classes/RayCast2D.xml b/doc/classes/RayCast2D.xml
index 51f3f0334d..4a594d3e1a 100644
--- a/doc/classes/RayCast2D.xml
+++ b/doc/classes/RayCast2D.xml
@@ -135,7 +135,7 @@
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected.
</member>
- <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="false">
+ <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
If [code]true[/code], collisions will be reported.
</member>
<member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" default="true">
diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml
index 08c6d6f40c..3512da9d77 100644
--- a/doc/classes/RayCast3D.xml
+++ b/doc/classes/RayCast3D.xml
@@ -138,7 +138,7 @@
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected.
</member>
- <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="false">
+ <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
If [code]true[/code], collisions will be reported.
</member>
<member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" default="true">
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 6d9def7ccb..78168562f1 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -332,7 +332,7 @@
<return type="String">
</return>
<description>
- Changes the case of some letters. Replaces underscores with spaces, converts all letters to lowercase, then capitalizes first and every letter following the space character. For [code]capitalize camelCase mixed_with_underscores[/code], it will return [code]Capitalize Camelcase Mixed With Underscores[/code].
+ Changes the case of some letters. Replaces underscores with spaces, adds spaces before in-word uppercase characters, converts all letters to lowercase, then capitalizes the first letter and every letter following a space character. For [code]capitalize camelCase mixed_with_underscores[/code], it will return [code]Capitalize Camel Case Mixed With Underscores[/code].
</description>
</method>
<method name="casecmp_to">
@@ -412,7 +412,8 @@
<argument index="1" name="from" type="int" default="0">
</argument>
<description>
- Finds the first occurrence of a substring. Returns the starting position of the substring or [code]-1[/code] if not found. Optionally, the initial search index can be passed.
+ Returns the index of the [b]first[/b] case-sensitive occurrence of the specified string in this instance, or [code]-1[/code]. Optionally, the starting search index can be specified, continuing to the end of the string.
+
[b]Note:[/b] If you just want to know whether a string contains a substring, use the [code]in[/code] operator as follows:
[codeblock]
# Will evaluate to `false`.
@@ -421,15 +422,6 @@
[/codeblock]
</description>
</method>
- <method name="find_last">
- <return type="int">
- </return>
- <argument index="0" name="what" type="String">
- </argument>
- <description>
- Finds the last occurrence of a substring. Returns the starting position of the substring or [code]-1[/code] if not found.
- </description>
- </method>
<method name="findn">
<return type="int">
</return>
@@ -438,7 +430,7 @@
<argument index="1" name="from" type="int" default="0">
</argument>
<description>
- Finds the first occurrence of a substring, ignoring case. Returns the starting position of the substring or [code]-1[/code] if not found. Optionally, the initial search index can be passed.
+ Returns the index of the [b]first[/b] case-insensitive occurrence of the specified string in this instance, or [code]-1[/code]. Optionally, the starting search index can be specified, continuing to the end of the string.
</description>
</method>
<method name="format">
@@ -801,7 +793,7 @@
<argument index="1" name="from" type="int" default="-1">
</argument>
<description>
- Performs a case-sensitive search for a substring, but starts from the end of the string instead of the beginning.
+ Returns the index of the [b]last[/b] case-sensitive occurrence of the specified string in this instance, or [code]-1[/code]. Optionally, the starting search index can be specified, continuing to the beginning of the string.
</description>
</method>
<method name="rfindn">
@@ -812,7 +804,7 @@
<argument index="1" name="from" type="int" default="-1">
</argument>
<description>
- Performs a case-insensitive search for a substring, but starts from the end of the string instead of the beginning.
+ Returns the index of the [b]last[/b] case-insensitive occurrence of the specified string in this instance, or [code]-1[/code]. Optionally, the starting search index can be specified, continuing to the beginning of the string.
</description>
</method>
<method name="right">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index d72d684ebc..b7b4278da0 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -335,6 +335,7 @@
</argument>
<description>
Perform selection, from line/column to line/column.
+ If [member selecting_enabled] is [code]false[/code], no selection will occur.
</description>
</method>
<method name="select_all">
@@ -342,6 +343,7 @@
</return>
<description>
Select all the text.
+ If [member selecting_enabled] is [code]false[/code], no selection will occur.
</description>
</method>
<method name="set_line">
@@ -440,8 +442,10 @@
If [code]true[/code], the line containing the cursor is highlighted.
</member>
<member name="minimap_draw" type="bool" setter="draw_minimap" getter="is_drawing_minimap" default="false">
+ If [code]true[/code], a minimap is shown, providing an outline of your source code.
</member>
<member name="minimap_width" type="int" setter="set_minimap_width" getter="get_minimap_width" default="80">
+ The width, in pixels, of the minimap.
</member>
<member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" />
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false">
@@ -457,6 +461,8 @@
The current vertical scroll value.
</member>
<member name="selecting_enabled" type="bool" setter="set_selecting_enabled" getter="is_selecting_enabled" default="true">
+ If [code]true[/code], text can be selected.
+ If [code]false[/code], text can not be selected by the user or by the [method select] or [method select_all] methods.
</member>
<member name="shortcut_keys_enabled" type="bool" setter="set_shortcut_keys_enabled" getter="is_shortcut_keys_enabled" default="true">
If [code]true[/code], shortcut keys for context menu items are enabled, even if the context menu is disabled.
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index e1a0f1f22a..c1a991fca1 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -377,9 +377,9 @@
</constant>
<constant name="CONTENT_SCALE_MODE_DISABLED" value="0" enum="ContentScaleMode">
</constant>
- <constant name="CONTENT_SCALE_MODE_OBJECTS" value="1" enum="ContentScaleMode">
+ <constant name="CONTENT_SCALE_MODE_CANVAS_ITEMS" value="1" enum="ContentScaleMode">
</constant>
- <constant name="CONTENT_SCALE_MODE_PIXELS" value="2" enum="ContentScaleMode">
+ <constant name="CONTENT_SCALE_MODE_VIEWPORT" value="2" enum="ContentScaleMode">
</constant>
<constant name="CONTENT_SCALE_ASPECT_IGNORE" value="0" enum="ContentScaleAspect">
</constant>
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index f36e84dab6..1d6770a32e 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -3557,7 +3557,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
if (track_path == np) {
value = p_value; //all good
} else {
- int sep = track_path.find_last(":");
+ int sep = track_path.rfind(":");
if (sep != -1) {
String base_path = track_path.substr(0, sep);
if (base_path == np) {
@@ -3656,7 +3656,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
value = p_value; //all good
} else {
String tpath = animation->track_get_path(i);
- int index = tpath.find_last(":");
+ int index = tpath.rfind(":");
if (NodePath(tpath.substr(0, index + 1)) == np) {
String subindex = tpath.substr(index + 1, tpath.length() - index);
value = p_value.get(subindex);
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 310de9dd90..a1bc7a9522 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -32,60 +32,38 @@
#include "core/class_db.h"
#include "core/os/keyboard.h"
-#include "core/print_string.h"
#include "editor_feature_profile.h"
-#include "editor_help.h"
#include "editor_node.h"
#include "editor_scale.h"
#include "editor_settings.h"
-#include "scene/gui/box_container.h"
void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const String &p_select_type) {
- type_list.clear();
- ClassDB::get_class_list(&type_list);
- ScriptServer::get_global_class_list(&type_list);
- type_list.sort_custom<StringName::AlphCompare>();
-
- recent->clear();
-
- FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::READ);
+ _fill_type_list();
- if (f) {
- TreeItem *root = recent->create_item();
+ icon_fallback = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object";
- String icon_fallback = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object";
-
- while (!f->eof_reached()) {
- String l = f->get_line().strip_edges();
- String name = l.split(" ")[0];
- if ((ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) && !_is_class_disabled_by_feature_profile(name)) {
- TreeItem *ti = recent->create_item(root);
- ti->set_text(0, l);
- ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(name, icon_fallback));
- }
- }
-
- memdelete(f);
+ if (p_dont_clear) {
+ search_box->select_all();
+ } else {
+ search_box->clear();
}
- favorites->clear();
-
- f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::READ);
-
- favorite_list.clear();
-
- if (f) {
- while (!f->eof_reached()) {
- String l = f->get_line().strip_edges();
+ if (p_replace_mode) {
+ search_box->set_text(p_select_type);
+ }
- if (l != String()) {
- favorite_list.push_back(l);
- }
- }
+ search_box->grab_focus();
+ _update_search();
- memdelete(f);
+ if (p_replace_mode) {
+ set_title(vformat(TTR("Change %s Type"), base_type));
+ get_ok()->set_text(TTR("Change"));
+ } else {
+ set_title(vformat(TTR("Create New %s"), base_type));
+ get_ok()->set_text(TTR("Create"));
}
+ _load_favorites_and_history();
_save_and_update_favorite_list();
// Restore valid window bounds or pop up at default size.
@@ -95,357 +73,263 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const St
} else {
popup_centered_clamped(Size2(900, 700) * EDSCALE, 0.8);
}
+}
- if (p_dont_clear) {
- search_box->select_all();
- } else {
- search_box->clear();
- }
+void CreateDialog::_fill_type_list() {
+ List<StringName> complete_type_list;
+ ClassDB::get_class_list(&complete_type_list);
+ ScriptServer::get_global_class_list(&complete_type_list);
- search_box->grab_focus();
+ EditorData &ed = EditorNode::get_editor_data();
- _update_search();
+ for (List<StringName>::Element *I = complete_type_list.front(); I; I = I->next()) {
+ String type = I->get();
+ if (!_should_hide_type(type)) {
+ type_list.push_back(type);
- is_replace_mode = p_replace_mode;
+ if (!ed.get_custom_types().has(type)) {
+ continue;
+ }
- if (p_replace_mode) {
- select_type(p_select_type);
- set_title(vformat(TTR("Change %s Type"), base_type));
- get_ok()->set_text(TTR("Change"));
- } else {
- set_title(vformat(TTR("Create New %s"), base_type));
- get_ok()->set_text(TTR("Create"));
+ const Vector<EditorData::CustomType> &ct = ed.get_custom_types()[type];
+ for (int i = 0; i < ct.size(); i++) {
+ custom_type_parents[ct[i].name] = type;
+ custom_type_indices[ct[i].name] = i;
+ type_list.push_back(ct[i].name);
+ }
+ }
}
+ type_list.sort_custom<StringName::AlphCompare>();
}
-void CreateDialog::_text_changed(const String &p_newtext) {
- _update_search();
+bool CreateDialog::_is_type_preferred(const String &p_type) const {
+ if (ClassDB::class_exists(p_type)) {
+ return ClassDB::is_parent_class(p_type, preferred_search_result_type);
+ }
+
+ return EditorNode::get_editor_data().script_class_is_parent(p_type, preferred_search_result_type);
}
-void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
- Ref<InputEventKey> k = p_ie;
- if (k.is_valid() && (k->get_keycode() == KEY_UP ||
- k->get_keycode() == KEY_DOWN ||
- k->get_keycode() == KEY_PAGEUP ||
- k->get_keycode() == KEY_PAGEDOWN)) {
- search_options->call("_gui_input", k);
- search_box->accept_event();
- }
+bool CreateDialog::_is_class_disabled_by_feature_profile(const StringName &p_class) const {
+ Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
+
+ return !profile.is_null() && profile->is_class_disabled(p_class);
}
-void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select) {
- if (p_types.has(p_type)) {
- return;
+bool CreateDialog::_should_hide_type(const String &p_type) const {
+ if (_is_class_disabled_by_feature_profile(p_type)) {
+ return true;
}
- bool cpp_type = ClassDB::class_exists(p_type);
- EditorData &ed = EditorNode::get_editor_data();
+ if (base_type == "Node" && p_type.begins_with("Editor")) {
+ return true; // Do not show editor nodes.
+ }
if (p_type == base_type) {
- return;
+ return true; // Root is already added.
}
- if (cpp_type) {
+ if (ClassDB::class_exists(p_type)) {
+ if (!ClassDB::can_instance(p_type)) {
+ return true; // Can't create abstract class.
+ }
+
if (!ClassDB::is_parent_class(p_type, base_type)) {
- return;
+ return true; // Wrong inheritance.
+ }
+
+ for (Set<StringName>::Element *E = type_blacklist.front(); E; E = E->next()) {
+ if (ClassDB::is_parent_class(p_type, E->get())) {
+ return true; // Parent type is blacklisted.
+ }
}
} else {
- if (!search_loaded_scripts.has(p_type)) {
- search_loaded_scripts[p_type] = ed.script_class_load_script(p_type);
+ if (!EditorNode::get_editor_data().script_class_is_parent(p_type, base_type)) {
+ return true; // Wrong inheritance.
}
-
- if (!ScriptServer::is_global_class(p_type) || !ed.script_class_is_parent(p_type, base_type)) {
- return;
+ if (!ScriptServer::is_global_class(p_type)) {
+ return true;
}
String script_path = ScriptServer::get_global_class_path(p_type);
- if (script_path.find("res://addons/", 0) != -1) {
+ if (script_path.begins_with("res://addons/")) {
if (!EditorNode::get_singleton()->is_addon_plugin_enabled(script_path.get_slicec('/', 3))) {
- return;
+ return true; // Plugin is not enabled.
}
}
}
- String inherits = cpp_type ? ClassDB::get_parent_class(p_type) : ed.script_class_get_base(p_type);
-
- TreeItem *parent = p_root;
+ return false;
+}
- if (inherits.length()) {
- if (!p_types.has(inherits)) {
- add_type(inherits, p_types, p_root, to_select);
- }
+void CreateDialog::_update_search() {
+ search_options->clear();
+ search_options_types.clear();
- if (p_types.has(inherits)) {
- parent = p_types[inherits];
- } else if (ScriptServer::is_global_class(inherits)) {
- return;
- }
- }
+ TreeItem *root = search_options->create_item();
+ root->set_text(0, base_type);
+ root->set_icon(0, search_options->get_theme_icon(icon_fallback, "EditorIcons"));
+ search_options_types[base_type] = root;
- bool can_instance = (cpp_type && ClassDB::can_instance(p_type)) || ScriptServer::is_global_class(p_type);
+ const String search_text = search_box->get_text();
+ bool empty_search = search_text == "";
- TreeItem *item = search_options->create_item(parent);
- if (cpp_type) {
- item->set_text(0, p_type);
- } else {
- item->set_metadata(0, p_type);
- item->set_text(0, p_type + " (" + ScriptServer::get_global_class_path(p_type).get_file() + ")");
+ // Filter all candidate results.
+ Vector<String> candidates;
+ for (List<StringName>::Element *I = type_list.front(); I; I = I->next()) {
+ if (empty_search || search_text.is_subsequence_ofi(I->get())) {
+ candidates.push_back(I->get());
+ }
}
- if (!can_instance) {
- item->set_custom_color(0, search_options->get_theme_color("disabled_font_color", "Editor"));
- item->set_selectable(0, false);
- } else if (!(*to_select && (*to_select)->get_text(0) == search_box->get_text())) {
- String search_term = search_box->get_text().to_lower();
-
- // if the node name matches exactly as the search, the node should be selected.
- // this also fixes when the user clicks on recent nodes.
- if (p_type.to_lower() == search_term) {
- *to_select = item;
- } else {
- bool current_type_prefered = _is_type_prefered(p_type);
- bool selected_type_prefered = *to_select ? _is_type_prefered((*to_select)->get_text(0).split(" ")[0]) : false;
-
- bool is_subsequence_of_type = search_box->get_text().is_subsequence_ofi(p_type);
- bool is_substring_of_type = p_type.to_lower().find(search_term) >= 0;
- bool is_substring_of_selected = false;
- bool is_subsequence_of_selected = false;
- bool is_selected_equal = false;
-
- if (*to_select) {
- String name = (*to_select)->get_text(0).split(" ")[0].to_lower();
- is_substring_of_selected = name.find(search_term) >= 0;
- is_subsequence_of_selected = search_term.is_subsequence_of(name);
- is_selected_equal = name == search_term;
- }
- if (is_subsequence_of_type && !is_selected_equal) {
- if (is_substring_of_type) {
- if (!is_substring_of_selected || (current_type_prefered && !selected_type_prefered)) {
- *to_select = item;
- }
- } else {
- // substring results weigh more than subsequences, so let's make sure we don't override them
- if (!is_substring_of_selected) {
- if (!is_subsequence_of_selected || (current_type_prefered && !selected_type_prefered)) {
- *to_select = item;
- }
- }
- }
- }
- }
+ // Build the type tree.
+ for (int i = 0; i < candidates.size(); i++) {
+ _add_type(candidates[i], ClassDB::class_exists(candidates[i]));
}
- if (bool(EditorSettings::get_singleton()->get("docks/scene_tree/start_create_dialog_fully_expanded"))) {
- item->set_collapsed(false);
+ // Select the best result.
+ if (empty_search) {
+ select_type(base_type);
+ } else if (candidates.size() > 0) {
+ select_type(_top_result(candidates, search_text));
} else {
- // don't collapse search results
- bool collapse = (search_box->get_text() == "");
- // don't collapse the root node
- collapse &= (item != p_root);
- // don't collapse abstract nodes on the first tree level
- collapse &= ((parent != p_root) || (can_instance));
- item->set_collapsed(collapse);
+ favorite->set_disabled(true);
+ help_bit->set_text("");
+ get_ok()->set_disabled(true);
+ search_options->deselect_all();
}
-
- const String &description = DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description);
- item->set_tooltip(0, description);
-
- String icon_fallback = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object";
- item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback));
-
- p_types[p_type] = item;
}
-bool CreateDialog::_is_type_prefered(const String &type) {
- bool cpp_type = ClassDB::class_exists(type);
- EditorData &ed = EditorNode::get_editor_data();
-
- if (cpp_type) {
- return ClassDB::is_parent_class(type, preferred_search_result_type);
+void CreateDialog::_add_type(const String &p_type, bool p_cpp_type) {
+ if (search_options_types.has(p_type)) {
+ return;
}
- return ed.script_class_is_parent(type, preferred_search_result_type);
-}
-bool CreateDialog::_is_class_disabled_by_feature_profile(const StringName &p_class) {
- Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
- if (profile.is_null()) {
- return false;
+ String inherits;
+ if (p_cpp_type) {
+ inherits = ClassDB::get_parent_class(p_type);
+ } else if (ScriptServer::is_global_class(p_type)) {
+ inherits = EditorNode::get_editor_data().script_class_get_base(p_type);
+ } else {
+ inherits = custom_type_parents[p_type];
}
- return profile->is_class_disabled(p_class);
+ _add_type(inherits, p_cpp_type || ClassDB::class_exists(inherits));
+
+ TreeItem *item = search_options->create_item(search_options_types[inherits]);
+ search_options_types[p_type] = item;
+ _configure_search_option_item(item, p_type, p_cpp_type);
}
-void CreateDialog::select_type(const String &p_type) {
- TreeItem *to_select;
- if (search_options_types.has(p_type)) {
- to_select = search_options_types[p_type];
+void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String &p_type, const bool p_cpp_type) {
+ bool script_type = ScriptServer::is_global_class(p_type);
+ if (p_cpp_type) {
+ r_item->set_text(0, p_type);
+ } else if (script_type) {
+ r_item->set_metadata(0, p_type);
+ r_item->set_text(0, p_type + " (" + ScriptServer::get_global_class_path(p_type).get_file() + ")");
} else {
- to_select = search_options->get_root();
+ r_item->set_metadata(0, custom_type_parents[p_type]);
+ r_item->set_text(0, p_type);
}
- // uncollapse from selected type to top level
- // TODO: should this be in tree?
- TreeItem *cur = to_select;
- while (cur) {
- cur->set_collapsed(false);
- cur = cur->get_parent();
+ bool can_instance = (p_cpp_type && ClassDB::can_instance(p_type)) || !p_cpp_type;
+ if (!can_instance) {
+ r_item->set_custom_color(0, search_options->get_theme_color("disabled_font_color", "Editor"));
+ r_item->set_selectable(0, false);
}
- to_select->select(0);
-
- search_options->scroll_to_item(to_select);
-}
-
-void CreateDialog::_update_search() {
- search_options->clear();
- favorite->set_disabled(true);
-
- help_bit->set_text("");
-
- search_options_types.clear();
-
- TreeItem *root = search_options->create_item();
- EditorData &ed = EditorNode::get_editor_data();
-
- root->set_text(0, base_type);
- String base_icon = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object";
- root->set_icon(0, search_options->get_theme_icon(base_icon, "EditorIcons"));
-
- TreeItem *to_select = search_box->get_text() == base_type ? root : nullptr;
-
- for (List<StringName>::Element *I = type_list.front(); I; I = I->next()) {
- String type = I->get();
+ if (search_box->get_text() != "") {
+ r_item->set_collapsed(false);
+ } else {
+ // Don't collapse the root node or an abstract node on the first tree level.
+ bool should_collapse = p_type != base_type && (r_item->get_parent()->get_text(0) != base_type || can_instance);
- if (_is_class_disabled_by_feature_profile(type)) {
- continue;
+ if (should_collapse && bool(EditorSettings::get_singleton()->get("docks/scene_tree/start_create_dialog_fully_expanded"))) {
+ should_collapse = false; // Collapse all nodes anyway.
}
- bool cpp_type = ClassDB::class_exists(type);
+ r_item->set_collapsed(should_collapse);
+ }
- if (base_type == "Node" && type.begins_with("Editor")) {
- continue; // do not show editor nodes
- }
+ const String &description = DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description);
+ r_item->set_tooltip(0, description);
+ r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback));
- if (cpp_type && !ClassDB::can_instance(type)) {
- continue; // can't create what can't be instanced
+ if (!p_cpp_type && !script_type) {
+ Ref<Texture2D> icon = EditorNode::get_editor_data().get_custom_types()[custom_type_parents[p_type]][custom_type_indices[p_type]].icon;
+ if (icon.is_valid()) {
+ r_item->set_icon(0, icon);
}
+ }
+}
- if (cpp_type) {
- bool skip = false;
-
- for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
- if (ClassDB::is_parent_class(type, E->get())) {
- skip = true;
- }
- }
- if (skip) {
- continue;
- }
+String CreateDialog::_top_result(const Vector<String> p_candidates, const String &p_search_text) const {
+ float highest_score = 0;
+ int highest_index = 0;
+ for (int i = 0; i < p_candidates.size(); i++) {
+ float score = _score_type(p_candidates[i].get_slicec(' ', 0), p_search_text);
+ if (score > highest_score) {
+ highest_score = score;
+ highest_index = i;
}
+ }
- if (search_box->get_text() == "") {
- add_type(type, search_options_types, root, &to_select);
- } else {
- bool found = false;
- String type2 = type;
- bool cpp_type2 = cpp_type;
-
- if (!cpp_type && !search_loaded_scripts.has(type)) {
- search_loaded_scripts[type] = ed.script_class_load_script(type);
- }
+ return p_candidates[highest_index];
+}
- while (type2 != "" && (cpp_type2 ? ClassDB::is_parent_class(type2, base_type) : ed.script_class_is_parent(type2, base_type)) && type2 != base_type) {
- if (search_box->get_text().is_subsequence_ofi(type2)) {
- found = true;
- break;
- }
+float CreateDialog::_score_type(const String &p_type, const String &p_search) const {
+ float inverse_length = 1.f / float(p_type.length());
- type2 = cpp_type2 ? ClassDB::get_parent_class(type2) : ed.script_class_get_base(type2);
- cpp_type2 = cpp_type2 || ClassDB::class_exists(type2); // Built-in class can't inherit from custom type, so we can skip the check if it's already true.
+ // Favor types where search term is a substring close to the start of the type.
+ float w = 0.5f;
+ int pos = p_type.findn(p_search);
+ float score = (pos > -1) ? 1.0f - w * MIN(1, 3 * pos * inverse_length) : MAX(0.f, .9f - w);
- if (!cpp_type2 && !search_loaded_scripts.has(type2)) {
- search_loaded_scripts[type2] = ed.script_class_load_script(type2);
- }
- }
+ // Favor shorter items: they resemble the search term more.
+ w = 0.1f;
+ score *= (1 - w) + w * (p_search.length() * inverse_length);
- if (found) {
- add_type(type, search_options_types, root, &to_select);
- }
- }
+ score *= _is_type_preferred(p_type) ? 1.0f : 0.8f;
- if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) {
- //there are custom types based on this... cool.
+ // Add score for being a favorite type.
+ score *= (favorite_list.find(p_type) > -1) ? 1.0f : 0.7f;
- const Vector<EditorData::CustomType> &ct = EditorNode::get_editor_data().get_custom_types()[type];
- for (int i = 0; i < ct.size(); i++) {
- bool show = search_box->get_text().is_subsequence_ofi(ct[i].name);
-
- if (!show) {
- continue;
- }
-
- if (!search_options_types.has(type)) {
- add_type(type, search_options_types, root, &to_select);
- }
-
- TreeItem *ti;
- if (search_options_types.has(type)) {
- ti = search_options_types[type];
- } else {
- ti = search_options->get_root();
- }
-
- TreeItem *item = search_options->create_item(ti);
- item->set_metadata(0, type);
- item->set_text(0, ct[i].name);
- item->set_icon(0, ct[i].icon.is_valid() ? ct[i].icon : search_options->get_theme_icon(base_icon, "EditorIcons"));
-
- if (!to_select || ct[i].name == search_box->get_text()) {
- to_select = item;
- }
- }
+ // Look through at most 5 recent items
+ bool in_recent = false;
+ for (int i = 0; i < MIN(5, recent->get_item_count()); i++) {
+ if (recent->get_item_text(i) == p_type) {
+ in_recent = true;
+ break;
}
}
+ score *= in_recent ? 1.0f : 0.8f;
- if (search_box->get_text() == "") {
- to_select = root;
- }
-
- if (to_select) {
- to_select->select(0);
- search_options->scroll_to_item(to_select);
- favorite->set_disabled(false);
- favorite->set_pressed(favorite_list.find(to_select->get_text(0)) != -1);
- }
+ return score;
+}
- get_ok()->set_disabled(root->get_children() == nullptr);
+void CreateDialog::_cleanup() {
+ type_list.clear();
+ favorite_list.clear();
+ favorites->clear();
+ recent->clear();
+ custom_type_parents.clear();
+ custom_type_indices.clear();
}
void CreateDialog::_confirmed() {
- TreeItem *ti = search_options->get_selected();
- if (!ti) {
+ String selected_item = get_selected_type();
+ if (selected_item == String()) {
return;
}
FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::WRITE);
-
if (f) {
- f->store_line(get_selected_type());
- TreeItem *t = recent->get_root();
- if (t) {
- t = t->get_children();
- }
- int count = 0;
- while (t) {
- if (t->get_text(0) != get_selected_type()) {
- f->store_line(t->get_text(0));
- }
+ f->store_line(selected_item);
- if (count > 32) {
- //limit it to 32 entries..
- break;
+ for (int i = 0; i < MIN(32, recent->get_item_count()); i++) {
+ if (recent->get_item_text(i) != selected_item) {
+ f->store_line(recent->get_item_text(i));
}
- t = t->get_next();
- count++;
}
memdelete(f);
@@ -453,6 +337,26 @@ void CreateDialog::_confirmed() {
emit_signal("create");
hide();
+ _cleanup();
+}
+
+void CreateDialog::_text_changed(const String &p_newtext) {
+ _update_search();
+}
+
+void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
+ Ref<InputEventKey> k = p_ie;
+ if (k.is_valid()) {
+ switch (k->get_keycode()) {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN: {
+ search_options->call("_gui_input", k);
+ search_box->accept_event();
+ } break;
+ }
+ }
}
void CreateDialog::_notification(int p_what) {
@@ -472,42 +376,36 @@ void CreateDialog::_notification(int p_what) {
search_box->select_all();
} else {
EditorSettings::get_singleton()->get_project_metadata("dialog_bounds", "create_new_node", Rect2(get_position(), get_size()));
- search_loaded_scripts.clear();
}
} break;
}
}
-void CreateDialog::set_base_type(const String &p_base) {
- base_type = p_base;
- if (is_replace_mode) {
- set_title(vformat(TTR("Change %s Type"), p_base));
- } else {
- set_title(vformat(TTR("Create New %s"), p_base));
+void CreateDialog::select_type(const String &p_type) {
+ if (!search_options_types.has(p_type)) {
+ return;
}
- _update_search();
-}
-
-String CreateDialog::get_base_type() const {
- return base_type;
-}
+ TreeItem *to_select = search_options_types[p_type];
+ to_select->select(0);
+ search_options->scroll_to_item(to_select);
-void CreateDialog::set_preferred_search_result_type(const String &p_preferred_type) {
- preferred_search_result_type = p_preferred_type;
-}
+ if (EditorHelp::get_doc_data()->class_list.has(p_type)) {
+ help_bit->set_text(DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description));
+ }
-String CreateDialog::get_preferred_search_result_type() {
- return preferred_search_result_type;
+ favorite->set_disabled(false);
+ favorite->set_pressed(favorite_list.find(p_type) != -1);
+ get_ok()->set_disabled(false);
}
String CreateDialog::get_selected_type() {
TreeItem *selected = search_options->get_selected();
- if (selected) {
- return selected->get_text(0);
- } else {
+ if (!selected) {
return String();
}
+
+ return selected->get_text(0);
}
Object *CreateDialog::instance_selected() {
@@ -518,14 +416,9 @@ Object *CreateDialog::instance_selected() {
}
Variant md = selected->get_metadata(0);
- String custom;
- if (md.get_type() != Variant::NIL) {
- custom = md;
- }
-
Object *obj = nullptr;
-
- if (!custom.empty()) {
+ if (md.get_type() != Variant::NIL) {
+ String custom = md;
if (ScriptServer::is_global_class(custom)) {
obj = EditorNode::get_editor_data().script_class_instance(custom);
Node *n = Object::cast_to<Node>(obj);
@@ -545,9 +438,10 @@ Object *CreateDialog::instance_selected() {
obj->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
- if (E->get().type == Variant::OBJECT && E->get().usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) {
- Object *prop = ClassDB::instance(E->get().class_name);
- obj->set(E->get().name, prop);
+ PropertyInfo pi = E->get();
+ if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) {
+ Object *prop = ClassDB::instance(pi.class_name);
+ obj->set(pi.name, prop);
}
}
@@ -555,29 +449,18 @@ Object *CreateDialog::instance_selected() {
}
void CreateDialog::_item_selected() {
- TreeItem *item = search_options->get_selected();
- if (!item) {
- return;
- }
-
- String name = item->get_text(0);
-
- favorite->set_disabled(false);
- favorite->set_pressed(favorite_list.find(name) != -1);
-
- if (!EditorHelp::get_doc_data()->class_list.has(name)) {
- return;
- }
-
- help_bit->set_text(DTR(EditorHelp::get_doc_data()->class_list[name].brief_description));
-
- get_ok()->set_disabled(false);
+ String name = get_selected_type();
+ select_type(name);
}
void CreateDialog::_hide_requested() {
_cancel_pressed(); // From AcceptDialog.
}
+void CreateDialog::cancel_pressed() {
+ _cleanup();
+}
+
void CreateDialog::_favorite_toggled() {
TreeItem *item = search_options->get_selected();
if (!item) {
@@ -597,50 +480,8 @@ void CreateDialog::_favorite_toggled() {
_save_and_update_favorite_list();
}
-void CreateDialog::_save_favorite_list() {
- FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::WRITE);
-
- if (f) {
- for (int i = 0; i < favorite_list.size(); i++) {
- String l = favorite_list[i];
- String name = l.split(" ")[0];
- if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name))) {
- continue;
- }
- f->store_line(l);
- }
- memdelete(f);
- }
-}
-
-void CreateDialog::_update_favorite_list() {
- favorites->clear();
-
- TreeItem *root = favorites->create_item();
-
- String icon_fallback = search_options->has_theme_icon(base_type, "EditorIcons") ? base_type : "Object";
-
- for (int i = 0; i < favorite_list.size(); i++) {
- String l = favorite_list[i];
- String name = l.split(" ")[0];
- if (!((ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) && !_is_class_disabled_by_feature_profile(name))) {
- continue;
- }
-
- TreeItem *ti = favorites->create_item(root);
- ti->set_text(0, l);
- ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(name, icon_fallback));
- }
- emit_signal("favorites_updated");
-}
-
-void CreateDialog::_history_selected() {
- TreeItem *item = recent->get_selected();
- if (!item) {
- return;
- }
-
- search_box->set_text(item->get_text(0).get_slicec(' ', 0));
+void CreateDialog::_history_selected(int p_idx) {
+ search_box->set_text(recent->get_item_text(p_idx).get_slicec(' ', 0));
favorites->deselect_all();
_update_search();
}
@@ -652,12 +493,12 @@ void CreateDialog::_favorite_selected() {
}
search_box->set_text(item->get_text(0).get_slicec(' ', 0));
- recent->deselect_all();
+ recent->unselect_all();
_update_search();
}
-void CreateDialog::_history_activated() {
- _history_selected();
+void CreateDialog::_history_activated(int p_idx) {
+ _history_selected(p_idx);
_confirmed();
}
@@ -740,8 +581,61 @@ void CreateDialog::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
}
void CreateDialog::_save_and_update_favorite_list() {
- _save_favorite_list();
- _update_favorite_list();
+ favorites->clear();
+ TreeItem *root = favorites->create_item();
+
+ FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::WRITE);
+ if (f) {
+ for (int i = 0; i < favorite_list.size(); i++) {
+ String l = favorite_list[i];
+ String name = l.get_slicec(' ', 0);
+ if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name))) {
+ continue;
+ }
+ f->store_line(l);
+
+ if (_is_class_disabled_by_feature_profile(name)) {
+ continue;
+ }
+
+ TreeItem *ti = favorites->create_item(root);
+ ti->set_text(0, l);
+ ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(name, icon_fallback));
+ }
+ memdelete(f);
+ }
+
+ emit_signal("favorites_updated");
+}
+
+void CreateDialog::_load_favorites_and_history() {
+ String dir = EditorSettings::get_singleton()->get_project_settings_dir();
+ FileAccess *f = FileAccess::open(dir.plus_file("create_recent." + base_type), FileAccess::READ);
+ if (f) {
+ while (!f->eof_reached()) {
+ String l = f->get_line().strip_edges();
+ String name = l.get_slicec(' ', 0);
+
+ if ((ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) && !_is_class_disabled_by_feature_profile(name)) {
+ recent->add_item(l, EditorNode::get_singleton()->get_class_icon(name, icon_fallback));
+ }
+ }
+
+ memdelete(f);
+ }
+
+ f = FileAccess::open(dir.plus_file("favorites." + base_type), FileAccess::READ);
+ if (f) {
+ while (!f->eof_reached()) {
+ String l = f->get_line().strip_edges();
+
+ if (l != String()) {
+ favorite_list.push_back(l);
+ }
+ }
+
+ memdelete(f);
+ }
}
void CreateDialog::_bind_methods() {
@@ -756,7 +650,11 @@ void CreateDialog::_bind_methods() {
}
CreateDialog::CreateDialog() {
- is_replace_mode = false;
+ base_type = "Object";
+ preferred_search_result_type = "";
+
+ type_blacklist.insert("PluginScript"); // PluginScript must be initialized before use, which is not possible here.
+ type_blacklist.insert("ScriptCreateDialog"); // This is an exposed editor Node that doesn't have an Editor prefix.
HSplitContainer *hsc = memnew(HSplitContainer);
add_child(hsc);
@@ -765,67 +663,64 @@ CreateDialog::CreateDialog() {
hsc->add_child(vsc);
VBoxContainer *fav_vb = memnew(VBoxContainer);
- vsc->add_child(fav_vb);
fav_vb->set_custom_minimum_size(Size2(150, 100) * EDSCALE);
fav_vb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ vsc->add_child(fav_vb);
favorites = memnew(Tree);
- fav_vb->add_margin_child(TTR("Favorites:"), favorites, true);
favorites->set_hide_root(true);
favorites->set_hide_folding(true);
favorites->set_allow_reselect(true);
favorites->connect("cell_selected", callable_mp(this, &CreateDialog::_favorite_selected));
favorites->connect("item_activated", callable_mp(this, &CreateDialog::_favorite_activated));
+ favorites->add_theme_constant_override("draw_guides", 1);
#ifndef _MSC_VER
#warning cant forward drag data to a non control, must be fixed
#endif
//favorites->set_drag_forwarding(this);
- favorites->add_theme_constant_override("draw_guides", 1);
+ fav_vb->add_margin_child(TTR("Favorites:"), favorites, true);
VBoxContainer *rec_vb = memnew(VBoxContainer);
vsc->add_child(rec_vb);
rec_vb->set_custom_minimum_size(Size2(150, 100) * EDSCALE);
rec_vb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- recent = memnew(Tree);
+ recent = memnew(ItemList);
rec_vb->add_margin_child(TTR("Recent:"), recent, true);
- recent->set_hide_root(true);
- recent->set_hide_folding(true);
recent->set_allow_reselect(true);
- recent->connect("cell_selected", callable_mp(this, &CreateDialog::_history_selected));
+ recent->connect("item_selected", callable_mp(this, &CreateDialog::_history_selected));
recent->connect("item_activated", callable_mp(this, &CreateDialog::_history_activated));
recent->add_theme_constant_override("draw_guides", 1);
VBoxContainer *vbc = memnew(VBoxContainer);
- hsc->add_child(vbc);
vbc->set_custom_minimum_size(Size2(300, 0) * EDSCALE);
vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- HBoxContainer *search_hb = memnew(HBoxContainer);
+ hsc->add_child(vbc);
+
search_box = memnew(LineEdit);
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ search_box->connect("text_changed", callable_mp(this, &CreateDialog::_text_changed));
+ search_box->connect("gui_input", callable_mp(this, &CreateDialog::_sbox_input));
+
+ HBoxContainer *search_hb = memnew(HBoxContainer);
search_hb->add_child(search_box);
+
favorite = memnew(Button);
favorite->set_flat(true);
favorite->set_toggle_mode(true);
- search_hb->add_child(favorite);
favorite->connect("pressed", callable_mp(this, &CreateDialog::_favorite_toggled));
+ search_hb->add_child(favorite);
vbc->add_margin_child(TTR("Search:"), search_hb);
- search_box->connect("text_changed", callable_mp(this, &CreateDialog::_text_changed));
- search_box->connect("gui_input", callable_mp(this, &CreateDialog::_sbox_input));
+
search_options = memnew(Tree);
- vbc->add_margin_child(TTR("Matches:"), search_options, true);
- get_ok()->set_disabled(true);
- register_text_enter(search_box);
- set_hide_on_ok(false);
search_options->connect("item_activated", callable_mp(this, &CreateDialog::_confirmed));
search_options->connect("cell_selected", callable_mp(this, &CreateDialog::_item_selected));
- base_type = "Object";
- preferred_search_result_type = "";
+ vbc->add_margin_child(TTR("Matches:"), search_options, true);
help_bit = memnew(EditorHelpBit);
- vbc->add_margin_child(TTR("Description:"), help_bit);
help_bit->connect("request_hide", callable_mp(this, &CreateDialog::_hide_requested));
+ vbc->add_margin_child(TTR("Description:"), help_bit);
- type_blacklist.insert("PluginScript"); // PluginScript must be initialized before use, which is not possible here
- type_blacklist.insert("ScriptCreateDialog"); // This is an exposed editor Node that doesn't have an Editor prefix.
+ register_text_enter(search_box);
+ set_hide_on_ok(false);
}
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index cdc91ae535..52eb9945af 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -35,60 +35,65 @@
#include "scene/gui/button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/item_list.h"
-#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/tree.h"
class CreateDialog : public ConfirmationDialog {
GDCLASS(CreateDialog, ConfirmationDialog);
- Vector<String> favorite_list;
- Tree *favorites;
- Tree *recent;
-
- Button *favorite;
LineEdit *search_box;
Tree *search_options;
- HashMap<String, TreeItem *> search_options_types;
- HashMap<String, RES> search_loaded_scripts;
- bool is_replace_mode;
+
String base_type;
+ String icon_fallback;
String preferred_search_result_type;
+
+ Button *favorite;
+ Vector<String> favorite_list;
+ Tree *favorites;
+ ItemList *recent;
EditorHelpBit *help_bit;
+
+ HashMap<String, TreeItem *> search_options_types;
+ HashMap<String, String> custom_type_parents;
+ HashMap<String, int> custom_type_indices;
List<StringName> type_list;
Set<StringName> type_blacklist;
- void _item_selected();
- void _hide_requested();
-
void _update_search();
- void _update_favorite_list();
- void _save_favorite_list();
- void _favorite_toggled();
+ bool _should_hide_type(const String &p_type) const;
+ void _add_type(const String &p_current, bool p_cpp_type);
+ void _configure_search_option_item(TreeItem *r_item, const String &p_type, const bool p_cpp_type);
+ String _top_result(const Vector<String> p_candidates, const String &p_search_text) const;
+ float _score_type(const String &p_type, const String &p_search) const;
+ bool _is_type_preferred(const String &p_type) const;
- void _history_selected();
- void _favorite_selected();
-
- void _history_activated();
- void _favorite_activated();
+ void _fill_type_list();
+ void _cleanup();
void _sbox_input(const Ref<InputEvent> &p_ie);
+ void _text_changed(const String &p_newtext);
+ void select_type(const String &p_type);
+ void _item_selected();
+ void _hide_requested();
void _confirmed();
- void _text_changed(const String &p_newtext);
+ virtual void cancel_pressed();
- Ref<Texture2D> _get_editor_icon(const String &p_type) const;
+ void _favorite_toggled();
- void add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select);
+ void _history_selected(int p_idx);
+ void _favorite_selected();
- void select_type(const String &p_type);
+ void _history_activated(int p_idx);
+ void _favorite_activated();
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
- bool _is_class_disabled_by_feature_profile(const StringName &p_class);
- bool _is_type_prefered(const String &type);
+ bool _is_class_disabled_by_feature_profile(const StringName &p_class) const;
+ void _load_favorites_and_history();
protected:
void _notification(int p_what);
@@ -100,11 +105,11 @@ public:
Object *instance_selected();
String get_selected_type();
- void set_base_type(const String &p_base);
- String get_base_type() const;
+ void set_base_type(const String &p_base) { base_type = p_base; }
+ String get_base_type() const { return base_type; }
- void set_preferred_search_result_type(const String &p_preferred_type);
- String get_preferred_search_result_type();
+ void set_preferred_search_result_type(const String &p_preferred_type) { preferred_search_result_type = p_preferred_type; }
+ String get_preferred_search_result_type() { return preferred_search_result_type; }
void popup_create(bool p_dont_clear, bool p_replace_mode = false, const String &p_select_type = "Node");
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index b43ee0e245..edb299bb90 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -159,7 +159,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
isdir = true;
}
- int pp = path.find_last("/");
+ int pp = path.rfind("/");
TreeItem *parent;
if (pp == -1) {
diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp
index 2a410c03e7..0d349eb247 100644
--- a/editor/editor_feature_profile.cpp
+++ b/editor/editor_feature_profile.cpp
@@ -335,7 +335,7 @@ void EditorFeatureProfileManager::_update_profile_list(const String &p_select_pr
}
if (!d->current_is_dir()) {
- int last_pos = f.find_last(".profile");
+ int last_pos = f.rfind(".profile");
if (last_pos != -1) {
profiles.push_back(f.substr(0, last_pos));
}
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 663f3dd856..50be291c91 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -55,7 +55,7 @@ VBoxContainer *EditorFileDialog::get_vbox() {
}
void EditorFileDialog::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
+ if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_THEME_CHANGED) {
// update icons
mode_thumbnails->set_icon(item_list->get_theme_icon("FileThumbnail", "EditorIcons"));
mode_list->set_icon(item_list->get_theme_icon("FileList", "EditorIcons"));
@@ -936,7 +936,7 @@ void EditorFileDialog::set_current_file(const String &p_file) {
file->set_text(p_file);
update_dir();
invalidate();
- int lp = p_file.find_last(".");
+ int lp = p_file.rfind(".");
if (lp != -1) {
file->select(0, lp);
file->grab_focus();
@@ -951,7 +951,7 @@ void EditorFileDialog::set_current_path(const String &p_path) {
if (!p_path.size()) {
return;
}
- int pos = MAX(p_path.find_last("/"), p_path.find_last("\\"));
+ int pos = MAX(p_path.rfind("/"), p_path.rfind("\\"));
if (pos == -1) {
set_current_file(p_path);
} else {
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 9ca3d387d9..e367ed4989 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1107,7 +1107,7 @@ void EditorFileSystem::_notification(int p_what) {
_queue_update_script_classes();
first_scan = false;
}
- } else if (!scanning) {
+ } else if (!scanning && thread) {
set_process(false);
if (filesystem) {
diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp
index f0e6e3a799..a7e76e9b2b 100644
--- a/editor/editor_folding.cpp
+++ b/editor/editor_folding.cpp
@@ -251,7 +251,7 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) {
}
}
} else { //path
- int last = E->get().name.find_last("/");
+ int last = E->get().name.rfind("/");
if (last != -1) {
bool can_revert = EditorPropertyRevert::can_property_revert(p_object, E->get().name);
if (can_revert) {
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index cf00c536a7..100c76c32b 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -231,7 +231,7 @@ void editor_register_fonts(Ref<Theme> p_theme) {
// Default font
MAKE_DEFAULT_FONT(df, default_font_size);
- p_theme->set_font("font", "Node", df); // Default theme font
+ p_theme->set_default_font(df); // Default theme font
p_theme->set_font("main", "EditorFonts", df);
// Bold font
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index cc58a0d5a0..7742382048 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -1664,7 +1664,7 @@ void EditorInspector::update_tree() {
basename = group + "/" + basename;
}
- String name = (basename.find("/") != -1) ? basename.right(basename.find_last("/") + 1) : basename;
+ String name = (basename.find("/") != -1) ? basename.right(basename.rfind("/") + 1) : basename;
if (capitalize_paths) {
int dot = name.find(".");
@@ -1679,7 +1679,7 @@ void EditorInspector::update_tree() {
}
}
- String path = basename.left(basename.find_last("/"));
+ String path = basename.left(basename.rfind("/"));
if (use_filter && filter != "") {
String cat = path;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 6e65103748..a4a53d8a92 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5520,10 +5520,10 @@ EditorNode::EditorNode() {
switch (display_scale) {
case 0: {
// Try applying a suitable display scale automatically
- const int screen = DisplayServer::get_singleton()->window_get_current_screen();
#ifdef OSX_ENABLED
- editor_set_scale(DisplayServer::get_singleton()->screen_get_scale(screen));
+ editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale());
#else
+ const int screen = DisplayServer::get_singleton()->window_get_current_screen();
editor_set_scale(DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).x > 2000 ? 2.0 : 1.0);
#endif
} break;
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 1148a6c7ec..6a73e6c072 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -108,24 +108,33 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
}
int window_placement = EditorSettings::get_singleton()->get("run/window_placement/rect");
+ bool hidpi_proj = ProjectSettings::get_singleton()->get("display/window/dpi/allow_hidpi");
+ int display_scale = 1;
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_HIDPI)) {
+ if (OS::get_singleton()->is_hidpi_allowed()) {
+ if (hidpi_proj) {
+ display_scale = 1; // Both editor and project runs in hiDPI mode, do not scale.
+ } else {
+ display_scale = DisplayServer::get_singleton()->screen_get_max_scale(); // Editor is in hiDPI mode, project is not, scale down.
+ }
+ } else {
+ if (hidpi_proj) {
+ display_scale = (1.f / DisplayServer::get_singleton()->screen_get_max_scale()); // Editor is not in hiDPI mode, project is, scale up.
+ } else {
+ display_scale = 1; // Both editor and project runs in lowDPI mode, do not scale.
+ }
+ }
+ screen_rect.position /= display_scale;
+ screen_rect.size /= display_scale;
+ }
switch (window_placement) {
case 0: { // top left
-
args.push_back("--position");
args.push_back(itos(screen_rect.position.x) + "," + itos(screen_rect.position.y));
} break;
case 1: { // centered
- int display_scale = 1;
-#ifdef OSX_ENABLED
- display_scale = DisplayServer::get_singleton()->screen_get_scale(screen);
-#else
- if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).x > 2000) {
- display_scale = 2;
- }
-#endif
-
- Vector2 pos = screen_rect.position + ((screen_rect.size / display_scale - desired_size) / 2).floor();
+ Vector2 pos = (screen_rect.position) + ((screen_rect.size - desired_size) / 2).floor();
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
} break;
@@ -140,10 +149,8 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
args.push_back("--maximized");
-
} break;
case 4: { // force fullscreen
-
Vector2 pos = screen_rect.position;
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 133aa39cd3..4f37fcf39c 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1688,7 +1688,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
String name = to_rename.path.get_file();
rename_dialog->set_title(TTR("Renaming file:") + " " + name);
rename_dialog_text->set_text(name);
- rename_dialog_text->select(0, name.find_last("."));
+ rename_dialog_text->select(0, name.rfind("."));
} else {
String name = to_rename.path.substr(0, to_rename.path.length() - 1).get_file();
rename_dialog->set_title(TTR("Renaming folder:") + " " + name);
@@ -1732,7 +1732,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
String name = to_duplicate.path.get_file();
duplicate_dialog->set_title(TTR("Duplicating file:") + " " + name);
duplicate_dialog_text->set_text(name);
- duplicate_dialog_text->select(0, name.find_last("."));
+ duplicate_dialog_text->select(0, name.rfind("."));
} else {
String name = to_duplicate.path.substr(0, to_duplicate.path.length() - 1).get_file();
duplicate_dialog->set_title(TTR("Duplicating folder:") + " " + name);
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 035526ca55..de04a299fb 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -702,30 +702,26 @@ void AnimationPlayerEditor::_animation_edit() {
}
}
-void AnimationPlayerEditor::_dialog_action(String p_file) {
+void AnimationPlayerEditor::_dialog_action(String p_path) {
switch (current_option) {
case RESOURCE_LOAD: {
ERR_FAIL_COND(!player);
- Ref<Resource> res = ResourceLoader::load(p_file, "Animation");
- ERR_FAIL_COND_MSG(res.is_null(), "Cannot load Animation from file '" + p_file + "'.");
- ERR_FAIL_COND_MSG(!res->is_class("Animation"), "Loaded resource from file '" + p_file + "' is not Animation.");
- if (p_file.find_last("/") != -1) {
- p_file = p_file.substr(p_file.find_last("/") + 1, p_file.length());
- }
- if (p_file.find_last("\\") != -1) {
- p_file = p_file.substr(p_file.find_last("\\") + 1, p_file.length());
- }
+ Ref<Resource> res = ResourceLoader::load(p_path, "Animation");
+ ERR_FAIL_COND_MSG(res.is_null(), "Cannot load Animation from file '" + p_path + "'.");
+ ERR_FAIL_COND_MSG(!res->is_class("Animation"), "Loaded resource from file '" + p_path + "' is not Animation.");
- if (p_file.find(".") != -1) {
- p_file = p_file.substr(0, p_file.find("."));
+ String anim_name = p_path.get_file();
+ int ext_pos = anim_name.rfind(".");
+ if (ext_pos != -1) {
+ anim_name = anim_name.substr(0, ext_pos);
}
undo_redo->create_action(TTR("Load Animation"));
- undo_redo->add_do_method(player, "add_animation", p_file, res);
- undo_redo->add_undo_method(player, "remove_animation", p_file);
- if (player->has_animation(p_file)) {
- undo_redo->add_undo_method(player, "add_animation", p_file, player->get_animation(p_file));
+ undo_redo->add_do_method(player, "add_animation", anim_name, res);
+ undo_redo->add_undo_method(player, "remove_animation", anim_name);
+ if (player->has_animation(anim_name)) {
+ undo_redo->add_undo_method(player, "add_animation", anim_name, player->get_animation(anim_name));
}
undo_redo->add_do_method(this, "_animation_player_changed", player);
undo_redo->add_undo_method(this, "_animation_player_changed", player);
@@ -741,7 +737,7 @@ void AnimationPlayerEditor::_dialog_action(String p_file) {
RES current_res = RES(Object::cast_to<Resource>(*anim));
- _animation_save_in_path(current_res, p_file);
+ _animation_save_in_path(current_res, p_path);
}
}
}
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 596629f8e8..105ac24950 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -242,9 +242,11 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
} break;
case CONCAVE_POLYGON_SHAPE: {
+ // Cannot be edited directly, use CollisionPolygon2D instead.
} break;
case CONVEX_POLYGON_SHAPE: {
+ // Cannot be edited directly, use CollisionPolygon2D instead.
} break;
case LINE_SHAPE: {
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 633863041f..dd1194d020 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -728,35 +728,37 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
bone_painting_bone = bone_selected;
}
}
+ } else {
+ if (uv_drag && !uv_create) {
+ if (uv_edit_mode[0]->is_pressed()) { // Edit UV.
+ undo_redo->create_action(TTR("Transform UV Map"));
+ undo_redo->add_do_method(node, "set_uv", node->get_uv());
+ undo_redo->add_undo_method(node, "set_uv", points_prev);
+ undo_redo->add_do_method(uv_edit_draw, "update");
+ undo_redo->add_undo_method(uv_edit_draw, "update");
+ undo_redo->commit_action();
+ } else if (uv_edit_mode[1]->is_pressed() && uv_move_current == UV_MODE_EDIT_POINT) { // Edit polygon.
+ undo_redo->create_action(TTR("Transform Polygon"));
+ undo_redo->add_do_method(node, "set_polygon", node->get_polygon());
+ undo_redo->add_undo_method(node, "set_polygon", points_prev);
+ undo_redo->add_do_method(uv_edit_draw, "update");
+ undo_redo->add_undo_method(uv_edit_draw, "update");
+ undo_redo->commit_action();
+ }
- } else if (uv_drag && !uv_create) {
- if (uv_edit_mode[0]->is_pressed()) { // Edit UV.
- undo_redo->create_action(TTR("Transform UV Map"));
- undo_redo->add_do_method(node, "set_uv", node->get_uv());
- undo_redo->add_undo_method(node, "set_uv", points_prev);
- undo_redo->add_do_method(uv_edit_draw, "update");
- undo_redo->add_undo_method(uv_edit_draw, "update");
- undo_redo->commit_action();
- } else if (uv_edit_mode[1]->is_pressed() && uv_move_current == UV_MODE_EDIT_POINT) { // Edit polygon.
- undo_redo->create_action(TTR("Transform Polygon"));
- undo_redo->add_do_method(node, "set_polygon", node->get_polygon());
- undo_redo->add_undo_method(node, "set_polygon", points_prev);
+ uv_drag = false;
+ }
+
+ if (bone_painting) {
+ undo_redo->create_action(TTR("Paint Bone Weights"));
+ undo_redo->add_do_method(node, "set_bone_weights", bone_painting_bone, node->get_bone_weights(bone_painting_bone));
+ undo_redo->add_undo_method(node, "set_bone_weights", bone_painting_bone, prev_weights);
undo_redo->add_do_method(uv_edit_draw, "update");
undo_redo->add_undo_method(uv_edit_draw, "update");
undo_redo->commit_action();
+ bone_painting = false;
}
-
- uv_drag = false;
- } else if (bone_painting) {
- undo_redo->create_action(TTR("Paint Bone Weights"));
- undo_redo->add_do_method(node, "set_bone_weights", bone_painting_bone, node->get_bone_weights(bone_painting_bone));
- undo_redo->add_undo_method(node, "set_bone_weights", bone_painting_bone, prev_weights);
- undo_redo->add_do_method(uv_edit_draw, "update");
- undo_redo->add_undo_method(uv_edit_draw, "update");
- undo_redo->commit_action();
- bone_painting = false;
}
-
} else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
_cancel_editing();
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 89ab747cde..13d8f0c856 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -2450,6 +2450,7 @@ VisualShaderEditor::VisualShaderEditor() {
members_dialog = memnew(ConfirmationDialog);
members_dialog->set_title(TTR("Create Shader Node"));
+ members_dialog->set_exclusive(false);
members_dialog->add_child(members_vb);
members_dialog->get_ok()->set_text(TTR("Create"));
members_dialog->get_ok()->connect("pressed", callable_mp(this, &VisualShaderEditor::_member_create));
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index a800f9e8eb..5184793760 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -294,7 +294,7 @@ private:
// If the project name is empty or default, infer the project name from the selected folder name
if (project_name->get_text() == "" || project_name->get_text() == TTR("New Game Project")) {
sp = sp.replace("\\", "/");
- int lidx = sp.find_last("/");
+ int lidx = sp.rfind("/");
if (lidx != -1) {
sp = sp.substr(lidx + 1, sp.length()).capitalize();
@@ -2336,10 +2336,10 @@ ProjectManager::ProjectManager() {
switch (display_scale) {
case 0: {
// Try applying a suitable display scale automatically
- const int screen = DisplayServer::get_singleton()->window_get_current_screen();
#ifdef OSX_ENABLED
- editor_set_scale(DisplayServer::get_singleton()->screen_get_scale(screen));
+ editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale());
#else
+ const int screen = DisplayServer::get_singleton()->window_get_current_screen();
editor_set_scale(DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).x > 2000 ? 2.0 : 1.0);
#endif
} break;
@@ -2371,11 +2371,8 @@ ProjectManager::ProjectManager() {
// Define a minimum window size to prevent UI elements from overlapping or being cut off
DisplayServer::get_singleton()->window_set_min_size(Size2(750, 420) * EDSCALE);
-#ifndef OSX_ENABLED
- // The macOS platform implementation uses its own hiDPI window resizing code
// TODO: Resize windows on hiDPI displays on Windows and Linux and remove the line below
DisplayServer::get_singleton()->window_set_size(DisplayServer::get_singleton()->window_get_size() * MAX(1, EDSCALE));
-#endif
}
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 389b53133e..f84845179b 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -1737,7 +1737,7 @@ void ProjectSettingsEditor::_update_translations() {
PackedStringArray selected = remaps[keys[i]];
for (int j = 0; j < selected.size(); j++) {
String s2 = selected[j];
- int qp = s2.find_last(":");
+ int qp = s2.rfind(":");
String path = s2.substr(0, qp);
String locale = s2.substr(qp + 1, s2.length());
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index ae5229b628..40e0582046 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -78,7 +78,7 @@ void ScriptCreateDialog::_notification(int p_what) {
void ScriptCreateDialog::_path_hbox_sorted() {
if (is_visible()) {
- int filename_start_pos = initial_bp.find_last("/") + 1;
+ int filename_start_pos = initial_bp.rfind("/") + 1;
int filename_end_pos = initial_bp.length();
if (!is_built_in) {
@@ -553,7 +553,7 @@ void ScriptCreateDialog::_file_selected(const String &p_file) {
_path_changed(p);
String filename = p.get_file().get_basename();
- int select_start = p.find_last(filename);
+ int select_start = p.rfind(filename);
file_path->select(select_start, select_start + filename.length());
file_path->set_cursor_position(select_start + filename.length());
file_path->grab_focus();
diff --git a/main/main.cpp b/main/main.cpp
index 96b71c1663..608b4a7c4d 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -780,7 +780,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get().ends_with("project.godot")) {
String path;
String file = I->get();
- int sep = MAX(file.find_last("/"), file.find_last("\\"));
+ int sep = MAX(file.rfind("/"), file.rfind("\\"));
if (sep == -1) {
path = ".";
} else {
@@ -1992,7 +1992,7 @@ bool Main::start() {
local_game_path = "res://" + local_game_path;
} else {
- int sep = local_game_path.find_last("/");
+ int sep = local_game_path.rfind("/");
if (sep == -1) {
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp
index 5a14492be5..73d59b0088 100644
--- a/main/tests/test_string.cpp
+++ b/main/tests/test_string.cpp
@@ -370,8 +370,11 @@ bool test_22() {
static const int num[4] = { 1237461283, -22, 0, -1123412 };
for (int i = 0; i < 4; i++) {
+#ifdef __MINGW32__ // MinGW can't handle normal format specifiers for some reason. So we need special code just for MinGW.
+ OS::get_singleton()->print("\tString: \"%s\" as Int is %I64i\n", nums[i], (long long)(String(nums[i]).to_int()));
+#else
OS::get_singleton()->print("\tString: \"%s\" as Int is %lli\n", nums[i], (long long)(String(nums[i]).to_int()));
-
+#endif
if (String(nums[i]).to_int() != num[i]) {
return false;
}
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index f89f647aca..8b0c7474e8 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -277,13 +277,6 @@ godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string
return self->findn(*what, p_from);
}
-godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what) {
- const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
-
- return self->find_last(*what);
-}
-
godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values) {
const String *self = (const String *)p_self;
const Variant *values = (const Variant *)p_values;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index ccd8d2041c..1284ebbd66 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -3825,14 +3825,6 @@
]
},
{
- "name": "godot_string_find_last",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
- ]
- },
- {
"name": "godot_string_format",
"return_type": "godot_string",
"arguments": [
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index 608978db76..dfd4fcab89 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -111,7 +111,6 @@ godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot
godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key);
godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what);
godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from);
-godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what);
godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values);
godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder);
godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len);
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index a213069e19..79220da7c2 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -43,27 +43,19 @@
<method name="get_cell_item" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="x" type="int">
- </argument>
- <argument index="1" name="y" type="int">
- </argument>
- <argument index="2" name="z" type="int">
+ <argument index="0" name="position" type="Vector3i">
</argument>
<description>
- The [MeshLibrary] item index located at the grid-based X, Y and Z coordinates. If the cell is empty, [constant INVALID_CELL_ITEM] will be returned.
+ The [MeshLibrary] item index located at the given grid coordinates. If the cell is empty, [constant INVALID_CELL_ITEM] will be returned.
</description>
</method>
<method name="get_cell_item_orientation" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="x" type="int">
- </argument>
- <argument index="1" name="y" type="int">
- </argument>
- <argument index="2" name="z" type="int">
+ <argument index="0" name="position" type="Vector3i">
</argument>
<description>
- The orientation of the cell at the grid-based X, Y and Z coordinates. -1 is returned if the cell is empty.
+ The orientation of the cell at the given grid coordinates. [code]-1[/code] is returned if the cell is empty.
</description>
</method>
<method name="get_collision_layer_bit" qualifiers="const">
@@ -111,11 +103,7 @@
<method name="map_to_world" qualifiers="const">
<return type="Vector3">
</return>
- <argument index="0" name="x" type="int">
- </argument>
- <argument index="1" name="y" type="int">
- </argument>
- <argument index="2" name="z" type="int">
+ <argument index="0" name="map_position" type="Vector3i">
</argument>
<description>
Returns the position of a grid cell in the GridMap's local coordinate space.
@@ -132,18 +120,14 @@
<method name="set_cell_item">
<return type="void">
</return>
- <argument index="0" name="x" type="int">
- </argument>
- <argument index="1" name="y" type="int">
+ <argument index="0" name="position" type="Vector3i">
</argument>
- <argument index="2" name="z" type="int">
+ <argument index="1" name="item" type="int">
</argument>
- <argument index="3" name="item" type="int">
- </argument>
- <argument index="4" name="orientation" type="int" default="0">
+ <argument index="2" name="orientation" type="int" default="0">
</argument>
<description>
- Sets the mesh index for the cell referenced by its grid-based X, Y and Z coordinates.
+ Sets the mesh index for the cell referenced by its grid coordinates.
A negative item index such as [constant INVALID_CELL_ITEM] will clear the cell.
Optionally, the item's orientation can be passed. For valid orientation values, see [method Basis.get_orthogonal_index].
</description>
@@ -185,9 +169,9 @@
</description>
</method>
<method name="world_to_map" qualifiers="const">
- <return type="Vector3">
+ <return type="Vector3i">
</return>
- <argument index="0" name="pos" type="Vector3">
+ <argument index="0" name="world_position" type="Vector3">
</argument>
<description>
Returns the coordinates of the grid cell containing the given point.
diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp
index 39e3a95afa..d7b2028204 100644
--- a/modules/mono/class_db_api_json.cpp
+++ b/modules/mono/class_db_api_json.cpp
@@ -53,8 +53,9 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
ClassDB::ClassInfo *t = ClassDB::classes.getptr(E->get());
ERR_FAIL_COND(!t);
- if (t->api != p_api || !t->exposed)
+ if (t->api != p_api || !t->exposed) {
continue;
+ }
Dictionary class_dict;
classes_dict[t->name] = class_dict;
@@ -72,8 +73,9 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
ERR_CONTINUE(name.empty());
- if (name[0] == '_')
+ if (name[0] == '_') {
continue; // Ignore non-virtual methods that start with an underscore
+ }
snames.push_back(*k);
}
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index ae25bd3544..22e4d84e98 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -125,8 +125,9 @@ void CSharpLanguage::init() {
print_line("Run this binary with '--generate-mono-glue path/to/modules/mono/glue'");
#endif
- if (gdmono->is_runtime_initialized())
+ if (gdmono->is_runtime_initialized()) {
gdmono->initialize_load_assemblies();
+ }
#ifdef TOOLS_ENABLED
EditorNode::add_init_callback(&_editor_init_callback);
@@ -134,8 +135,13 @@ void CSharpLanguage::init() {
}
void CSharpLanguage::finish() {
- if (finalized)
+ finalize();
+}
+
+void CSharpLanguage::finalize() {
+ if (finalized) {
return;
+ }
finalizing = true;
@@ -390,15 +396,17 @@ bool CSharpLanguage::supports_builtin_mode() const {
#ifdef TOOLS_ENABLED
static String variant_type_to_managed_name(const String &p_var_type_name) {
- if (p_var_type_name.empty())
+ if (p_var_type_name.empty()) {
return "object";
+ }
if (!ClassDB::class_exists(p_var_type_name)) {
return p_var_type_name;
}
- if (p_var_type_name == Variant::get_type_name(Variant::OBJECT))
+ if (p_var_type_name == Variant::get_type_name(Variant::OBJECT)) {
return "Godot.Object";
+ }
if (p_var_type_name == Variant::get_type_name(Variant::FLOAT)) {
#ifdef REAL_T_IS_DOUBLE
@@ -408,36 +416,49 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
#endif
}
- if (p_var_type_name == Variant::get_type_name(Variant::STRING))
+ if (p_var_type_name == Variant::get_type_name(Variant::STRING)) {
return "string"; // I prefer this one >:[
+ }
- if (p_var_type_name == Variant::get_type_name(Variant::DICTIONARY))
+ if (p_var_type_name == Variant::get_type_name(Variant::DICTIONARY)) {
return "Collections.Dictionary";
+ }
- if (p_var_type_name == Variant::get_type_name(Variant::ARRAY))
+ if (p_var_type_name == Variant::get_type_name(Variant::ARRAY)) {
return "Collections.Array";
+ }
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_BYTE_ARRAY))
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_BYTE_ARRAY)) {
return "byte[]";
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY))
+ }
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY)) {
return "int[]";
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY))
+ }
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY)) {
return "long[]";
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY))
+ }
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY)) {
return "float[]";
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY))
+ }
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY)) {
return "double[]";
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY))
+ }
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY)) {
return "string[]";
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY))
+ }
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY)) {
return "Vector2[]";
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR3_ARRAY))
+ }
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR3_ARRAY)) {
return "Vector3[]";
- if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY))
+ }
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY)) {
return "Color[]";
+ }
- if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL))
+ if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL)) {
return "SignalInfo";
+ }
Variant::Type var_types[] = {
Variant::BOOL,
@@ -462,8 +483,9 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
};
for (unsigned int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) {
- if (p_var_type_name == Variant::get_type_name(var_types[i]))
+ if (p_var_type_name == Variant::get_type_name(var_types[i])) {
return p_var_type_name;
+ }
}
return "object";
@@ -477,8 +499,9 @@ String CSharpLanguage::make_function(const String &, const String &p_name, const
for (int i = 0; i < p_args.size(); i++) {
const String &arg = p_args[i];
- if (i > 0)
+ if (i > 0) {
s += ", ";
+ }
s += variant_type_to_managed_name(arg.get_slice(":", 1)) + " " + escape_csharp_keyword(arg.get_slice(":", 0));
}
@@ -516,32 +539,36 @@ String CSharpLanguage::debug_get_error() const {
}
int CSharpLanguage::debug_get_stack_level_count() const {
- if (_debug_parse_err_line >= 0)
+ if (_debug_parse_err_line >= 0) {
return 1;
+ }
// TODO: StackTrace
return 1;
}
int CSharpLanguage::debug_get_stack_level_line(int p_level) const {
- if (_debug_parse_err_line >= 0)
+ if (_debug_parse_err_line >= 0) {
return _debug_parse_err_line;
+ }
// TODO: StackTrace
return 1;
}
String CSharpLanguage::debug_get_stack_level_function(int p_level) const {
- if (_debug_parse_err_line >= 0)
+ if (_debug_parse_err_line >= 0) {
return String();
+ }
// TODO: StackTrace
return String();
}
String CSharpLanguage::debug_get_stack_level_source(int p_level) const {
- if (_debug_parse_err_line >= 0)
+ if (_debug_parse_err_line >= 0) {
return _debug_parse_err_file;
+ }
// TODO: StackTrace
return String();
@@ -551,15 +578,17 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info()
#ifdef DEBUG_ENABLED
// Printing an error here will result in endless recursion, so we must be careful
static thread_local bool _recursion_flag_ = false;
- if (_recursion_flag_)
+ if (_recursion_flag_) {
return Vector<StackInfo>();
+ }
_recursion_flag_ = true;
SCOPE_EXIT { _recursion_flag_ = false; };
GD_MONO_SCOPE_THREAD_ATTACH;
- if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoCache::cached_data.corlib_cache_updated)
+ if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoCache::cached_data.corlib_cache_updated) {
return Vector<StackInfo>();
+ }
MonoObject *stack_trace = mono_object_new(mono_domain_get(), CACHED_CLASS(System_Diagnostics_StackTrace)->get_mono_ptr());
@@ -581,8 +610,9 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info()
Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) {
// Printing an error here will result in endless recursion, so we must be careful
static thread_local bool _recursion_flag_ = false;
- if (_recursion_flag_)
+ if (_recursion_flag_) {
return Vector<StackInfo>();
+ }
_recursion_flag_ = true;
SCOPE_EXIT { _recursion_flag_ = false; };
@@ -599,8 +629,9 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
int frame_count = mono_array_length(frames);
- if (frame_count <= 0)
+ if (frame_count <= 0) {
return Vector<StackInfo>();
+ }
Vector<StackInfo> si;
si.resize(frame_count);
@@ -646,8 +677,9 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
ObjectID id = p_obj->get_instance_id();
Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id);
ERR_FAIL_NULL(elem);
- if (--elem->value() == 0)
+ if (--elem->value() == 0) {
unsafe_object_references.erase(elem);
+ }
#endif
}
@@ -673,8 +705,9 @@ void CSharpLanguage::frame() {
struct CSharpScriptDepSort {
// must support sorting so inheritance works properly (parent must be reloaded first)
bool operator()(const Ref<CSharpScript> &A, const Ref<CSharpScript> &B) const {
- if (A == B)
+ if (A == B) {
return false; // shouldn't happen but..
+ }
GDMonoClass *I = B->base;
while (I) {
if (I == A->script_class) {
@@ -717,8 +750,9 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft
#ifdef GD_MONO_HOT_RELOAD
bool CSharpLanguage::is_assembly_reloading_needed() {
- if (!gdmono->is_runtime_initialized())
+ if (!gdmono->is_runtime_initialized()) {
return false;
+ }
GDMonoAssembly *proj_assembly = gdmono->get_project_assembly();
@@ -736,23 +770,27 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
if (!FileAccess::exists(proj_asm_path)) {
// Maybe it wasn't loaded from the default path, so check this as well
proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe);
- if (!FileAccess::exists(proj_asm_path))
+ if (!FileAccess::exists(proj_asm_path)) {
return false; // No assembly to load
+ }
}
- if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time())
+ if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time()) {
return false; // Already up to date
+ }
} else {
- if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe)))
+ if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe))) {
return false; // No assembly to load
+ }
}
return true;
}
void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
- if (!gdmono->is_runtime_initialized())
+ if (!gdmono->is_runtime_initialized()) {
return;
+ }
// There is no soft reloading with Mono. It's always hard reloading.
@@ -858,8 +896,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
CSharpInstance *csi = static_cast<CSharpInstance *>(obj->get_script_instance());
// Call OnBeforeSerialize
- if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener)))
+ if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) {
obj->get_script_instance()->call_multilevel(string_names.on_before_serialize);
+ }
// Save instance info
CSharpScript::StateBackup state;
@@ -894,8 +933,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
for (const Map<ObjectID, CSharpScript::StateBackup>::Element *F = scr->pending_reload_state.front(); F; F = F->next()) {
Object *obj = ObjectDB::get_instance(F->key());
- if (!obj)
+ if (!obj) {
continue;
+ }
ObjectID obj_id = obj->get_instance_id();
@@ -1092,8 +1132,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
}
// Call OnAfterDeserialization
- if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener)))
+ if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) {
obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize);
+ }
}
}
@@ -1246,6 +1287,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() {
script_binding.inited = false;
}
+#ifdef GD_MONO_HOT_RELOAD
{
MutexLock lock(ManagedCallable::instances_mutex);
@@ -1255,6 +1297,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() {
managed_callable->delegate_invoke = nullptr;
}
}
+#endif
scripts_metadata_invalidated = true;
}
@@ -1275,7 +1318,8 @@ void CSharpLanguage::_editor_init_callback() {
GDMonoUtils::runtime_object_init(mono_object, editor_klass, &exc);
UNHANDLED_EXCEPTION(exc);
- EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>(GDMonoMarshal::mono_object_to_variant(mono_object));
+ EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>(
+ GDMonoMarshal::mono_object_to_variant(mono_object).operator Object *());
CRASH_COND(godotsharp_editor == nullptr);
// Enable it as a plugin
@@ -1324,7 +1368,7 @@ CSharpLanguage::CSharpLanguage() {
}
CSharpLanguage::~CSharpLanguage() {
- finish();
+ finalize();
singleton = nullptr;
}
@@ -1341,8 +1385,9 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
// ¯\_(ツ)_/¯
const ClassDB::ClassInfo *classinfo = ClassDB::classes.getptr(type_name);
- while (classinfo && !classinfo->exposed)
+ while (classinfo && !classinfo->exposed) {
classinfo = classinfo->inherits_ptr;
+ }
ERR_FAIL_NULL_V(classinfo, false);
type_name = classinfo->name;
@@ -1380,13 +1425,15 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
MutexLock lock(language_bind_mutex);
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
- if (match)
+ if (match) {
return (void *)match;
+ }
CSharpScriptBinding script_binding;
- if (!setup_csharp_script_binding(script_binding, p_object))
+ if (!setup_csharp_script_binding(script_binding, p_object)) {
return nullptr;
+ }
return (void *)insert_script_binding(p_object, script_binding);
}
@@ -1404,8 +1451,9 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
return;
}
- if (finalizing)
+ if (finalizing) {
return; // inside CSharpLanguage::finish(), all the gchandle bindings are released there
+ }
GD_MONO_ASSERT_THREAD_ATTACHED;
@@ -1444,8 +1492,9 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
MonoGCHandleData &gchandle = script_binding.gchandle;
- if (!script_binding.inited)
+ if (!script_binding.inited) {
return;
+ }
if (ref_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -1455,8 +1504,9 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
// so the owner must hold the managed side alive again to avoid it from being GCed.
MonoObject *target = gchandle.get_target();
- if (!target)
+ if (!target) {
return; // Called after the managed side was collected, so nothing to do here
+ }
// Release the current weak handle and replace it with a strong handle.
MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target);
@@ -1481,8 +1531,9 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
int refcount = ref_owner->reference_get_count();
- if (!script_binding.inited)
+ if (!script_binding.inited) {
return refcount == 0;
+ }
if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -1491,8 +1542,9 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
// the managed instance takes responsibility of deleting the owner when GCed.
MonoObject *target = gchandle.get_target();
- if (!target)
+ if (!target) {
return refcount == 0; // Called after the managed side was collected, so nothing to do here
+ }
// Release the current strong handle and replace it with a weak handle.
MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(target);
@@ -1514,8 +1566,9 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS
instance->owner = p_owner;
instance->gchandle = p_gchandle;
- if (instance->base_ref)
+ if (instance->base_ref) {
instance->_reference_owner_unsafe();
+ }
p_script->instances.insert(p_owner);
@@ -1572,8 +1625,9 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) {
MonoObject *ret = method->invoke(mono_object, args);
- if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret))
+ if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret)) {
return true;
+ }
break;
}
@@ -1658,8 +1712,9 @@ void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Va
ManagedType managedType;
GDMonoField *field = script->script_class->get_field(state_pair.first);
- if (!field)
+ if (!field) {
continue; // Properties ignored. We get the property baking fields instead.
+ }
managedType = field->get_type();
@@ -1679,8 +1734,9 @@ void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName,
const CSharpScript::EventSignal &event_signal = E->value();
MonoDelegate *delegate_field_value = (MonoDelegate *)event_signal.field->get_value(owner_managed);
- if (!delegate_field_value)
+ if (!delegate_field_value) {
continue; // Empty
+ }
Array serialized_data;
MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data);
@@ -1725,8 +1781,9 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
if (ret) {
Array array = Array(GDMonoMarshal::mono_object_to_variant(ret));
- for (int i = 0, size = array.size(); i < size; i++)
+ for (int i = 0, size = array.size(); i < size; i++) {
p_properties->push_back(PropertyInfo::from_dict(array.get(i)));
+ }
return;
}
@@ -1739,20 +1796,23 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
if (script->member_info.has(p_name)) {
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = true;
+ }
return script->member_info[p_name].type;
}
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = false;
+ }
return Variant::NIL;
}
bool CSharpInstance::has_method(const StringName &p_method) const {
- if (!script.is_valid())
+ if (!script.is_valid()) {
return false;
+ }
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -1868,8 +1928,9 @@ bool CSharpInstance::_unreference_owner_unsafe() {
CRASH_COND(owner == nullptr);
#endif
- if (!unsafe_referenced)
+ if (!unsafe_referenced) {
return false; // Already unreferenced
+ }
unsafe_referenced = false;
@@ -1912,8 +1973,9 @@ MonoObject *CSharpInstance::_internal_new_managed() {
// Tie managed to unmanaged
gchandle = MonoGCHandleData::new_strong_handle(mono_object);
- if (base_ref)
+ if (base_ref) {
_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
+ }
CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, owner);
@@ -2130,7 +2192,7 @@ void CSharpInstance::_call_notification(int p_notification) {
// Custom version of _call_multilevel, optimized for _notification
- uint32_t arg = p_notification;
+ int32_t arg = p_notification;
void *args[1] = { &arg };
StringName method_name = CACHED_STRING_NAME(_notification);
@@ -2154,8 +2216,9 @@ String CSharpInstance::to_string(bool *r_valid) {
MonoObject *mono_object = get_mono_object();
if (mono_object == nullptr) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return String();
}
@@ -2164,14 +2227,16 @@ String CSharpInstance::to_string(bool *r_valid) {
if (exc) {
GDMonoUtils::set_pending_exception(exc);
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return String();
}
if (result == nullptr) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return String();
}
@@ -2342,11 +2407,13 @@ void CSharpScript::_update_member_info_no_exports() {
bool CSharpScript::_update_exports() {
#ifdef TOOLS_ENABLED
bool is_editor = Engine::get_singleton()->is_editor_hint();
- if (is_editor)
+ if (is_editor) {
placeholder_fallback_enabled = true; // until proven otherwise
+ }
#endif
- if (!valid)
+ if (!valid) {
return false;
+ }
bool changed = false;
@@ -2543,8 +2610,9 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati
for (int i = delegates.size() - 1; i >= 0; --i) {
GDMonoClass *delegate = delegates[i];
- if (!delegate->has_attribute(CACHED_CLASS(SignalAttribute)))
+ if (!delegate->has_attribute(CACHED_CLASS(SignalAttribute))) {
continue;
+ }
// Arguments are accessibles as arguments of .Invoke method
GDMonoMethod *invoke_method = delegate->get_method(mono_get_delegate_invoke(delegate->get_mono_ptr()));
@@ -2577,11 +2645,13 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati
GDMonoClass *field_class = field->get_type().type_class;
- if (!mono_class_is_delegate(field_class->get_mono_ptr()))
+ if (!mono_class_is_delegate(field_class->get_mono_ptr())) {
continue;
+ }
- if (!found_event_signals.find(field->get_name()))
+ if (!found_event_signals.find(field->get_name())) {
continue;
+ }
GDMonoMethod *invoke_method = field_class->get_method(mono_get_delegate_invoke(field_class->get_mono_ptr()));
@@ -2640,14 +2710,16 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
if (p_member->is_static()) {
#ifdef TOOLS_ENABLED
- if (p_member->has_attribute(CACHED_CLASS(ExportAttribute)))
+ if (p_member->has_attribute(CACHED_CLASS(ExportAttribute))) {
ERR_PRINT("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
+ }
#endif
return false;
}
- if (member_info.has(p_member->get_name()))
+ if (member_info.has(p_member->get_name())) {
return false;
+ }
ManagedType type;
@@ -2665,15 +2737,17 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member);
if (!property->has_getter()) {
#ifdef TOOLS_ENABLED
- if (exported)
+ if (exported) {
ERR_PRINT("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
+ }
#endif
return false;
}
if (!property->has_setter()) {
#ifdef TOOLS_ENABLED
- if (exported)
+ if (exported) {
ERR_PRINT("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
+ }
#endif
return false;
}
@@ -2802,8 +2876,9 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
ManagedType elem_type;
- if (!GDMonoMarshal::try_get_array_element_type(p_type, elem_type))
+ if (!GDMonoMarshal::try_get_array_element_type(p_type, elem_type)) {
return 0;
+ }
Variant::Type elem_variant_type = GDMonoMarshal::managed_to_variant_type(elem_type);
@@ -2830,15 +2905,6 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
}
#endif
-void CSharpScript::_clear() {
- tool = false;
- valid = false;
-
- base = nullptr;
- native = nullptr;
- script_class = nullptr;
-}
-
Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (unlikely(GDMono::get_singleton() == nullptr)) {
// Probably not the best error but eh.
@@ -2871,11 +2937,7 @@ Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, i
}
void CSharpScript::_resource_path_changed() {
- String path = get_path();
-
- if (!path.empty()) {
- name = get_path().get_file().get_basename();
- }
+ _update_name();
}
bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const {
@@ -2931,8 +2993,9 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
GDMonoClass *base = p_script->script_class->get_parent_class();
- if (base != p_script->native)
+ if (base != p_script->native) {
p_script->base = base;
+ }
p_script->valid = true;
p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute));
@@ -2958,8 +3021,9 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
while (native_top) {
native_top->fetch_methods_with_godot_api_checks(p_script->native);
- if (native_top == CACHED_CLASS(GodotObject))
+ if (native_top == CACHED_CLASS(GodotObject)) {
break;
+ }
native_top = native_top->get_parent_class();
}
@@ -3005,10 +3069,11 @@ bool CSharpScript::can_instance() const {
}
StringName CSharpScript::get_instance_base_type() const {
- if (native)
+ if (native) {
return native->get_name();
- else
+ } else {
return StringName();
+ }
}
CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) {
@@ -3081,8 +3146,9 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
// Tie managed to unmanaged
instance->gchandle = MonoGCHandleData::new_strong_handle(mono_object);
- if (instance->base_ref)
+ if (instance->base_ref) {
instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
+ }
{
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
@@ -3184,8 +3250,9 @@ String CSharpScript::get_source_code() const {
}
void CSharpScript::set_source_code(const String &p_code) {
- if (source == p_code)
+ if (source == p_code) {
return;
+ }
source = p_code;
#ifdef TOOLS_ENABLED
source_changed_cache = true;
@@ -3193,8 +3260,9 @@ void CSharpScript::set_source_code(const String &p_code) {
}
void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const {
- if (!script_class)
+ if (!script_class) {
return;
+ }
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -3206,8 +3274,9 @@ void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const {
}
bool CSharpScript::has_method(const StringName &p_method) const {
- if (!script_class)
+ if (!script_class) {
return false;
+ }
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -3215,8 +3284,9 @@ bool CSharpScript::has_method(const StringName &p_method) const {
}
MethodInfo CSharpScript::get_method_info(const StringName &p_method) const {
- if (!script_class)
+ if (!script_class) {
return MethodInfo();
+ }
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -3290,8 +3360,9 @@ Error CSharpScript::reload(bool p_keep_state) {
GDMonoClass *base_class = script_class->get_parent_class();
- if (base_class != native)
+ if (base_class != native) {
base = base_class;
+ }
#ifdef DEBUG_ENABLED
// For debug builds, we must fetch from all native base methods as well.
@@ -3303,8 +3374,9 @@ Error CSharpScript::reload(bool p_keep_state) {
while (native_top) {
native_top->fetch_methods_with_godot_api_checks(native);
- if (native_top == CACHED_CLASS(GodotObject))
+ if (native_top == CACHED_CLASS(GodotObject)) {
break;
+ }
native_top = native_top->get_parent_class();
}
@@ -3434,8 +3506,9 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
const SignalParameter &param = params[i];
PropertyInfo arg_info = PropertyInfo(param.type, param.name);
- if (param.type == Variant::NIL && param.nil_is_variant)
+ if (param.type == Variant::NIL && param.nil_is_variant) {
arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ }
mi.arguments.push_back(arg_info);
}
@@ -3453,8 +3526,9 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
const SignalParameter &param = params[i];
PropertyInfo arg_info = PropertyInfo(param.type, param.name);
- if (param.type == Variant::NIL && param.nil_is_variant)
+ if (param.type == Variant::NIL && param.nil_is_variant) {
arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ }
mi.arguments.push_back(arg_info);
}
@@ -3497,18 +3571,24 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
}
MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
- if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute)))
+ if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) {
return MultiplayerAPI::RPC_MODE_REMOTE;
- if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
+ }
+ if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) {
return MultiplayerAPI::RPC_MODE_MASTER;
- if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute)))
+ }
+ if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) {
return MultiplayerAPI::RPC_MODE_PUPPET;
- if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute)))
+ }
+ if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute)))
+ }
+ if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute)))
+ }
+ if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ }
return MultiplayerAPI::RPC_MODE_DISABLED;
}
@@ -3583,14 +3663,27 @@ Error CSharpScript::load_source_code(const String &p_path) {
return OK;
}
-StringName CSharpScript::get_script_name() const {
- return name;
+void CSharpScript::_update_name() {
+ String path = get_path();
+
+ if (!path.empty()) {
+ name = get_path().get_file().get_basename();
+ }
+}
+
+void CSharpScript::_clear() {
+ tool = false;
+ valid = false;
+
+ base = nullptr;
+ native = nullptr;
+ script_class = nullptr;
}
CSharpScript::CSharpScript() {
_clear();
- _resource_path_changed();
+ _update_name();
#ifdef DEBUG_ENABLED
{
@@ -3620,8 +3713,9 @@ void CSharpScript::get_members(Set<StringName> *p_members) {
/*************** RESOURCE ***************/
RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
- if (r_error)
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
// TODO ignore anything inside bin/ and obj/ in tools builds?
@@ -3638,8 +3732,9 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p
script->reload();
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return scriptres;
}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 0bf08ceafd..c2370364f9 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -135,7 +135,7 @@ private:
bool exports_invalidated = true;
void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames);
void _update_member_info_no_exports();
- virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder);
+ void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override;
#endif
#if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED)
@@ -146,6 +146,8 @@ private:
void _clear();
+ void _update_name();
+
void load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class);
bool _get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> &params);
@@ -169,68 +171,66 @@ private:
protected:
static void _bind_methods();
- Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
- virtual void _resource_path_changed();
+ Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
+ void _resource_path_changed() override;
bool _get(const StringName &p_name, Variant &r_ret) const;
bool _set(const StringName &p_name, const Variant &p_value);
void _get_property_list(List<PropertyInfo> *p_properties) const;
public:
- virtual bool can_instance() const;
- virtual StringName get_instance_base_type() const;
- virtual ScriptInstance *instance_create(Object *p_this);
- virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this);
- virtual bool instance_has(const Object *p_this) const;
+ bool can_instance() const override;
+ StringName get_instance_base_type() const override;
+ ScriptInstance *instance_create(Object *p_this) override;
+ PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override;
+ bool instance_has(const Object *p_this) const override;
- virtual bool has_source_code() const;
- virtual String get_source_code() const;
- virtual void set_source_code(const String &p_code);
+ bool has_source_code() const override;
+ String get_source_code() const override;
+ void set_source_code(const String &p_code) override;
- virtual Error reload(bool p_keep_state = false);
+ Error reload(bool p_keep_state = false) override;
- virtual bool has_script_signal(const StringName &p_signal) const;
- virtual void get_script_signal_list(List<MethodInfo> *r_signals) const;
+ bool has_script_signal(const StringName &p_signal) const override;
+ void get_script_signal_list(List<MethodInfo> *r_signals) const override;
- virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const;
- virtual void get_script_property_list(List<PropertyInfo> *p_list) const;
- virtual void update_exports();
+ bool get_property_default_value(const StringName &p_property, Variant &r_value) const override;
+ void get_script_property_list(List<PropertyInfo> *p_list) const override;
+ void update_exports() override;
void get_members(Set<StringName> *p_members) override;
- virtual bool is_tool() const { return tool; }
- virtual bool is_valid() const { return valid; }
+ bool is_tool() const override { return tool; }
+ bool is_valid() const override { return valid; }
- bool inherits_script(const Ref<Script> &p_script) const;
+ bool inherits_script(const Ref<Script> &p_script) const override;
- virtual Ref<Script> get_base_script() const;
- virtual ScriptLanguage *get_language() const;
+ Ref<Script> get_base_script() const override;
+ ScriptLanguage *get_language() const override;
- virtual void get_script_method_list(List<MethodInfo> *p_list) const;
- bool has_method(const StringName &p_method) const;
- MethodInfo get_method_info(const StringName &p_method) const;
+ void get_script_method_list(List<MethodInfo> *p_list) const override;
+ bool has_method(const StringName &p_method) const override;
+ MethodInfo get_method_info(const StringName &p_method) const override;
- virtual int get_member_line(const StringName &p_member) const;
+ int get_member_line(const StringName &p_member) const override;
- virtual Vector<ScriptNetData> get_rpc_methods() const;
- virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
- virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
- virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
- virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+ Vector<ScriptNetData> get_rpc_methods() const override;
+ uint16_t get_rpc_method_id(const StringName &p_method) const override;
+ StringName get_rpc_method(const uint16_t p_rpc_method_id) const override;
+ MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override;
+ MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override;
- virtual Vector<ScriptNetData> get_rset_properties() const;
- virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
- virtual StringName get_rset_property(const uint16_t p_variable_id) const;
- virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
- virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+ Vector<ScriptNetData> get_rset_properties() const override;
+ uint16_t get_rset_property_id(const StringName &p_variable) const override;
+ StringName get_rset_property(const uint16_t p_variable_id) const override;
+ MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override;
+ MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override;
#ifdef TOOLS_ENABLED
- virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; }
+ bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; }
#endif
Error load_source_code(const String &p_path);
- StringName get_script_name() const;
-
CSharpScript();
~CSharpScript();
};
@@ -249,8 +249,6 @@ class CSharpInstance : public ScriptInstance {
Ref<CSharpScript> script;
MonoGCHandleData gchandle;
- Vector<Callable> event_signal_callables;
-
bool _reference_owner_unsafe();
/*
@@ -277,18 +275,18 @@ public:
_FORCE_INLINE_ bool is_destructing_script_instance() { return destructing_script_instance; }
- virtual Object *get_owner();
+ Object *get_owner() override;
- 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) const;
+ bool set(const StringName &p_name, const Variant &p_value) override;
+ bool get(const StringName &p_name, Variant &r_ret) const override;
+ void get_property_list(List<PropertyInfo> *p_properties) const override;
+ Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const override;
- /* TODO */ virtual void get_method_list(List<MethodInfo> *p_list) const {}
- virtual bool has_method(const StringName &p_method) const;
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
- virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
- virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
+ /* TODO */ void get_method_list(List<MethodInfo> *p_list) const override {}
+ bool has_method(const StringName &p_method) const override;
+ Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
+ void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) override;
+ void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) override;
void mono_object_disposed(MonoObject *p_obj);
@@ -301,29 +299,29 @@ public:
void connect_event_signals();
void disconnect_event_signals();
- virtual void refcount_incremented();
- virtual bool refcount_decremented();
+ void refcount_incremented() override;
+ bool refcount_decremented() override;
- virtual Vector<ScriptNetData> get_rpc_methods() const;
- virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
- virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
- virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
- virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+ Vector<ScriptNetData> get_rpc_methods() const override;
+ uint16_t get_rpc_method_id(const StringName &p_method) const override;
+ StringName get_rpc_method(const uint16_t p_rpc_method_id) const override;
+ MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override;
+ MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override;
- virtual Vector<ScriptNetData> get_rset_properties() const;
- virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
- virtual StringName get_rset_property(const uint16_t p_variable_id) const;
- virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
- virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+ Vector<ScriptNetData> get_rset_properties() const override;
+ uint16_t get_rset_property_id(const StringName &p_variable) const override;
+ StringName get_rset_property(const uint16_t p_variable_id) const override;
+ MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override;
+ MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override;
- virtual void notification(int p_notification);
+ void notification(int p_notification) override;
void _call_notification(int p_notification);
- virtual String to_string(bool *r_valid);
+ String to_string(bool *r_valid) override;
- virtual Ref<Script> get_script() const;
+ Ref<Script> get_script() const override;
- virtual ScriptLanguage *get_language();
+ ScriptLanguage *get_language() override;
CSharpInstance(const Ref<CSharpScript> &p_script);
~CSharpInstance();
@@ -437,83 +435,90 @@ public:
}
_FORCE_INLINE_ const Dictionary &get_scripts_metadata() {
- if (scripts_metadata_invalidated)
+ if (scripts_metadata_invalidated) {
_load_scripts_metadata();
+ }
return scripts_metadata;
}
_FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; }
- virtual String get_name() const;
+ String get_name() const override;
/* LANGUAGE FUNCTIONS */
- virtual String get_type() const;
- virtual String get_extension() const;
- virtual Error execute_file(const String &p_path);
- virtual void init();
- virtual void finish();
+ String get_type() const override;
+ String get_extension() const override;
+ Error execute_file(const String &p_path) override;
+ void init() override;
+ void finish() override;
+
+ void finalize();
/* EDITOR FUNCTIONS */
- virtual void get_reserved_words(List<String> *p_words) const;
- virtual void get_comment_delimiters(List<String> *p_delimiters) const;
- virtual void get_string_delimiters(List<String> *p_delimiters) const;
- virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
- virtual bool is_using_templates();
- virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
- /* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const { return true; }
- virtual String validate_path(const String &p_path) const;
- virtual Script *create_script() const;
- virtual bool has_named_classes() const;
- virtual bool supports_builtin_mode() const;
- /* TODO? */ virtual int find_function(const String &p_function, const String &p_code) const { return -1; }
- virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const;
+ void get_reserved_words(List<String> *p_words) const override;
+ void get_comment_delimiters(List<String> *p_delimiters) const override;
+ void get_string_delimiters(List<String> *p_delimiters) const override;
+ Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const override;
+ bool is_using_templates() override;
+ void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) override;
+ /* TODO */ bool validate(const String &p_script, int &r_line_error, int &r_col_error,
+ String &r_test_error, const String &p_path, List<String> *r_functions,
+ List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override {
+ return true;
+ }
+ String validate_path(const String &p_path) const override;
+ Script *create_script() const override;
+ bool has_named_classes() const override;
+ bool supports_builtin_mode() const override;
+ /* TODO? */ int find_function(const String &p_function, const String &p_code) const override { return -1; }
+ String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const override;
virtual String _get_indentation() const;
- /* TODO? */ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {}
- /* TODO */ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) {}
+ /* TODO? */ void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override {}
+ /* TODO */ void add_global_constant(const StringName &p_variable, const Variant &p_value) override {}
/* DEBUGGER FUNCTIONS */
- virtual String debug_get_error() const;
- virtual int debug_get_stack_level_count() const;
- virtual int debug_get_stack_level_line(int p_level) const;
- virtual String debug_get_stack_level_function(int p_level) const;
- virtual String debug_get_stack_level_source(int p_level) const;
- /* TODO */ virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {}
- /* TODO */ virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {}
- /* TODO */ virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {}
- /* TODO */ virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { return ""; }
- virtual Vector<StackInfo> debug_get_current_stack_info();
+ String debug_get_error() const override;
+ int debug_get_stack_level_count() const override;
+ int debug_get_stack_level_line(int p_level) const override;
+ String debug_get_stack_level_function(int p_level) const override;
+ String debug_get_stack_level_source(int p_level) const override;
+ /* TODO */ void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {}
+ /* TODO */ void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {}
+ /* TODO */ void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {}
+ /* TODO */ String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) override { return ""; }
+ Vector<StackInfo> debug_get_current_stack_info() override;
/* PROFILING FUNCTIONS */
- /* TODO */ virtual void profiling_start() {}
- /* TODO */ virtual void profiling_stop() {}
- /* TODO */ virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) { return 0; }
- /* TODO */ virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) { return 0; }
+ /* TODO */ void profiling_start() override {}
+ /* TODO */ void profiling_stop() override {}
+ /* TODO */ int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override { return 0; }
+ /* TODO */ int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override { return 0; }
- virtual void frame();
+ void frame() override;
- /* TODO? */ virtual void get_public_functions(List<MethodInfo> *p_functions) const {}
- /* TODO? */ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const {}
+ /* TODO? */ void get_public_functions(List<MethodInfo> *p_functions) const override {}
+ /* TODO? */ void get_public_constants(List<Pair<String, Variant>> *p_constants) const override {}
- virtual void reload_all_scripts();
- virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload);
+ void reload_all_scripts() override;
+ void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) override;
/* LOADER FUNCTIONS */
- virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ void get_recognized_extensions(List<String> *p_extensions) const override;
#ifdef TOOLS_ENABLED
- virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col);
- virtual bool overrides_external_editor();
+ Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) override;
+ bool overrides_external_editor() override;
#endif
/* THREAD ATTACHING */
- virtual void thread_enter();
- virtual void thread_exit();
+ void thread_enter() override;
+ void thread_exit() override;
// Don't use these. I'm watching you
- virtual void *alloc_instance_binding_data(Object *p_object);
- virtual void free_instance_binding_data(void *p_data);
- virtual void refcount_incremented_instance_binding(Object *p_object);
- virtual bool refcount_decremented_instance_binding(Object *p_object);
+ void *alloc_instance_binding_data(Object *p_object) override;
+ void free_instance_binding_data(void *p_data) override;
+ void refcount_incremented_instance_binding(Object *p_object) override;
+ bool refcount_decremented_instance_binding(Object *p_object) override;
Map<Object *, CSharpScriptBinding>::Element *insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding);
bool setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object);
@@ -531,17 +536,17 @@ public:
class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
- virtual void get_recognized_extensions(List<String> *p_extensions) const;
- virtual bool handles_type(const String &p_type) const;
- virtual String get_resource_type(const String &p_path) const;
+ RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false) override;
+ void get_recognized_extensions(List<String> *p_extensions) const override;
+ bool handles_type(const String &p_type) const override;
+ String get_resource_type(const String &p_path) const override;
};
class ResourceFormatSaverCSharpScript : public ResourceFormatSaver {
public:
- virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
- virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
- virtual bool recognize(const RES &p_resource) const;
+ Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0) override;
+ void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const override;
+ bool recognize(const RES &p_resource) const override;
};
#endif // CSHARP_SCRIPT_H
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 730ffcb945..79e4b7c794 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -62,10 +62,8 @@
#define OPEN_BLOCK_L2 INDENT2 OPEN_BLOCK INDENT3
#define OPEN_BLOCK_L3 INDENT3 OPEN_BLOCK INDENT4
-#define OPEN_BLOCK_L4 INDENT4 OPEN_BLOCK INDENT5
#define CLOSE_BLOCK_L2 INDENT2 CLOSE_BLOCK
#define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK
-#define CLOSE_BLOCK_L4 INDENT4 CLOSE_BLOCK
#define CS_FIELD_MEMORYOWN "memoryOwn"
#define CS_PARAM_METHODBIND "method"
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
index 7a5e465e7a..df1547607d 100644
--- a/modules/mono/editor/code_completion.cpp
+++ b/modules/mono/editor/code_completion.cpp
@@ -45,8 +45,9 @@ _FORCE_INLINE_ String quoted(const String &p_str) {
}
void _add_nodes_suggestions(const Node *p_base, const Node *p_node, PackedStringArray &r_suggestions) {
- if (p_node != p_base && !p_node->get_owner())
+ if (p_node != p_base && !p_node->get_owner()) {
return;
+ }
String path_relative_to_orig = p_base->get_path_to(p_node);
@@ -58,18 +59,21 @@ void _add_nodes_suggestions(const Node *p_base, const Node *p_node, PackedString
}
Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) {
- if (p_current->get_owner() != p_base && p_base != p_current)
+ if (p_current->get_owner() != p_base && p_base != p_current) {
return nullptr;
+ }
Ref<Script> c = p_current->get_script();
- if (c == p_script)
+ if (c == p_script) {
return p_current;
+ }
for (int i = 0; i < p_current->get_child_count(); i++) {
Node *found = _find_node_for_script(p_base, p_current->get_child(i), p_script);
- if (found)
+ if (found) {
return found;
+ }
}
return nullptr;
@@ -87,8 +91,9 @@ void _get_directory_contents(EditorFileSystemDirectory *p_dir, PackedStringArray
Node *_try_find_owner_node_in_tree(const Ref<Script> p_script) {
SceneTree *tree = SceneTree::get_singleton();
- if (!tree)
+ if (!tree) {
return nullptr;
+ }
Node *base = tree->get_edited_scene_root();
if (base) {
base = _find_node_for_script(base, base, p_script);
@@ -107,8 +112,9 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
for (List<PropertyInfo>::Element *E = project_props.front(); E; E = E->next()) {
const PropertyInfo &prop = E->get();
- if (!prop.name.begins_with("input/"))
+ if (!prop.name.begins_with("input/")) {
continue;
+ }
String name = prop.name.substr(prop.name.find("/") + 1, prop.name.length());
suggestions.push_back(quoted(name));
diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp
index 3a30f3106c..6f54eb09a2 100644
--- a/modules/mono/editor/csharp_project.cpp
+++ b/modules/mono/editor/csharp_project.cpp
@@ -45,8 +45,9 @@
namespace CSharpProject {
void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) {
- if (!GLOBAL_DEF("mono/project/auto_update_project", true))
+ if (!GLOBAL_DEF("mono/project/auto_update_project", true)) {
return;
+ }
GDMonoAssembly *tools_project_editor_assembly = GDMono::get_singleton()->get_tools_project_editor_assembly();
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index b183787618..68fc372959 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -324,7 +324,7 @@ MonoObject *godot_icall_Internal_GetScriptsMetadataOrNothing(MonoReflectionType
MonoType *dict_type = mono_reflection_type_get_type(p_dict_reftype);
- uint32_t type_encoding = mono_type_get_type(dict_type);
+ int type_encoding = mono_type_get_type(dict_type);
MonoClass *type_class_raw = mono_class_from_mono_type(dict_type);
GDMonoClass *type_class = GDMono::get_singleton()->get_class(type_class_raw);
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index 1cdb08d50e..b15e9b060a 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -75,8 +75,9 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
const String &ref_name = ref_info.name;
- if (r_assembly_dependencies.has(ref_name))
+ if (r_assembly_dependencies.has(ref_name)) {
continue;
+ }
GDMonoAssembly *ref_assembly = nullptr;
@@ -130,8 +131,9 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'.");
Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
}
return OK;
diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp
index 7276612230..012ccd5339 100644
--- a/modules/mono/editor/script_class_parser.cpp
+++ b/modules/mono/editor/script_class_parser.cpp
@@ -208,8 +208,9 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
tk_string += res;
} else {
- if (code[idx] == '\n')
+ if (code[idx] == '\n') {
line++;
+ }
tk_string += code[idx];
}
idx++;
@@ -300,15 +301,17 @@ Error ScriptClassParser::_skip_generic_type_params() {
tk = get_token();
- if (tk != TK_PERIOD)
+ if (tk != TK_PERIOD) {
break;
+ }
}
}
if (tk == TK_OP_LESS) {
Error err = _skip_generic_type_params();
- if (err)
+ if (err) {
return err;
+ }
tk = get_token();
}
@@ -349,12 +352,14 @@ Error ScriptClassParser::_parse_type_full_name(String &r_full_name) {
// We don't mind if the base is generic, but we skip it any ways since this information is not needed
Error err = _skip_generic_type_params();
- if (err)
+ if (err) {
return err;
+ }
}
- if (code[idx] != '.') // We only want to take the next token if it's a period
+ if (code[idx] != '.') { // We only want to take the next token if it's a period
return OK;
+ }
tk = get_token();
@@ -369,15 +374,17 @@ Error ScriptClassParser::_parse_class_base(Vector<String> &r_base) {
String name;
Error err = _parse_type_full_name(name);
- if (err)
+ if (err) {
return err;
+ }
Token tk = get_token();
if (tk == TK_COMMA) {
err = _parse_class_base(r_base);
- if (err)
+ if (err) {
return err;
+ }
} else if (tk == TK_IDENTIFIER && String(value) == "where") {
err = _parse_type_constraints();
if (err) {
@@ -433,8 +440,9 @@ Error ScriptClassParser::_parse_type_constraints() {
tk = get_token();
- if (tk != TK_PERIOD)
+ if (tk != TK_PERIOD) {
break;
+ }
}
}
}
@@ -452,8 +460,9 @@ Error ScriptClassParser::_parse_type_constraints() {
}
} else if (tk == TK_OP_LESS) {
Error err = _skip_generic_type_params();
- if (err)
+ if (err) {
return err;
+ }
} else if (tk == TK_CURLY_BRACKET_OPEN) {
return OK;
} else {
@@ -522,8 +531,9 @@ Error ScriptClassParser::parse(const String &p_code) {
const NameDecl &name_decl = E->value();
if (name_decl.type == NameDecl::NAMESPACE_DECL) {
- if (E != name_stack.front())
+ if (E != name_stack.front()) {
class_decl.namespace_ += ".";
+ }
class_decl.namespace_ += name_decl.name;
} else {
class_decl.name += name_decl.name + ".";
@@ -540,8 +550,9 @@ Error ScriptClassParser::parse(const String &p_code) {
if (tk == TK_COLON) {
Error err = _parse_class_base(class_decl.base);
- if (err)
+ if (err) {
return err;
+ }
curly_stack++;
type_curly_stack++;
@@ -555,8 +566,9 @@ Error ScriptClassParser::parse(const String &p_code) {
generic = true;
Error err = _skip_generic_type_params();
- if (err)
+ if (err) {
return err;
+ }
} else if (tk == TK_IDENTIFIER && String(value) == "where") {
Error err = _parse_type_constraints();
if (err) {
@@ -584,8 +596,9 @@ Error ScriptClassParser::parse(const String &p_code) {
classes.push_back(class_decl);
} else if (OS::get_singleton()->is_stdout_verbose()) {
String full_name = class_decl.namespace_;
- if (full_name.length())
+ if (full_name.length()) {
full_name += ".";
+ }
full_name += class_decl.name;
OS::get_singleton()->print("Ignoring generic class declaration: %s\n", full_name.utf8().get_data());
}
@@ -602,8 +615,9 @@ Error ScriptClassParser::parse(const String &p_code) {
int at_level = curly_stack;
Error err = _parse_namespace_name(name, curly_stack);
- if (err)
+ if (err) {
return err;
+ }
NameDecl name_decl;
name_decl.name = name;
@@ -614,8 +628,9 @@ Error ScriptClassParser::parse(const String &p_code) {
} else if (tk == TK_CURLY_BRACKET_CLOSE) {
curly_stack--;
if (name_stack.has(curly_stack)) {
- if (name_stack[curly_stack].type != NameDecl::NAMESPACE_DECL)
+ if (name_stack[curly_stack].type != NameDecl::NAMESPACE_DECL) {
type_curly_stack--;
+ }
name_stack.erase(curly_stack);
}
}
@@ -628,8 +643,9 @@ Error ScriptClassParser::parse(const String &p_code) {
error = true;
}
- if (error)
+ if (error) {
return ERR_PARSE_ERROR;
+ }
return OK;
}
@@ -702,8 +718,9 @@ static void run_dummy_preprocessor(String &r_source, const String &p_filepath) {
// Custom join ignoring lines removed by the preprocessor
for (int i = 0; i < lines.size(); i++) {
- if (i > 0 && include_lines[i - 1])
+ if (i > 0 && include_lines[i - 1]) {
r_source += '\n';
+ }
if (include_lines[i]) {
r_source += lines[i];
diff --git a/modules/mono/editor/script_class_parser.h b/modules/mono/editor/script_class_parser.h
index c194ed1422..d611e8fb74 100644
--- a/modules/mono/editor/script_class_parser.h
+++ b/modules/mono/editor/script_class_parser.h
@@ -53,7 +53,6 @@ public:
String namespace_;
Vector<String> base;
bool nested;
- bool has_script_attr;
};
private:
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index 9384da0e48..e050d1fdd1 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -84,7 +84,7 @@ namespace Godot
public static void Print(params object[] what)
{
- godot_icall_GD_print(Array.ConvertAll(what, x => x?.ToString()));
+ godot_icall_GD_print(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null"));
}
public static void PrintStack()
@@ -94,22 +94,22 @@ namespace Godot
public static void PrintErr(params object[] what)
{
- godot_icall_GD_printerr(Array.ConvertAll(what, x => x?.ToString()));
+ godot_icall_GD_printerr(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null"));
}
public static void PrintRaw(params object[] what)
{
- godot_icall_GD_printraw(Array.ConvertAll(what, x => x?.ToString()));
+ godot_icall_GD_printraw(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null"));
}
public static void PrintS(params object[] what)
{
- godot_icall_GD_prints(Array.ConvertAll(what, x => x?.ToString()));
+ godot_icall_GD_prints(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null"));
}
public static void PrintT(params object[] what)
{
- godot_icall_GD_printt(Array.ConvertAll(what, x => x?.ToString()));
+ godot_icall_GD_printt(Array.ConvertAll(what ?? new object[]{"null"}, x => x != null ? x.ToString() : "null"));
}
public static float Randf()
diff --git a/modules/mono/glue/arguments_vector.h b/modules/mono/glue/arguments_vector.h
index 4ee553fc11..ab48904571 100644
--- a/modules/mono/glue/arguments_vector.h
+++ b/modules/mono/glue/arguments_vector.h
@@ -40,8 +40,8 @@ private:
T *_ptr;
int size;
- ArgumentsVector();
- ArgumentsVector(const ArgumentsVector &);
+ ArgumentsVector() = delete;
+ ArgumentsVector(const ArgumentsVector &) = delete;
public:
T *ptr() { return _ptr; }
diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp
index f370883320..ebcd6d5e9c 100644
--- a/modules/mono/glue/base_object_glue.cpp
+++ b/modules/mono/glue/base_object_glue.cpp
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "base_object_glue.h"
-
#ifdef MONO_GLUE_ENABLED
+#include "core/class_db.h"
+#include "core/object.h"
#include "core/reference.h"
#include "core/string_name.h"
@@ -39,6 +39,7 @@
#include "../mono_gd/gd_mono_cache.h"
#include "../mono_gd/gd_mono_class.h"
#include "../mono_gd/gd_mono_internals.h"
+#include "../mono_gd/gd_mono_marshal.h"
#include "../mono_gd/gd_mono_utils.h"
#include "../signal_awaiter_utils.h"
#include "arguments_vector.h"
@@ -140,16 +141,18 @@ MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString
}
MonoObject *godot_icall_Object_weakref(Object *p_ptr) {
- if (!p_ptr)
+ if (!p_ptr) {
return nullptr;
+ }
Ref<WeakRef> wref;
Reference *ref = Object::cast_to<Reference>(p_ptr);
if (ref) {
REF r = ref;
- if (!r.is_valid())
+ if (!r.is_valid()) {
return nullptr;
+ }
wref.instance();
wref->set_ref(r);
@@ -241,6 +244,7 @@ void godot_register_object_icalls() {
mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor);
mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed);
mono_add_internal_call("Godot.Object::godot_icall_Reference_Disposed", (void *)godot_icall_Reference_Disposed);
+ mono_add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", (void *)godot_icall_Object_ConnectEventSignals);
mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method);
mono_add_internal_call("Godot.Object::godot_icall_Object_ToString", (void *)godot_icall_Object_ToString);
mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref);
diff --git a/modules/mono/glue/base_object_glue.h b/modules/mono/glue/base_object_glue.h
deleted file mode 100644
index 67769f3061..0000000000
--- a/modules/mono/glue/base_object_glue.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*************************************************************************/
-/* base_object_glue.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 BASE_OBJECT_GLUE_H
-#define BASE_OBJECT_GLUE_H
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "core/class_db.h"
-#include "core/object.h"
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-Object *godot_icall_Object_Ctor(MonoObject *p_obj);
-
-void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr);
-
-void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer);
-
-void godot_icall_Object_ConnectEventSignals(Object *p_ptr);
-
-MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString *p_method);
-
-MonoObject *godot_icall_Object_weakref(Object *p_ptr);
-
-Error godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter);
-
-// DynamicGodotObject
-
-MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr);
-
-MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoString *p_name, MonoArray *p_args, MonoObject **r_result);
-
-MonoBoolean godot_icall_DynamicGodotObject_GetMember(Object *p_ptr, MonoString *p_name, MonoObject **r_result);
-
-MonoBoolean godot_icall_DynamicGodotObject_SetMember(Object *p_ptr, MonoString *p_name, MonoObject *p_value);
-
-MonoString *godot_icall_Object_ToString(Object *p_ptr);
-
-// Register internal calls
-
-void godot_register_object_icalls();
-
-#endif // MONO_GLUE_ENABLED
-
-#endif // BASE_OBJECT_GLUE_H
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
index 4e3dc9c4ea..766b00d612 100644
--- a/modules/mono/glue/collections_glue.cpp
+++ b/modules/mono/glue/collections_glue.cpp
@@ -28,14 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "collections_glue.h"
-
#ifdef MONO_GLUE_ENABLED
#include <mono/metadata/exception.h>
+#include "core/array.h"
+
#include "../mono_gd/gd_mono_cache.h"
#include "../mono_gd/gd_mono_class.h"
+#include "../mono_gd/gd_mono_marshal.h"
#include "../mono_gd/gd_mono_utils.h"
Array *godot_icall_Array_Ctor() {
diff --git a/modules/mono/glue/collections_glue.h b/modules/mono/glue/collections_glue.h
deleted file mode 100644
index f8351a1fc7..0000000000
--- a/modules/mono/glue/collections_glue.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*************************************************************************/
-/* collections_glue.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 COLLECTIONS_GLUE_H
-#define COLLECTIONS_GLUE_H
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "core/array.h"
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-// Array
-
-Array *godot_icall_Array_Ctor();
-
-void godot_icall_Array_Dtor(Array *ptr);
-
-MonoObject *godot_icall_Array_At(Array *ptr, int index);
-
-MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_encoding, GDMonoClass *type_class);
-
-void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value);
-
-int godot_icall_Array_Count(Array *ptr);
-
-int godot_icall_Array_Add(Array *ptr, MonoObject *item);
-
-void godot_icall_Array_Clear(Array *ptr);
-
-MonoBoolean godot_icall_Array_Contains(Array *ptr, MonoObject *item);
-
-void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index);
-
-Array *godot_icall_Array_Duplicate(Array *ptr, MonoBoolean deep);
-
-int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item);
-
-void godot_icall_Array_Insert(Array *ptr, int index, MonoObject *item);
-
-MonoBoolean godot_icall_Array_Remove(Array *ptr, MonoObject *item);
-
-void godot_icall_Array_RemoveAt(Array *ptr, int index);
-
-Error godot_icall_Array_Resize(Array *ptr, int new_size);
-
-void godot_icall_Array_Generic_GetElementTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class);
-
-MonoString *godot_icall_Array_ToString(Array *ptr);
-
-// Dictionary
-
-Dictionary *godot_icall_Dictionary_Ctor();
-
-void godot_icall_Dictionary_Dtor(Dictionary *ptr);
-
-MonoObject *godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key);
-
-MonoObject *godot_icall_Dictionary_GetValue_Generic(Dictionary *ptr, MonoObject *key, uint32_t type_encoding, GDMonoClass *type_class);
-
-void godot_icall_Dictionary_SetValue(Dictionary *ptr, MonoObject *key, MonoObject *value);
-
-Array *godot_icall_Dictionary_Keys(Dictionary *ptr);
-
-Array *godot_icall_Dictionary_Values(Dictionary *ptr);
-
-int godot_icall_Dictionary_Count(Dictionary *ptr);
-
-void godot_icall_Dictionary_Add(Dictionary *ptr, MonoObject *key, MonoObject *value);
-
-void godot_icall_Dictionary_Clear(Dictionary *ptr);
-
-MonoBoolean godot_icall_Dictionary_Contains(Dictionary *ptr, MonoObject *key, MonoObject *value);
-
-MonoBoolean godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key);
-
-Dictionary *godot_icall_Dictionary_Duplicate(Dictionary *ptr, MonoBoolean deep);
-
-MonoBoolean godot_icall_Dictionary_RemoveKey(Dictionary *ptr, MonoObject *key);
-
-MonoBoolean godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, MonoObject *value);
-
-MonoBoolean godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoObject **value);
-
-MonoBoolean godot_icall_Dictionary_TryGetValue_Generic(Dictionary *ptr, MonoObject *key, MonoObject **value, uint32_t type_encoding, GDMonoClass *type_class);
-
-void godot_icall_Dictionary_Generic_GetValueTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class);
-
-MonoString *godot_icall_Dictionary_ToString(Dictionary *ptr);
-
-// Register internal calls
-
-void godot_register_collections_icalls();
-
-#endif // MONO_GLUE_ENABLED
-
-#endif // COLLECTIONS_GLUE_H
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index e43b06d18e..5e892b616b 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -28,8 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "gd_glue.h"
-
#ifdef MONO_GLUE_ENABLED
#include "core/array.h"
@@ -40,6 +38,7 @@
#include "core/variant_parser.h"
#include "../mono_gd/gd_mono_cache.h"
+#include "../mono_gd/gd_mono_marshal.h"
#include "../mono_gd/gd_mono_utils.h"
MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects) {
@@ -147,8 +146,9 @@ void godot_icall_GD_prints(MonoArray *p_what) {
return;
}
- if (i)
+ if (i) {
str += " ";
+ }
str += elem_str;
}
@@ -171,8 +171,9 @@ void godot_icall_GD_printt(MonoArray *p_what) {
return;
}
- if (i)
+ if (i) {
str += "\t";
+ }
str += elem_str;
}
@@ -197,7 +198,7 @@ double godot_icall_GD_rand_range(double from, double to) {
}
uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed) {
- int ret = Math::rand_from_seed(&seed);
+ uint32_t ret = Math::rand_from_seed(&seed);
*newSeed = seed;
return ret;
}
@@ -213,10 +214,11 @@ MonoString *godot_icall_GD_str(MonoArray *p_what) {
for (int i = 0; i < what.size(); i++) {
String os = what[i].operator String();
- if (i == 0)
+ if (i == 0) {
str = os;
- else
+ } else {
str += os;
+ }
}
return GDMonoMarshal::mono_string_from_godot(str);
diff --git a/modules/mono/glue/gd_glue.h b/modules/mono/glue/gd_glue.h
deleted file mode 100644
index 3ad6058205..0000000000
--- a/modules/mono/glue/gd_glue.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*************************************************************************/
-/* gd_glue.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 GD_GLUE_H
-#define GD_GLUE_H
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects);
-
-MonoObject *godot_icall_GD_convert(MonoObject *p_what, int32_t p_type);
-
-int godot_icall_GD_hash(MonoObject *p_var);
-
-MonoObject *godot_icall_GD_instance_from_id(uint64_t p_instance_id);
-
-void godot_icall_GD_print(MonoArray *p_what);
-
-void godot_icall_GD_printerr(MonoArray *p_what);
-
-void godot_icall_GD_printraw(MonoArray *p_what);
-
-void godot_icall_GD_prints(MonoArray *p_what);
-
-void godot_icall_GD_printt(MonoArray *p_what);
-
-float godot_icall_GD_randf();
-
-uint32_t godot_icall_GD_randi();
-
-void godot_icall_GD_randomize();
-
-double godot_icall_GD_rand_range(double from, double to);
-
-uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed);
-
-void godot_icall_GD_seed(uint64_t p_seed);
-
-MonoString *godot_icall_GD_str(MonoArray *p_what);
-
-MonoObject *godot_icall_GD_str2var(MonoString *p_str);
-
-MonoBoolean godot_icall_GD_type_exists(StringName *p_type);
-
-MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects);
-
-MonoString *godot_icall_GD_var2str(MonoObject *p_var);
-
-MonoObject *godot_icall_DefaultGodotTaskScheduler();
-
-// Register internal calls
-
-void godot_register_gd_icalls();
-
-#endif // MONO_GLUE_ENABLED
-
-#endif // GD_GLUE_H
diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h
index f6999d01fb..c1f1936711 100644
--- a/modules/mono/glue/glue_header.h
+++ b/modules/mono/glue/glue_header.h
@@ -30,14 +30,16 @@
#ifdef MONO_GLUE_ENABLED
-#include "base_object_glue.h"
-#include "collections_glue.h"
-#include "gd_glue.h"
-#include "nodepath_glue.h"
-#include "rid_glue.h"
-#include "scene_tree_glue.h"
-#include "string_glue.h"
-#include "string_name_glue.h"
+#include "../mono_gd/gd_mono_marshal.h"
+
+void godot_register_collections_icalls();
+void godot_register_gd_icalls();
+void godot_register_string_name_icalls();
+void godot_register_nodepath_icalls();
+void godot_register_object_icalls();
+void godot_register_rid_icalls();
+void godot_register_string_icalls();
+void godot_register_scene_tree_icalls();
/**
* Registers internal calls that were not generated. This function is called
diff --git a/modules/mono/glue/nodepath_glue.cpp b/modules/mono/glue/nodepath_glue.cpp
index e413f404d8..2aa75dd309 100644
--- a/modules/mono/glue/nodepath_glue.cpp
+++ b/modules/mono/glue/nodepath_glue.cpp
@@ -28,12 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "nodepath_glue.h"
-
#ifdef MONO_GLUE_ENABLED
+#include "core/node_path.h"
#include "core/ustring.h"
+#include "../mono_gd/gd_mono_marshal.h"
+
NodePath *godot_icall_NodePath_Ctor(MonoString *p_path) {
return memnew(NodePath(GDMonoMarshal::mono_string_to_godot(p_path)));
}
@@ -51,7 +52,7 @@ MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr) {
return (MonoBoolean)p_ptr->is_absolute();
}
-uint32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr) {
+int32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr) {
return p_ptr->get_name_count();
}
@@ -59,7 +60,7 @@ MonoString *godot_icall_NodePath_get_name(NodePath *p_ptr, uint32_t p_idx) {
return GDMonoMarshal::mono_string_from_godot(p_ptr->get_name(p_idx));
}
-uint32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr) {
+int32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr) {
return p_ptr->get_subname_count();
}
diff --git a/modules/mono/glue/nodepath_glue.h b/modules/mono/glue/nodepath_glue.h
deleted file mode 100644
index 727679c278..0000000000
--- a/modules/mono/glue/nodepath_glue.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*************************************************************************/
-/* nodepath_glue.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 NODEPATH_GLUE_H
-#define NODEPATH_GLUE_H
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "core/node_path.h"
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-NodePath *godot_icall_NodePath_Ctor(MonoString *p_path);
-
-void godot_icall_NodePath_Dtor(NodePath *p_ptr);
-
-MonoString *godot_icall_NodePath_operator_String(NodePath *p_np);
-
-MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr);
-
-uint32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr);
-
-MonoString *godot_icall_NodePath_get_name(NodePath *p_ptr, uint32_t p_idx);
-
-uint32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr);
-
-MonoString *godot_icall_NodePath_get_subname(NodePath *p_ptr, uint32_t p_idx);
-
-MonoString *godot_icall_NodePath_get_concatenated_subnames(NodePath *p_ptr);
-
-NodePath *godot_icall_NodePath_get_as_property_path(NodePath *p_ptr);
-
-MonoBoolean godot_icall_NodePath_is_empty(NodePath *p_ptr);
-
-// Register internal calls
-
-void godot_register_nodepath_icalls();
-
-#endif // MONO_GLUE_ENABLED
-
-#endif // NODEPATH_GLUE_H
diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp
index 66a49d8fec..6d2e6b559f 100644
--- a/modules/mono/glue/rid_glue.cpp
+++ b/modules/mono/glue/rid_glue.cpp
@@ -28,17 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rid_glue.h"
-
#ifdef MONO_GLUE_ENABLED
+#include "core/object.h"
#include "core/resource.h"
+#include "core/rid.h"
+
+#include "../mono_gd/gd_mono_marshal.h"
RID *godot_icall_RID_Ctor(Object *p_from) {
Resource *res_from = Object::cast_to<Resource>(p_from);
- if (res_from)
+ if (res_from) {
return memnew(RID(res_from->get_rid()));
+ }
return memnew(RID);
}
diff --git a/modules/mono/glue/rid_glue.h b/modules/mono/glue/rid_glue.h
deleted file mode 100644
index 506d715451..0000000000
--- a/modules/mono/glue/rid_glue.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*************************************************************************/
-/* rid_glue.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 RID_GLUE_H
-#define RID_GLUE_H
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "core/object.h"
-#include "core/rid.h"
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-RID *godot_icall_RID_Ctor(Object *p_from);
-
-void godot_icall_RID_Dtor(RID *p_ptr);
-
-uint32_t godot_icall_RID_get_id(RID *p_ptr);
-
-// Register internal calls
-
-void godot_register_rid_icalls();
-
-#endif // MONO_GLUE_ENABLED
-
-#endif // RID_GLUE_H
diff --git a/modules/mono/glue/scene_tree_glue.cpp b/modules/mono/glue/scene_tree_glue.cpp
index bea9544b08..b43daccc1b 100644
--- a/modules/mono/glue/scene_tree_glue.cpp
+++ b/modules/mono/glue/scene_tree_glue.cpp
@@ -28,14 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "scene_tree_glue.h"
-
#ifdef MONO_GLUE_ENABLED
+#include "core/array.h"
#include "core/class_db.h"
-#include "modules/mono/csharp_script.h"
-#include "modules/mono/mono_gd/gd_mono_utils.h"
+#include "core/string_name.h"
#include "scene/main/node.h"
+#include "scene/main/scene_tree.h"
+
+#include "../csharp_script.h"
+#include "../mono_gd/gd_mono_marshal.h"
+#include "../mono_gd/gd_mono_utils.h"
Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringName *group, MonoReflectionType *refltype) {
List<Node *> nodes;
@@ -54,8 +57,9 @@ Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringNa
// If we're trying to get native objects, just check the inheritance list
StringName native_class_name = GDMonoUtils::get_native_godot_class_name(klass);
for (int i = 0; i < nodes.size(); ++i) {
- if (ClassDB::is_parent_class(nodes[i]->get_class(), native_class_name))
+ if (ClassDB::is_parent_class(nodes[i]->get_class(), native_class_name)) {
ret.push_back(nodes[i]);
+ }
}
} else {
// If we're trying to get csharpscript instances, get the mono object and compare the classes
diff --git a/modules/mono/glue/scene_tree_glue.h b/modules/mono/glue/scene_tree_glue.h
deleted file mode 100644
index e9af35a30b..0000000000
--- a/modules/mono/glue/scene_tree_glue.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*************************************************************************/
-/* scene_tree_glue.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 SCENE_TREE_GLUE_H
-#define SCENE_TREE_GLUE_H
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "core/array.h"
-#include "core/string_name.h"
-#include "scene/main/scene_tree.h"
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringName *group, MonoReflectionType *refltype);
-
-// Register internal calls
-
-void godot_register_scene_tree_icalls();
-
-#endif // MONO_GLUE_ENABLED
-
-#endif // SCENE_TREE_GLUE_H
diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp
index e407a70db9..595b8d71f1 100644
--- a/modules/mono/glue/string_glue.cpp
+++ b/modules/mono/glue/string_glue.cpp
@@ -28,14 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "string_glue.h"
-
#ifdef MONO_GLUE_ENABLED
#include "core/ustring.h"
#include "core/variant.h"
#include "core/vector.h"
+#include "../mono_gd/gd_mono_marshal.h"
+
MonoArray *godot_icall_String_md5_buffer(MonoString *p_str) {
Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_buffer();
// TODO Check possible Array/Vector<uint8_t> problem?
diff --git a/modules/mono/glue/string_glue.h b/modules/mono/glue/string_glue.h
deleted file mode 100644
index a5e833ba61..0000000000
--- a/modules/mono/glue/string_glue.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*************************************************************************/
-/* string_glue.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 STRING_GLUE_H
-#define STRING_GLUE_H
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-MonoArray *godot_icall_String_md5_buffer(MonoString *p_str);
-
-MonoString *godot_icall_String_md5_text(MonoString *p_str);
-
-int godot_icall_String_rfind(MonoString *p_str, MonoString *p_what, int p_from);
-
-int godot_icall_String_rfindn(MonoString *p_str, MonoString *p_what, int p_from);
-
-MonoArray *godot_icall_String_sha256_buffer(MonoString *p_str);
-
-MonoString *godot_icall_String_sha256_text(MonoString *p_str);
-
-// Register internal calls
-
-void godot_register_string_icalls();
-
-#endif // MONO_GLUE_ENABLED
-
-#endif // STRING_GLUE_H
diff --git a/modules/mono/glue/string_name_glue.cpp b/modules/mono/glue/string_name_glue.cpp
index 81006e5849..4b2e88569b 100644
--- a/modules/mono/glue/string_name_glue.cpp
+++ b/modules/mono/glue/string_name_glue.cpp
@@ -28,12 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "string_name_glue.h"
-
#ifdef MONO_GLUE_ENABLED
+#include "core/string_name.h"
#include "core/ustring.h"
+#include "../mono_gd/gd_mono_marshal.h"
+
StringName *godot_icall_StringName_Ctor(MonoString *p_path) {
return memnew(StringName(GDMonoMarshal::mono_string_to_godot(p_path)));
}
@@ -48,7 +49,7 @@ MonoString *godot_icall_StringName_operator_String(StringName *p_np) {
}
MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr) {
- return (MonoBoolean)(p_ptr == StringName());
+ return (MonoBoolean)(*p_ptr == StringName());
}
void godot_register_string_name_icalls() {
diff --git a/modules/mono/glue/string_name_glue.h b/modules/mono/glue/string_name_glue.h
deleted file mode 100644
index 88354ddd84..0000000000
--- a/modules/mono/glue/string_name_glue.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*************************************************************************/
-/* string_name_glue.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 STRING_NAME_GLUE_H
-#define STRING_NAME_GLUE_H
-
-#ifdef MONO_GLUE_ENABLED
-
-#include "core/string_name.h"
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-StringName *godot_icall_StringName_Ctor(MonoString *p_path);
-
-void godot_icall_StringName_Dtor(StringName *p_ptr);
-
-MonoString *godot_icall_StringName_operator_String(StringName *p_np);
-
-MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr);
-
-// Register internal calls
-
-void godot_register_string_name_icalls();
-
-#endif // MONO_GLUE_ENABLED
-
-#endif // STRING_NAME_GLUE_H
diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp
index 26347e9162..dbe9c7fc5d 100644
--- a/modules/mono/managed_callable.cpp
+++ b/modules/mono/managed_callable.cpp
@@ -48,8 +48,9 @@ bool ManagedCallable::compare_equal(const CallableCustom *p_a, const CallableCus
MonoDelegate *delegate_b = (MonoDelegate *)b->delegate_handle.get_target();
if (!delegate_a || !delegate_b) {
- if (!delegate_a && !delegate_b)
+ if (!delegate_a && !delegate_b) {
return true;
+ }
return false;
}
@@ -58,8 +59,9 @@ bool ManagedCallable::compare_equal(const CallableCustom *p_a, const CallableCus
}
bool ManagedCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
- if (compare_equal(p_a, p_b))
+ if (compare_equal(p_a, p_b)) {
return false;
+ }
return p_a < p_b;
}
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 39c3bd8934..cf5ac33d20 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -144,8 +144,9 @@ void gd_mono_debug_init() {
if (Engine::get_singleton()->is_editor_hint() ||
ProjectSettings::get_singleton()->get_resource_path().empty() ||
Main::is_project_manager()) {
- if (da_args.size() == 0)
+ if (da_args.size() == 0) {
return;
+ }
}
if (da_args.length() == 0) {
@@ -423,24 +424,27 @@ void GDMono::initialize_load_assemblies() {
bool tool_assemblies_loaded = _load_tools_assemblies();
CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
- if (Main::is_project_manager())
+ if (Main::is_project_manager()) {
return;
+ }
#endif
// Load the project's main assembly. This doesn't necessarily need to succeed.
// The game may not be using .NET at all, or if the project does use .NET and
// we're running in the editor, it may just happen to be it wasn't built yet.
if (!_load_project_assembly()) {
- if (OS::get_singleton()->is_stdout_verbose())
+ if (OS::get_singleton()->is_stdout_verbose()) {
print_error("Mono: Failed to load project assembly");
+ }
}
}
bool GDMono::_are_api_assemblies_out_of_sync() {
bool out_of_sync = core_api_assembly.assembly && (core_api_assembly.out_of_sync || !GDMonoCache::cached_data.godot_api_cache_updated);
#ifdef TOOLS_ENABLED
- if (!out_of_sync)
+ if (!out_of_sync) {
out_of_sync = editor_api_assembly.assembly && editor_api_assembly.out_of_sync;
+ }
#endif
return out_of_sync;
}
@@ -512,16 +516,17 @@ void GDMono::_init_exception_policy() {
}
}
-void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) {
+void GDMono::add_assembly(int32_t p_domain_id, GDMonoAssembly *p_assembly) {
assemblies[p_domain_id][p_assembly->get_name()] = p_assembly;
}
GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) {
- if (p_name == "mscorlib" && corlib_assembly)
+ if (p_name == "mscorlib" && corlib_assembly) {
return corlib_assembly;
+ }
MonoDomain *domain = mono_domain_get();
- uint32_t domain_id = domain ? mono_domain_get_id(domain) : 0;
+ int32_t domain_id = domain ? mono_domain_get_id(domain) : 0;
GDMonoAssembly **result = assemblies[domain_id].getptr(p_name);
return result ? *result : nullptr;
}
@@ -556,8 +561,9 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo
GDMonoAssembly *assembly = GDMonoAssembly::load(p_name, p_aname, p_refonly, p_search_dirs);
- if (!assembly)
+ if (!assembly) {
return false;
+ }
*r_assembly = assembly;
@@ -573,8 +579,9 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo
GDMonoAssembly *assembly = GDMonoAssembly::load_from(p_name, p_path, p_refonly);
- if (!assembly)
+ if (!assembly) {
return false;
+ }
*r_assembly = assembly;
@@ -594,16 +601,19 @@ ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMo
if (nativecalls_klass) {
GDMonoField *api_hash_field = nativecalls_klass->get_field("godot_api_hash");
- if (api_hash_field)
+ if (api_hash_field) {
api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(nullptr));
+ }
GDMonoField *binds_ver_field = nativecalls_klass->get_field("bindings_version");
- if (binds_ver_field)
+ if (binds_ver_field) {
api_assembly_version.bindings_version = GDMonoMarshal::unbox<uint32_t>(binds_ver_field->get_value(nullptr));
+ }
GDMonoField *cs_glue_ver_field = nativecalls_klass->get_field("cs_glue_version");
- if (cs_glue_ver_field)
+ if (cs_glue_ver_field) {
api_assembly_version.cs_glue_version = GDMonoMarshal::unbox<uint32_t>(cs_glue_ver_field->get_value(nullptr));
+ }
}
return api_assembly_version;
@@ -614,13 +624,15 @@ String ApiAssemblyInfo::to_string(ApiAssemblyInfo::Type p_type) {
}
bool GDMono::_load_corlib_assembly() {
- if (corlib_assembly)
+ if (corlib_assembly) {
return true;
+ }
bool success = load_assembly("mscorlib", &corlib_assembly);
- if (success)
+ if (success) {
GDMonoCache::update_corlib_cache();
+ }
return success;
}
@@ -647,12 +659,14 @@ bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
String xml_file = assembly_name + ".xml";
- if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK)
+ if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) {
WARN_PRINT("Failed to copy '" + xml_file + "'.");
+ }
String pdb_file = assembly_name + ".pdb";
- if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK)
+ if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) {
WARN_PRINT("Failed to copy '" + pdb_file + "'.");
+ }
String assembly_file = assembly_name + ".dll";
if (da->copy(src_dir.plus_file(assembly_file), dst_dir.plus_file(assembly_file)) != OK) {
@@ -667,13 +681,15 @@ static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool
String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
- if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path))
+ if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) {
return false;
+ }
String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg");
- if (!FileAccess::exists(cached_api_hash_path))
+ if (!FileAccess::exists(cached_api_hash_path)) {
return false;
+ }
Ref<ConfigFile> cfg;
cfg.instance();
@@ -766,8 +782,9 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const
// Note: Even if only one of the assemblies if missing or out of sync, we update both
- if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path))
+ if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) {
return String(); // No update needed
+ }
print_verbose("Updating '" + p_config + "' API assemblies");
@@ -795,8 +812,9 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const
#endif
bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) {
- if (r_loaded_api_assembly.assembly)
+ if (r_loaded_api_assembly.assembly) {
return true;
+ }
#ifdef TOOLS_ENABLED
// For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date
@@ -828,8 +846,9 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c
#ifdef TOOLS_ENABLED
bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) {
- if (r_loaded_api_assembly.assembly)
+ if (r_loaded_api_assembly.assembly) {
return true;
+ }
// For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date
@@ -859,30 +878,35 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly,
bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly,
const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback) {
if (!_load_core_api_assembly(r_core_api_assembly, p_config, p_refonly)) {
- if (OS::get_singleton()->is_stdout_verbose())
+ if (OS::get_singleton()->is_stdout_verbose()) {
print_error("Mono: Failed to load Core API assembly");
+ }
return false;
}
#ifdef TOOLS_ENABLED
if (!_load_editor_api_assembly(r_editor_api_assembly, p_config, p_refonly)) {
- if (OS::get_singleton()->is_stdout_verbose())
+ if (OS::get_singleton()->is_stdout_verbose()) {
print_error("Mono: Failed to load Editor API assembly");
+ }
return false;
}
- if (r_editor_api_assembly.out_of_sync)
+ if (r_editor_api_assembly.out_of_sync) {
return false;
+ }
#endif
// Check if the core API assembly is out of sync only after trying to load the
// editor API assembly. Otherwise, if both assemblies are out of sync, we would
// only update the former as we won't know the latter also needs to be updated.
- if (r_core_api_assembly.out_of_sync)
+ if (r_core_api_assembly.out_of_sync) {
return false;
+ }
- if (p_callback)
+ if (p_callback) {
return p_callback();
+ }
return true;
}
@@ -890,8 +914,9 @@ bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, Lo
bool GDMono::_on_core_api_assembly_loaded() {
GDMonoCache::update_godot_api_cache();
- if (!GDMonoCache::cached_data.godot_api_cache_updated)
+ if (!GDMonoCache::cached_data.godot_api_cache_updated) {
return false;
+ }
get_singleton()->_install_trace_listener();
@@ -956,8 +981,9 @@ void GDMono::_load_api_assemblies() {
#ifdef TOOLS_ENABLED
bool GDMono::_load_tools_assemblies() {
- if (tools_assembly && tools_project_editor_assembly)
+ if (tools_assembly && tools_project_editor_assembly) {
return true;
+ }
bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) &&
load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly);
@@ -967,8 +993,9 @@ bool GDMono::_load_tools_assemblies() {
#endif
bool GDMono::_load_project_assembly() {
- if (project_assembly)
+ if (project_assembly) {
return true;
+ }
String appname = ProjectSettings::get_singleton()->get("application/config/name");
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
@@ -1020,8 +1047,9 @@ Error GDMono::_unload_scripts_domain() {
print_verbose("Mono: Finalizing scripts domain...");
- if (mono_domain_get() != root_domain)
+ if (mono_domain_get() != root_domain) {
mono_domain_set(root_domain, true);
+ }
finalizing_scripts_domain = true;
@@ -1111,8 +1139,9 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
print_verbose("Mono: Unloading domain '" + domain_name + "'...");
- if (mono_domain_get() == p_domain)
+ if (mono_domain_get() == p_domain) {
mono_domain_set(root_domain, true);
+ }
if (!mono_domain_finalize(p_domain, 2000)) {
ERR_PRINT("Mono: Domain finalization timeout.");
@@ -1138,10 +1167,11 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
MonoImage *image = mono_class_get_image(p_raw_class);
- if (image == corlib_assembly->get_image())
+ if (image == corlib_assembly->get_image()) {
return corlib_assembly->get_class(p_raw_class);
+ }
- uint32_t domain_id = mono_domain_get_id(mono_domain_get());
+ int32_t domain_id = mono_domain_get_id(mono_domain_get());
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
const String *k = nullptr;
@@ -1149,9 +1179,9 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
GDMonoAssembly *assembly = domain_assemblies.get(*k);
if (assembly->get_image() == image) {
GDMonoClass *klass = assembly->get_class(p_raw_class);
-
- if (klass)
+ if (klass) {
return klass;
+ }
}
}
@@ -1160,24 +1190,26 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) {
GDMonoClass *klass = corlib_assembly->get_class(p_namespace, p_name);
- if (klass)
+ if (klass) {
return klass;
+ }
- uint32_t domain_id = mono_domain_get_id(mono_domain_get());
+ int32_t domain_id = mono_domain_get_id(mono_domain_get());
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
const String *k = nullptr;
while ((k = domain_assemblies.next(k))) {
GDMonoAssembly *assembly = domain_assemblies.get(*k);
klass = assembly->get_class(p_namespace, p_name);
- if (klass)
+ if (klass) {
return klass;
+ }
}
return nullptr;
}
-void GDMono::_domain_assemblies_cleanup(uint32_t p_domain_id) {
+void GDMono::_domain_assemblies_cleanup(int32_t p_domain_id) {
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id];
const String *k = nullptr;
@@ -1195,8 +1227,9 @@ void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) {
#ifdef DEBUG_ENABLED
GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc);
- if (EngineDebugger::is_active())
+ if (EngineDebugger::is_active()) {
EngineDebugger::get_singleton()->poll_events(false);
+ }
#endif
exit(mono_environment_exitcode_get());
@@ -1271,7 +1304,7 @@ GDMono::~GDMono() {
// Leave the rest to 'mono_jit_cleanup'
#endif
- const uint32_t *k = nullptr;
+ const int32_t *k = nullptr;
while ((k = assemblies.next(k))) {
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies.get(*k);
@@ -1295,8 +1328,9 @@ GDMono::~GDMono() {
gdmono::android::support::cleanup();
#endif
- if (gdmono_log)
+ if (gdmono_log) {
memdelete(gdmono_log);
+ }
singleton = nullptr;
}
@@ -1313,37 +1347,44 @@ void _GodotSharp::detach_thread() {
int32_t _GodotSharp::get_domain_id() {
MonoDomain *domain = mono_domain_get();
- CRASH_COND(!domain); // User must check if runtime is initialized before calling this method
+ ERR_FAIL_NULL_V(domain, -1);
return mono_domain_get_id(domain);
}
int32_t _GodotSharp::get_scripts_domain_id() {
+ ERR_FAIL_NULL_V_MSG(GDMono::get_singleton(),
+ -1, "The Mono runtime is not initialized");
MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain();
- CRASH_COND(!domain); // User must check if scripts domain is loaded before calling this method
+ ERR_FAIL_NULL_V(domain, -1);
return mono_domain_get_id(domain);
}
bool _GodotSharp::is_scripts_domain_loaded() {
- return GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != nullptr;
+ return GDMono::get_singleton() != nullptr &&
+ GDMono::get_singleton()->is_runtime_initialized() &&
+ GDMono::get_singleton()->get_scripts_domain() != nullptr;
}
bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) {
return is_domain_finalizing_for_unload(p_domain_id);
}
-bool _GodotSharp::is_domain_finalizing_for_unload() {
- return is_domain_finalizing_for_unload(mono_domain_get());
-}
-
bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) {
return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id));
}
bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) {
- if (!p_domain)
- return true;
- if (p_domain == GDMono::get_singleton()->get_scripts_domain() && GDMono::get_singleton()->is_finalizing_scripts_domain())
+ GDMono *gd_mono = GDMono::get_singleton();
+
+ ERR_FAIL_COND_V_MSG(!gd_mono || !gd_mono->is_runtime_initialized(),
+ false, "The Mono runtime is not initialized");
+
+ ERR_FAIL_NULL_V(p_domain, true);
+
+ if (p_domain == gd_mono->get_scripts_domain() && gd_mono->is_finalizing_scripts_domain()) {
return true;
+ }
+
return mono_domain_is_unloading(p_domain);
}
@@ -1352,15 +1393,17 @@ bool _GodotSharp::is_runtime_shutting_down() {
}
bool _GodotSharp::is_runtime_initialized() {
- return GDMono::get_singleton()->is_runtime_initialized();
+ return GDMono::get_singleton() != nullptr && GDMono::get_singleton()->is_runtime_initialized();
}
void _GodotSharp::_reload_assemblies(bool p_soft_reload) {
#ifdef GD_MONO_HOT_RELOAD
+ CRASH_COND(CSharpLanguage::get_singleton() == nullptr);
// This method may be called more than once with `call_deferred`, so we need to check
// again if reloading is needed to avoid reloading multiple times unnecessarily.
- if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed())
+ if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) {
CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
+ }
#endif
}
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index 833855b371..18f7418049 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -97,7 +97,7 @@ private:
MonoDomain *root_domain;
MonoDomain *scripts_domain;
- HashMap<uint32_t, HashMap<String, GDMonoAssembly *>> assemblies;
+ HashMap<int32_t, HashMap<String, GDMonoAssembly *>> assemblies;
GDMonoAssembly *corlib_assembly;
GDMonoAssembly *project_assembly;
@@ -141,7 +141,7 @@ private:
Error _unload_scripts_domain();
#endif
- void _domain_assemblies_cleanup(uint32_t p_domain_id);
+ void _domain_assemblies_cleanup(int32_t p_domain_id);
uint64_t api_core_hash;
#ifdef TOOLS_ENABLED
@@ -165,14 +165,16 @@ protected:
public:
#ifdef DEBUG_METHODS_ENABLED
uint64_t get_api_core_hash() {
- if (api_core_hash == 0)
+ if (api_core_hash == 0) {
api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE);
+ }
return api_core_hash;
}
#ifdef TOOLS_ENABLED
uint64_t get_api_editor_hash() {
- if (api_editor_hash == 0)
+ if (api_editor_hash == 0) {
api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR);
+ }
return api_editor_hash;
}
#endif // TOOLS_ENABLED
@@ -202,7 +204,7 @@ public:
UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; }
// Do not use these, unless you know what you're doing
- void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly);
+ void add_assembly(int32_t p_domain_id, GDMonoAssembly *p_assembly);
GDMonoAssembly *get_loaded_assembly(const String &p_name);
_FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized && !mono_runtime_is_shutting_down() /* stays true after shutdown finished */; }
@@ -252,18 +254,18 @@ class ScopeDomain {
public:
ScopeDomain(MonoDomain *p_domain) {
- MonoDomain *prev_domain = mono_domain_get();
+ prev_domain = mono_domain_get();
if (prev_domain != p_domain) {
- this->prev_domain = prev_domain;
mono_domain_set(p_domain, false);
} else {
- this->prev_domain = nullptr;
+ prev_domain = nullptr;
}
}
~ScopeDomain() {
- if (prev_domain)
+ if (prev_domain) {
mono_domain_set(prev_domain, false);
+ }
}
};
@@ -276,8 +278,9 @@ public:
}
~ScopeExitDomainUnload() {
- if (domain)
+ if (domain) {
GDMono::get_singleton()->finalize_and_unload_domain(domain);
+ }
}
};
@@ -298,9 +301,6 @@ class _GodotSharp : public Object {
bool _is_domain_finalizing_for_unload(int32_t p_domain_id);
- List<NodePath *> np_delete_queue;
- List<RID *> rid_delete_queue;
-
void _reload_assemblies(bool p_soft_reload);
protected:
@@ -318,7 +318,6 @@ public:
bool is_scripts_domain_loaded();
- bool is_domain_finalizing_for_unload();
bool is_domain_finalizing_for_unload(int32_t p_domain_id);
bool is_domain_finalizing_for_unload(MonoDomain *p_domain);
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 073c9a5214..a170fd36e7 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -108,8 +108,9 @@ void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, [[maybe_unused]]
#ifdef GD_MONO_HOT_RELOAD
const char *path = mono_image_get_filename(image);
- if (FileAccess::exists(path))
+ if (FileAccess::exists(path)) {
gdassembly->modified_time = FileAccess::get_modified_time(path);
+ }
#endif
MonoDomain *domain = mono_domain_get();
@@ -137,8 +138,9 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, [[maybe_unus
bool has_extension = name.ends_with(".dll") || name.ends_with(".exe");
GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
- if (loaded_asm)
+ if (loaded_asm) {
return loaded_asm->get_assembly();
+ }
return nullptr;
}
@@ -161,22 +163,25 @@ MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, MonoAs
path = search_dir.plus_file(p_name);
if (FileAccess::exists(path)) {
res = _real_load_assembly_from(path, p_refonly, p_aname);
- if (res != nullptr)
+ if (res != nullptr) {
return res;
+ }
}
} else {
path = search_dir.plus_file(p_name + ".dll");
if (FileAccess::exists(path)) {
res = _real_load_assembly_from(path, p_refonly, p_aname);
- if (res != nullptr)
+ if (res != nullptr) {
return res;
+ }
}
path = search_dir.plus_file(p_name + ".exe");
if (FileAccess::exists(path)) {
res = _real_load_assembly_from(path, p_refonly, p_aname);
- if (res != nullptr)
+ if (res != nullptr) {
return res;
+ }
}
}
}
@@ -194,16 +199,19 @@ String GDMonoAssembly::find_assembly(const String &p_name) {
if (has_extension) {
path = search_dir.plus_file(p_name);
- if (FileAccess::exists(path))
+ if (FileAccess::exists(path)) {
return path;
+ }
} else {
path = search_dir.plus_file(p_name + ".dll");
- if (FileAccess::exists(path))
+ if (FileAccess::exists(path)) {
return path;
+ }
path = search_dir.plus_file(p_name + ".exe");
- if (FileAccess::exists(path))
+ if (FileAccess::exists(path)) {
return path;
+ }
}
}
@@ -279,8 +287,9 @@ MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, boo
if (!FileAccess::exists(pdb_path)) {
pdb_path = p_path.get_basename() + ".pdb"; // without .dll
- if (!FileAccess::exists(pdb_path))
+ if (!FileAccess::exists(pdb_path)) {
goto no_pdb;
+ }
}
pdb_data = FileAccess::get_file_as_array(pdb_path);
@@ -307,8 +316,9 @@ no_pdb:
String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly)));
bool has_extension = name.ends_with(".dll") || name.ends_with(".exe");
GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
- if (!loaded_asm)
+ if (!loaded_asm) {
assembly_load_hook(assembly, nullptr);
+ }
}
// Decrement refcount which was previously incremented by mono_image_open_from_data_with_name
@@ -342,13 +352,15 @@ GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const Stri
GDMonoClass **match = cached_classes.getptr(key);
- if (match)
+ if (match) {
return *match;
+ }
MonoClass *mono_class = mono_class_from_name(image, String(p_namespace).utf8(), String(p_name).utf8());
- if (!mono_class)
+ if (!mono_class) {
return nullptr;
+ }
GDMonoClass *wrapped_class = memnew(GDMonoClass(p_namespace, p_name, mono_class, this));
@@ -363,8 +375,9 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
Map<MonoClass *, GDMonoClass *>::Element *match = cached_raw.find(p_mono_class);
- if (match)
+ if (match) {
return match->value();
+ }
StringName namespace_name = mono_class_get_namespace(p_mono_class);
StringName class_name = mono_class_get_name(p_mono_class);
@@ -383,8 +396,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
if (gdobject_class_cache_updated) {
Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class);
- if (result)
+ if (result) {
match = result->get();
+ }
} else {
List<GDMonoClass *> nested_classes;
@@ -393,18 +407,21 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
for (int i = 1; i < rows; i++) {
MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF);
- if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class))
+ if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) {
continue;
+ }
GDMonoClass *current = get_class(mono_class);
- if (!current)
+ if (!current) {
continue;
+ }
nested_classes.push_back(current);
- if (!match && current->get_name() == p_class)
+ if (!match && current->get_name() == p_class) {
match = current;
+ }
while (!nested_classes.empty()) {
GDMonoClass *current_nested = nested_classes.front()->get();
@@ -415,8 +432,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
while (true) {
MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter);
- if (!raw_nested)
+ if (!raw_nested) {
break;
+ }
GDMonoClass *nested_class = get_class(raw_nested);
@@ -437,8 +455,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
}
GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) {
- if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll"))
+ if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) {
return GDMono::get_singleton()->get_corlib_assembly();
+ }
// We need to manually call the search hook in this case, as it won't be called in the next step
MonoAssembly *assembly = mono_assembly_invoke_search_hook(p_aname);
@@ -456,8 +475,9 @@ GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_a
}
GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) {
- if (p_name == "mscorlib" || p_name == "mscorlib.dll")
+ if (p_name == "mscorlib" || p_name == "mscorlib.dll") {
return GDMono::get_singleton()->get_corlib_assembly();
+ }
// We need to manually call the search hook in this case, as it won't be called in the next step
MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8());
@@ -477,6 +497,7 @@ GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_
}
GDMonoAssembly::~GDMonoAssembly() {
- if (image)
+ if (image) {
unload();
+ }
}
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp
index c002ad2139..29aef6e609 100644
--- a/modules/mono/mono_gd/gd_mono_cache.cpp
+++ b/modules/mono/mono_gd/gd_mono_cache.cpp
@@ -217,7 +217,7 @@ void update_corlib_cache() {
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true));
#endif
- CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", true));
CACHE_CLASS_AND_CHECK(KeyNotFoundException, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections.Generic", "KeyNotFoundException"));
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index 691da55b10..6575cbc1c8 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -81,15 +81,17 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const {
StringName GDMonoClass::get_namespace() const {
GDMonoClass *nesting_class = get_nesting_class();
- if (!nesting_class)
+ if (!nesting_class) {
return namespace_name;
+ }
return nesting_class->get_namespace();
}
String GDMonoClass::get_name_for_lookup() const {
GDMonoClass *nesting_class = get_nesting_class();
- if (!nesting_class)
+ if (!nesting_class) {
return class_name;
+ }
return nesting_class->get_name_for_lookup() + "/" + class_name;
}
@@ -131,11 +133,13 @@ bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, false);
#endif
- if (!attrs_fetched)
+ if (!attrs_fetched) {
fetch_attributes();
+ }
- if (!attributes)
+ if (!attributes) {
return false;
+ }
return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
}
@@ -145,11 +149,13 @@ MonoObject *GDMonoClass::get_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, nullptr);
#endif
- if (!attrs_fetched)
+ if (!attrs_fetched) {
fetch_attributes();
+ }
- if (!attributes)
+ if (!attributes) {
return nullptr;
+ }
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
}
@@ -164,8 +170,9 @@ void GDMonoClass::fetch_attributes() {
void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base) {
CRASH_COND(!CACHED_CLASS(GodotObject)->is_assignable_from(this));
- if (methods_fetched)
+ if (methods_fetched) {
return;
+ }
void *iter = nullptr;
MonoMethod *raw_method = nullptr;
@@ -202,8 +209,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
break;
}
- if (native_top == CACHED_CLASS(GodotObject))
+ if (native_top == CACHED_CLASS(GodotObject)) {
break;
+ }
native_top = native_top->get_parent_class();
}
@@ -212,8 +220,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
uint32_t flags = mono_method_get_flags(method->mono_method, nullptr);
- if (!(flags & MONO_METHOD_ATTR_VIRTUAL))
+ if (!(flags & MONO_METHOD_ATTR_VIRTUAL)) {
continue;
+ }
// Virtual method of Godot Object derived type, let's try to find GodotMethod attribute
@@ -235,15 +244,17 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
#endif
MethodKey key = MethodKey(godot_method_name, method->get_parameters_count());
GDMonoMethod **existing_method = methods.getptr(key);
- if (existing_method)
+ if (existing_method) {
memdelete(*existing_method); // Must delete old one
+ }
methods.set(key, method);
break;
}
- if (top == CACHED_CLASS(GodotObject))
+ if (top == CACHED_CLASS(GodotObject)) {
break;
+ }
top = top->get_parent_class();
}
@@ -258,8 +269,9 @@ GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p
const MethodKey *k = nullptr;
while ((k = methods.next(k))) {
- if (k->name == p_name)
+ if (k->name == p_name) {
return methods.get(*k);
+ }
}
return nullptr;
@@ -283,11 +295,13 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_cou
GDMonoMethod **match = methods.getptr(key);
- if (match)
+ if (match) {
return *match;
+ }
- if (methods_fetched)
+ if (methods_fetched) {
return nullptr;
+ }
MonoMethod *raw_method = mono_class_get_method_from_name(mono_class, String(p_name).utf8().get_data(), p_params_count);
@@ -323,8 +337,9 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName
GDMonoMethod **match = methods.getptr(key);
- if (match)
+ if (match) {
return *match;
+ }
GDMonoMethod *method = memnew(GDMonoMethod(p_name, p_raw_method));
methods.set(key, method);
@@ -337,8 +352,9 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo
MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class);
mono_method_desc_free(desc);
- if (!method)
+ if (!method) {
return nullptr;
+ }
ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr);
@@ -348,11 +364,13 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo
GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
Map<StringName, GDMonoField *>::Element *result = fields.find(p_name);
- if (result)
+ if (result) {
return result->value();
+ }
- if (fields_fetched)
+ if (fields_fetched) {
return nullptr;
+ }
MonoClassField *raw_field = mono_class_get_field_from_name(mono_class, String(p_name).utf8().get_data());
@@ -367,8 +385,9 @@ GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
}
const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
- if (fields_fetched)
+ if (fields_fetched) {
return fields_list;
+ }
void *iter = nullptr;
MonoClassField *raw_field = nullptr;
@@ -394,11 +413,13 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) {
Map<StringName, GDMonoProperty *>::Element *result = properties.find(p_name);
- if (result)
+ if (result) {
return result->value();
+ }
- if (properties_fetched)
+ if (properties_fetched) {
return nullptr;
+ }
MonoProperty *raw_property = mono_class_get_property_from_name(mono_class, String(p_name).utf8().get_data());
@@ -413,8 +434,9 @@ GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) {
}
const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
- if (properties_fetched)
+ if (properties_fetched) {
return properties_list;
+ }
void *iter = nullptr;
MonoProperty *raw_property = nullptr;
@@ -438,8 +460,9 @@ const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
}
const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
- if (delegates_fetched)
+ if (delegates_fetched) {
return delegates_list;
+ }
void *iter = nullptr;
MonoClass *raw_class = nullptr;
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index 948170f51c..563c45e71f 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -597,11 +597,13 @@ String GDMonoField::get_string_value(MonoObject *p_object) {
bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, false);
- if (!attrs_fetched)
+ if (!attrs_fetched) {
fetch_attributes();
+ }
- if (!attributes)
+ if (!attributes) {
return false;
+ }
return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
}
@@ -609,11 +611,13 @@ bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) {
MonoObject *GDMonoField::get_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, nullptr);
- if (!attrs_fetched)
+ if (!attrs_fetched) {
fetch_attributes();
+ }
- if (!attributes)
+ if (!attributes) {
return nullptr;
+ }
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
}
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index abb2761909..fe1c2d28dd 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -122,9 +122,10 @@ void unhandled_exception(MonoException *p_exc) {
GD_UNREACHABLE();
} else {
#ifdef DEBUG_ENABLED
- GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc);
- if (EngineDebugger::is_active())
+ GDMonoUtils::debug_send_unhandled_exception_error(p_exc);
+ if (EngineDebugger::is_active()) {
EngineDebugger::get_singleton()->poll_events(false);
+ }
#endif
}
}
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index 04728be725..c5a988b8c3 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -55,8 +55,9 @@ static int get_log_level_id(const char *p_log_level) {
int i = 0;
while (valid_log_levels[i]) {
- if (!strcmp(valid_log_levels[i], p_log_level))
+ if (!strcmp(valid_log_levels[i], p_log_level)) {
return i;
+ }
i++;
}
@@ -115,10 +116,12 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
String current;
while ((current = da->get_next()).length()) {
- if (da->current_is_dir())
+ if (da->current_is_dir()) {
continue;
- if (!current.ends_with(".txt"))
+ }
+ if (!current.ends_with(".txt")) {
continue;
+ }
uint64_t modified_time = FileAccess::get_modified_time(da->get_current_dir().plus_file(current));
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 158742846b..1a50f3c414 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -72,92 +72,119 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
case MONO_TYPE_VALUETYPE: {
GDMonoClass *vtclass = p_type.type_class;
- if (vtclass == CACHED_CLASS(Vector2))
+ if (vtclass == CACHED_CLASS(Vector2)) {
return Variant::VECTOR2;
+ }
- if (vtclass == CACHED_CLASS(Vector2i))
+ if (vtclass == CACHED_CLASS(Vector2i)) {
return Variant::VECTOR2I;
+ }
- if (vtclass == CACHED_CLASS(Rect2))
+ if (vtclass == CACHED_CLASS(Rect2)) {
return Variant::RECT2;
+ }
- if (vtclass == CACHED_CLASS(Rect2i))
+ if (vtclass == CACHED_CLASS(Rect2i)) {
return Variant::RECT2I;
+ }
- if (vtclass == CACHED_CLASS(Transform2D))
+ if (vtclass == CACHED_CLASS(Transform2D)) {
return Variant::TRANSFORM2D;
+ }
- if (vtclass == CACHED_CLASS(Vector3))
+ if (vtclass == CACHED_CLASS(Vector3)) {
return Variant::VECTOR3;
+ }
- if (vtclass == CACHED_CLASS(Vector3i))
+ if (vtclass == CACHED_CLASS(Vector3i)) {
return Variant::VECTOR3I;
+ }
- if (vtclass == CACHED_CLASS(Basis))
+ if (vtclass == CACHED_CLASS(Basis)) {
return Variant::BASIS;
+ }
- if (vtclass == CACHED_CLASS(Quat))
+ if (vtclass == CACHED_CLASS(Quat)) {
return Variant::QUAT;
+ }
- if (vtclass == CACHED_CLASS(Transform))
+ if (vtclass == CACHED_CLASS(Transform)) {
return Variant::TRANSFORM;
+ }
- if (vtclass == CACHED_CLASS(AABB))
+ if (vtclass == CACHED_CLASS(AABB)) {
return Variant::AABB;
+ }
- if (vtclass == CACHED_CLASS(Color))
+ if (vtclass == CACHED_CLASS(Color)) {
return Variant::COLOR;
+ }
- if (vtclass == CACHED_CLASS(Plane))
+ if (vtclass == CACHED_CLASS(Plane)) {
return Variant::PLANE;
+ }
- if (vtclass == CACHED_CLASS(Callable))
+ if (vtclass == CACHED_CLASS(Callable)) {
return Variant::CALLABLE;
+ }
- if (vtclass == CACHED_CLASS(SignalInfo))
+ if (vtclass == CACHED_CLASS(SignalInfo)) {
return Variant::SIGNAL;
+ }
- if (mono_class_is_enum(vtclass->get_mono_ptr()))
+ if (mono_class_is_enum(vtclass->get_mono_ptr())) {
return Variant::INT;
+ }
} break;
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY: {
MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
- if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
+ if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
return Variant::ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
return Variant::PACKED_BYTE_ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
return Variant::PACKED_INT32_ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(int64_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
return Variant::PACKED_INT64_ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(float))
+ if (array_type->eklass == CACHED_CLASS_RAW(float)) {
return Variant::PACKED_FLOAT32_ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(double))
+ if (array_type->eklass == CACHED_CLASS_RAW(double)) {
return Variant::PACKED_FLOAT64_ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(String))
+ if (array_type->eklass == CACHED_CLASS_RAW(String)) {
return Variant::PACKED_STRING_ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
+ if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
return Variant::PACKED_VECTOR2_ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
+ if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
return Variant::PACKED_VECTOR3_ARRAY;
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Color))
+ if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
return Variant::PACKED_COLOR_ARRAY;
+ }
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
- if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
return Variant::ARRAY;
+ }
} break;
case MONO_TYPE_CLASS: {
@@ -201,8 +228,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
} break;
case MONO_TYPE_OBJECT: {
- if (r_nil_is_variant)
+ if (r_nil_is_variant) {
*r_nil_is_variant = true;
+ }
return Variant::NIL;
} break;
@@ -244,8 +272,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
} break;
}
- if (r_nil_is_variant)
+ if (r_nil_is_variant) {
*r_nil_is_variant = false;
+ }
// Unknown
return Variant::NIL;
@@ -282,31 +311,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_
return false;
}
-bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type) {
- switch (p_dictionary_type.type_encoding) {
- case MONO_TYPE_GENERICINST: {
- MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type());
-
- if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) ||
- GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) ||
- GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) {
- MonoReflectionType *key_reftype;
- MonoReflectionType *value_reftype;
-
- GDMonoUtils::Marshal::dictionary_get_key_value_types(dict_reftype, &key_reftype, &value_reftype);
-
- r_key_type = ManagedType::from_reftype(key_reftype);
- r_value_type = ManagedType::from_reftype(value_reftype);
- return true;
- }
- } break;
- default: {
- } break;
- }
-
- return false;
-}
-
String mono_to_utf8_string(MonoString *p_mono_string) {
MonoError error;
char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error);
@@ -328,8 +332,9 @@ String mono_to_utf16_string(MonoString *p_mono_string) {
int len = mono_string_length(p_mono_string);
String ret;
- if (len == 0)
+ if (len == 0) {
return ret;
+ }
ret.resize(len + 1);
ret.set(len, 0);
@@ -409,8 +414,9 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
}
case MONO_TYPE_STRING: {
- if (p_var->get_type() == Variant::NIL)
+ if (p_var->get_type() == Variant::NIL) {
return nullptr; // Otherwise, Variant -> String would return the string "Null"
+ }
return (MonoObject *)mono_string_from_godot(p_var->operator String());
} break;
@@ -547,39 +553,50 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
case MONO_TYPE_SZARRAY: {
MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
- if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
+ if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
return (MonoObject *)Array_to_mono_array(p_var->operator Array());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(int64_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(float))
+ if (array_type->eklass == CACHED_CLASS_RAW(float)) {
return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(double))
+ if (array_type->eklass == CACHED_CLASS_RAW(double)) {
return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(String))
+ if (array_type->eklass == CACHED_CLASS_RAW(String)) {
return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
+ if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
+ if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array());
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Color))
+ if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());
+ }
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
- if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class);
+ }
ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
@@ -820,100 +837,128 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return unbox<double>(p_obj);
case MONO_TYPE_STRING: {
- if (p_obj == nullptr)
+ if (p_obj == nullptr) {
return Variant(); // NIL
+ }
return mono_string_to_godot_not_null((MonoString *)p_obj);
} break;
case MONO_TYPE_VALUETYPE: {
GDMonoClass *vtclass = p_type.type_class;
- if (vtclass == CACHED_CLASS(Vector2))
+ if (vtclass == CACHED_CLASS(Vector2)) {
return MARSHALLED_IN(Vector2, unbox_addr<GDMonoMarshal::M_Vector2>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Vector2i))
+ if (vtclass == CACHED_CLASS(Vector2i)) {
return MARSHALLED_IN(Vector2i, unbox_addr<GDMonoMarshal::M_Vector2i>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Rect2))
+ if (vtclass == CACHED_CLASS(Rect2)) {
return MARSHALLED_IN(Rect2, unbox_addr<GDMonoMarshal::M_Rect2>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Rect2i))
+ if (vtclass == CACHED_CLASS(Rect2i)) {
return MARSHALLED_IN(Rect2i, unbox_addr<GDMonoMarshal::M_Rect2i>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Transform2D))
+ if (vtclass == CACHED_CLASS(Transform2D)) {
return MARSHALLED_IN(Transform2D, unbox_addr<GDMonoMarshal::M_Transform2D>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Vector3))
+ if (vtclass == CACHED_CLASS(Vector3)) {
return MARSHALLED_IN(Vector3, unbox_addr<GDMonoMarshal::M_Vector3>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Vector3i))
+ if (vtclass == CACHED_CLASS(Vector3i)) {
return MARSHALLED_IN(Vector3i, unbox_addr<GDMonoMarshal::M_Vector3i>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Basis))
+ if (vtclass == CACHED_CLASS(Basis)) {
return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Quat))
+ if (vtclass == CACHED_CLASS(Quat)) {
return MARSHALLED_IN(Quat, unbox_addr<GDMonoMarshal::M_Quat>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Transform))
+ if (vtclass == CACHED_CLASS(Transform)) {
return MARSHALLED_IN(Transform, unbox_addr<GDMonoMarshal::M_Transform>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(AABB))
+ if (vtclass == CACHED_CLASS(AABB)) {
return MARSHALLED_IN(AABB, unbox_addr<GDMonoMarshal::M_AABB>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Color))
+ if (vtclass == CACHED_CLASS(Color)) {
return MARSHALLED_IN(Color, unbox_addr<GDMonoMarshal::M_Color>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Plane))
+ if (vtclass == CACHED_CLASS(Plane)) {
return MARSHALLED_IN(Plane, unbox_addr<GDMonoMarshal::M_Plane>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(Callable))
+ if (vtclass == CACHED_CLASS(Callable)) {
return managed_to_callable(unbox<GDMonoMarshal::M_Callable>(p_obj));
+ }
- if (vtclass == CACHED_CLASS(SignalInfo))
+ if (vtclass == CACHED_CLASS(SignalInfo)) {
return managed_to_signal_info(unbox<GDMonoMarshal::M_SignalInfo>(p_obj));
+ }
- if (mono_class_is_enum(vtclass->get_mono_ptr()))
+ if (mono_class_is_enum(vtclass->get_mono_ptr())) {
return unbox<int32_t>(p_obj);
+ }
} break;
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY: {
MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
- if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
+ if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
return mono_array_to_Array((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
return mono_array_to_PackedByteArray((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
return mono_array_to_PackedInt32Array((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(int64_t))
+ if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
return mono_array_to_PackedInt64Array((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(float))
+ if (array_type->eklass == CACHED_CLASS_RAW(float)) {
return mono_array_to_PackedFloat32Array((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(double))
+ if (array_type->eklass == CACHED_CLASS_RAW(double)) {
return mono_array_to_PackedFloat64Array((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(String))
+ if (array_type->eklass == CACHED_CLASS_RAW(String)) {
return mono_array_to_PackedStringArray((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
+ if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
return mono_array_to_PackedVector2Array((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
+ if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
return mono_array_to_PackedVector3Array((MonoArray *)p_obj);
+ }
- if (array_type->eklass == CACHED_CLASS_RAW(Color))
+ if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
return mono_array_to_PackedColorArray((MonoArray *)p_obj);
+ }
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
- if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
return mono_array_to_Array((MonoArray *)p_obj);
+ }
if (p_fail_with_err) {
ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
@@ -1012,8 +1057,9 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
}
Variant mono_object_to_variant(MonoObject *p_obj) {
- if (!p_obj)
+ if (!p_obj) {
return Variant();
+ }
ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj));
@@ -1021,20 +1067,26 @@ Variant mono_object_to_variant(MonoObject *p_obj) {
}
Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
- if (!p_obj)
+ if (!p_obj) {
return Variant();
+ }
return mono_object_to_variant_impl(p_obj, p_type);
}
Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_type) {
- if (!p_obj)
+ if (!p_obj) {
return Variant();
+ }
return mono_object_to_variant_impl(p_obj, p_type, /* fail_with_err: */ false);
}
String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
+ if (p_obj == nullptr) {
+ return String("null");
+ }
+
ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj));
Variant var = GDMonoMarshal::mono_object_to_variant_no_err(p_obj, type);
@@ -1044,8 +1096,9 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc);
if (exc) {
- if (r_exc)
+ if (r_exc) {
*r_exc = exc;
+ }
return String();
}
@@ -1155,8 +1208,9 @@ MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_c
Array mono_array_to_Array(MonoArray *p_array) {
Array ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
@@ -1174,7 +1228,7 @@ MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), length);
- int32_t *dst = (int32_t *)mono_array_addr(ret, int32_t, 0);
+ int32_t *dst = mono_array_addr(ret, int32_t, 0);
memcpy(dst, src, length);
return ret;
@@ -1182,13 +1236,14 @@ MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array) {
PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array) {
PackedInt32Array ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
int32_t *dst = ret.ptrw();
- const int32_t *src = (const int32_t *)mono_array_addr(p_array, int32_t, 0);
+ const int32_t *src = mono_array_addr(p_array, int32_t, 0);
memcpy(dst, src, length);
return ret;
@@ -1200,7 +1255,7 @@ MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int64_t), length);
- int64_t *dst = (int64_t *)mono_array_addr(ret, int64_t, 0);
+ int64_t *dst = mono_array_addr(ret, int64_t, 0);
memcpy(dst, src, length);
return ret;
@@ -1208,13 +1263,14 @@ MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array) {
PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array) {
PackedInt64Array ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
int64_t *dst = ret.ptrw();
- const int64_t *src = (const int64_t *)mono_array_addr(p_array, int64_t, 0);
+ const int64_t *src = mono_array_addr(p_array, int64_t, 0);
memcpy(dst, src, length);
return ret;
@@ -1226,7 +1282,7 @@ MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), length);
- uint8_t *dst = (uint8_t *)mono_array_addr(ret, uint8_t, 0);
+ uint8_t *dst = mono_array_addr(ret, uint8_t, 0);
memcpy(dst, src, length);
return ret;
@@ -1234,13 +1290,14 @@ MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array) {
PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array) {
PackedByteArray ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
uint8_t *dst = ret.ptrw();
- const uint8_t *src = (const uint8_t *)mono_array_addr(p_array, uint8_t, 0);
+ const uint8_t *src = mono_array_addr(p_array, uint8_t, 0);
memcpy(dst, src, length);
return ret;
@@ -1252,7 +1309,7 @@ MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(float), length);
- float *dst = (float *)mono_array_addr(ret, float, 0);
+ float *dst = mono_array_addr(ret, float, 0);
memcpy(dst, src, length);
return ret;
@@ -1260,13 +1317,14 @@ MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array) {
PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array) {
PackedFloat32Array ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
float *dst = ret.ptrw();
- const float *src = (const float *)mono_array_addr(p_array, float, 0);
+ const float *src = mono_array_addr(p_array, float, 0);
memcpy(dst, src, length);
return ret;
@@ -1278,7 +1336,7 @@ MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(double), length);
- double *dst = (double *)mono_array_addr(ret, double, 0);
+ double *dst = mono_array_addr(ret, double, 0);
memcpy(dst, src, length);
return ret;
@@ -1286,13 +1344,14 @@ MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array) {
PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array) {
PackedFloat64Array ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
double *dst = ret.ptrw();
- const double *src = (const double *)mono_array_addr(p_array, double, 0);
+ const double *src = mono_array_addr(p_array, double, 0);
memcpy(dst, src, length);
return ret;
@@ -1314,8 +1373,9 @@ MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) {
PackedStringArray mono_array_to_PackedStringArray(MonoArray *p_array) {
PackedStringArray ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
String *w = ret.ptrw();
@@ -1335,7 +1395,7 @@ MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), length);
if constexpr (InteropLayout::MATCHES_Color) {
- Color *dst = (Color *)mono_array_addr(ret, Color, 0);
+ Color *dst = mono_array_addr(ret, Color, 0);
memcpy(dst, src, length);
} else {
for (int i = 0; i < length; i++) {
@@ -1349,14 +1409,15 @@ MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) {
PackedColorArray mono_array_to_PackedColorArray(MonoArray *p_array) {
PackedColorArray ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
Color *dst = ret.ptrw();
if constexpr (InteropLayout::MATCHES_Color) {
- const Color *src = (const Color *)mono_array_addr(p_array, Color, 0);
+ const Color *src = mono_array_addr(p_array, Color, 0);
memcpy(dst, src, length);
} else {
for (int i = 0; i < length; i++) {
@@ -1374,7 +1435,7 @@ MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), length);
if constexpr (InteropLayout::MATCHES_Vector2) {
- Vector2 *dst = (Vector2 *)mono_array_addr(ret, Vector2, 0);
+ Vector2 *dst = mono_array_addr(ret, Vector2, 0);
memcpy(dst, src, length);
} else {
for (int i = 0; i < length; i++) {
@@ -1388,14 +1449,15 @@ MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) {
PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array) {
PackedVector2Array ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
Vector2 *dst = ret.ptrw();
if constexpr (InteropLayout::MATCHES_Vector2) {
- const Vector2 *src = (const Vector2 *)mono_array_addr(p_array, Vector2, 0);
+ const Vector2 *src = mono_array_addr(p_array, Vector2, 0);
memcpy(dst, src, length);
} else {
for (int i = 0; i < length; i++) {
@@ -1413,7 +1475,7 @@ MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), length);
if constexpr (InteropLayout::MATCHES_Vector3) {
- Vector3 *dst = (Vector3 *)mono_array_addr(ret, Vector3, 0);
+ Vector3 *dst = mono_array_addr(ret, Vector3, 0);
memcpy(dst, src, length);
} else {
for (int i = 0; i < length; i++) {
@@ -1427,14 +1489,15 @@ MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) {
PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array) {
PackedVector3Array ret;
- if (!p_array)
+ if (!p_array) {
return ret;
+ }
int length = mono_array_length(p_array);
ret.resize(length);
Vector3 *dst = ret.ptrw();
if constexpr (InteropLayout::MATCHES_Vector3) {
- const Vector3 *src = (const Vector3 *)mono_array_addr(p_array, Vector3, 0);
+ const Vector3 *src = mono_array_addr(p_array, Vector3, 0);
memcpy(dst, src, length);
} else {
for (int i = 0; i < length; i++) {
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index f2d887e6d6..4ff330fd43 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -66,7 +66,6 @@ T *unbox_addr(MonoObject *p_obj) {
Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant = nullptr);
bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type);
-bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type);
// String
@@ -74,15 +73,17 @@ String mono_to_utf8_string(MonoString *p_mono_string);
String mono_to_utf16_string(MonoString *p_mono_string);
_FORCE_INLINE_ String mono_string_to_godot_not_null(MonoString *p_mono_string) {
- if (sizeof(CharType) == 2)
+ if constexpr (sizeof(CharType) == 2) {
return mono_to_utf16_string(p_mono_string);
+ }
return mono_to_utf8_string(p_mono_string);
}
_FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) {
- if (p_mono_string == nullptr)
+ if (p_mono_string == nullptr) {
return String();
+ }
return mono_string_to_godot_not_null(p_mono_string);
}
@@ -96,8 +97,9 @@ _FORCE_INLINE_ MonoString *mono_from_utf16_string(const String &p_string) {
}
_FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) {
- if (sizeof(CharType) == 2)
+ if constexpr (sizeof(CharType) == 2) {
return mono_from_utf16_string(p_string);
+ }
return mono_from_utf8_string(p_string);
}
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index e601bb12ad..04f3b25a70 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -155,11 +155,13 @@ MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, Mono
bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, false);
- if (!attrs_fetched)
+ if (!attrs_fetched) {
fetch_attributes();
+ }
- if (!attributes)
+ if (!attributes) {
return false;
+ }
return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
}
@@ -167,11 +169,13 @@ bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) {
MonoObject *GDMonoMethod::get_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, nullptr);
- if (!attrs_fetched)
+ if (!attrs_fetched) {
fetch_attributes();
+ }
- if (!attributes)
+ if (!attributes) {
return nullptr;
+ }
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
}
@@ -250,8 +254,9 @@ const MethodInfo &GDMonoMethod::get_method_info() {
bool nil_is_variant = false;
method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), "");
- if (method_info.return_val.type == Variant::NIL && nil_is_variant)
+ if (method_info.return_val.type == Variant::NIL && nil_is_variant) {
method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ }
Vector<StringName> names;
get_parameter_names(names);
@@ -259,8 +264,9 @@ const MethodInfo &GDMonoMethod::get_method_info() {
for (int i = 0; i < params_count; ++i) {
nil_is_variant = false;
PropertyInfo arg_info = PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i], &nil_is_variant), names[i]);
- if (arg_info.type == Variant::NIL && nil_is_variant)
+ if (arg_info.type == Variant::NIL && nil_is_variant) {
arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ }
method_info.arguments.push_back(arg_info);
}
diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp
index c3e7598f2d..bc3be97102 100644
--- a/modules/mono/mono_gd/gd_mono_property.cpp
+++ b/modules/mono/mono_gd/gd_mono_property.cpp
@@ -77,15 +77,17 @@ GDMonoProperty::~GDMonoProperty() {
bool GDMonoProperty::is_static() {
MonoMethod *prop_method = mono_property_get_get_method(mono_property);
- if (prop_method == nullptr)
+ if (prop_method == nullptr) {
prop_method = mono_property_get_set_method(mono_property);
+ }
return mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_STATIC;
}
IMonoClassMember::Visibility GDMonoProperty::get_visibility() {
MonoMethod *prop_method = mono_property_get_get_method(mono_property);
- if (prop_method == nullptr)
+ if (prop_method == nullptr) {
prop_method = mono_property_get_set_method(mono_property);
+ }
switch (mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_ACCESS_MASK) {
case MONO_METHOD_ATTR_PRIVATE:
@@ -106,11 +108,13 @@ IMonoClassMember::Visibility GDMonoProperty::get_visibility() {
bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, false);
- if (!attrs_fetched)
+ if (!attrs_fetched) {
fetch_attributes();
+ }
- if (!attributes)
+ if (!attributes) {
return false;
+ }
return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
}
@@ -118,11 +122,13 @@ bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) {
MonoObject *GDMonoProperty::get_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, nullptr);
- if (!attrs_fetched)
+ if (!attrs_fetched) {
fetch_attributes();
+ }
- if (!attributes)
+ if (!attributes) {
return nullptr;
+ }
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
}
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 332744ae6e..3f1155f430 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -38,7 +38,6 @@
#include "core/os/dir_access.h"
#include "core/os/mutex.h"
#include "core/os/os.h"
-#include "core/project_settings.h"
#include "core/reference.h"
#ifdef TOOLS_ENABLED
@@ -51,13 +50,13 @@
#include "gd_mono_cache.h"
#include "gd_mono_class.h"
#include "gd_mono_marshal.h"
-#include "gd_mono_method_thunk.h"
namespace GDMonoUtils {
MonoObject *unmanaged_get_managed(Object *unmanaged) {
- if (!unmanaged)
+ if (!unmanaged) {
return nullptr;
+ }
if (unmanaged->get_script_instance()) {
CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(unmanaged->get_script_instance());
@@ -90,8 +89,9 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
MonoObject *target = gchandle.get_target();
- if (target)
+ if (target) {
return target;
+ }
CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
@@ -196,8 +196,9 @@ GDMonoClass *get_object_class(MonoObject *p_object) {
GDMonoClass *type_get_proxy_class(const StringName &p_type) {
String class_name = p_type;
- if (class_name[0] == '_')
+ if (class_name[0] == '_') {
class_name = class_name.substr(1, class_name.length());
+ }
GDMonoClass *klass = GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name);
@@ -220,11 +221,14 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) {
do {
const GDMonoAssembly *assembly = klass->get_assembly();
- if (assembly == GDMono::get_singleton()->get_core_api_assembly())
+
+ if (assembly == GDMono::get_singleton()->get_core_api_assembly()) {
return klass;
+ }
#ifdef TOOLS_ENABLED
- if (assembly == GDMono::get_singleton()->get_editor_api_assembly())
+ if (assembly == GDMono::get_singleton()->get_editor_api_assembly()) {
return klass;
+ }
#endif
} while ((klass = klass->get_parent_class()) != nullptr);
@@ -385,14 +389,6 @@ String get_exception_name_and_message(MonoException *p_exc) {
return res;
}
-void set_exception_message(MonoException *p_exc, String message) {
- MonoClass *klass = mono_object_get_class((MonoObject *)p_exc);
- MonoProperty *prop = mono_class_get_property_from_name(klass, "Message");
- MonoString *msg = GDMonoMarshal::mono_string_from_godot(message);
- void *params[1] = { msg };
- property_set_value(prop, (MonoObject *)p_exc, params, nullptr);
-}
-
void debug_print_unhandled_exception(MonoException *p_exc) {
print_unhandled_exception(p_exc);
debug_send_unhandled_exception_error(p_exc);
@@ -410,8 +406,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
}
static thread_local bool _recursion_flag_ = false;
- if (_recursion_flag_)
+ if (_recursion_flag_) {
return;
+ }
_recursion_flag_ = true;
SCOPE_EXIT { _recursion_flag_ = false; };
@@ -441,8 +438,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
Vector<ScriptLanguage::StackInfo> _si;
if (stack_trace != nullptr) {
_si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace);
- for (int i = _si.size() - 1; i >= 0; i--)
+ for (int i = _si.size() - 1; i >= 0; i--) {
si.insert(0, _si[i]);
+ }
}
exc_msg += (exc_msg.length() > 0 ? " ---> " : "") + GDMonoUtils::get_exception_name_and_message(p_exc);
@@ -452,8 +450,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
CRASH_COND(inner_exc_prop == nullptr);
MonoObject *inner_exc = inner_exc_prop->get_value((MonoObject *)p_exc);
- if (inner_exc != nullptr)
+ if (inner_exc != nullptr) {
si.insert(0, separator);
+ }
p_exc = (MonoException *)inner_exc;
}
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index a7ca46f012..9db4a5f3f0 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -84,10 +84,6 @@ void detach_current_thread(MonoThread *p_mono_thread);
MonoThread *get_current_thread();
bool is_thread_attached();
-_FORCE_INLINE_ bool is_main_thread() {
- return mono_domain_get() != nullptr && mono_thread_get_main() == mono_thread_current();
-}
-
uint32_t new_strong_gchandle(MonoObject *p_object);
uint32_t new_strong_gchandle_pinned(MonoObject *p_object);
uint32_t new_weak_gchandle(MonoObject *p_object);
@@ -115,7 +111,6 @@ String get_type_desc(MonoType *p_type);
String get_type_desc(MonoReflectionType *p_reftype);
String get_exception_name_and_message(MonoException *p_exc);
-void set_exception_message(MonoException *p_exc, String message);
void debug_print_unhandled_exception(MonoException *p_exc);
void debug_send_unhandled_exception_error(MonoException *p_exc);
diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp
index 94431e7c30..98c3ba1324 100644
--- a/modules/mono/register_types.cpp
+++ b/modules/mono/register_types.cpp
@@ -62,8 +62,9 @@ void register_mono_types() {
void unregister_mono_types() {
ScriptServer::unregister_language(script_language_cs);
- if (script_language_cs)
+ if (script_language_cs) {
memdelete(script_language_cs);
+ }
ResourceLoader::remove_resource_format_loader(resource_loader_cs);
resource_loader_cs.unref();
@@ -71,6 +72,7 @@ void unregister_mono_types() {
ResourceSaver::remove_resource_format_saver(resource_saver_cs);
resource_saver_cs.unref();
- if (_godotsharp)
+ if (_godotsharp) {
memdelete(_godotsharp);
+ }
}
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index ed0dc5cc28..bd67b03c8e 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -51,18 +51,21 @@ bool SignalAwaiterCallable::compare_equal(const CallableCustom *p_a, const Calla
const SignalAwaiterCallable *a = static_cast<const SignalAwaiterCallable *>(p_a);
const SignalAwaiterCallable *b = static_cast<const SignalAwaiterCallable *>(p_b);
- if (a->target_id != b->target_id)
+ if (a->target_id != b->target_id) {
return false;
+ }
- if (a->signal != b->signal)
+ if (a->signal != b->signal) {
return false;
+ }
return true;
}
bool SignalAwaiterCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
- if (compare_equal(p_a, p_b))
+ if (compare_equal(p_a, p_b)) {
return false;
+ }
return p_a < p_b;
}
@@ -145,18 +148,21 @@ bool EventSignalCallable::compare_equal(const CallableCustom *p_a, const Callabl
const EventSignalCallable *a = static_cast<const EventSignalCallable *>(p_a);
const EventSignalCallable *b = static_cast<const EventSignalCallable *>(p_b);
- if (a->owner != b->owner)
+ if (a->owner != b->owner) {
return false;
+ }
- if (a->event_signal != b->event_signal)
+ if (a->event_signal != b->event_signal) {
return false;
+ }
return true;
}
bool EventSignalCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
- if (compare_equal(p_a, p_b))
+ if (compare_equal(p_a, p_b)) {
return false;
+ }
return p_a < p_b;
}
diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp
index 973375a471..ccfaf5aba7 100644
--- a/modules/mono/utils/path_utils.cpp
+++ b/modules/mono/utils/path_utils.cpp
@@ -50,34 +50,6 @@
namespace path {
-String find_executable(const String &p_name) {
-#ifdef WINDOWS_ENABLED
- Vector<String> exts = OS::get_singleton()->get_environment("PATHEXT").split(ENV_PATH_SEP, false);
-#endif
- Vector<String> env_path = OS::get_singleton()->get_environment("PATH").split(ENV_PATH_SEP, false);
-
- if (env_path.empty())
- return String();
-
- for (int i = 0; i < env_path.size(); i++) {
- String p = path::join(env_path[i], p_name);
-
-#ifdef WINDOWS_ENABLED
- for (int j = 0; j < exts.size(); j++) {
- String p2 = p + exts[j].to_lower(); // lowercase to reduce risk of case mismatch warning
-
- if (FileAccess::exists(p2))
- return p2;
- }
-#else
- if (FileAccess::exists(p))
- return p;
-#endif
- }
-
- return String();
-}
-
String cwd() {
#ifdef WINDOWS_ENABLED
const DWORD expected_size = ::GetCurrentDirectoryW(0, nullptr);
@@ -90,12 +62,14 @@ String cwd() {
return buffer.simplify_path();
#else
char buffer[PATH_MAX];
- if (::getcwd(buffer, sizeof(buffer)) == nullptr)
+ if (::getcwd(buffer, sizeof(buffer)) == nullptr) {
return ".";
+ }
String result;
- if (result.parse_utf8(buffer))
+ if (result.parse_utf8(buffer)) {
return ".";
+ }
return result.simplify_path();
#endif
@@ -135,23 +109,26 @@ String realpath(const String &p_path) {
#elif UNIX_ENABLED
char *resolved_path = ::realpath(p_path.utf8().get_data(), nullptr);
- if (!resolved_path)
+ if (!resolved_path) {
return p_path;
+ }
String result;
bool parse_ok = result.parse_utf8(resolved_path);
::free(resolved_path);
- if (parse_ok)
+ if (parse_ok) {
return p_path;
+ }
return result.simplify_path();
#endif
}
String join(const String &p_a, const String &p_b) {
- if (p_a.empty())
+ if (p_a.empty()) {
return p_b;
+ }
const CharType a_last = p_a[p_a.length() - 1];
if ((a_last == '/' || a_last == '\\') ||
@@ -178,8 +155,9 @@ String relative_to_impl(const String &p_path, const String &p_relative_to) {
} else {
String base_dir = p_relative_to.get_base_dir();
- if (base_dir.length() <= 2 && (base_dir.empty() || base_dir.ends_with(":")))
+ if (base_dir.length() <= 2 && (base_dir.empty() || base_dir.ends_with(":"))) {
return p_path;
+ }
return String("..").plus_file(relative_to_impl(p_path, base_dir));
}
diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h
index 9965f58b0a..bcd8af8bb9 100644
--- a/modules/mono/utils/path_utils.h
+++ b/modules/mono/utils/path_utils.h
@@ -40,8 +40,6 @@ String join(const String &p_a, const String &p_b);
String join(const String &p_a, const String &p_b, const String &p_c);
String join(const String &p_a, const String &p_b, const String &p_c, const String &p_d);
-String find_executable(const String &p_name);
-
/// Returns a normalized absolute path to the current working directory
String cwd();
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index da1b719d99..f8d9804de4 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -38,14 +38,16 @@
namespace {
int sfind(const String &p_text, int p_from) {
- if (p_from < 0)
+ if (p_from < 0) {
return -1;
+ }
int src_len = 2;
int len = p_text.length();
- if (len == 0)
+ if (len == 0) {
return -1;
+ }
const CharType *src = p_text.c_str();
@@ -75,8 +77,9 @@ int sfind(const String &p_text, int p_from) {
}
}
- if (found)
+ if (found) {
return i;
+ }
}
return -1;
@@ -85,8 +88,9 @@ int sfind(const String &p_text, int p_from) {
} // namespace
String sformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
- if (p_text.length() < 2)
+ if (p_text.length() < 2) {
return p_text;
+ }
Array args;
diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp
index 3900180739..8feaa9af5a 100644
--- a/modules/websocket/websocket_client.cpp
+++ b/modules/websocket/websocket_client.cpp
@@ -66,7 +66,7 @@ Error WebSocketClient::connect_to_url(String p_url, const Vector<String> p_proto
}
// Port
- p_len = host.find_last(":");
+ p_len = host.rfind(":");
if (p_len != -1 && p_len == host.find(":")) {
port = host.substr(p_len, host.length() - p_len).to_int();
host = host.substr(0, p_len);
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 2f6f483edf..474458b00f 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1334,7 +1334,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
str = get_project_name(package_name);
} else {
- String lang = str.substr(str.find_last("-") + 1, str.length()).replace("-", "_");
+ String lang = str.substr(str.rfind("-") + 1, str.length()).replace("-", "_");
String prop = "application/config/name_" + lang;
if (ProjectSettings::get_singleton()->has_setting(prop)) {
str = ProjectSettings::get_singleton()->get(prop);
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 827d0361b9..c9b951f4d9 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -410,7 +410,18 @@ void DisplayServerX11::mouse_warp_to_position(const Point2i &p_to) {
}
Point2i DisplayServerX11::mouse_get_position() const {
- return last_mouse_pos;
+ int root_x, root_y;
+ int win_x, win_y;
+ unsigned int mask_return;
+ Window window_returned;
+
+ Bool result = XQueryPointer(x11_display, RootWindow(x11_display, DefaultScreen(x11_display)), &window_returned,
+ &window_returned, &root_x, &root_y, &win_x, &win_y,
+ &mask_return);
+ if (result == True) {
+ return Point2i(root_x, root_y);
+ }
+ return Point2i();
}
Point2i DisplayServerX11::mouse_get_absolute_position() const {
@@ -718,6 +729,14 @@ ObjectID DisplayServerX11::window_get_attached_instance_id(WindowID p_window) co
}
DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const Point2i &p_position) const {
+#warning This is an incorrect implementation, if windows overlap, it should return the topmost visible one or none if occluded by a foreign window
+
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ Rect2i win_rect = Rect2i(window_get_position(E->key()), window_get_size(E->key()));
+ if (win_rect.has_point(p_position)) {
+ return E->key();
+ }
+ }
return INVALID_WINDOW_ID;
}
@@ -2345,6 +2364,7 @@ void DisplayServerX11::process_events() {
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
if (E->get().focused) {
focus_found = true;
+ break;
}
}
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index 8e27f10dc2..3e6b59f58c 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -132,6 +132,7 @@ public:
bool on_top = false;
bool borderless = false;
bool resize_disabled = false;
+ bool no_focus = false;
};
Point2i im_selection;
@@ -150,7 +151,6 @@ public:
void _set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window);
- float _display_scale(id screen) const;
Point2i _get_screens_origin() const;
Point2i _get_native_screen_position(int p_screen) const;
@@ -224,6 +224,7 @@ public:
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual float screen_get_max_scale() const;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
virtual Vector<int> get_window_list() const;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index ee67f46a4c..b7b750a975 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -47,6 +47,8 @@
#if defined(OPENGL_ENABLED)
#include "drivers/gles2/rasterizer_gles2.h"
//TODO - reimplement OpenGLES
+
+#import <AppKit/NSOpenGLView.h>
#endif
#if defined(VULKAN_ENABLED)
@@ -68,11 +70,11 @@ static void _get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWith
r_state->set_metakey((p_osx_state & NSEventModifierFlagCommand));
}
-static Vector2i _get_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_locationInWindow, CGFloat p_backingScaleFactor) {
+static Vector2i _get_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_locationInWindow) {
const NSRect contentRect = [p_wd.window_view frame];
- const NSPoint p = p_locationInWindow;
- p_wd.mouse_pos.x = p.x * p_backingScaleFactor;
- p_wd.mouse_pos.y = (contentRect.size.height - p.y) * p_backingScaleFactor;
+ const float scale = DS_OSX->screen_get_max_scale();
+ p_wd.mouse_pos.x = p_locationInWindow.x * scale;
+ p_wd.mouse_pos.y = (contentRect.size.height - p_locationInWindow.y) * scale;
DS_OSX->last_mouse_pos = p_wd.mouse_pos;
Input::get_singleton()->set_mouse_position(p_wd.mouse_pos);
return p_wd.mouse_pos;
@@ -131,10 +133,11 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
// This works around an AppKit bug, where key up events while holding
// down the command key don't get sent to the key window.
- if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand))
+ if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) {
[[self keyWindow] sendEvent:event];
- else
+ } else {
[super sendEvent:event];
+ }
}
@end
@@ -210,8 +213,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)globalMenuCallback:(id)sender {
- if (![sender representedObject])
+ if (![sender representedObject]) {
return;
+ }
GlobalMenuItem *value = [sender representedObject];
@@ -264,8 +268,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)showAbout:(id)sender {
- if (OS_OSX::get_singleton()->get_main_loop())
+ if (OS_OSX::get_singleton()->get_main_loop()) {
OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT);
+ }
}
@end
@@ -318,6 +323,11 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
[pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to main window if there is no parent or other windows left.
}
+#if defined(OPENGL_ENABLED)
+ if (DS_OSX->rendering_driver == "opengl_es") {
+ //TODO - reimplement OpenGLES
+ }
+#endif
#ifdef VULKAN_ENABLED
if (DS_OSX->rendering_driver == "vulkan") {
DS_OSX->context_vulkan->window_destroy(window_id);
@@ -345,22 +355,25 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
wd.fullscreen = false;
+ const float scale = DS_OSX->screen_get_max_scale();
if (wd.min_size != Size2i()) {
- Size2i size = wd.min_size / DS_OSX->_display_scale([wd.window_object screen]);
+ Size2i size = wd.min_size / scale;
[wd.window_object setContentMinSize:NSMakeSize(size.x, size.y)];
}
if (wd.max_size != Size2i()) {
- Size2i size = wd.max_size / DS_OSX->_display_scale([wd.window_object screen]);
+ Size2i size = wd.max_size / scale;
[wd.window_object setContentMaxSize:NSMakeSize(size.x, size.y)];
}
- if (wd.resize_disabled)
+ if (wd.resize_disabled) {
[wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable];
+ }
}
- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
- if (!DisplayServerOSX::get_singleton())
+ if (!DisplayServerOSX::get_singleton()) {
return;
+ }
ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
@@ -368,34 +381,21 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
CGFloat newBackingScaleFactor = [wd.window_object backingScaleFactor];
CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
-#if defined(OPENGL_ENABLED)
- if (DS_OSX->rendering_driver == "opengl_es") {
- //TODO - reimplement OpenGLES
- if (OS_OSX::get_singleton()->is_hidpi_allowed()) {
- [wd.window_view setWantsBestResolutionOpenGLSurface:YES];
- } else {
- [wd.window_view setWantsBestResolutionOpenGLSurface:NO];
- }
- }
-#endif
-
if (newBackingScaleFactor != oldBackingScaleFactor) {
//Set new display scale and window size
- float newDisplayScale = OS_OSX::get_singleton()->is_hidpi_allowed() ? newBackingScaleFactor : 1.0;
-
+ const float scale = DS_OSX->screen_get_max_scale();
const NSRect contentRect = [wd.window_view frame];
- wd.size.width = contentRect.size.width * newDisplayScale;
- wd.size.height = contentRect.size.height * newDisplayScale;
+ wd.size.width = contentRect.size.width * scale;
+ wd.size.height = contentRect.size.height * scale;
DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_DPI_CHANGE);
-#if defined(VULKAN_ENABLED)
- if (DS_OSX->rendering_driver == "vulkan") {
- CALayer *layer = [wd.window_view layer];
- layer.contentsScale = DS_OSX->_display_scale([wd.window_object screen]);
+ CALayer *layer = [wd.window_view layer];
+ if (layer) {
+ layer.contentsScale = scale;
}
-#endif
+
//Force window resize event
[self windowDidResize:notification];
}
@@ -407,22 +407,24 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
+ const NSRect contentRect = [wd.window_view frame];
+
+ const float scale = DS_OSX->screen_get_max_scale();
+ wd.size.width = contentRect.size.width * scale;
+ wd.size.height = contentRect.size.height * scale;
+
+ CALayer *layer = [wd.window_view layer];
+ if (layer) {
+ layer.contentsScale = scale;
+ }
+
#if defined(OPENGL_ENABLED)
if (DS_OSX->rendering_driver == "opengl_es") {
//TODO - reimplement OpenGLES
- wd.context_gles2->update();
}
#endif
- const NSRect contentRect = [wd.window_view frame];
-
- float displayScale = DS_OSX->_display_scale([wd.window_object screen]);
- wd.size.width = contentRect.size.width * displayScale;
- wd.size.height = contentRect.size.height * displayScale;
-
#if defined(VULKAN_ENABLED)
if (DS_OSX->rendering_driver == "vulkan") {
- CALayer *layer = [wd.window_view layer];
- layer.contentsScale = displayScale;
DS_OSX->context_vulkan->window_resize(window_id, wd.size.width, wd.size.height);
}
#endif
@@ -467,8 +469,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
- const CGFloat backingScaleFactor = (OS::get_singleton()->is_hidpi_allowed()) ? [wd.window_view backingScaleFactor] : 1.0;
- _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream], backingScaleFactor);
+ _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
Input::get_singleton()->set_mouse_position(wd.mouse_pos);
DS_OSX->window_focused = true;
@@ -543,6 +544,12 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (CALayer *)makeBackingLayer {
+#if defined(OPENGL_ENABLED)
+ if (DS_OSX->rendering_driver == "opengl_es") {
+ CALayer *layer = [[NSOpenGLLayer class] layer];
+ return layer;
+ }
+#endif
#if defined(VULKAN_ENABLED)
if (DS_OSX->rendering_driver == "vulkan") {
CALayer *layer = [[CAMetalLayer class] layer];
@@ -553,20 +560,17 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)updateLayer {
-#if defined(VULKAN_ENABLED)
- if (DS_OSX->rendering_driver == "vulkan") {
- [super updateLayer];
- }
-#endif
#if defined(OPENGL_ENABLED)
if (DS_OSX->rendering_driver == "opengl_es") {
- ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
- DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
-
- wd.context_gles2->update();
+ [super updateLayer];
//TODO - reimplement OpenGLES
}
#endif
+#if defined(VULKAN_ENABLED)
+ if (DS_OSX->rendering_driver == "vulkan") {
+ [super updateLayer];
+ }
+#endif
}
- (BOOL)wantsUpdateLayer {
@@ -631,8 +635,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
}
- (void)doCommandBySelector:(SEL)aSelector {
- if ([self respondsToSelector:aSelector])
+ if ([self respondsToSelector:aSelector]) {
[self performSelector:aSelector];
+ }
}
- (void)unmarkText {
@@ -667,8 +672,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
const NSRect contentRect = [wd.window_view frame];
- float displayScale = DS_OSX->_display_scale([wd.window_object screen]);
- NSRect pointInWindowRect = NSMakeRect(wd.im_position.x / displayScale, contentRect.size.height - (wd.im_position.y / displayScale) - 1, 0, 0);
+ const float scale = DS_OSX->screen_get_max_scale();
+ NSRect pointInWindowRect = NSMakeRect(wd.im_position.x / scale, contentRect.size.height - (wd.im_position.y / scale) - 1, 0, 0);
NSPoint pointOnScreen = [wd.window_object convertRectToScreen:pointInWindowRect].origin;
return NSMakeRect(pointOnScreen.x, pointOnScreen.y, 0, 0);
@@ -707,8 +712,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
for (i = 0; i < length; i++) {
const unichar codepoint = [characters characterAtIndex:i];
- if ((codepoint & 0xFF00) == 0xF700)
+ if ((codepoint & 0xFF00) == 0xF700) {
continue;
+ }
DisplayServerOSX::KeyEvent ke;
@@ -775,6 +781,12 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
}
- (BOOL)canBecomeKeyView {
+ if (DS_OSX->windows.has(window_id)) {
+ DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
+ if (wd.no_focus) {
+ return NO;
+ }
+ }
return YES;
}
@@ -801,8 +813,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
Ref<InputEventMouseButton> mb;
mb.instance();
mb->set_window_id(window_id);
- const CGFloat backingScaleFactor = (OS::get_singleton()->is_hidpi_allowed()) ? [[event window] backingScaleFactor] : 1.0;
- const Vector2 pos = _get_mouse_pos(wd, [event locationInWindow], backingScaleFactor);
+ const Vector2 pos = _get_mouse_pos(wd, [event locationInWindow]);
_get_key_modifier_state([event modifierFlags], mb);
mb->set_button_index(index);
mb->set_pressed(pressed);
@@ -899,8 +910,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
mm->set_window_id(window_id);
mm->set_button_mask(DS_OSX->last_button_state);
- const CGFloat backingScaleFactor = (OS::get_singleton()->is_hidpi_allowed()) ? [[event window] backingScaleFactor] : 1.0;
- const Vector2i pos = _get_mouse_pos(wd, mpos, backingScaleFactor);
+ const Vector2i pos = _get_mouse_pos(wd, mpos);
mm->set_position(pos);
mm->set_pressure([event pressure]);
if ([event subtype] == NSEventSubtypeTabletPoint) {
@@ -909,7 +919,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
}
mm->set_global_position(pos);
mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
- const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * backingScaleFactor;
+ const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * DS_OSX->screen_get_max_scale();
mm->set_relative(relativeMotion);
_get_key_modifier_state([event modifierFlags], mm);
@@ -961,16 +971,18 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
- if (DS_OSX->mouse_mode != DisplayServer::MOUSE_MODE_CAPTURED)
+ if (DS_OSX->mouse_mode != DisplayServer::MOUSE_MODE_CAPTURED) {
DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_EXIT);
+ }
}
- (void)mouseEntered:(NSEvent *)event {
ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
- if (DS_OSX->mouse_mode != DisplayServer::MOUSE_MODE_CAPTURED)
+ if (DS_OSX->mouse_mode != DisplayServer::MOUSE_MODE_CAPTURED) {
DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_ENTER);
+ }
DisplayServer::CursorShape p_shape = DS_OSX->cursor_shape;
DS_OSX->cursor_shape = DisplayServer::CURSOR_MAX;
@@ -985,8 +997,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
ev.instance();
ev->set_window_id(window_id);
_get_key_modifier_state([event modifierFlags], ev);
- const CGFloat backingScaleFactor = (OS::get_singleton()->is_hidpi_allowed()) ? [[event window] backingScaleFactor] : 1.0;
- ev->set_position(_get_mouse_pos(wd, [event locationInWindow], backingScaleFactor));
+ ev->set_position(_get_mouse_pos(wd, [event locationInWindow]));
ev->set_factor([event magnification] + 1.0);
Input::get_singleton()->accumulate_input_event(ev);
@@ -1002,17 +1013,8 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
[trackingArea release];
}
- NSTrackingAreaOptions options =
- NSTrackingMouseEnteredAndExited |
- NSTrackingActiveInKeyWindow |
- NSTrackingCursorUpdate |
- NSTrackingInVisibleRect;
-
- trackingArea = [[NSTrackingArea alloc]
- initWithRect:[self bounds]
- options:options
- owner:self
- userInfo:nil];
+ NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingCursorUpdate | NSTrackingInVisibleRect;
+ trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:options owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
[super updateTrackingAreas];
@@ -1042,8 +1044,9 @@ static bool isNumpadKey(unsigned int key) {
0x00
};
for (int i = 0; table[i] != 0; i++) {
- if (key == table[i])
+ if (key == table[i]) {
return true;
+ }
}
return false;
}
@@ -1183,8 +1186,9 @@ static int translateKey(unsigned int key) {
/* 7f */ KEY_UNKNOWN,
};
- if (key >= 128)
+ if (key >= 128) {
return KEY_UNKNOWN;
+ }
return table[key];
}
@@ -1253,16 +1257,19 @@ static const _KeyCodeMap _keycodes[55] = {
};
static int remapKey(unsigned int key, unsigned int state) {
- if (isNumpadKey(key))
+ if (isNumpadKey(key)) {
return translateKey(key);
+ }
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
- if (!currentKeyboard)
+ if (!currentKeyboard) {
return translateKey(key);
+ }
CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
- if (!layoutData)
+ if (!layoutData) {
return translateKey(key);
+ }
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
@@ -1335,8 +1342,9 @@ static int remapKey(unsigned int key, unsigned int state) {
}
// Pass events to IME handler
- if (wd.im_active)
+ if (wd.im_active) {
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
+ }
}
- (void)flagsChanged:(NSEvent *)event {
@@ -1489,8 +1497,7 @@ inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy
double deltaX, deltaY;
- const CGFloat backingScaleFactor = (OS::get_singleton()->is_hidpi_allowed()) ? [[event window] backingScaleFactor] : 1.0;
- _get_mouse_pos(wd, [event locationInWindow], backingScaleFactor);
+ _get_mouse_pos(wd, [event locationInWindow]);
deltaX = [event scrollingDeltaX];
deltaY = [event scrollingDeltaY];
@@ -1527,6 +1534,25 @@ inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy
- (BOOL)canBecomeKeyWindow {
// Required for NSBorderlessWindowMask windows
+ for (Map<DisplayServer::WindowID, DisplayServerOSX::WindowData>::Element *E = DS_OSX->windows.front(); E; E = E->next()) {
+ if (E->get().window_object == self) {
+ if (E->get().no_focus) {
+ return NO;
+ }
+ }
+ }
+ return YES;
+}
+
+- (BOOL)canBecomeMainWindow {
+ // Required for NSBorderlessWindowMask windows
+ for (Map<DisplayServer::WindowID, DisplayServerOSX::WindowData>::Element *E = DS_OSX->windows.front(); E; E = E->next()) {
+ if (E->get().window_object == self) {
+ if (E->get().no_focus) {
+ return NO;
+ }
+ }
+ }
return YES;
}
@@ -1553,6 +1579,7 @@ bool DisplayServerOSX::has_feature(Feature p_feature) const {
case FEATURE_HIDPI:
case FEATURE_ICON:
case FEATURE_NATIVE_ICON:
+ //case FEATURE_KEEP_SCREEN_ON:
case FEATURE_SWAP_BUFFERS:
return true;
default: {
@@ -1998,8 +2025,9 @@ Error DisplayServerOSX::dialog_input_text(String p_title, String p_description,
void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
_THREAD_SAFE_METHOD_
- if (p_mode == mouse_mode)
+ if (p_mode == mouse_mode) {
return;
+ }
if (p_mode == MOUSE_MODE_CAPTURED) {
// Apple Docs state that the display parameter is not used.
@@ -2040,8 +2068,8 @@ void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) {
//local point in window coords
const NSRect contentRect = [wd.window_view frame];
- float displayScale = _display_scale([wd.window_object screen]);
- NSRect pointInWindowRect = NSMakeRect(p_to.x / displayScale, contentRect.size.height - (p_to.y / displayScale) - 1, 0, 0);
+ const float scale = screen_get_max_scale();
+ NSRect pointInWindowRect = NSMakeRect(p_to.x / scale, contentRect.size.height - (p_to.y / scale - 1), 0, 0);
NSPoint pointOnScreen = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin;
//point in scren coords
@@ -2066,11 +2094,12 @@ Point2i DisplayServerOSX::mouse_get_absolute_position() const {
_THREAD_SAFE_METHOD_
const NSPoint mouse_pos = [NSEvent mouseLocation];
+ const float scale = screen_get_max_scale();
for (NSScreen *screen in [NSScreen screens]) {
NSRect frame = [screen frame];
if (NSMouseInRect(mouse_pos, frame, NO)) {
- return Vector2i((int)mouse_pos.x, (int)-mouse_pos.y) + _get_screens_origin();
+ return Vector2i((int)mouse_pos.x, (int)-mouse_pos.y) * scale + _get_screens_origin();
}
}
return Vector2i();
@@ -2128,17 +2157,10 @@ int DisplayServerOSX::get_screen_count() const {
// to convert between OS X native screen coordinates and the ones expected by Godot
static bool displays_arrangement_dirty = true;
+static bool displays_scale_dirty = true;
static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) {
displays_arrangement_dirty = true;
-}
-
-float DisplayServerOSX::_display_scale(id screen) const {
- if (OS_OSX::get_singleton()->is_hidpi_allowed()) {
- if ([screen respondsToSelector:@selector(backingScaleFactor)]) {
- return fmax(1.0, [screen backingScaleFactor]);
- }
- }
- return 1.0;
+ displays_scale_dirty = true;
}
Point2i DisplayServerOSX::_get_screens_origin() const {
@@ -2165,10 +2187,9 @@ Point2i DisplayServerOSX::_get_screens_origin() const {
Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const {
NSArray *screenArray = [NSScreen screens];
if ((NSUInteger)p_screen < [screenArray count]) {
- float display_scale = _display_scale([screenArray objectAtIndex:p_screen]);
NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
// Return the top-left corner of the screen, for OS X the y starts at the bottom
- return Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * display_scale;
+ return Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * screen_get_max_scale();
}
return Point2i();
@@ -2197,10 +2218,9 @@ Size2i DisplayServerOSX::screen_get_size(int p_screen) const {
NSArray *screenArray = [NSScreen screens];
if ((NSUInteger)p_screen < [screenArray count]) {
- float displayScale = _display_scale([screenArray objectAtIndex:p_screen]);
// Note: Use frame to get the whole screen size
NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
- return Size2i(nsrect.size.width, nsrect.size.height) * displayScale;
+ return Size2i(nsrect.size.width, nsrect.size.height) * screen_get_max_scale();
}
return Size2i();
@@ -2215,13 +2235,9 @@ int DisplayServerOSX::screen_get_dpi(int p_screen) const {
NSArray *screenArray = [NSScreen screens];
if ((NSUInteger)p_screen < [screenArray count]) {
- float displayScale = _display_scale([screenArray objectAtIndex:p_screen]);
NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription];
- NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
- CGSize displayPhysicalSize = CGDisplayScreenSize(
- [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
-
- return (displayPixelSize.width * 25.4f / displayPhysicalSize.width) * displayScale;
+ NSSize displayDPI = [[description objectForKey:NSDeviceResolution] sizeValue];
+ return (displayDPI.width + displayDPI.height) / 2;
}
return 96;
@@ -2233,14 +2249,32 @@ float DisplayServerOSX::screen_get_scale(int p_screen) const {
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
p_screen = window_get_current_screen();
}
- NSArray *screenArray = [NSScreen screens];
- if ((NSUInteger)p_screen < [screenArray count]) {
- return _display_scale([screenArray objectAtIndex:p_screen]);
+ if (OS::get_singleton()->is_hidpi_allowed()) {
+ NSArray *screenArray = [NSScreen screens];
+ if ((NSUInteger)p_screen < [screenArray count]) {
+ if ([[screenArray objectAtIndex:p_screen] respondsToSelector:@selector(backingScaleFactor)]) {
+ return fmax(1.0, [[screenArray objectAtIndex:p_screen] backingScaleFactor]);
+ }
+ }
}
return 1.f;
}
+float DisplayServerOSX::screen_get_max_scale() const {
+ _THREAD_SAFE_METHOD_
+
+ static float scale = 1.f;
+ if (displays_scale_dirty) {
+ int screen_count = get_screen_count();
+ for (int i = 0; i < screen_count; i++) {
+ scale = fmax(scale, screen_get_scale(i));
+ }
+ displays_scale_dirty = false;
+ }
+ return scale;
+}
+
Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
_THREAD_SAFE_METHOD_
@@ -2250,12 +2284,12 @@ Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
NSArray *screenArray = [NSScreen screens];
if ((NSUInteger)p_screen < [screenArray count]) {
- float displayScale = _display_scale([screenArray objectAtIndex:p_screen]);
+ const float scale = screen_get_max_scale();
NSRect nsrect = [[screenArray objectAtIndex:p_screen] visibleFrame];
- Point2i position = Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * displayScale - _get_screens_origin();
+ Point2i position = Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * scale - _get_screens_origin();
position.y *= -1;
- Size2i size = Size2i(nsrect.size.width, nsrect.size.height) * displayScale;
+ Size2i size = Size2i(nsrect.size.width, nsrect.size.height) * scale;
return Rect2i(position, size);
}
@@ -2283,7 +2317,11 @@ DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, u
window_set_flag(WindowFlags(i), true, id);
}
}
- [wd.window_object makeKeyAndOrderFront:nil];
+ if (wd.no_focus) {
+ [wd.window_object orderFront:nil];
+ } else {
+ [wd.window_object makeKeyAndOrderFront:nil];
+ }
return id;
}
@@ -2301,8 +2339,9 @@ void DisplayServerOSX::_send_window_event(const WindowData &wd, WindowEvent p_ev
DisplayServerOSX::WindowID DisplayServerOSX::_find_window_id(id p_window) {
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- if (E->get().window_object == p_window)
+ if (E->get().window_object == p_window) {
return E->key();
+ }
}
return INVALID_WINDOW_ID;
}
@@ -2447,11 +2486,12 @@ Point2i DisplayServerOSX::window_get_position(WindowID p_window) const {
NSRect nsrect = [wd.window_object frame];
Point2i pos;
- float display_scale = _display_scale([wd.window_object screen]);
// Return the position of the top-left corner, for OS X the y starts at the bottom
- pos.x = nsrect.origin.x * display_scale;
- pos.y = (nsrect.origin.y + nsrect.size.height) * display_scale;
+ const float scale = screen_get_max_scale();
+ pos.x = nsrect.origin.x;
+ pos.y = (nsrect.origin.y + nsrect.size.height);
+ pos *= scale;
pos -= _get_screens_origin();
// OS X native y-coordinate relative to _get_screens_origin() is negative,
// Godot expects a positive value
@@ -2470,17 +2510,12 @@ void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p
// Godot passes a positive value
position.y *= -1;
position += _get_screens_origin();
+ position /= screen_get_max_scale();
- NSPoint pos;
- float displayScale = _display_scale([wd.window_object screen]);
-
- pos.x = position.x / displayScale;
- pos.y = position.y / displayScale;
-
- [wd.window_object setFrameTopLeftPoint:pos];
+ [wd.window_object setFrameTopLeftPoint:NSMakePoint(position.x, position.y)];
_update_window(wd);
- _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream], displayScale);
+ _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
}
void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_window) {
@@ -2496,7 +2531,7 @@ void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_windo
wd.max_size = p_size;
if ((wd.max_size != Size2i()) && !wd.fullscreen) {
- Size2i size = wd.max_size / _display_scale([wd.window_object screen]);
+ Size2i size = wd.max_size / screen_get_max_scale();
[wd.window_object setContentMaxSize:NSMakeSize(size.x, size.y)];
} else {
[wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
@@ -2524,7 +2559,7 @@ void DisplayServerOSX::window_set_min_size(const Size2i p_size, WindowID p_windo
wd.min_size = p_size;
if ((wd.min_size != Size2i()) && !wd.fullscreen) {
- Size2i size = wd.min_size / _display_scale([wd.window_object screen]);
+ Size2i size = wd.min_size / screen_get_max_scale();
[wd.window_object setContentMinSize:NSMakeSize(size.x, size.y)];
} else {
[wd.window_object setContentMinSize:NSMakeSize(0, 0)];
@@ -2546,7 +2581,7 @@ void DisplayServerOSX::window_set_size(const Size2i p_size, WindowID p_window) {
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
- Size2i size = p_size / _display_scale([wd.window_object screen]);
+ Size2i size = p_size / screen_get_max_scale();
if (!wd.borderless) {
// NSRect used by setFrame includes the title bar, so add it to our size.y
@@ -2576,7 +2611,7 @@ Size2i DisplayServerOSX::window_get_real_size(WindowID p_window) const {
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
const WindowData &wd = windows[p_window];
NSRect frame = [wd.window_object frame];
- return Size2i(frame.size.width, frame.size.height) * _display_scale([wd.window_object screen]);
+ return Size2i(frame.size.width, frame.size.height) * screen_get_max_scale();
}
bool DisplayServerOSX::window_is_maximize_allowed(WindowID p_window) const {
@@ -2587,24 +2622,26 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
- if (!OS_OSX::get_singleton()->is_layered_allowed())
+ if (!OS_OSX::get_singleton()->is_layered_allowed()) {
return;
+ }
if (wd.layered_window != p_enabled) {
if (p_enabled) {
[wd.window_object setBackgroundColor:[NSColor clearColor]];
[wd.window_object setOpaque:NO];
[wd.window_object setHasShadow:NO];
+ CALayer *layer = [wd.window_view layer];
+ if (layer) {
+ [layer setOpaque:NO];
+ }
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
- CALayer *layer = [wd.window_view layer];
- [layer setOpaque:NO];
//TODO - implement transparency for Vulkan
}
#endif
#if defined(OPENGL_ENABLED)
if (rendering_driver == "opengl_es") {
//TODO - reimplement OpenGLES
- wd.context_gles2->set_opacity(0);
}
#endif
wd.layered_window = true;
@@ -2612,17 +2649,18 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
[wd.window_object setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1]];
[wd.window_object setOpaque:YES];
[wd.window_object setHasShadow:YES];
+ CALayer *layer = [wd.window_view layer];
+ if (layer) {
+ [layer setOpaque:YES];
+ }
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
- CALayer *layer = [wd.window_view layer];
- [layer setOpaque:YES];
//TODO - implement transparency for Vulkan
}
#endif
#if defined(OPENGL_ENABLED)
if (rendering_driver == "opengl_es") {
//TODO - reimplement OpenGLES
- wd.context_gles2->set_opacity(1);
}
#endif
wd.layered_window = false;
@@ -2630,7 +2668,11 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
#if defined(OPENGL_ENABLED)
if (rendering_driver == "opengl_es") {
//TODO - reimplement OpenGLES
- wd.context_gles2->update();
+ }
+#endif
+#if defined(VULKAN_ENABLED)
+ if (rendering_driver == "vulkan") {
+ //TODO - implement transparency for Vulkan
}
#endif
NSRect frameRect = [wd.window_object frame];
@@ -2658,16 +2700,18 @@ void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) {
[wd.window_object deminiaturize:nil];
} break;
case WINDOW_MODE_FULLSCREEN: {
- if (wd.layered_window)
+ if (wd.layered_window) {
_set_window_per_pixel_transparency_enabled(true, p_window);
- if (wd.resize_disabled) //restore resize disabled
+ }
+ if (wd.resize_disabled) { //restore resize disabled
[wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable];
+ }
if (wd.min_size != Size2i()) {
- Size2i size = wd.min_size / _display_scale([wd.window_object screen]);
+ Size2i size = wd.min_size / screen_get_max_scale();
[wd.window_object setContentMinSize:NSMakeSize(size.x, size.y)];
}
if (wd.max_size != Size2i()) {
- Size2i size = wd.max_size / _display_scale([wd.window_object screen]);
+ Size2i size = wd.max_size / screen_get_max_scale();
[wd.window_object setContentMaxSize:NSMakeSize(size.x, size.y)];
}
[wd.window_object toggleFullScreen:nil];
@@ -2736,8 +2780,9 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
switch (p_flag) {
case WINDOW_FLAG_RESIZE_DISABLED: {
wd.resize_disabled = p_enabled;
- if (wd.fullscreen) //fullscreen window should be resizable, style will be applyed on exiting fs
+ if (wd.fullscreen) { //fullscreen window should be resizable, style will be applyed on exiting fs
return;
+ }
if (p_enabled) {
[wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable];
} else {
@@ -2778,7 +2823,9 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
[wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (wd.resize_disabled ? 0 : NSWindowStyleMaskResizable)];
}
_set_window_per_pixel_transparency_enabled(p_enabled, p_window);
-
+ } break;
+ case WINDOW_FLAG_NO_FOCUS: {
+ wd.no_focus = p_enabled;
} break;
default: {
}
@@ -2804,6 +2851,9 @@ bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) co
case WINDOW_FLAG_TRANSPARENT: {
return wd.layered_window;
} break;
+ case WINDOW_FLAG_NO_FOCUS: {
+ return wd.no_focus;
+ } break;
default: {
}
}
@@ -2849,8 +2899,9 @@ void DisplayServerOSX::window_set_ime_active(const bool p_active, WindowID p_win
wd.im_active = p_active;
- if (!p_active)
+ if (!p_active) {
[wd.window_view cancelComposition];
+ }
}
void DisplayServerOSX::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
@@ -2871,8 +2922,9 @@ void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) {
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
- if (cursor_shape == p_shape)
+ if (cursor_shape == p_shape) {
return;
+ }
if (mouse_mode != MOUSE_MODE_VISIBLE && mouse_mode != MOUSE_MODE_CONFINED) {
cursor_shape = p_shape;
@@ -3266,8 +3318,9 @@ void DisplayServerOSX::process_events() {
inMode:NSDefaultRunLoopMode
dequeue:YES];
- if (event == nil)
+ if (event == nil) {
break;
+ }
[NSApp sendEvent:event];
}
@@ -3355,11 +3408,11 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
Vector<String> drivers;
-#ifdef VULKAN_ENABLED
+#if defined(VULKAN_ENABLED)
drivers.push_back("vulkan");
#endif
-#ifdef OPENGL_ENABLED
- drivers.push_back("opengl");
+#if defined(OPENGL_ENABLED)
+ drivers.push_back("opengl_es");
#endif
return drivers;
@@ -3374,9 +3427,14 @@ String DisplayServerOSX::ime_get_text() const {
}
DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Point2i &p_position) const {
+ Point2i position = p_position;
+ position.y *= -1;
+ position += _get_screens_origin();
+ position /= screen_get_max_scale();
+
+ NSInteger wnum = [NSWindow windowNumberAtPoint:NSMakePoint(position.x, position.y) belowWindowWithWindowNumber:0 /*topmost*/];
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- Rect2i win_rect = Rect2i(window_get_position(E->key()), window_get_size(E->key()));
- if (win_rect.has_point(p_position)) {
+ if ([E->get().window_object windowNumber] == wnum) {
return E->key();
}
}
@@ -3403,18 +3461,10 @@ DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, W
DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, const Rect2i &p_rect) {
WindowID id;
+ const float scale = screen_get_max_scale();
{
WindowData wd;
- float displayScale = 1.0;
- if (OS_OSX::get_singleton()->is_hidpi_allowed()) {
- // note that mainScreen is not screen #0 but the one with the keyboard focus.
- NSScreen *screen = [NSScreen mainScreen];
- if ([screen respondsToSelector:@selector(backingScaleFactor)]) {
- displayScale = fmax(displayScale, [screen backingScaleFactor]);
- }
- }
-
wd.window_delegate = [[GodotWindowDelegate alloc] init];
ERR_FAIL_COND_V_MSG(wd.window_delegate == nil, INVALID_WINDOW_ID, "Can't create a window delegate");
[wd.window_delegate setWindowID:window_id_counter];
@@ -3427,7 +3477,7 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, c
// initWithContentRect uses bottom-left corner of the window’s frame as origin.
wd.window_object = [[GodotWindow alloc]
- initWithContentRect:NSMakeRect(position.x / displayScale, (position.y - p_rect.size.height) / displayScale, p_rect.size.width / displayScale, p_rect.size.height / displayScale)
+ initWithContentRect:NSMakeRect(position.x / scale, (position.y - p_rect.size.height) / scale, p_rect.size.width / scale, p_rect.size.height / scale)
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable
backing:NSBackingStoreBuffered
defer:NO];
@@ -3440,54 +3490,32 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, c
[wd.window_view setWantsLayer:TRUE];
}
- if (displayScale > 1.0) {
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
- [wd.window_view setWantsBestResolutionOpenGLSurface:YES];
- }
-#endif
- [wd.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
- } else {
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
- [wd.window_view setWantsBestResolutionOpenGLSurface:NO];
- }
-#endif
- }
-
[wd.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
[wd.window_object setContentView:wd.window_view];
[wd.window_object setDelegate:wd.window_delegate];
[wd.window_object setAcceptsMouseMovedEvents:YES];
[wd.window_object setRestorable:NO];
- if ([wd.window_object respondsToSelector:@selector(setTabbingMode:)])
+ if ([wd.window_object respondsToSelector:@selector(setTabbingMode:)]) {
[wd.window_object setTabbingMode:NSWindowTabbingModeDisallowed];
+ }
+
+ CALayer *layer = [wd.window_view layer];
+ if (layer) {
+ layer.contentsScale = scale;
+ }
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
if (context_vulkan) {
- CALayer *layer = [wd.window_view layer];
- layer.contentsScale = displayScale;
Error err = context_vulkan->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan context");
}
}
#endif
-#ifdef OPENGL_ENABLED
+#if defined(OPENGL_ENABLED)
if (rendering_driver == "opengl_es") {
//TODO - reimplement OpenGLES
- wd.context_gles2 = memnew(ContextGL_OSX(wd.window_view, false));
-
- if (wd.context_gles2->initialize() != OK) {
- memdelete(wd.context_gles2);
- ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a OpenGL context");
- }
-
- //if (RasterizerGLES2::is_viable() == OK) {
- // RasterizerGLES2::register_config();
- // RasterizerGLES2::make_current();
- //}
}
#endif
id = window_id_counter++;
@@ -3497,25 +3525,22 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, c
WindowData &wd = windows[id];
window_set_mode(p_mode, id);
- float displayScale = _display_scale([wd.window_object screen]);
const NSRect contentRect = [wd.window_view frame];
- wd.size.width = contentRect.size.width * displayScale;
- wd.size.height = contentRect.size.height * displayScale;
+ wd.size.width = contentRect.size.width * scale;
+ wd.size.height = contentRect.size.height * scale;
+
+ CALayer *layer = [wd.window_view layer];
+ if (layer) {
+ layer.contentsScale = scale;
+ }
#if defined(OPENGL_ENABLED)
if (rendering_driver == "opengl_es") {
- if (OS_OSX::singleton->is_hidpi_allowed()) {
- [wd.window_view setWantsBestResolutionOpenGLSurface:YES];
- } else {
- [wd.window_view setWantsBestResolutionOpenGLSurface:NO];
- }
- wd.context_gles2->update();
+ //TODO - reimplement OpenGLES
}
#endif
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
- CALayer *layer = [wd.window_view layer];
- layer.contentsScale = displayScale;
context_vulkan->window_resize(id, wd.size.width, wd.size.height);
}
#endif
@@ -3610,6 +3635,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
keyboard_layout_dirty = true;
displays_arrangement_dirty = true;
+ displays_scale_dirty = true;
// Register to be notified on keyboard layout changes
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
@@ -3627,8 +3653,9 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
NSString *title;
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
- if (nsappname == nil)
+ if (nsappname == nil) {
nsappname = [[NSProcessInfo processInfo] processName];
+ }
// Setup Dock menu
dock_menu = [[NSMenu alloc] initWithTitle:@"_dock"];
@@ -3681,8 +3708,9 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
inMode:NSDefaultRunLoopMode
dequeue:YES];
- if (event == nil)
+ if (event == nil) {
break;
+ }
[NSApp sendEvent:event];
}
@@ -3714,8 +3742,8 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#endif
Point2i window_position(
- (screen_get_size(0).width - p_resolution.width) / 2,
- (screen_get_size(0).height - p_resolution.height) / 2);
+ screen_get_position(0).x + (screen_get_size(0).width - p_resolution.width) / 2,
+ screen_get_position(0).y + (screen_get_size(0).height - p_resolution.height) / 2);
WindowID main_window = _create_window(p_mode, Rect2i(window_position, p_resolution));
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
@@ -3724,6 +3752,11 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
}
[windows[main_window].window_object makeKeyAndOrderFront:nil];
+#if defined(OPENGL_ENABLED)
+ if (rendering_driver == "opengl_es") {
+ //TODO - reimplement OpenGLES
+ }
+#endif
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
@@ -3734,14 +3767,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#endif
[NSApp activateIgnoringOtherApps:YES];
-
- /*
- visual_server = memnew(VisualServerRaster);
- if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
- visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
- }
- visual_server->init();
- */
}
DisplayServerOSX::~DisplayServerOSX() {
@@ -3760,6 +3785,11 @@ DisplayServerOSX::~DisplayServerOSX() {
}
//destroy drivers
+#if defined(OPENGL_ENABLED)
+ if (rendering_driver == "opengl_es") {
+ //TODO - reimplement OpenGLES
+ }
+#endif
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
if (rendering_device_vulkan) {
@@ -3767,8 +3797,9 @@ DisplayServerOSX::~DisplayServerOSX() {
memdelete(rendering_device_vulkan);
}
- if (context_vulkan)
+ if (context_vulkan) {
memdelete(context_vulkan);
+ }
}
#endif
@@ -3776,9 +3807,6 @@ DisplayServerOSX::~DisplayServerOSX() {
CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL);
cursors_cache.clear();
-
- //visual_server->finish();
- //memdelete(visual_server);
}
void DisplayServerOSX::register_osx_driver() {
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index dba96ccfcd..4ca89ff4b2 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -272,7 +272,13 @@ String OS_OSX::get_system_dir(SystemDir p_dir) const {
}
Error OS_OSX::shell_open(String p_uri) {
- [[NSWorkspace sharedWorkspace] openURL:[[NSURL alloc] initWithString:[[NSString stringWithUTF8String:p_uri.utf8().get_data()] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]]];
+ NSString *string = [NSString stringWithUTF8String:p_uri.utf8().get_data()];
+ NSURL *uri = [[NSURL alloc] initWithString:string];
+ // Escape special characters in filenames
+ if (!uri || !uri.scheme || [uri.scheme isEqual:@"file"]) {
+ uri = [[NSURL alloc] initWithString:[string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
+ }
+ [[NSWorkspace sharedWorkspace] openURL:uri];
return OK;
}
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 790277ca3a..103e858d97 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -476,6 +476,7 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
_THREAD_SAFE_METHOD_
WindowID window_id = _create_window(p_mode, p_flags, p_rect);
+ ERR_FAIL_COND_V_MSG(window_id == INVALID_WINDOW_ID, INVALID_WINDOW_ID, "Failed to create sub window.");
WindowData &wd = windows[window_id];
@@ -1773,14 +1774,22 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
};
WindowID window_id = INVALID_WINDOW_ID;
+ bool window_created = false;
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
if (E->get().hWnd == hWnd) {
window_id = E->key();
+ window_created = true;
break;
}
}
+ if (!window_created) {
+ // Window creation in progress.
+ window_id = window_id_counter;
+ ERR_FAIL_COND_V(!windows.has(window_id), 0);
+ }
+
switch (uMsg) // Check For Windows Messages
{
case WM_SETFOCUS: {
@@ -2512,7 +2521,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
windows[window_id].height = window_h;
#if defined(VULKAN_ENABLED)
- if (rendering_driver == "vulkan") {
+ if ((rendering_driver == "vulkan") && window_created) {
context_vulkan->window_resize(window_id, windows[window_id].width, windows[window_id].height);
}
#endif
@@ -2889,7 +2898,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
WindowID id = window_id_counter;
{
- WindowData wd;
+ WindowData &wd = windows[id];
wd.hWnd = CreateWindowExW(
dwExStyle,
@@ -2904,6 +2913,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
nullptr, nullptr, hInstance, nullptr);
if (!wd.hWnd) {
MessageBoxW(nullptr, L"Window Creation Error.", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
+ windows.erase(id);
return INVALID_WINDOW_ID;
}
#ifdef VULKAN_ENABLED
@@ -2912,7 +2922,8 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
if (context_vulkan->window_create(id, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) {
memdelete(context_vulkan);
context_vulkan = nullptr;
- ERR_FAIL_V(INVALID_WINDOW_ID);
+ windows.erase(id);
+ ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create Vulkan Window.");
}
}
#endif
@@ -2970,8 +2981,6 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
wd.width = p_rect.size.width;
wd.height = p_rect.size.height;
- windows[id] = wd;
-
window_id_counter++;
}
@@ -3102,7 +3111,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
Point2i window_position(
(screen_get_size(0).width - p_resolution.width) / 2,
(screen_get_size(0).height - p_resolution.height) / 2);
+
WindowID main_window = _create_window(p_mode, 0, Rect2i(window_position, p_resolution));
+ ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window.");
+
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, main_window);
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index 88d124536c..d022c857f3 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -176,11 +176,14 @@ String CollisionShape2D::get_configuration_warning() const {
if (!Object::cast_to<CollisionObject2D>(get_parent())) {
return TTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
}
-
if (!shape.is_valid()) {
return TTR("A shape must be provided for CollisionShape2D to function. Please create a shape resource for it!");
}
-
+ Ref<ConvexPolygonShape2D> convex = shape;
+ Ref<ConcavePolygonShape2D> concave = shape;
+ if (convex.is_valid() || concave.is_valid()) {
+ return TTR("Polygon-based shapes are not meant be used nor edited directly through the CollisionShape2D node. Please use the CollisionPolygon2D node instead.");
+ }
return String();
}
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 41ca6458af..1e0d3d9f7b 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -604,7 +604,7 @@ void FileDialog::set_current_file(const String &p_file) {
file->set_text(p_file);
update_dir();
invalidate();
- int lp = p_file.find_last(".");
+ int lp = p_file.rfind(".");
if (lp != -1) {
file->select(0, lp);
if (file->is_inside_tree() && !get_tree()->is_node_being_edited(file)) {
@@ -617,7 +617,7 @@ void FileDialog::set_current_path(const String &p_path) {
if (!p_path.size()) {
return;
}
- int pos = MAX(p_path.find_last("/"), p_path.find_last("\\"));
+ int pos = MAX(p_path.rfind("/"), p_path.rfind("\\"));
if (pos == -1) {
set_current_file(p_path);
} else {
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 2b0e084db4..1ea790fc4f 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -370,8 +370,9 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
+ connecting_valid = false;
Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
- Vector2 mpos(mb->get_position().x, mb->get_position().y);
+ click_pos = mb->get_position();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
if (!gn) {
@@ -380,7 +381,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
for (int j = 0; j < gn->get_connection_output_count(); j++) {
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
- if (is_in_hot_zone(pos, mpos)) {
+ if (is_in_hot_zone(pos, click_pos)) {
if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) {
//check disconnect
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
@@ -422,7 +423,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
for (int j = 0; j < gn->get_connection_input_count(); j++) {
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
- if (is_in_hot_zone(pos, mpos)) {
+ if (is_in_hot_zone(pos, click_pos)) {
if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) {
//check disconnect
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
@@ -470,37 +471,40 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_to = mm->get_position();
connecting_target = false;
top_layer->update();
+ connecting_valid = just_disconnected || click_pos.distance_to(connecting_to) > 20.0 * zoom;
- Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
- Vector2 mpos = mm->get_position();
- for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn) {
- continue;
- }
+ if (connecting_valid) {
+ Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
+ Vector2 mpos = mm->get_position();
+ for (int i = get_child_count() - 1; i >= 0; i--) {
+ GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
+ if (!gn) {
+ continue;
+ }
- if (!connecting_out) {
- for (int j = 0; j < gn->get_connection_output_count(); j++) {
- Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
- int type = gn->get_connection_output_type(j);
- if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
- connecting_target = true;
- connecting_to = pos;
- connecting_target_to = gn->get_name();
- connecting_target_index = j;
- return;
+ if (!connecting_out) {
+ for (int j = 0; j < gn->get_connection_output_count(); j++) {
+ Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
+ int type = gn->get_connection_output_type(j);
+ if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
+ connecting_target = true;
+ connecting_to = pos;
+ connecting_target_to = gn->get_name();
+ connecting_target_index = j;
+ return;
+ }
}
- }
- } else {
- for (int j = 0; j < gn->get_connection_input_count(); j++) {
- Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
- int type = gn->get_connection_input_type(j);
- if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
- connecting_target = true;
- connecting_to = pos;
- connecting_target_to = gn->get_name();
- connecting_target_index = j;
- return;
+ } else {
+ for (int j = 0; j < gn->get_connection_input_count(); j++) {
+ Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
+ int type = gn->get_connection_input_type(j);
+ if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
+ connecting_target = true;
+ connecting_to = pos;
+ connecting_target_to = gn->get_name();
+ connecting_target_index = j;
+ return;
+ }
}
}
}
@@ -508,27 +512,29 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
- if (connecting && connecting_target) {
- String from = connecting_from;
- int from_slot = connecting_index;
- String to = connecting_target_to;
- int to_slot = connecting_target_index;
-
- if (!connecting_out) {
- SWAP(from, to);
- SWAP(from_slot, to_slot);
- }
- emit_signal("connection_request", from, from_slot, to, to_slot);
+ if (connecting_valid) {
+ if (connecting && connecting_target) {
+ String from = connecting_from;
+ int from_slot = connecting_index;
+ String to = connecting_target_to;
+ int to_slot = connecting_target_index;
+
+ if (!connecting_out) {
+ SWAP(from, to);
+ SWAP(from_slot, to_slot);
+ }
+ emit_signal("connection_request", from, from_slot, to, to_slot);
- } else if (!just_disconnected) {
- String from = connecting_from;
- int from_slot = connecting_index;
- Vector2 ofs = Vector2(mb->get_position().x, mb->get_position().y);
+ } else if (!just_disconnected) {
+ String from = connecting_from;
+ int from_slot = connecting_index;
+ Vector2 ofs = Vector2(mb->get_position().x, mb->get_position().y);
- if (!connecting_out) {
- emit_signal("connection_from_empty", from, from_slot, ofs);
- } else {
- emit_signal("connection_to_empty", from, from_slot, ofs);
+ if (!connecting_out) {
+ emit_signal("connection_from_empty", from, from_slot, ofs);
+ } else {
+ emit_signal("connection_to_empty", from, from_slot, ofs);
+ }
}
}
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index a627a8eec8..454047f228 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -93,6 +93,8 @@ private:
String connecting_target_to;
int connecting_target_index;
bool just_disconnected;
+ bool connecting_valid;
+ Vector2 click_pos;
bool dragging;
bool just_selected;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 48540b7bc9..ae30972558 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -338,6 +338,7 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
emit_signal("go_back_requested");
} break;
case DisplayServer::WINDOW_EVENT_DPI_CHANGE: {
+ _update_viewport_size();
_propagate_window_notification(this, NOTIFICATION_WM_DPI_CHANGE);
emit_signal("dpi_changed");
} break;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 83d4db7bae..b0c01da2b0 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -181,7 +181,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("disabled", "Button", sb_button_disabled);
theme->set_stylebox("focus", "Button", sb_button_focus);
- theme->set_font("font", "Button", default_font);
+ theme->set_font("font", "Button", Ref<Font>());
theme->set_color("font_color", "Button", control_font_color);
theme->set_color("font_color_pressed", "Button", control_font_color_pressed);
@@ -194,7 +194,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("focus", "LinkButton", focus);
- theme->set_font("font", "LinkButton", default_font);
+ theme->set_font("font", "LinkButton", Ref<Font>());
theme->set_color("font_color", "LinkButton", control_font_color);
theme->set_color("font_color_pressed", "LinkButton", control_font_color_pressed);
@@ -210,7 +210,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("disabled", "ColorPickerButton", sb_button_disabled);
theme->set_stylebox("focus", "ColorPickerButton", sb_button_focus);
- theme->set_font("font", "ColorPickerButton", default_font);
+ theme->set_font("font", "ColorPickerButton", Ref<Font>());
theme->set_color("font_color", "ColorPickerButton", Color(1, 1, 1, 1));
theme->set_color("font_color_pressed", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1));
@@ -235,7 +235,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("arrow", "OptionButton", make_icon(option_arrow_png));
- theme->set_font("font", "OptionButton", default_font);
+ theme->set_font("font", "OptionButton", Ref<Font>());
theme->set_color("font_color", "OptionButton", control_font_color);
theme->set_color("font_color_pressed", "OptionButton", control_font_color_pressed);
@@ -253,7 +253,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("disabled", "MenuButton", sb_button_disabled);
theme->set_stylebox("focus", "MenuButton", sb_button_focus);
- theme->set_font("font", "MenuButton", default_font);
+ theme->set_font("font", "MenuButton", Ref<Font>());
theme->set_color("font_color", "MenuButton", control_font_color);
theme->set_color("font_color_pressed", "MenuButton", control_font_color_pressed);
@@ -287,7 +287,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("radio_checked", "CheckBox", make_icon(radio_checked_png));
theme->set_icon("radio_unchecked", "CheckBox", make_icon(radio_unchecked_png));
- theme->set_font("font", "CheckBox", default_font);
+ theme->set_font("font", "CheckBox", Ref<Font>());
theme->set_color("font_color", "CheckBox", control_font_color);
theme->set_color("font_color_pressed", "CheckBox", control_font_color_pressed);
@@ -318,7 +318,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("off", "CheckButton", make_icon(toggle_off_png));
theme->set_icon("off_disabled", "CheckButton", make_icon(toggle_off_disabled_png));
- theme->set_font("font", "CheckButton", default_font);
+ theme->set_font("font", "CheckButton", Ref<Font>());
theme->set_color("font_color", "CheckButton", control_font_color);
theme->set_color("font_color_pressed", "CheckButton", control_font_color_pressed);
@@ -332,7 +332,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// Label
theme->set_stylebox("normal", "Label", memnew(StyleBoxEmpty));
- theme->set_font("font", "Label", default_font);
+ theme->set_font("font", "Label", Ref<Font>());
theme->set_color("font_color", "Label", Color(1, 1, 1));
theme->set_color("font_color_shadow", "Label", Color(0, 0, 0, 0));
@@ -349,7 +349,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("focus", "LineEdit", focus);
theme->set_stylebox("read_only", "LineEdit", make_stylebox(line_edit_disabled_png, 6, 6, 6, 6));
- theme->set_font("font", "LineEdit", default_font);
+ theme->set_font("font", "LineEdit", Ref<Font>());
theme->set_color("font_color", "LineEdit", control_font_color);
theme->set_color("font_color_selected", "LineEdit", Color(0, 0, 0));
@@ -368,7 +368,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("bg", "ProgressBar", make_stylebox(progress_bar_png, 4, 4, 4, 4, 0, 0, 0, 0));
theme->set_stylebox("fg", "ProgressBar", make_stylebox(progress_fill_png, 6, 6, 6, 6, 2, 1, 2, 1));
- theme->set_font("font", "ProgressBar", default_font);
+ theme->set_font("font", "ProgressBar", Ref<Font>());
theme->set_color("font_color", "ProgressBar", control_font_color_hover);
theme->set_color("font_color_shadow", "ProgressBar", Color(0, 0, 0));
@@ -385,7 +385,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("folded", "TextEdit", make_icon(arrow_right_png));
theme->set_icon("fold", "TextEdit", make_icon(arrow_down_png));
- theme->set_font("font", "TextEdit", default_font);
+ theme->set_font("font", "TextEdit", Ref<Font>());
theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0));
theme->set_color("completion_background_color", "TextEdit", Color(0.17, 0.16, 0.2));
@@ -531,7 +531,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("radio_unchecked", "PopupMenu", make_icon(radio_unchecked_png));
theme->set_icon("submenu", "PopupMenu", make_icon(submenu_png));
- theme->set_font("font", "PopupMenu", default_font);
+ theme->set_font("font", "PopupMenu", Ref<Font>());
theme->set_color("font_color", "PopupMenu", control_font_color);
theme->set_color("font_color_accel", "PopupMenu", Color(0.7, 0.7, 0.7, 0.8));
@@ -566,7 +566,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("port", "GraphNode", make_icon(graph_port_png));
theme->set_icon("close", "GraphNode", make_icon(graph_node_close_png));
theme->set_icon("resizer", "GraphNode", make_icon(window_resizer_png));
- theme->set_font("title_font", "GraphNode", default_font);
+ theme->set_font("title_font", "GraphNode", Ref<Font>());
theme->set_color("title_color", "GraphNode", Color(0, 0, 0, 1));
theme->set_color("close_color", "GraphNode", Color(0, 0, 0, 1));
theme->set_color("resizer_color", "GraphNode", Color(0, 0, 0, 1));
@@ -600,8 +600,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("arrow", "Tree", make_icon(arrow_down_png));
theme->set_icon("arrow_collapsed", "Tree", make_icon(arrow_right_png));
- theme->set_font("title_button_font", "Tree", default_font);
- theme->set_font("font", "Tree", default_font);
+ theme->set_font("title_button_font", "Tree", Ref<Font>());
+ theme->set_font("font", "Tree", Ref<Font>());
theme->set_color("title_button_color", "Tree", control_font_color);
theme->set_color("font_color", "Tree", control_font_color_low);
@@ -630,7 +630,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("vseparation", "ItemList", 2);
theme->set_constant("icon_margin", "ItemList", 4);
theme->set_constant("line_separation", "ItemList", 2 * scale);
- theme->set_font("font", "ItemList", default_font);
+ theme->set_font("font", "ItemList", Ref<Font>());
theme->set_color("font_color", "ItemList", control_font_color_lower);
theme->set_color("font_color_selected", "ItemList", control_font_color_pressed);
theme->set_color("guide_color", "ItemList", Color(0, 0, 0, 0.1));
@@ -658,7 +658,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("menu", "TabContainer", make_icon(tab_menu_png));
theme->set_icon("menu_highlight", "TabContainer", make_icon(tab_menu_hl_png));
- theme->set_font("font", "TabContainer", default_font);
+ theme->set_font("font", "TabContainer", Ref<Font>());
theme->set_color("font_color_fg", "TabContainer", control_font_color_hover);
theme->set_color("font_color_bg", "TabContainer", control_font_color_low);
@@ -682,7 +682,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("decrement_highlight", "Tabs", make_icon(scroll_button_left_hl_png));
theme->set_icon("close", "Tabs", make_icon(tab_close_png));
- theme->set_font("font", "Tabs", default_font);
+ theme->set_font("font", "Tabs", Ref<Font>());
theme->set_color("font_color_fg", "Tabs", control_font_color_hover);
theme->set_color("font_color_bg", "Tabs", control_font_color_low);
@@ -696,7 +696,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("separator", "VSeparator", make_stylebox(hseparator_png, 3, 3, 3, 3));
theme->set_icon("close", "Icons", make_icon(icon_close_png));
- theme->set_font("normal", "Fonts", default_font);
+ theme->set_font("normal", "Fonts", Ref<Font>());
theme->set_font("large", "Fonts", large_font);
theme->set_constant("separation", "HSeparator", 4 * scale);
@@ -741,7 +741,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("panel", "TooltipPanel", style_tt);
- theme->set_font("font", "TooltipLabel", default_font);
+ theme->set_font("font", "TooltipLabel", Ref<Font>());
theme->set_color("font_color", "TooltipLabel", Color(0, 0, 0));
theme->set_color("font_color_shadow", "TooltipLabel", Color(0, 0, 0, 0.1));
@@ -754,11 +754,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("focus", "RichTextLabel", focus);
theme->set_stylebox("normal", "RichTextLabel", make_empty_stylebox(0, 0, 0, 0));
- theme->set_font("normal_font", "RichTextLabel", default_font);
- theme->set_font("bold_font", "RichTextLabel", default_font);
- theme->set_font("italics_font", "RichTextLabel", default_font);
- theme->set_font("bold_italics_font", "RichTextLabel", default_font);
- theme->set_font("mono_font", "RichTextLabel", default_font);
+ theme->set_font("normal_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("bold_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("italics_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("bold_italics_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("mono_font", "RichTextLabel", Ref<Font>());
theme->set_color("default_color", "RichTextLabel", Color(1, 1, 1));
theme->set_color("font_color_selected", "RichTextLabel", font_color_selection);
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 83e0a797a9..72cfd87880 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -392,6 +392,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("screen_get_dpi", "screen"), &DisplayServer::screen_get_dpi, DEFVAL(SCREEN_OF_MAIN_WINDOW));
ClassDB::bind_method(D_METHOD("screen_get_scale", "screen"), &DisplayServer::screen_get_scale, DEFVAL(SCREEN_OF_MAIN_WINDOW));
ClassDB::bind_method(D_METHOD("screen_is_touchscreen", "screen"), &DisplayServer::screen_is_touchscreen, DEFVAL(SCREEN_OF_MAIN_WINDOW));
+ ClassDB::bind_method(D_METHOD("screen_get_max_scale"), &DisplayServer::screen_get_max_scale);
ClassDB::bind_method(D_METHOD("screen_set_orientation", "orientation", "screen"), &DisplayServer::screen_set_orientation, DEFVAL(SCREEN_OF_MAIN_WINDOW));
ClassDB::bind_method(D_METHOD("screen_get_orientation", "screen"), &DisplayServer::screen_get_orientation, DEFVAL(SCREEN_OF_MAIN_WINDOW));
diff --git a/servers/display_server.h b/servers/display_server.h
index a4fcd29a4a..79f6f5d0fc 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -167,6 +167,14 @@ public:
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual float screen_get_max_scale() const {
+ float scale = 1.f;
+ int screen_count = get_screen_count();
+ for (int i = 0; i < screen_count; i++) {
+ scale = fmax(scale, screen_get_scale(i));
+ }
+ return scale;
+ }
virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
enum ScreenOrientation {
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index acbbb7e1e8..7485f31afc 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -213,9 +213,10 @@ void Area2DSW::call_queries() {
return;
}
- for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E; E = E->next()) {
- if (E->get().state == 0) {
- continue; //nothing happened
+ for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) {
+ if (E->get().state == 0) { // Nothing happened
+ E = E->next();
+ continue;
}
res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED;
@@ -224,13 +225,15 @@ void Area2DSW::call_queries() {
res[3] = E->key().body_shape;
res[4] = E->key().area_shape;
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_bodies.erase(E);
+ E = next;
+
Callable::CallError ce;
obj->call(monitor_callback_method, (const Variant **)resptr, 5, ce);
}
}
- monitored_bodies.clear();
-
if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) {
Variant res[5];
Variant *resptr[5];
@@ -245,9 +248,10 @@ void Area2DSW::call_queries() {
return;
}
- for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E; E = E->next()) {
- if (E->get().state == 0) {
- continue; //nothing happened
+ for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) {
+ if (E->get().state == 0) { // Nothing happened
+ E = E->next();
+ continue;
}
res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED;
@@ -256,14 +260,14 @@ void Area2DSW::call_queries() {
res[3] = E->key().body_shape;
res[4] = E->key().area_shape;
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_areas.erase(E);
+ E = next;
+
Callable::CallError ce;
obj->call(area_monitor_callback_method, (const Variant **)resptr, 5, ce);
}
}
-
- monitored_areas.clear();
-
- //get_space()->area_remove_from_monitor_query_list(&monitor_query_list);
}
Area2DSW::Area2DSW() :
diff --git a/servers/physics_3d/area_3d_sw.cpp b/servers/physics_3d/area_3d_sw.cpp
index 98237dd91c..571f1435de 100644
--- a/servers/physics_3d/area_3d_sw.cpp
+++ b/servers/physics_3d/area_3d_sw.cpp
@@ -213,9 +213,10 @@ void Area3DSW::call_queries() {
return;
}
- for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E; E = E->next()) {
- if (E->get().state == 0) {
- continue; //nothing happened
+ for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) {
+ if (E->get().state == 0) { // Nothing happened
+ E = E->next();
+ continue;
}
res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED;
@@ -224,13 +225,15 @@ void Area3DSW::call_queries() {
res[3] = E->key().body_shape;
res[4] = E->key().area_shape;
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_bodies.erase(E);
+ E = next;
+
Callable::CallError ce;
obj->call(monitor_callback_method, (const Variant **)resptr, 5, ce);
}
}
- monitored_bodies.clear();
-
if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) {
Variant res[5];
Variant *resptr[5];
@@ -245,9 +248,10 @@ void Area3DSW::call_queries() {
return;
}
- for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E; E = E->next()) {
- if (E->get().state == 0) {
- continue; //nothing happened
+ for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) {
+ if (E->get().state == 0) { // Nothing happened
+ E = E->next();
+ continue;
}
res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED;
@@ -256,13 +260,14 @@ void Area3DSW::call_queries() {
res[3] = E->key().body_shape;
res[4] = E->key().area_shape;
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_areas.erase(E);
+ E = next;
+
Callable::CallError ce;
obj->call(area_monitor_callback_method, (const Variant **)resptr, 5, ce);
}
}
-
- monitored_areas.clear();
- //get_space()->area_remove_from_monitor_query_list(&monitor_query_list);
}
Area3DSW::Area3DSW() :