summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/class_db.h4
-rw-r--r--core/color.h4
-rw-r--r--core/command_queue_mt.h4
-rw-r--r--core/io/image_loader.h4
-rw-r--r--core/io/resource_loader.h3
-rw-r--r--core/io/resource_saver.h4
-rw-r--r--core/map.h4
-rw-r--r--core/math/a_star.h1
-rw-r--r--core/math/basis.h4
-rw-r--r--core/math/bsp_tree.h4
-rw-r--r--core/math/camera_matrix.h4
-rw-r--r--core/math/geometry.h4
-rw-r--r--core/math/octree.h4
-rw-r--r--core/math/quat.h4
-rw-r--r--core/math/transform.cpp5
-rw-r--r--core/math/transform.h5
-rw-r--r--core/method_bind.h4
-rw-r--r--core/node_path.h4
-rw-r--r--core/os/dir_access.h16
-rw-r--r--core/os/input_event.h4
-rw-r--r--core/os/keyboard.h4
-rw-r--r--core/os/main_loop.h4
-rw-r--r--core/os/memory.h4
-rw-r--r--core/os/os.h4
-rw-r--r--core/os/semaphore.h4
-rw-r--r--core/os/thread.h4
-rw-r--r--core/pool_vector.h4
-rw-r--r--core/project_settings.h4
-rw-r--r--core/reference.h3
-rw-r--r--core/register_core_types.h4
-rw-r--r--core/resource.h4
-rw-r--r--core/rid.h4
-rw-r--r--core/script_debugger_remote.cpp14
-rw-r--r--core/script_language.h4
-rw-r--r--core/set.h4
-rw-r--r--core/string_name.h3
-rw-r--r--core/ustring.h4
-rw-r--r--core/variant.h4
-rw-r--r--core/variant_call.cpp26
-rw-r--r--doc/classes/AudioServer.xml28
-rw-r--r--doc/classes/Basis.xml8
-rw-r--r--doc/classes/Camera2D.xml4
-rw-r--r--doc/classes/Control.xml2
-rw-r--r--doc/classes/EditorInterface.xml16
-rw-r--r--doc/classes/EditorPlugin.xml4
-rw-r--r--doc/classes/Image.xml12
-rw-r--r--doc/classes/Popup.xml7
-rw-r--r--doc/classes/VisualShaderNodeVectorScalarMix.xml13
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp8
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp5
-rw-r--r--drivers/gles3/shader_gles3.h4
-rw-r--r--drivers/png/image_loader_png.h3
-rw-r--r--drivers/register_driver_types.h4
-rw-r--r--drivers/unix/dir_access_unix.h4
-rw-r--r--drivers/unix/file_access_unix.h4
-rw-r--r--drivers/unix/os_unix.h4
-rw-r--r--drivers/unix/semaphore_posix.h4
-rw-r--r--drivers/unix/thread_posix.h4
-rw-r--r--drivers/windows/file_access_windows.h4
-rw-r--r--drivers/windows/mutex_windows.h4
-rw-r--r--drivers/windows/semaphore_windows.h4
-rw-r--r--drivers/windows/thread_windows.h4
-rw-r--r--editor/code_editor.cpp97
-rw-r--r--editor/code_editor.h6
-rw-r--r--editor/create_dialog.h3
-rw-r--r--editor/editor_about.h3
-rw-r--r--editor/editor_export.cpp38
-rw-r--r--editor/editor_file_dialog.h3
-rw-r--r--editor/editor_help.cpp12
-rw-r--r--editor/editor_node.cpp48
-rw-r--r--editor/editor_node.h7
-rw-r--r--editor/editor_plugin.h4
-rw-r--r--editor/editor_spin_slider.cpp5
-rw-r--r--editor/export_template_manager.cpp33
-rw-r--r--editor/find_in_files.cpp1
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h3
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h3
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h3
-rw-r--r--editor/plugins/animation_player_editor_plugin.h3
-rw-r--r--editor/plugins/animation_tree_player_editor_plugin.h3
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp13
-rw-r--r--editor/plugins/camera_editor_plugin.h4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h3
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.h3
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.h4
-rw-r--r--editor/plugins/item_list_editor_plugin.h4
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h3
-rw-r--r--editor/plugins/multimesh_editor_plugin.h4
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.h3
-rw-r--r--editor/plugins/particles_editor_plugin.h4
-rw-r--r--editor/plugins/path_2d_editor_plugin.h3
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h4
-rw-r--r--editor/plugins/script_editor_plugin.cpp21
-rw-r--r--editor/plugins/script_text_editor.cpp44
-rw-r--r--editor/plugins/script_text_editor.h1
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp11
-rw-r--r--editor/plugins/spatial_editor_plugin.h3
-rw-r--r--editor/plugins/text_editor.cpp14
-rw-r--r--editor/plugins/text_editor.h1
-rw-r--r--editor/plugins/theme_editor_plugin.cpp71
-rw-r--r--editor/plugins/theme_editor_plugin.h2
-rw-r--r--editor/plugins/tile_map_editor_plugin.h4
-rw-r--r--editor/project_manager.cpp4
-rw-r--r--editor/property_editor.h4
-rw-r--r--editor/pvrtc_compress.cpp53
-rw-r--r--editor/scene_tree_editor.h4
-rw-r--r--editor/script_create_dialog.cpp25
-rw-r--r--editor/script_create_dialog.h1
-rw-r--r--main/main.h4
-rw-r--r--main/tests/test_gui.h3
-rw-r--r--main/tests/test_physics.h4
-rw-r--r--main/tests/test_render.h4
-rw-r--r--modules/assimp/editor_scene_importer_assimp.cpp9
-rw-r--r--modules/bmp/image_loader_bmp.cpp4
-rw-r--r--modules/bullet/bullet_physics_server.cpp3
-rw-r--r--modules/bullet/cone_twist_joint_bullet.cpp6
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp9
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp6
-rw-r--r--modules/bullet/pin_joint_bullet.cpp3
-rw-r--r--modules/bullet/shape_bullet.cpp3
-rw-r--r--modules/bullet/space_bullet.cpp6
-rw-r--r--modules/dds/texture_loader_dds.cpp10
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp11
-rw-r--r--modules/etc/texture_loader_pkm.cpp3
-rw-r--r--modules/gdnative/gdnative_builders.py2
-rw-r--r--modules/gdscript/register_types.cpp4
-rw-r--r--modules/gridmap/grid_map.cpp6
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp10
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h3
-rw-r--r--modules/hdr/image_loader_hdr.cpp5
-rw-r--r--modules/hdr/image_loader_hdr.h3
-rw-r--r--modules/jpg/image_loader_jpegd.h3
-rw-r--r--modules/mono/.gitignore2
-rw-r--r--modules/mono/build_scripts/godot_tools_build.py10
-rw-r--r--modules/mono/build_scripts/mono_configure.py6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs33
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs94
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs219
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs207
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs45
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj52
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs13
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs21
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs46
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs88
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs35
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.sln6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs (renamed from modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs)30
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs16
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs (renamed from modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs)8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildManager.cs (renamed from modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs)87
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildTab.cs (renamed from modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs)20
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs (renamed from modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs)2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs11
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs121
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs166
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs208
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/EditorId.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs (renamed from modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs)43
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs15
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs64
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp19
-rw-r--r--modules/mono/glue/Managed/Files/Basis.cs77
-rw-r--r--modules/mono/glue/Managed/Files/Dispatcher.cs13
-rw-r--r--modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs7
-rw-r--r--modules/mono/glue/Managed/Files/GodotTaskScheduler.cs9
-rw-r--r--modules/mono/glue/Managed/Managed.csproj4
-rw-r--r--modules/mono/glue/gd_glue.cpp7
-rw-r--r--modules/mono/glue/gd_glue.h2
-rw-r--r--modules/mono/icons/icon_c_#.svg5
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp34
-rw-r--r--modules/mono/mono_gd/gd_mono.h2
-rw-r--r--modules/opus/audio_stream_opus.cpp3
-rw-r--r--modules/pvr/texture_loader_pvr.cpp3
-rw-r--r--modules/squish/image_compress_squish.cpp3
-rw-r--r--modules/svg/image_loader_svg.cpp6
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h3
-rw-r--r--modules/visual_script/visual_script.cpp31
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp3
-rw-r--r--modules/webm/video_stream_webm.cpp3
-rw-r--r--modules/webp/image_loader_webp.cpp3
-rw-r--r--modules/webp/image_loader_webp.h3
-rw-r--r--modules/webrtc/webrtc_data_channel_js.cpp6
-rw-r--r--modules/webrtc/webrtc_multiplayer.cpp6
-rw-r--r--modules/webrtc/webrtc_peer_connection_gdnative.cpp6
-rw-r--r--modules/websocket/emws_peer.cpp6
-rw-r--r--modules/websocket/websocket_multiplayer_peer.cpp15
-rw-r--r--modules/websocket/wsl_client.cpp33
-rw-r--r--modules/websocket/wsl_server.cpp30
-rw-r--r--platform/SCsub2
-rw-r--r--platform/android/export/export.cpp90
-rw-r--r--platform/android/thread_jandroid.h4
-rw-r--r--platform/javascript/detect.py3
-rw-r--r--platform/javascript/export/export.cpp13
-rw-r--r--platform/osx/dir_access_osx.h3
-rw-r--r--platform/osx/export/export.cpp21
-rw-r--r--platform/osx/os_osx.h3
-rw-r--r--platform/server/os_server.h3
-rw-r--r--platform/uwp/export/export.cpp57
-rw-r--r--platform/uwp/os_uwp.h3
-rw-r--r--platform/windows/os_windows.h4
-rw-r--r--platform/x11/context_gl_x11.h3
-rw-r--r--platform/x11/key_mapping_x11.h3
-rw-r--r--platform/x11/os_x11.h3
-rw-r--r--scene/2d/cpu_particles_2d.h4
-rw-r--r--scene/3d/camera.h4
-rw-r--r--scene/3d/cpu_particles.h4
-rw-r--r--scene/3d/light.h4
-rw-r--r--scene/3d/mesh_instance.h3
-rw-r--r--scene/3d/multimesh_instance.h4
-rw-r--r--scene/3d/particles.h4
-rw-r--r--scene/3d/portal.h3
-rw-r--r--scene/3d/room_instance.h4
-rw-r--r--scene/3d/skeleton.h4
-rw-r--r--scene/3d/spatial.h4
-rw-r--r--scene/3d/visual_instance.h4
-rw-r--r--scene/3d/world_environment.h4
-rw-r--r--scene/animation/animation_player.h3
-rw-r--r--scene/gui/base_button.h3
-rw-r--r--scene/gui/button.h3
-rw-r--r--scene/gui/control.h3
-rw-r--r--scene/gui/dialogs.h3
-rw-r--r--scene/gui/file_dialog.h4
-rw-r--r--scene/gui/label.h4
-rw-r--r--scene/gui/line_edit.cpp20
-rw-r--r--scene/gui/line_edit.h3
-rw-r--r--scene/gui/menu_button.h4
-rw-r--r--scene/gui/nine_patch_rect.h4
-rw-r--r--scene/gui/option_button.h4
-rw-r--r--scene/gui/panel.h4
-rw-r--r--scene/gui/popup.cpp3
-rw-r--r--scene/gui/popup.h3
-rw-r--r--scene/gui/popup_menu.h4
-rw-r--r--scene/gui/range.h4
-rw-r--r--scene/gui/scroll_bar.h4
-rw-r--r--scene/gui/separator.h4
-rw-r--r--scene/gui/spin_box.cpp4
-rw-r--r--scene/gui/text_edit.cpp22
-rw-r--r--scene/gui/texture_rect.h4
-rw-r--r--scene/gui/tree.h4
-rw-r--r--scene/main/scene_tree.h4
-rw-r--r--scene/main/viewport.h3
-rw-r--r--scene/register_scene_types.h4
-rw-r--r--scene/resources/animation.h4
-rw-r--r--scene/resources/default_theme/default_theme.h3
-rw-r--r--scene/resources/font.h3
-rw-r--r--scene/resources/material.h3
-rw-r--r--scene/resources/mesh.h3
-rw-r--r--scene/resources/room.h3
-rw-r--r--scene/resources/style_box.h4
-rw-r--r--scene/resources/texture.h4
-rw-r--r--scene/resources/theme.h3
-rw-r--r--servers/physics/gjk_epa.h5
-rw-r--r--servers/visual/shader_language.cpp72
-rw-r--r--servers/visual/visual_server_raster.h3
-rw-r--r--servers/visual/visual_server_wrap_mt.h3
-rw-r--r--servers/visual_server.h3
264 files changed, 2430 insertions, 1264 deletions
diff --git a/core/class_db.h b/core/class_db.h
index 3d9a695f02..3864522be4 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -35,10 +35,6 @@
#include "core/object.h"
#include "core/print_string.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
/** To bind more then 6 parameters include this:
* #include "core/method_bind_ext.gen.inc"
*/
diff --git a/core/color.h b/core/color.h
index 77f95b5dc9..8fb78d1ced 100644
--- a/core/color.h
+++ b/core/color.h
@@ -33,9 +33,7 @@
#include "core/math/math_funcs.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
struct Color {
union {
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 3789eda5db..98f5bc56d7 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -37,10 +37,6 @@
#include "core/simple_type.h"
#include "core/typedefs.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#define COMMA(N) _COMMA_##N
#define _COMMA_0
#define _COMMA_1 ,
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index f1fccc5230..af6b0551a3 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -37,10 +37,6 @@
#include "core/os/file_access.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ImageLoader;
class ImageFormatLoader {
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 70e7bdc224..93df8cadb0 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -33,9 +33,6 @@
#include "core/os/thread.h"
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ResourceInteractiveLoader : public Reference {
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 0fba47a5e8..20e05d827a 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -33,10 +33,6 @@
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ResourceFormatSaver : public Reference {
GDCLASS(ResourceFormatSaver, Reference);
diff --git a/core/map.h b/core/map.h
index c8197639f2..c87ee42e1b 100644
--- a/core/map.h
+++ b/core/map.h
@@ -33,10 +33,6 @@
#include "core/set.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
// based on the very nice implementation of rb-trees by:
// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
diff --git a/core/math/a_star.h b/core/math/a_star.h
index ec333efc1d..cbabcce974 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -32,7 +32,6 @@
#define ASTAR_H
#include "core/reference.h"
-#include "core/self_list.h"
/**
A* pathfinding algorithm
diff --git a/core/math/basis.h b/core/math/basis.h
index d3adad3d90..053effda69 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -36,10 +36,6 @@
#include "core/math/quat.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Basis {
public:
Vector3 elements[3];
diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h
index a7a3697990..90b5e8322a 100644
--- a/core/math/bsp_tree.h
+++ b/core/math/bsp_tree.h
@@ -38,9 +38,7 @@
#include "core/pool_vector.h"
#include "core/variant.h"
#include "core/vector.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class BSP_Tree {
public:
enum {
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index 3bcf48f5da..63cc88553d 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -34,10 +34,6 @@
#include "core/math/rect2.h"
#include "core/math/transform.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
struct CameraMatrix {
enum Planes {
diff --git a/core/math/geometry.h b/core/math/geometry.h
index e4f3ff799e..a32ed2f56b 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -41,10 +41,6 @@
#include "core/print_string.h"
#include "core/vector.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Geometry {
Geometry();
diff --git a/core/math/octree.h b/core/math/octree.h
index d6fc9776bc..e752e10abc 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -38,10 +38,6 @@
#include "core/print_string.h"
#include "core/variant.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef uint32_t OctreeElementID;
#define OCTREE_ELEMENT_INVALID_ID 0
diff --git a/core/math/quat.h b/core/math/quat.h
index 8ed2fa7cc2..3d6602e466 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -38,10 +38,6 @@
#include "core/math/math_funcs.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Quat {
public:
real_t x, y, z, w;
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 7ff7cac914..4056975da8 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -213,3 +213,8 @@ Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) :
basis(p_basis),
origin(p_origin) {
}
+
+Transform::Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz) {
+ basis = Basis(xx, xy, xz, yx, yy, yz, zx, zy, zz);
+ origin = Vector3(ox, oy, oz);
+}
diff --git a/core/math/transform.h b/core/math/transform.h
index 2f43f6b035..4c8d915305 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -35,10 +35,6 @@
#include "core/math/basis.h"
#include "core/math/plane.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Transform {
public:
Basis basis;
@@ -108,6 +104,7 @@ public:
operator String() const;
+ Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz);
Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3());
Transform() {}
};
diff --git a/core/method_bind.h b/core/method_bind.h
index 1b0c3b27c0..7bb75e778f 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -38,10 +38,6 @@
#include <stdio.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifdef DEBUG_ENABLED
#define DEBUG_METHODS_ENABLED
#endif
diff --git a/core/node_path.h b/core/node_path.h
index 24725123d6..1b21c4ef1c 100644
--- a/core/node_path.h
+++ b/core/node_path.h
@@ -34,10 +34,6 @@
#include "core/string_name.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class NodePath {
struct Data {
diff --git a/core/os/dir_access.h b/core/os/dir_access.h
index 704eedae5b..d3eb1e13f6 100644
--- a/core/os/dir_access.h
+++ b/core/os/dir_access.h
@@ -34,10 +34,6 @@
#include "core/typedefs.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
//@ TODO, excellent candidate for THREAD_SAFE MACRO, should go through all these and add THREAD_SAFE where it applies
class DirAccess {
public:
@@ -97,6 +93,18 @@ public:
virtual Error rename(String p_from, String p_to) = 0;
virtual Error remove(String p_name) = 0;
+ // Meant for editor code when we want to quickly remove a file without custom
+ // handling (e.g. removing a cache file).
+ static void remove_file_or_error(String p_path) {
+ DirAccess *da = create(ACCESS_FILESYSTEM);
+ if (da->file_exists(p_path)) {
+ if (da->remove(p_path) != OK) {
+ ERR_FAIL_MSG("Cannot remove file or directory: " + p_path);
+ }
+ }
+ memdelete(da);
+ }
+
virtual String get_filesystem_type() const = 0;
static String get_full_path(const String &p_path, AccessType p_access);
static DirAccess *create_for_path(const String &p_path);
diff --git a/core/os/input_event.h b/core/os/input_event.h
index 4f5762e756..28658e3865 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -38,10 +38,6 @@
#include "core/ustring.h"
/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
-/**
* Input Event classes. These are used in the main loop.
* The events are pretty obvious.
*/
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index 58a0807579..5c8a2e90e9 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -33,10 +33,6 @@
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
/*
Special Key:
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index ad734d3fc8..6ddaf5bee7 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -35,10 +35,6 @@
#include "core/reference.h"
#include "core/script_language.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MainLoop : public Object {
GDCLASS(MainLoop, Object);
diff --git a/core/os/memory.h b/core/os/memory.h
index e073b11e76..8778cb63ad 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -35,10 +35,6 @@
#include <stddef.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifndef PAD_ALIGN
#define PAD_ALIGN 16 //must always be greater than this at much
#endif
diff --git a/core/os/os.h b/core/os/os.h
index 2224d3b006..c0c346e9aa 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -41,10 +41,6 @@
#include <stdarg.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Mutex;
class OS {
diff --git a/core/os/semaphore.h b/core/os/semaphore.h
index ccbba0dacd..a0862dce84 100644
--- a/core/os/semaphore.h
+++ b/core/os/semaphore.h
@@ -33,10 +33,6 @@
#include "core/error_list.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Semaphore {
protected:
static Semaphore *(*create_func)();
diff --git a/core/os/thread.h b/core/os/thread.h
index e7a6e8cb1f..169280a208 100644
--- a/core/os/thread.h
+++ b/core/os/thread.h
@@ -34,10 +34,6 @@
#include "core/typedefs.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef void (*ThreadCreateCallback)(void *p_userdata);
class Thread {
diff --git a/core/pool_vector.h b/core/pool_vector.h
index 3d28d86803..39a8eccc51 100644
--- a/core/pool_vector.h
+++ b/core/pool_vector.h
@@ -77,10 +77,6 @@ struct MemoryPool {
static void cleanup();
};
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
template <class T>
class PoolVector {
diff --git a/core/project_settings.h b/core/project_settings.h
index d7651417d5..a8deab028c 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -35,10 +35,6 @@
#include "core/os/thread_safe.h"
#include "core/set.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ProjectSettings : public Object {
GDCLASS(ProjectSettings, Object);
diff --git a/core/reference.h b/core/reference.h
index 8a19f846c7..20ee22ddfc 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -36,9 +36,6 @@
#include "core/ref_ptr.h"
#include "core/safe_refcount.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Reference : public Object {
GDCLASS(Reference, Object);
diff --git a/core/register_core_types.h b/core/register_core_types.h
index b5a6aa985b..2d397b55f9 100644
--- a/core/register_core_types.h
+++ b/core/register_core_types.h
@@ -31,10 +31,6 @@
#ifndef REGISTER_CORE_TYPES_H
#define REGISTER_CORE_TYPES_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
void register_core_types();
void register_core_settings();
void register_core_singletons();
diff --git a/core/resource.h b/core/resource.h
index 853b2859c7..038b4f6278 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -38,10 +38,6 @@
#include "core/safe_refcount.h"
#include "core/self_list.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#define RES_BASE_EXTENSION(m_ext) \
public: \
static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension(m_ext, get_class_static()); } \
diff --git a/core/rid.h b/core/rid.h
index c7a71a03a0..381eee645b 100644
--- a/core/rid.h
+++ b/core/rid.h
@@ -37,10 +37,6 @@
#include "core/set.h"
#include "core/typedefs.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class RID_OwnerBase;
class RID_Data {
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 5f01e043c4..6dd9054aaa 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -601,9 +601,19 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
}
}
}
+
if (Node *node = Object::cast_to<Node>(obj)) {
- PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
- properties.push_front(PropertyDesc(pi, node->get_path()));
+ // in some cases node will not be in tree here
+ // for instance where it created as variable and not yet added to tree
+ // in such cases we can't ask for it's path
+ if (node->is_inside_tree()) {
+ PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
+ properties.push_front(PropertyDesc(pi, node->get_path()));
+ } else {
+ PropertyInfo pi(Variant::STRING, String("Node/path"));
+ properties.push_front(PropertyDesc(pi, "[Orphan]"));
+ }
+
} else if (Resource *res = Object::cast_to<Resource>(obj)) {
if (Script *s = Object::cast_to<Script>(res)) {
Map<StringName, Variant> constants;
diff --git a/core/script_language.h b/core/script_language.h
index 87f103bb33..dfb2e0ad31 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -36,10 +36,6 @@
#include "core/pair.h"
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ScriptLanguage;
typedef void (*ScriptEditRequestFunction)(const String &p_path);
diff --git a/core/set.h b/core/set.h
index b2c717880d..68431c294a 100644
--- a/core/set.h
+++ b/core/set.h
@@ -34,10 +34,6 @@
#include "core/os/memory.h"
#include "core/typedefs.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
// based on the very nice implementation of rb-trees by:
// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
diff --git a/core/string_name.h b/core/string_name.h
index 0984b0181f..6dd960abd5 100644
--- a/core/string_name.h
+++ b/core/string_name.h
@@ -34,9 +34,6 @@
#include "core/os/mutex.h"
#include "core/safe_refcount.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
struct StaticCString {
diff --git a/core/ustring.h b/core/ustring.h
index 3eb5c47b3a..bbd0bcceb5 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -36,10 +36,6 @@
#include "core/typedefs.h"
#include "core/vector.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
template <class T>
class CharProxy {
friend class CharString;
diff --git a/core/variant.h b/core/variant.h
index a8e99c13f1..c4f69c3e8d 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -31,10 +31,6 @@
#ifndef VARIANT_H
#define VARIANT_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/array.h"
#include "core/color.h"
#include "core/dictionary.h"
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 1f6e5bb653..eca5d0567b 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -1955,19 +1955,27 @@ void register_variant_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR2, "UP", Vector2(0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR2, "DOWN", Vector2(0, 1));
- _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D(1, 0, 0, 1, 0, 0));
+ _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D());
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0));
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0));
- Transform identity_transform, transform_x, transform_y, transform_z;
- identity_transform.set(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
+ Transform identity_transform = Transform();
+ Transform flip_x_transform = Transform(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
+ Transform flip_y_transform = Transform(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0);
+ Transform flip_z_transform = Transform(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0);
_VariantCall::add_variant_constant(Variant::TRANSFORM, "IDENTITY", identity_transform);
- transform_x.set(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_X", transform_x);
- transform_y.set(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Y", transform_y);
- transform_z.set(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", transform_z);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_X", flip_x_transform);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Y", flip_y_transform);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", flip_z_transform);
+
+ Basis identity_basis = Basis();
+ Basis flip_x_basis = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1);
+ Basis flip_y_basis = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1);
+ Basis flip_z_basis = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1);
+ _VariantCall::add_variant_constant(Variant::BASIS, "IDENTITY", identity_basis);
+ _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_X", flip_x_basis);
+ _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_Y", flip_y_basis);
+ _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_Z", flip_z_basis);
_VariantCall::add_variant_constant(Variant::PLANE, "PLANE_YZ", Plane(Vector3(1, 0, 0), 0));
_VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XZ", Plane(Vector3(0, 1, 0), 0));
diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml
index 6f82b103db..2d3ceebed5 100644
--- a/doc/classes/AudioServer.xml
+++ b/doc/classes/AudioServer.xml
@@ -32,12 +32,6 @@
Adds an [AudioEffect] effect to the bus [code]bus_idx[/code] at [code]at_position[/code].
</description>
</method>
- <method name="capture_get_device">
- <return type="String">
- </return>
- <description>
- </description>
- </method>
<method name="capture_get_device_list">
<return type="Array">
</return>
@@ -45,14 +39,6 @@
Returns the names of all audio input devices detected on the system.
</description>
</method>
- <method name="capture_set_device">
- <return type="void">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- </description>
- </method>
<method name="capture_start">
<return type="int" enum="Error">
</return>
@@ -423,17 +409,25 @@
<member name="bus_count" type="int" setter="set_bus_count" getter="get_bus_count" default="1">
Number of available audio buses.
</member>
+ <member name="capture_device" type="String" setter="capture_set_device" getter="capture_get_device" default="&quot;&quot;">
+ Name of the current device for audio input (see [method capture_get_device_list]).
+ </member>
<member name="device" type="String" setter="set_device" getter="get_device" default="&quot;Default&quot;">
Name of the current device for audio output (see [method get_device_list]).
</member>
- <member name="capture_device" type="String" setter="capture_set_device" getter="capture_get_device" default="&quot;Default&quot;">
- Name of the current device for audio input (see [method capture_get_device_list]).
- </member>
<member name="global_rate_scale" type="float" setter="set_global_rate_scale" getter="get_global_rate_scale" default="1.0">
Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast).
</member>
</members>
<signals>
+ <signal name="audio_mix_callback">
+ <description>
+ </description>
+ </signal>
+ <signal name="audio_update_callback">
+ <description>
+ </description>
+ </signal>
<signal name="bus_layout_changed">
<description>
Emitted when the [AudioBusLayout] changes.
diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml
index 4d5c76a75c..df9438e695 100644
--- a/doc/classes/Basis.xml
+++ b/doc/classes/Basis.xml
@@ -208,5 +208,13 @@
</member>
</members>
<constants>
+ <constant name="IDENTITY" value="Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1 )">
+ </constant>
+ <constant name="FLIP_X" value="Basis( -1, 0, 0, 0, 1, 0, 0, 0, 1 )">
+ </constant>
+ <constant name="FLIP_Y" value="Basis( 1, 0, 0, 0, -1, 0, 0, 0, 1 )">
+ </constant>
+ <constant name="FLIP_Z" value="Basis( 1, 0, 0, 0, 1, 0, 0, 0, -1 )">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml
index f524a02934..16fb483249 100644
--- a/doc/classes/Camera2D.xml
+++ b/doc/classes/Camera2D.xml
@@ -110,7 +110,7 @@
<member name="drag_margin_bottom" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
Bottom margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
</member>
- <member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled" default="true">
+ <member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled" default="false">
If [code]true[/code], the camera only moves when reaching the horizontal drag margins. If [code]false[/code], the camera moves horizontally regardless of margins.
</member>
<member name="drag_margin_left" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
@@ -122,7 +122,7 @@
<member name="drag_margin_top" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
Top margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
</member>
- <member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" default="true">
+ <member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" default="false">
If [code]true[/code], the camera only moves when reaching the vertical drag margins. If [code]false[/code], the camera moves vertically regardless of margins.
</member>
<member name="editor_draw_drag_margin" type="bool" setter="set_margin_drawing_enabled" getter="is_margin_drawing_enabled" default="false">
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 6c3cf66c20..acceffb3bf 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -229,7 +229,7 @@
[codeblock]
func _ready():
modulate = get_color("font_color", "Button") #get the color defined for button fonts
- [/codeblock]
+ [/codeblock]
</description>
</method>
<method name="get_combined_minimum_size" qualifiers="const">
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index d55e810c9e..4f7a6d89a9 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -169,6 +169,22 @@
Selects the file, with the path provided by [code]file[/code], in the FileSystem dock.
</description>
</method>
+ <method name="set_distraction_free_mode">
+ <return type="void">
+ </return>
+ <argument index="0" name="enter" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_main_screen_editor">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_plugin_enabled">
<return type="void">
</return>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index fddc5e9d36..89e2f0580b 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -128,7 +128,7 @@
<argument index="3" name="ud" type="Variant" default="null">
</argument>
<description>
- Adds a custom menu to [b]Project &gt; Tools[/b] as [code]name[/code] that calls [code]callback[/code] on an instance of [code]handler[/code] with a parameter [code]ud[/code] when user activates it.
+ Adds a custom menu item to [b]Project &gt; Tools[/b] as [code]name[/code] that calls [code]callback[/code] on an instance of [code]handler[/code] with a parameter [code]ud[/code] when user activates it.
</description>
</method>
<method name="add_tool_submenu_item">
@@ -139,7 +139,7 @@
<argument index="1" name="submenu" type="Object">
</argument>
<description>
- Like [method add_tool_menu_item] but adds the [code]submenu[/code] item inside the [code]name[/code] menu.
+ Adds a custom submenu under [b]Project &gt; Tools &gt;[/b] [code]name[/code]. [code]submenu[/code] should be an object of class [PopupMenu]. This submenu should be cleaned up using [code]remove_tool_menu_item(name)[/code].
</description>
</method>
<method name="apply_changes" qualifiers="virtual">
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index a4df0d5c19..10be66feb8 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -406,24 +406,24 @@
<description>
</description>
</method>
- <method name="save_png" qualifiers="const">
+ <method name="save_exr" qualifiers="const">
<return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
+ <argument index="1" name="grayscale" type="bool" default="false">
+ </argument>
<description>
- Saves the image as a PNG file to [code]path[/code].
+ Saves the image as an EXR file to [code]path[/code]. If grayscale is true and the image has only one channel, it will be saved explicitely as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module.
</description>
</method>
- <method name="save_exr" qualifiers="const">
+ <method name="save_png" qualifiers="const">
<return type="int" enum="Error">
</return>
<argument index="0" name="path" type="String">
</argument>
- <argument index="1" name="grayscale" type="bool" default="false">
- </argument>
<description>
- Saves the image as an EXR file to [code]path[/code]. If grayscale is true and the image has only one channel, it will be saved explicitely as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module.
+ Saves the image as a PNG file to [code]path[/code].
</description>
</method>
<method name="set_pixel">
diff --git a/doc/classes/Popup.xml b/doc/classes/Popup.xml
index 1e24aadfd9..fb8168c344 100644
--- a/doc/classes/Popup.xml
+++ b/doc/classes/Popup.xml
@@ -56,6 +56,13 @@
Popup (show the control in modal form) in the center of the screen relative to the current canvas transform, scaled at a ratio of size of the screen.
</description>
</method>
+ <method name="set_as_minsize">
+ <return type="void">
+ </return>
+ <description>
+ Shrink popup to keep to the minimum size of content.
+ </description>
+ </method>
</methods>
<members>
<member name="popup_exclusive" type="bool" setter="set_exclusive" getter="is_exclusive" default="false">
diff --git a/doc/classes/VisualShaderNodeVectorScalarMix.xml b/doc/classes/VisualShaderNodeVectorScalarMix.xml
new file mode 100644
index 0000000000..d83c2e7d44
--- /dev/null
+++ b/doc/classes/VisualShaderNodeVectorScalarMix.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeVectorScalarMix" inherits="VisualShaderNode" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 935cb32fda..9c9a8e9717 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -802,6 +802,14 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += "else\n";
code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
+ } else if (cf_node->flow_op == SL::FLOW_OP_DO) {
+ code += _mktab(p_level);
+ code += "do";
+ code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _mktab(p_level);
+ code += "while (";
+ code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += ");";
} else if (cf_node->flow_op == SL::FLOW_OP_WHILE) {
code += _mktab(p_level);
code += "while (";
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index d48ee7709c..6b477ec78b 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -799,6 +799,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += _mktab(p_level) + "else\n";
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
+ } else if (cfnode->flow_op == SL::FLOW_OP_DO) {
+ code += _mktab(p_level) + "do";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ");";
+
} else if (cfnode->flow_op == SL::FLOW_OP_WHILE) {
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h
index be2c34ba07..d8d49868f4 100644
--- a/drivers/gles3/shader_gles3.h
+++ b/drivers/gles3/shader_gles3.h
@@ -45,10 +45,6 @@
#include <stdio.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ShaderGLES3 {
protected:
struct Enum {
diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h
index cc789f95d6..c910c31f1e 100644
--- a/drivers/png/image_loader_png.h
+++ b/drivers/png/image_loader_png.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderPNG : public ImageFormatLoader {
private:
static PoolVector<uint8_t> lossless_pack_png(const Ref<Image> &p_image);
diff --git a/drivers/register_driver_types.h b/drivers/register_driver_types.h
index 3fdf802c9f..a3398964dd 100644
--- a/drivers/register_driver_types.h
+++ b/drivers/register_driver_types.h
@@ -31,10 +31,6 @@
#ifndef REGISTER_DRIVER_TYPES_H
#define REGISTER_DRIVER_TYPES_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
void register_core_driver_types();
void unregister_core_driver_types();
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index 579cb0e798..88674d2769 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -40,10 +40,6 @@
#include <sys/types.h>
#include <unistd.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class DirAccessUnix : public DirAccess {
DIR *dir_stream;
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 2a369048a4..e26591e3e8 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -38,10 +38,6 @@
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef void (*CloseNotificationFunc)(const String &p_file, int p_flags);
class FileAccessUnix : public FileAccess {
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 53446a6b6f..a263147e23 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -31,10 +31,6 @@
#ifndef OS_UNIX_H
#define OS_UNIX_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifdef UNIX_ENABLED
#include "core/os/os.h"
diff --git a/drivers/unix/semaphore_posix.h b/drivers/unix/semaphore_posix.h
index 089f088d33..83e75c9a82 100644
--- a/drivers/unix/semaphore_posix.h
+++ b/drivers/unix/semaphore_posix.h
@@ -36,9 +36,7 @@
#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
#include <semaphore.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class SemaphorePosix : public Semaphore {
mutable sem_t sem;
diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h
index d6b6267c49..5edacd3a0c 100644
--- a/drivers/unix/thread_posix.h
+++ b/drivers/unix/thread_posix.h
@@ -31,10 +31,6 @@
#ifndef THREAD_POSIX_H
#define THREAD_POSIX_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
#include "core/os/thread.h"
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 2848ed5279..e7f9fc690d 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -38,10 +38,6 @@
#include <stdio.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class FileAccessWindows : public FileAccess {
FILE *f;
diff --git a/drivers/windows/mutex_windows.h b/drivers/windows/mutex_windows.h
index 6d3b641a26..582d26029c 100644
--- a/drivers/windows/mutex_windows.h
+++ b/drivers/windows/mutex_windows.h
@@ -37,10 +37,6 @@
#include <windows.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MutexWindows : public Mutex {
#ifdef WINDOWS_USE_MUTEX
diff --git a/drivers/windows/semaphore_windows.h b/drivers/windows/semaphore_windows.h
index 8adeffbb7f..cfd33d033a 100644
--- a/drivers/windows/semaphore_windows.h
+++ b/drivers/windows/semaphore_windows.h
@@ -37,10 +37,6 @@
#include <windows.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class SemaphoreWindows : public Semaphore {
mutable HANDLE semaphore;
diff --git a/drivers/windows/thread_windows.h b/drivers/windows/thread_windows.h
index a74d4e46f3..b47452838c 100644
--- a/drivers/windows/thread_windows.h
+++ b/drivers/windows/thread_windows.h
@@ -38,10 +38,6 @@
#include <windows.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ThreadWindows : public Thread {
ThreadCreateCallback callback;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 89a88dc6e7..5b1a460a54 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -163,16 +163,16 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
result_col = col;
_update_results_count();
- set_error(vformat(TTR("Found %d match(es)."), results_count));
} else {
result_line = -1;
result_col = -1;
text_edit->set_search_text("");
text_edit->set_search_flags(p_flags);
text_edit->set_current_search_result(line, col);
- set_error(text.empty() ? "" : TTR("No Matches"));
}
+ _update_matches_label();
+
return found;
}
@@ -283,20 +283,6 @@ void FindReplaceBar::_get_search_from(int &r_line, int &r_col) {
r_line = text_edit->cursor_get_line();
r_col = text_edit->cursor_get_column();
- if (text_edit->is_selection_active() && !replace_all_mode) {
-
- int selection_line = text_edit->get_selection_from_line();
-
- if (text_edit->get_selection_text() == get_search_text() && r_line == selection_line) {
-
- int selection_from_col = text_edit->get_selection_from_column();
-
- if (r_col >= selection_from_col && r_col <= text_edit->get_selection_to_column()) {
- r_col = selection_from_col;
- }
- }
- }
-
if (r_line == result_line && r_col >= result_col && r_col <= result_col + get_search_text().length()) {
r_col = result_col;
}
@@ -332,6 +318,18 @@ void FindReplaceBar::_update_results_count() {
}
}
+void FindReplaceBar::_update_matches_label() {
+
+ if (search_text->get_text().empty() || results_count == -1) {
+ matches_label->hide();
+ } else {
+ matches_label->show();
+
+ matches_label->add_color_override("font_color", results_count > 0 ? Color(1, 1, 1) : EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
+ matches_label->set_text(vformat(results_count == 1 ? TTR("%d match.") : TTR("%d matches."), results_count));
+ }
+}
+
bool FindReplaceBar::search_current() {
uint32_t flags = 0;
@@ -349,6 +347,9 @@ bool FindReplaceBar::search_current() {
bool FindReplaceBar::search_prev() {
+ if (!is_visible())
+ popup_search(true);
+
uint32_t flags = 0;
String text = get_search_text();
@@ -361,13 +362,17 @@ bool FindReplaceBar::search_prev() {
int line, col;
_get_search_from(line, col);
+ if (text_edit->is_selection_active())
+ col--; //Skip currently selected word.
- col -= text.length();
- if (col < 0) {
- line -= 1;
- if (line < 0)
- line = text_edit->get_line_count() - 1;
- col = text_edit->get_line(line).length();
+ if (line == result_line && col == result_col) {
+ col -= text.length();
+ if (col < 0) {
+ line -= 1;
+ if (line < 0)
+ line = text_edit->get_line_count() - 1;
+ col = text_edit->get_line(line).length();
+ }
}
return _search(flags, line, col);
@@ -375,6 +380,9 @@ bool FindReplaceBar::search_prev() {
bool FindReplaceBar::search_next() {
+ if (!is_visible())
+ popup_search(true);
+
uint32_t flags = 0;
String text;
if (replace_all_mode)
@@ -411,38 +419,54 @@ void FindReplaceBar::_hide_bar() {
text_edit->set_search_text("");
result_line = -1;
result_col = -1;
- set_error("");
hide();
}
-void FindReplaceBar::_show_search() {
+void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) {
show();
- search_text->call_deferred("grab_focus");
+ if (p_show_only)
+ return;
+
+ if (p_focus_replace) {
+ search_text->deselect();
+ replace_text->call_deferred("grab_focus");
+ } else {
+ replace_text->deselect();
+ search_text->call_deferred("grab_focus");
+ }
if (text_edit->is_selection_active() && !selection_only->is_pressed()) {
search_text->set_text(text_edit->get_selection_text());
}
if (!get_search_text().empty()) {
- search_text->select_all();
- search_text->set_cursor_position(search_text->get_text().length());
- search_current();
+ if (p_focus_replace) {
+ replace_text->select_all();
+ replace_text->set_cursor_position(replace_text->get_text().length());
+ } else {
+ search_text->select_all();
+ search_text->set_cursor_position(search_text->get_text().length());
+ }
+
+ results_count = -1;
+ _update_results_count();
+ _update_matches_label();
}
}
-void FindReplaceBar::popup_search() {
+void FindReplaceBar::popup_search(bool p_show_only) {
- replace_text->hide();
+ if (!is_visible())
+ replace_text->hide();
hbc_button_replace->hide();
hbc_option_replace->hide();
- _show_search();
+ _show_search(false, p_show_only);
}
void FindReplaceBar::popup_replace() {
if (!replace_text->is_visible_in_tree()) {
- replace_text->clear();
replace_text->show();
hbc_button_replace->show();
hbc_option_replace->show();
@@ -450,7 +474,7 @@ void FindReplaceBar::popup_replace() {
selection_only->set_pressed((text_edit->is_selection_active() && text_edit->get_selection_from_line() < text_edit->get_selection_to_line()));
- _show_search();
+ _show_search(is_visible() || text_edit->is_selection_active());
}
void FindReplaceBar::_search_options_changed(bool p_pressed) {
@@ -557,6 +581,7 @@ FindReplaceBar::FindReplaceBar() {
vbc_lineedit = memnew(VBoxContainer);
add_child(vbc_lineedit);
+ vbc_lineedit->set_alignment(ALIGN_CENTER);
vbc_lineedit->set_h_size_flags(SIZE_EXPAND_FILL);
VBoxContainer *vbc_button = memnew(VBoxContainer);
add_child(vbc_button);
@@ -565,8 +590,10 @@ FindReplaceBar::FindReplaceBar() {
HBoxContainer *hbc_button_search = memnew(HBoxContainer);
vbc_button->add_child(hbc_button_search);
+ hbc_button_search->set_alignment(ALIGN_END);
hbc_button_replace = memnew(HBoxContainer);
vbc_button->add_child(hbc_button_replace);
+ hbc_button_replace->set_alignment(ALIGN_END);
HBoxContainer *hbc_option_search = memnew(HBoxContainer);
vbc_option->add_child(hbc_option_search);
@@ -580,6 +607,10 @@ FindReplaceBar::FindReplaceBar() {
search_text->connect("text_changed", this, "_search_text_changed");
search_text->connect("text_entered", this, "_search_text_entered");
+ matches_label = memnew(Label);
+ hbc_button_search->add_child(matches_label);
+ matches_label->hide();
+
find_prev = memnew(ToolButton);
hbc_button_search->add_child(find_prev);
find_prev->set_focus_mode(FOCUS_NONE);
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 700e72627c..f2a55cfb70 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -64,6 +64,7 @@ class FindReplaceBar : public HBoxContainer {
GDCLASS(FindReplaceBar, HBoxContainer);
LineEdit *search_text;
+ Label *matches_label;
ToolButton *find_prev;
ToolButton *find_next;
CheckBox *case_sensitive;
@@ -90,8 +91,9 @@ class FindReplaceBar : public HBoxContainer {
void _get_search_from(int &r_line, int &r_col);
void _update_results_count();
+ void _update_matches_label();
- void _show_search();
+ void _show_search(bool p_focus_replace = false, bool p_show_only = false);
void _hide_bar();
void _editor_text_changed();
@@ -123,7 +125,7 @@ public:
void set_text_edit(TextEdit *p_text_edit);
- void popup_search();
+ void popup_search(bool p_show_only = false);
void popup_replace();
bool search_current();
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index f6c3b57589..f3ed1d7af6 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -38,9 +38,6 @@
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CreateDialog : public ConfirmationDialog {
diff --git a/editor/editor_about.h b/editor/editor_about.h
index 87e824083e..e2ba366c65 100644
--- a/editor/editor_about.h
+++ b/editor/editor_about.h
@@ -43,9 +43,6 @@
#include "scene/gui/tree.h"
#include "editor_scale.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class EditorAbout : public AcceptDialog {
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index ed262d9c4f..e1f2635275 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -35,6 +35,7 @@
#include "core/io/resource_saver.h"
#include "core/io/zip_io.h"
#include "core/math/crypto_core.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
#include "core/script_language.h"
@@ -884,6 +885,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
String engine_cfb = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp" + config_file);
ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list);
Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb);
+ DirAccess::remove_file_or_error(engine_cfb);
p_func(p_udata, "res://" + config_file, data, idx, total);
@@ -916,8 +918,10 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
memdelete(ftmp); //close tmp file
- if (err)
+ if (err != OK) {
+ DirAccess::remove_file_or_error(tmppath);
return err;
+ }
pd.file_ofs.sort(); //do sort, so we can do binary search later
@@ -926,11 +930,17 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
if (!p_embed) {
// Regular output to separate PCK file
f = FileAccess::open(p_path, FileAccess::WRITE);
- ERR_FAIL_COND_V(!f, ERR_CANT_CREATE);
+ if (!f) {
+ DirAccess::remove_file_or_error(tmppath);
+ ERR_FAIL_V(ERR_CANT_CREATE);
+ }
} else {
// Append to executable
f = FileAccess::open(p_path, FileAccess::READ_WRITE);
- ERR_FAIL_COND_V(!f, ERR_FILE_CANT_OPEN);
+ if (!f) {
+ DirAccess::remove_file_or_error(tmppath);
+ ERR_FAIL_V(ERR_FILE_CANT_OPEN);
+ }
f->seek_end();
embed_pos = f->get_position();
@@ -995,13 +1005,13 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
f->store_8(0);
}
- //save the rest of the data
+ // Save the rest of the data.
ftmp = FileAccess::open(tmppath, FileAccess::READ);
if (!ftmp) {
memdelete(f);
- ERR_EXPLAIN("Can't open file to read from path: " + String(tmppath));
- ERR_FAIL_V(ERR_CANT_CREATE);
+ DirAccess::remove_file_or_error(tmppath);
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't open file to read from path: " + String(tmppath));
}
const int bufsize = 16384;
@@ -1035,6 +1045,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
}
memdelete(f);
+ DirAccess::remove_file_or_error(tmppath);
return OK;
}
@@ -1043,8 +1054,6 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
EditorProgress ep("savezip", TTR("Packing"), 102, true);
- //FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE);
-
FileAccess *src_f;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io);
@@ -1694,11 +1703,18 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con
bool convert = GLOBAL_GET("editor/convert_text_resources_to_binary_on_export");
if (!convert)
return;
- String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("file.res");
+ String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpfile.res");
Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path);
- ERR_FAIL_COND(err != OK);
+ if (err != OK) {
+ DirAccess::remove_file_or_error(tmp_path);
+ ERR_FAIL();
+ }
Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path);
- ERR_FAIL_COND(data.size() == 0);
+ if (data.size() == 0) {
+ DirAccess::remove_file_or_error(tmp_path);
+ ERR_FAIL();
+ }
+ DirAccess::remove_file_or_error(tmp_path);
add_file(p_path + ".converted.res", data, true);
}
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index 86bf0f0eb3..2ecfa7db15 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -44,9 +44,6 @@
class DependencyRemoveDialog;
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class EditorFileDialog : public ConfirmationDialog {
GDCLASS(EditorFileDialog, ConfirmationDialog);
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 7aa24c7476..385b6924df 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -1738,19 +1738,13 @@ void FindBar::_update_results_count() {
void FindBar::_update_matches_label() {
- if (results_count > 0) {
- matches_label->show();
-
- matches_label->add_color_override("font_color", Color(1, 1, 1));
- matches_label->set_text(vformat(TTR("Found %d match(es)."), results_count));
- } else if (search_text->get_text().empty()) {
-
+ if (search_text->get_text().empty() || results_count == -1) {
matches_label->hide();
} else {
matches_label->show();
- matches_label->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
- matches_label->set_text(TTR("No Matches"));
+ matches_label->add_color_override("font_color", results_count > 0 ? Color(1, 1, 1) : EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
+ matches_label->set_text(vformat(results_count == 1 ? TTR("%d match.") : TTR("%d matches."), results_count));
}
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ae2a6d2802..866a90ff10 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4366,6 +4366,15 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
return true;
}
+void EditorNode::run_play() {
+ _menu_option_confirm(RUN_STOP, true);
+ _run(false);
+}
+
+void EditorNode::run_stop() {
+ _menu_option_confirm(RUN_STOP, false);
+}
+
int EditorNode::get_current_tab() {
return scene_tabs->get_current_tab();
}
@@ -5934,19 +5943,19 @@ EditorNode::EditorNode() {
p->add_shortcut(ED_SHORTCUT("editor/new_scene", TTR("New Scene")), FILE_NEW_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/new_inherited_scene", TTR("New Inherited Scene...")), FILE_NEW_INHERITED_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/open_scene", TTR("Open Scene..."), KEY_MASK_CMD + KEY_O), FILE_OPEN_SCENE);
+ p->add_shortcut(ED_SHORTCUT("editor/reopen_closed_scene", TTR("Reopen Closed Scene"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_T), FILE_OPEN_PREV);
+ p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/save_scene", TTR("Save Scene"), KEY_MASK_CMD + KEY_S), FILE_SAVE_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_AS_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save All Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES);
- p->add_separator();
- p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
- p->add_separator();
- p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
- p->add_shortcut(ED_SHORTCUT("editor/reopen_closed_scene", TTR("Reopen Closed Scene"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_T), FILE_OPEN_PREV);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/quick_open", TTR("Quick Open..."), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_O), FILE_QUICK_OPEN);
p->add_shortcut(ED_SHORTCUT("editor/quick_open_scene", TTR("Quick Open Scene..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/quick_open_script", TTR("Quick Open Script..."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCRIPT);
+
p->add_separator();
PopupMenu *pm_export = memnew(PopupMenu);
pm_export->set_name("Export");
@@ -5959,8 +5968,10 @@ EditorNode::EditorNode() {
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true);
p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Z), EDIT_REDO, true);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/revert_scene", TTR("Revert Scene")), EDIT_REVERT);
+ p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
recent_scenes = memnew(PopupMenu);
recent_scenes->set_name("RecentScenes");
@@ -5980,27 +5991,27 @@ EditorNode::EditorNode() {
p = project_menu->get_popup();
p->set_hide_on_window_lose_focus(true);
- p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings")), RUN_SETTINGS);
- p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings...")), RUN_SETTINGS);
p->connect("id_pressed", this, "_menu_option");
- p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export")), FILE_EXPORT_PROJECT);
+
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export...")), FILE_EXPORT_PROJECT);
+ p->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE);
+ p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
plugin_config_dialog = memnew(PluginConfigDialog);
plugin_config_dialog->connect("plugin_ready", this, "_on_plugin_ready");
gui_base->add_child(plugin_config_dialog);
+ p->add_separator();
tool_menu = memnew(PopupMenu);
tool_menu->set_name("Tools");
tool_menu->connect("index_pressed", this, "_tool_menu_option");
- p->add_separator();
p->add_child(tool_menu);
p->add_submenu_item(TTR("Tools"), "Tools");
- tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
- tool_menu->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
- p->add_separator();
- p->add_item(TTR("Install Android Build Template"), FILE_INSTALL_ANDROID_SOURCE);
- p->add_separator();
+ tool_menu->add_item(TTR("Orphan Resource Explorer..."), TOOLS_ORPHAN_RESOURCES);
+ p->add_separator();
#ifdef OSX_ENABLED
p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q), RUN_PROJECT_MANAGER, true);
#else
@@ -6052,7 +6063,7 @@ EditorNode::EditorNode() {
p = settings_menu->get_popup();
p->set_hide_on_window_lose_focus(true);
- p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings")), SETTINGS_PREFERENCES);
+ p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings...")), SETTINGS_PREFERENCES);
p->add_separator();
editor_layouts = memnew(PopupMenu);
@@ -6087,11 +6098,8 @@ EditorNode::EditorNode() {
}
p->add_separator();
- p->add_item(TTR("Manage Editor Features"), SETTINGS_MANAGE_FEATURE_PROFILES);
-
- p->add_separator();
-
- p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
+ p->add_item(TTR("Manage Editor Features..."), SETTINGS_MANAGE_FEATURE_PROFILES);
+ p->add_item(TTR("Manage Export Templates..."), SETTINGS_MANAGE_EXPORT_TEMPLATES);
// Help Menu
help_menu = memnew(MenuButton);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 8d536a1b86..10ad2d691e 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -86,10 +86,6 @@
#include "scene/gui/tree.h"
#include "scene/gui/viewport_container.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef void (*EditorNodeInitCallback)();
typedef void (*EditorPluginInitializeCallback)();
typedef bool (*EditorBuildCallback)();
@@ -869,6 +865,9 @@ public:
static void add_build_callback(EditorBuildCallback p_callback);
bool ensure_main_scene(bool p_from_native);
+
+ void run_play();
+ void run_stop();
};
struct EditorProgress {
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 52ab444522..7b6f55e93d 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -41,10 +41,6 @@
#include "scene/main/node.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class EditorNode;
class Spatial;
class Camera;
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 9966394025..379b8a2980 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -347,6 +347,11 @@ void EditorSpinSlider::_value_input_closed() {
//focus_exited signal
void EditorSpinSlider::_value_focus_exited() {
+
+ // discontinue because the focus_exit was caused by right-click context menu
+ if (value_input->get_menu()->is_visible())
+ return;
+
_evaluate_input_text();
// focus is not on the same element after the vlalue_input was exited
// -> focus is on next element
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index ecfad4d146..72a4b43737 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -69,6 +69,9 @@ void ExportTemplateManager::_update_template_list() {
memdelete(d);
String current_version = VERSION_FULL_CONFIG;
+ // Downloadable export templates are only available for stable, alpha, beta and RC versions.
+ // Therefore, don't display download-related features when using a development version
+ const bool downloads_available = String(VERSION_STATUS) != String("dev");
Label *current = memnew(Label);
current->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -76,10 +79,14 @@ void ExportTemplateManager::_update_template_list() {
if (templates.has(current_version)) {
current->add_color_override("font_color", get_color("success_color", "Editor"));
- Button *redownload = memnew(Button);
- redownload->set_text(TTR("Re-Download"));
- current_hb->add_child(redownload);
- redownload->connect("pressed", this, "_download_template", varray(current_version));
+
+ // Only display a redownload button if it can be downloaded in the first place
+ if (downloads_available) {
+ Button *redownload = memnew(Button);
+ redownload->set_text(TTR("Redownload"));
+ current_hb->add_child(redownload);
+ redownload->connect("pressed", this, "_download_template", varray(current_version));
+ }
Button *uninstall = memnew(Button);
uninstall->set_text(TTR("Uninstall"));
@@ -91,6 +98,12 @@ void ExportTemplateManager::_update_template_list() {
current->add_color_override("font_color", get_color("error_color", "Editor"));
Button *redownload = memnew(Button);
redownload->set_text(TTR("Download"));
+
+ if (!downloads_available) {
+ redownload->set_disabled(true);
+ redownload->set_tooltip(TTR("Official export templates aren't available for development builds."));
+ }
+
redownload->connect("pressed", this, "_download_template", varray(current_version));
current_hb->add_child(redownload);
current->set_text(current_version + " " + TTR("(Missing)"));
@@ -422,14 +435,16 @@ void ExportTemplateManager::_http_download_templates_completed(int p_status, int
String path = download_templates->get_download_file();
template_list_state->set_text(TTR("Download Complete."));
template_downloader->hide();
- int ret = _install_from_file(path, false);
+ bool ret = _install_from_file(path, false);
if (ret) {
- Error err = OS::get_singleton()->move_to_trash(path);
+ // Clean up downloaded file.
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Error err = da->remove(path);
if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:") + "\n" + path + "\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot remove temporary file:") + "\n" + path + "\n");
}
} else {
- WARN_PRINTS(vformat(TTR("Templates installation failed. The problematic templates archives can be found at '%s'."), path));
+ EditorNode::get_singleton()->add_io_error(vformat(TTR("Templates installation failed.\nThe problematic templates archives can be found at '%s'."), path));
}
}
} break;
@@ -458,7 +473,7 @@ void ExportTemplateManager::_begin_template_download(const String &p_url) {
Error err = download_templates->request(p_url);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Error requesting url: ") + p_url);
+ EditorNode::get_singleton()->show_warning(TTR("Error requesting URL:") + " " + p_url);
return;
}
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index 8665467f2d..cc2efb92ae 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -547,6 +547,7 @@ FindInFilesPanel::FindInFilesPanel() {
_results_display->connect("item_edited", this, "_on_item_edited");
_results_display->set_hide_root(true);
_results_display->set_select_mode(Tree::SELECT_ROW);
+ _results_display->set_allow_rmb_select(true);
_results_display->create_item(); // Root
vbc->add_child(_results_display);
diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 97244fa4e9..a00cdd0cf6 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -36,9 +36,6 @@
#include "scene/2d/polygon_2d.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditor;
class AbstractPolygon2DEditor : public HBoxContainer {
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index 74186791e1..850a6201bb 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -40,9 +40,6 @@
#include "scene/gui/graph_edit.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index cb40159a40..77b57a50d0 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -40,9 +40,6 @@
#include "scene/gui/graph_edit.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 22152fa8f4..2ab2df68e6 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -39,9 +39,6 @@
#include "scene/gui/spin_box.h"
#include "scene/gui/texture_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationTrackEditor;
class AnimationPlayerEditorPlugin;
diff --git a/editor/plugins/animation_tree_player_editor_plugin.h b/editor/plugins/animation_tree_player_editor_plugin.h
index f4bfe58909..03bc559b86 100644
--- a/editor/plugins/animation_tree_player_editor_plugin.h
+++ b/editor/plugins/animation_tree_player_editor_plugin.h
@@ -38,9 +38,6 @@
#include "scene/gui/button.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationTreePlayerEditor : public Control {
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 4a2295fab2..e053a34a4d 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -354,16 +354,16 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
} break;
case HTTPRequest::RESULT_REQUEST_FAILED: {
error_text = TTR("Request failed, return code:") + " " + itos(p_code);
- status->set_text(TTR("Request Failed."));
+ status->set_text(TTR("Request failed."));
} break;
case HTTPRequest::RESULT_DOWNLOAD_FILE_CANT_OPEN:
case HTTPRequest::RESULT_DOWNLOAD_FILE_WRITE_ERROR: {
- error_text = TTR("Cannot save response to") + " " + download->get_download_file();
+ error_text = TTR("Cannot save response to:") + " " + download->get_download_file();
status->set_text(TTR("Write error."));
} break;
case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: {
error_text = TTR("Request failed, too many redirects");
- status->set_text(TTR("Redirect Loop."));
+ status->set_text(TTR("Redirect loop."));
} break;
case HTTPRequest::RESULT_TIMEOUT: {
error_text = TTR("Request failed, timeout");
@@ -472,9 +472,8 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
}
void EditorAssetLibraryItemDownload::_close() {
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->remove(download->get_download_file()); //clean up removed file
- memdelete(da);
+ // Clean up downloaded file.
+ DirAccess::remove_file_or_error(download->get_download_file());
queue_delete();
}
@@ -759,7 +758,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
switch (image_queue[p_queue_id].image_type) {
case IMAGE_QUEUE_ICON:
- image->resize(64 * EDSCALE, 64 * EDSCALE, Image::INTERPOLATE_CUBIC);
+ image->resize(64 * EDSCALE, 64 * EDSCALE, Image::INTERPOLATE_LANCZOS);
break;
case IMAGE_QUEUE_THUMBNAIL: {
diff --git a/editor/plugins/camera_editor_plugin.h b/editor/plugins/camera_editor_plugin.h
index eac9acab93..400aee132d 100644
--- a/editor/plugins/camera_editor_plugin.h
+++ b/editor/plugins/camera_editor_plugin.h
@@ -35,10 +35,6 @@
#include "editor/editor_plugin.h"
#include "scene/3d/camera.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CameraEditor : public Control {
GDCLASS(CameraEditor, Control);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index ff134ff2d1..98c2f21e45 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -4998,11 +4998,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->set_hide_on_checkable_item_selection(false);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_grid", TTR("Snap to Grid")), SNAP_USE_GRID);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
p->add_submenu_item(TTR("Smart Snapping"), "SmartSnapping");
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE);
+
smartsnap_config_popup = memnew(PopupMenu);
p->add_child(smartsnap_config_popup);
smartsnap_config_popup->set_name("SmartSnapping");
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 553ded6b14..e6eab57810 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -39,9 +39,6 @@
#include "scene/gui/label.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditorViewport;
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h
index e15360d4e5..3f0734fb19 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/collision_polygon_2d.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CollisionPolygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(CollisionPolygon2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h
index a699641aba..2a904a53ba 100644
--- a/editor/plugins/collision_polygon_editor_plugin.h
+++ b/editor/plugins/collision_polygon_editor_plugin.h
@@ -38,10 +38,6 @@
#include "scene/3d/mesh_instance.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CanvasItemEditor;
class Polygon3DEditor : public HBoxContainer {
diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h
index 701632e576..78b176620e 100644
--- a/editor/plugins/item_list_editor_plugin.h
+++ b/editor/plugins/item_list_editor_plugin.h
@@ -39,10 +39,6 @@
#include "scene/gui/option_button.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ItemListPlugin : public Object {
GDCLASS(ItemListPlugin, Object);
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index 633fda7091..95fa0df2c1 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/light_occluder_2d.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class LightOccluder2DEditor : public AbstractPolygon2DEditor {
GDCLASS(LightOccluder2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h
index fe87a2b9cb..5323441bd8 100644
--- a/editor/plugins/multimesh_editor_plugin.h
+++ b/editor/plugins/multimesh_editor_plugin.h
@@ -36,10 +36,6 @@
#include "scene/3d/multimesh_instance.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MultiMeshEditor : public Control {
GDCLASS(MultiMeshEditor, Control);
diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h
index 336c28d642..2a387a8b1e 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.h
+++ b/editor/plugins/navigation_polygon_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/navigation_polygon.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class NavigationPolygonEditor : public AbstractPolygon2DEditor {
GDCLASS(NavigationPolygonEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h
index 5d05fbd4ac..f689240371 100644
--- a/editor/plugins/particles_editor_plugin.h
+++ b/editor/plugins/particles_editor_plugin.h
@@ -36,10 +36,6 @@
#include "scene/3d/particles.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ParticlesEditorBase : public Control {
GDCLASS(ParticlesEditorBase, Control);
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 44472f7a81..ecec5f5253 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -36,9 +36,6 @@
#include "scene/2d/path_2d.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditor;
class Path2DEditor : public HBoxContainer {
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index 24ca2ea3f4..009501a70c 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -33,9 +33,7 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/gui/scroll_container.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Polygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index ec391186c3..76c7545874 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -490,9 +490,6 @@ void ScriptEditor::_update_recent_scripts() {
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scripts", Array());
recent_scripts->clear();
- recent_scripts->add_shortcut(ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent")));
- recent_scripts->add_separator();
-
String path;
for (int i = 0; i < rc.size(); i++) {
@@ -515,11 +512,6 @@ void ScriptEditor::_open_recent_script(int p_idx) {
return;
}
- // take two for the open recent button
- if (p_idx > 0) {
- p_idx -= 2;
- }
-
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scripts", Array());
ERR_FAIL_INDEX(p_idx, rc.size());
@@ -1000,7 +992,7 @@ void ScriptEditor::_menu_option(int p_option) {
file_dialog->clear_filters();
file_dialog->popup_centered_ratio();
- file_dialog->set_title(TTR("New TextFile..."));
+ file_dialog->set_title(TTR("New Text File..."));
} break;
case FILE_OPEN: {
file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
@@ -1072,6 +1064,7 @@ void ScriptEditor::_menu_option(int p_option) {
save_all_scripts();
} break;
case SEARCH_IN_FILES: {
+
_on_find_in_files_requested("");
} break;
case SEARCH_HELP: {
@@ -3240,7 +3233,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->set_switch_on_hover(true);
file_menu->get_popup()->set_hide_on_window_lose_focus(true);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New Script...")), FILE_NEW);
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New TextFile...")), FILE_NEW_TEXTFILE);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New Text File...")), FILE_NEW_TEXTFILE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open...")), FILE_OPEN);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T), FILE_REOPEN_CLOSED);
file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT);
@@ -3273,17 +3266,20 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
theme_submenu->connect("id_pressed", this, "_theme_option");
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/import_theme", TTR("Import Theme...")), THEME_IMPORT);
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/reload_theme", TTR("Reload Theme")), THEME_RELOAD);
+
theme_submenu->add_separator();
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), THEME_SAVE);
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As...")), THEME_SAVE_AS);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD | KEY_W), FILE_CLOSE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_all", TTR("Close All")), CLOSE_ALL);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_other_tabs", TTR("Close Other Tabs")), CLOSE_OTHER_TABS);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS);
+
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/run_file", TTR("Run"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_X), FILE_RUN);
+
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/toggle_scripts_panel", TTR("Toggle Scripts Panel"), KEY_MASK_CMD | KEY_BACKSLASH), TOGGLE_SCRIPTS_PANEL);
file_menu->get_popup()->connect("id_pressed", this, "_menu_option");
@@ -3572,8 +3568,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "text_editor/external/exec_flags", PROPERTY_HINT_PLACEHOLDER_TEXT, "Call flags with placeholders: {project}, {file}, {col}, {line}."));
ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T);
- ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent"));
- ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Files"));
+ ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Scripts"));
}
ScriptEditorPlugin::~ScriptEditorPlugin() {
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index ddb87b200d..bded590351 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -30,6 +30,7 @@
#include "script_text_editor.h"
+#include "core/math/expression.h"
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
@@ -1147,6 +1148,32 @@ void ScriptTextEditor::_edit_option(int p_op) {
_convert_case(CodeTextEditor::CAPITALIZE);
} break;
+ case EDIT_EVALUATE: {
+
+ Expression expression;
+ Vector<String> lines = code_editor->get_text_edit()->get_selection_text().split("\n");
+ PoolStringArray results;
+
+ for (int i = 0; i < lines.size(); i++) {
+ String line = lines[i];
+ String whitespace = line.substr(0, line.size() - line.strip_edges(true, false).size()); //extract the whitespace at the beginning
+
+ if (expression.parse(line) == OK) {
+ Variant result = expression.execute(Array(), Variant(), false);
+ if (expression.get_error_text() == "") {
+ results.append(whitespace + (String)result);
+ } else {
+ results.append(line);
+ }
+ } else {
+ results.append(line);
+ }
+ }
+
+ code_editor->get_text_edit()->begin_complex_operation(); //prevents creating a two-step undo
+ code_editor->get_text_edit()->insert_text_at_cursor(results.join("\n"));
+ code_editor->get_text_edit()->end_complex_operation();
+ } break;
case SEARCH_FIND: {
code_editor->get_find_replace_bar()->popup_search();
@@ -1170,7 +1197,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
// Yep, because it doesn't make sense to instance this dialog for every single script open...
// So this will be delegated to the ScriptEditor.
emit_signal("search_in_files_requested", selected_text);
-
} break;
case SEARCH_LOCATE_FUNCTION: {
@@ -1630,16 +1656,17 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition) {
context_menu->clear();
- if (p_selection) {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
- }
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ context_menu->add_separator();
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
@@ -1650,6 +1677,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
}
if (p_foldable)
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
@@ -1750,6 +1778,7 @@ ScriptTextEditor::ScriptTextEditor() {
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS);
@@ -1875,6 +1904,7 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D);
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
#endif
+ ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E);
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T);
ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y);
ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_I);
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 4b2307555b..38c6da5c33 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -120,6 +120,7 @@ class ScriptTextEditor : public ScriptEditorBase {
EDIT_TO_UPPERCASE,
EDIT_TO_LOWERCASE,
EDIT_CAPITALIZE,
+ EDIT_EVALUATE,
EDIT_TOGGLE_FOLD_LINE,
EDIT_FOLD_ALL_LINES,
EDIT_UNFOLD_ALL_LINES,
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 58234ba954..f2b1aad59d 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -3551,7 +3551,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_half_resolution", TTR("Half Resolution")), VIEW_HALF_RESOLUTION);
view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_listener", TTR("Audio Listener")), VIEW_AUDIO_LISTENER);
- view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_doppler", TTR("Doppler Enable")), VIEW_AUDIO_DOPPLER);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_doppler", TTR("Enable Doppler")), VIEW_AUDIO_DOPPLER);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
view_menu->get_popup()->add_separator();
@@ -5647,10 +5647,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p = transform_menu->get_popup();
p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap Object to Floor"), KEY_PAGEDOWN), MENU_SNAP_TO_FLOOR);
- p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP);
- p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog...")), MENU_TRANSFORM_DIALOG);
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP);
+
p->connect("id_pressed", this, "_menu_item_pressed");
view_menu = memnew(MenuButton);
@@ -5674,11 +5675,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p->add_submenu_item(TTR("Gizmos"), "GizmosMenu");
p->add_separator();
-
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid")), MENU_VIEW_GRID);
+
p->add_separator();
- p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
+ p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings...")), MENU_VIEW_CAMERA_SETTINGS);
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 523573333b..728b67f6fa 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -37,9 +37,6 @@
#include "scene/3d/light.h"
#include "scene/3d/visual_instance.h"
#include "scene/gui/panel_container.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Camera;
class SpatialEditor;
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index eb0794ba77..89e419ede8 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -482,6 +482,14 @@ void TextEditor::_edit_option(int p_op) {
code_editor->get_find_replace_bar()->popup_replace();
} break;
+ case SEARCH_IN_FILES: {
+
+ String selected_text = code_editor->get_text_edit()->get_selection_text();
+
+ // Yep, because it doesn't make sense to instance this dialog for every single script open...
+ // So this will be delegated to the ScriptEditor.
+ emit_signal("search_in_files_requested", selected_text);
+ } break;
case SEARCH_GOTO_LINE: {
goto_line_dialog->popup_find_line(tx);
@@ -558,7 +566,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
int to_column = tx->get_selection_to_column();
if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
- // Right click is outside the selected text
+ // Right click is outside the selected text.
tx->deselect();
}
}
@@ -636,13 +644,15 @@ TextEditor::TextEditor() {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
+ search_menu->get_popup()->add_separator();
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES);
edit_menu = memnew(MenuButton);
+ edit_hb->add_child(edit_menu);
edit_menu->set_text(TTR("Edit"));
edit_menu->set_switch_on_hover(true);
edit_menu->get_popup()->connect("id_pressed", this, "_edit_option");
- edit_hb->add_child(edit_menu);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index c69e1672c5..c8b49a61e0 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -87,6 +87,7 @@ private:
SEARCH_FIND_NEXT,
SEARCH_FIND_PREV,
SEARCH_REPLACE,
+ SEARCH_IN_FILES,
SEARCH_GOTO_LINE,
BOOKMARK_TOGGLE,
BOOKMARK_GOTO_NEXT,
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 873b125200..56357f298a 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -36,6 +36,7 @@
void ThemeEditor::edit(const Ref<Theme> &p_theme) {
theme = p_theme;
+ main_panel->set_theme(p_theme);
main_container->set_theme(p_theme);
}
@@ -53,6 +54,7 @@ void ThemeEditor::_propagate_redraw(Control *p_at) {
void ThemeEditor::_refresh_interval() {
+ _propagate_redraw(main_panel);
_propagate_redraw(main_container);
}
@@ -130,14 +132,14 @@ void ThemeEditor::_save_template_cbk(String fname) {
Map<String, _TECategory> categories;
- //fill types
+ // Fill types.
List<StringName> type_list;
Theme::get_default()->get_type_list(&type_list);
for (List<StringName>::Element *E = type_list.front(); E; E = E->next()) {
categories.insert(E->get(), _TECategory());
}
- //fill default theme
+ // Fill default theme.
for (Map<String, _TECategory>::Element *E = categories.front(); E; E = E->next()) {
_TECategory &tc = E->get();
@@ -256,7 +258,7 @@ void ThemeEditor::_save_template_cbk(String fname) {
file->store_line("");
file->store_line("");
- //write default theme
+ // Write default theme.
for (Map<String, _TECategory>::Element *E = categories.front(); E; E = E->next()) {
_TECategory &tc = E->get();
@@ -501,7 +503,7 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
type_select_label->show();
type_select->show();
- if (p_option == POPUP_ADD) { //add
+ if (p_option == POPUP_ADD) { // Add.
add_del_dialog->set_title(TTR("Add Item"));
add_del_dialog->get_ok()->set_text(TTR("Add"));
@@ -509,7 +511,7 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
base_theme = Theme::get_default();
- } else if (p_option == POPUP_CLASS_ADD) { //add
+ } else if (p_option == POPUP_CLASS_ADD) { // Add.
add_del_dialog->set_title(TTR("Add All Items"));
add_del_dialog->get_ok()->set_text(TTR("Add All"));
@@ -552,12 +554,10 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
type_menu->get_popup()->clear();
- if (p_option == 0 || p_option == 1) { //add
+ if (p_option == 0 || p_option == 1) { // Add.
List<StringName> new_types;
theme->get_type_list(&new_types);
-
- //uh kind of sucks
for (List<StringName>::Element *F = new_types.front(); F; F = F->next()) {
bool found = false;
@@ -583,15 +583,17 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
void ThemeEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PROCESS) {
-
- time_left -= get_process_delta_time();
- if (time_left < 0) {
- time_left = 1.5;
- _refresh_interval();
- }
- } else if (p_what == NOTIFICATION_THEME_CHANGED) {
- theme_menu->set_icon(get_icon("Theme", "EditorIcons"));
+ switch (p_what) {
+ case NOTIFICATION_PROCESS: {
+ time_left -= get_process_delta_time();
+ if (time_left < 0) {
+ time_left = 1.5;
+ _refresh_interval();
+ }
+ } break;
+ case NOTIFICATION_THEME_CHANGED: {
+ theme_menu->set_icon(get_icon("Theme", "EditorIcons"));
+ } break;
}
}
@@ -629,35 +631,34 @@ ThemeEditor::ThemeEditor() {
top_menu->add_child(theme_menu);
theme_menu->get_popup()->connect("id_pressed", this, "_theme_menu_cbk");
- scroll = memnew(ScrollContainer);
+ ScrollContainer *scroll = memnew(ScrollContainer);
add_child(scroll);
scroll->set_enable_v_scroll(true);
scroll->set_enable_h_scroll(false);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
- main_container = memnew(MarginContainer);
- scroll->add_child(main_container);
- main_container->set_clip_contents(true);
- main_container->set_custom_minimum_size(Size2(700, 0) * EDSCALE);
- main_container->set_v_size_flags(SIZE_EXPAND_FILL);
- main_container->set_h_size_flags(SIZE_EXPAND_FILL);
+ MarginContainer *root_container = memnew(MarginContainer);
+ scroll->add_child(root_container);
+ root_container->set_theme(Theme::get_default());
+ root_container->set_clip_contents(true);
+ root_container->set_custom_minimum_size(Size2(700, 0) * EDSCALE);
+ root_container->set_v_size_flags(SIZE_EXPAND_FILL);
+ root_container->set_h_size_flags(SIZE_EXPAND_FILL);
//// Preview Controls ////
- Panel *panel = memnew(Panel);
- main_container->add_child(panel);
- panel->set_theme(Theme::get_default());
+ main_panel = memnew(Panel);
+ root_container->add_child(main_panel);
- MarginContainer *mc = memnew(MarginContainer);
- main_container->add_child(mc);
- mc->set_theme(Theme::get_default());
- mc->add_constant_override("margin_right", 4 * EDSCALE);
- mc->add_constant_override("margin_top", 4 * EDSCALE);
- mc->add_constant_override("margin_left", 4 * EDSCALE);
- mc->add_constant_override("margin_bottom", 4 * EDSCALE);
+ main_container = memnew(MarginContainer);
+ root_container->add_child(main_container);
+ main_container->add_constant_override("margin_right", 4 * EDSCALE);
+ main_container->add_constant_override("margin_top", 4 * EDSCALE);
+ main_container->add_constant_override("margin_left", 4 * EDSCALE);
+ main_container->add_constant_override("margin_bottom", 4 * EDSCALE);
HBoxContainer *main_hb = memnew(HBoxContainer);
- mc->add_child(main_hb);
+ main_container->add_child(main_hb);
VBoxContainer *first_vb = memnew(VBoxContainer);
main_hb->add_child(first_vb);
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index cc236907a9..6ffee46569 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -45,7 +45,7 @@ class ThemeEditor : public VBoxContainer {
GDCLASS(ThemeEditor, VBoxContainer);
- ScrollContainer *scroll;
+ Panel *main_panel;
MarginContainer *main_container;
Ref<Theme> theme;
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index 3331fb971f..c841eb1f98 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -41,10 +41,6 @@
#include "scene/gui/menu_button.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class TileMapEditor : public VBoxContainer {
GDCLASS(TileMapEditor, VBoxContainer);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index feb2cdd071..46d125e735 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1109,7 +1109,7 @@ void ProjectList::load_project_icon(int p_index) {
Error err = img->load(item.icon.replace_first("res://", item.path + "/"));
if (err == OK) {
- img->resize(default_icon->get_width(), default_icon->get_height());
+ img->resize(default_icon->get_width(), default_icon->get_height(), Image::INTERPOLATE_LANCZOS);
Ref<ImageTexture> it = memnew(ImageTexture);
it->create_from_image(img);
icon = it;
@@ -1312,7 +1312,7 @@ void ProjectList::set_filter_option(ProjectListFilter::FilterOption p_option) {
void ProjectList::set_order_option(ProjectListFilter::FilterOption p_option) {
if (_order_option != p_option) {
_order_option = p_option;
- EditorSettings::get_singleton()->set("project_manager/sorting_order", (int)_filter_option);
+ EditorSettings::get_singleton()->set("project_manager/sorting_order", (int)_order_option);
EditorSettings::get_singleton()->save();
}
}
diff --git a/editor/property_editor.h b/editor/property_editor.h
index a8ef1d6fc1..029c2211d5 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -46,10 +46,6 @@
#include "scene/gui/texture_rect.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class PropertyValueEvaluator;
class CreateDialog;
class PropertySelector;
diff --git a/editor/pvrtc_compress.cpp b/editor/pvrtc_compress.cpp
index 84cd6da3d9..7cdd900d25 100644
--- a/editor/pvrtc_compress.cpp
+++ b/editor/pvrtc_compress.cpp
@@ -32,6 +32,7 @@
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "editor_settings.h"
@@ -52,57 +53,75 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) {
_base_image_compress_pvrtc2_func(p_image);
else if (_base_image_compress_pvrtc4_func)
_base_image_compress_pvrtc4_func(p_image);
-
break;
case Image::COMPRESS_PVRTC4:
if (_base_image_compress_pvrtc4_func)
_base_image_compress_pvrtc4_func(p_image);
-
break;
- default: ERR_FAIL();
+ default:
+ ERR_FAIL_MSG("Unsupported Image compress mode used in PVRTC module.");
}
return;
}
- String tmppath = EditorSettings::get_singleton()->get_cache_dir();
-
- List<String> args;
+ String tmppath = EditorSettings::get_singleton()->get_cache_dir();
String src_img = tmppath.plus_file("_tmp_src_img.png");
String dst_img = tmppath.plus_file("_tmp_dst_img.pvr");
+ List<String> args;
args.push_back("-i");
args.push_back(src_img);
args.push_back("-o");
args.push_back(dst_img);
args.push_back("-f");
- switch (p_mode) {
- case Image::COMPRESS_PVRTC2: args.push_back("PVRTC2"); break;
- case Image::COMPRESS_PVRTC4: args.push_back("PVRTC4"); break;
- case Image::COMPRESS_ETC: args.push_back("ETC"); break;
- default: ERR_FAIL();
+ switch (p_mode) {
+ case Image::COMPRESS_PVRTC2:
+ args.push_back("PVRTC2");
+ break;
+ case Image::COMPRESS_PVRTC4:
+ args.push_back("PVRTC4");
+ break;
+ case Image::COMPRESS_ETC:
+ args.push_back("ETC");
+ break;
+ default:
+ ERR_FAIL_MSG("Unsupported Image compress mode used in PVRTC module.");
}
if (EditorSettings::get_singleton()->get("filesystem/import/pvrtc_fast_conversion").operator bool()) {
args.push_back("-pvrtcfast");
}
- if (p_image->has_mipmaps())
+ if (p_image->has_mipmaps()) {
args.push_back("-m");
+ }
+ // Save source PNG.
Ref<ImageTexture> t = memnew(ImageTexture);
t->create_from_image(Ref<Image>(p_image), 0);
ResourceSaver::save(src_img, t);
Error err = OS::get_singleton()->execute(ttpath, args, true);
- ERR_EXPLAIN(TTR("Could not execute PVRTC tool:") + " " + ttpath);
- ERR_FAIL_COND(err != OK);
+ if (err != OK) {
+ // Clean up generated files.
+ DirAccess::remove_file_or_error(src_img);
+ DirAccess::remove_file_or_error(dst_img);
+ ERR_FAIL_MSG("Could not execute PVRTC tool: " + ttpath);
+ }
t = ResourceLoader::load(dst_img, "Texture");
-
- ERR_EXPLAIN(TTR("Can't load back converted image using PVRTC tool:") + " " + dst_img);
- ERR_FAIL_COND(t.is_null());
+ if (t.is_null()) {
+ // Clean up generated files.
+ DirAccess::remove_file_or_error(src_img);
+ DirAccess::remove_file_or_error(dst_img);
+ ERR_FAIL_MSG("Can't load back converted image using PVRTC tool.");
+ }
p_image->copy_internals_from(t->get_data());
+
+ // Clean up generated files.
+ DirAccess::remove_file_or_error(src_img);
+ DirAccess::remove_file_or_error(dst_img);
}
static void _compress_pvrtc2(Image *p_image) {
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index 61cb59ce6f..b216be3b59 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -37,9 +37,7 @@
#include "scene/gui/button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class SceneTreeEditor : public Control {
GDCLASS(SceneTreeEditor, Control);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index ed9a24311d..7d0f40fe91 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -44,6 +44,23 @@ void ScriptCreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ String lang = ScriptServer::get_language(i)->get_name();
+ Ref<Texture> lang_icon = get_icon(lang, "EditorIcons");
+ if (lang_icon.is_valid()) {
+ language_menu->set_item_icon(i, lang_icon);
+ }
+ }
+ String last_lang = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_language", "");
+ Ref<Texture> last_lang_icon;
+ if (!last_lang.empty()) {
+ last_lang_icon = get_icon(last_lang, "EditorIcons");
+ } else {
+ last_lang_icon = language_menu->get_item_icon(default_language);
+ }
+ if (last_lang_icon.is_valid()) {
+ language_menu->set_icon(last_lang_icon);
+ }
path_button->set_icon(get_icon("Folder", "EditorIcons"));
parent_browse_button->set_icon(get_icon("Folder", "EditorIcons"));
parent_search_button->set_icon(get_icon("ClassList", "EditorIcons"));
@@ -671,13 +688,13 @@ ScriptCreateDialog::ScriptCreateDialog() {
gc->add_child(l);
gc->add_child(language_menu);
- int default_lang = 0;
+ default_language = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
String lang = ScriptServer::get_language(i)->get_name();
language_menu->add_item(lang);
if (lang == "GDScript") {
- default_lang = i;
+ default_language = i;
}
}
@@ -691,8 +708,8 @@ ScriptCreateDialog::ScriptCreateDialog() {
}
}
} else {
- language_menu->select(default_lang);
- current_language = default_lang;
+ language_menu->select(default_language);
+ current_language = default_language;
}
language_menu->connect("item_selected", this, "_lang_changed");
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index 288b8f604b..202846fd3c 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -76,6 +76,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
bool is_built_in;
bool built_in_enabled;
int current_language;
+ int default_language;
bool re_check_path;
String script_template;
Vector<String> template_list;
diff --git a/main/main.h b/main/main.h
index 694305526a..b0b90dc0fe 100644
--- a/main/main.h
+++ b/main/main.h
@@ -31,10 +31,6 @@
#ifndef MAIN_H
#define MAIN_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/error_list.h"
#include "core/os/thread.h"
#include "core/typedefs.h"
diff --git a/main/tests/test_gui.h b/main/tests/test_gui.h
index 1752818981..075bc40aa7 100644
--- a/main/tests/test_gui.h
+++ b/main/tests/test_gui.h
@@ -33,9 +33,6 @@
#include "core/os/main_loop.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
namespace TestGUI {
MainLoop *test();
diff --git a/main/tests/test_physics.h b/main/tests/test_physics.h
index 699e31f492..a281f669e0 100644
--- a/main/tests/test_physics.h
+++ b/main/tests/test_physics.h
@@ -31,10 +31,6 @@
#ifndef TEST_PHYSICS_H
#define TEST_PHYSICS_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/os/main_loop.h"
namespace TestPhysics {
diff --git a/main/tests/test_render.h b/main/tests/test_render.h
index 3810760b56..6dda57db5b 100644
--- a/main/tests/test_render.h
+++ b/main/tests/test_render.h
@@ -31,10 +31,6 @@
#ifndef TEST_RENDER_H
#define TEST_RENDER_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/os/main_loop.h"
namespace TestRender {
diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp
index 65fa8b6459..05f9120a07 100644
--- a/modules/assimp/editor_scene_importer_assimp.cpp
+++ b/modules/assimp/editor_scene_importer_assimp.cpp
@@ -150,8 +150,7 @@ Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_f
0;
const aiScene *scene = importer.ReadFile(s_path.c_str(),
post_process_Steps);
- ERR_EXPLAIN(String("Open Asset Import failed to open: ") + String(importer.GetErrorString()));
- ERR_FAIL_COND_V(scene == NULL, NULL);
+ ERR_FAIL_COND_V_MSG(scene == NULL, NULL, String("Open Asset Import failed to open: ") + String(importer.GetErrorString()) + ".");
return _generate_scene(p_path, scene, p_flags, p_bake_fps, max_bone_weights);
}
@@ -348,8 +347,7 @@ void EditorSceneImporterAssimp::_fill_node_relationships(ImportState &state, con
} else if (ownership[name] != p_skeleton_id) {
//oh, it's from another skeleton? fine.. reparent all bones to this skeleton.
int prev_owner = ownership[name];
- ERR_EXPLAIN("A previous skeleton exists for bone '" + name + "', this type of skeleton layout is unsupported.");
- ERR_FAIL_COND(skeleton_map.has(prev_owner));
+ ERR_FAIL_COND_MSG(skeleton_map.has(prev_owner), "A previous skeleton exists for bone '" + name + "', this type of skeleton layout is unsupported.");
for (Map<String, int>::Element *E = ownership.front(); E; E = E->next()) {
if (E->get() == prev_owner) {
E->get() = p_skeleton_id;
@@ -779,8 +777,7 @@ Ref<Texture> EditorSceneImporterAssimp::_load_texture(ImportState &state, String
t->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY);
return t;
} else if (tex->CheckFormat("dds")) {
- ERR_EXPLAIN("Open Asset Import: Embedded dds not implemented");
- ERR_FAIL_COND_V(true, Ref<Texture>());
+ ERR_FAIL_V_MSG(Ref<Texture>(), "Open Asset Import: Embedded dds not implemented.");
//Ref<Image> img = Image::_dds_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth);
//ERR_FAIL_COND_V(img.is_null(), Ref<Texture>());
//Ref<ImageTexture> t;
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index 88732dff33..5a32fa1c2c 100644
--- a/modules/bmp/image_loader_bmp.cpp
+++ b/modules/bmp/image_loader_bmp.cpp
@@ -241,9 +241,9 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f,
case BI_CMYKRLE8:
case BI_CMYKRLE4: {
// Stop parsing
- ERR_EXPLAIN("Compressed BMP files are not supported: " + f->get_path());
+ String bmp_path = f->get_path();
f->close();
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Compressed BMP files are not supported: " + bmp_path + ".");
} break;
}
// Don't rely on sizeof(bmp_file_header) as structure padding
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 038001996d..e01928191a 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -1548,8 +1548,7 @@ void BulletPhysicsServer::free(RID p_rid) {
bulletdelete(space);
} else {
- ERR_EXPLAIN("Invalid ID");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid ID.");
}
}
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
index bc7fd52cf6..97b9a81f77 100644
--- a/modules/bullet/cone_twist_joint_bullet.cpp
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -83,8 +83,7 @@ void ConeTwistJointBullet::set_param(PhysicsServer::ConeTwistJointParam p_param,
coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), coneConstraint->getBiasFactor(), p_value);
break;
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
break;
}
}
@@ -102,8 +101,7 @@ real_t ConeTwistJointBullet::get_param(PhysicsServer::ConeTwistJointParam p_para
case PhysicsServer::CONE_TWIST_JOINT_RELAXATION:
return coneConstraint->getRelaxationFactor();
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
index 0d2c46c579..4aae87c220 100644
--- a/modules/bullet/generic_6dof_joint_bullet.cpp
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -174,8 +174,7 @@ void Generic6DOFJointBullet::set_param(Vector3::Axis p_axis, PhysicsServer::G6DO
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint = p_value;
break;
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
break;
}
}
@@ -216,8 +215,7 @@ real_t Generic6DOFJointBullet::get_param(Vector3::Axis p_axis, PhysicsServer::G6
case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint;
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
@@ -255,8 +253,7 @@ void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOF
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableSpring = p_value;
break;
default:
- ERR_EXPLAIN("This flag " + itos(p_flag) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The flag " + itos(p_flag) + " is deprecated.");
break;
}
}
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index b7e1e1a4c2..4d26e729db 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -117,8 +117,7 @@ void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t
hingeConstraint->setMaxMotorImpulse(p_value);
break;
default:
- ERR_EXPLAIN("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
break;
}
}
@@ -143,8 +142,7 @@ real_t HingeJointBullet::get_param(PhysicsServer::HingeJointParam p_param) const
case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
return hingeConstraint->getMaxMotorImpulse();
default:
- ERR_EXPLAIN("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
index c9c4d1af7e..8d404e7f04 100644
--- a/modules/bullet/pin_joint_bullet.cpp
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -85,8 +85,7 @@ real_t PinJointBullet::get_param(PhysicsServer::PinJointParam p_param) const {
case PhysicsServer::PIN_JOINT_IMPULSE_CLAMP:
return p2pConstraint->m_setting.m_impulseClamp;
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index f15bcec914..85f47c3bbb 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -505,8 +505,7 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
}
} else {
- ERR_EXPLAIN("Expected PoolRealArray or float Image.");
- ERR_FAIL();
+ ERR_FAIL_MSG("Expected PoolRealArray or float Image.");
}
ERR_FAIL_COND(l_width <= 0);
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index f475ba23f6..d2b16b0fd1 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -581,10 +581,8 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
} else {
world_mem = malloc(sizeof(btDiscreteDynamicsWorld));
}
- if (!world_mem) {
- ERR_EXPLAIN("Out of memory");
- ERR_FAIL();
- }
+
+ ERR_FAIL_COND_MSG(!world_mem, "Out of memory.");
if (p_create_soft_world) {
collisionConfiguration = bulletnew(GodotSoftCollisionConfiguration(static_cast<btDiscreteDynamicsWorld *>(world_mem)));
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index 4628bd9a5b..0220dcae4a 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -108,8 +108,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
if (r_error)
*r_error = ERR_FILE_CORRUPT;
- ERR_EXPLAIN("Unable to open DDS texture file: " + p_path);
- ERR_FAIL_COND_V(err != OK, RES());
+ ERR_FAIL_COND_V_MSG(err != OK, RES(), "Unable to open DDS texture file: " + p_path + ".");
uint32_t magic = f->get_32();
uint32_t hsize = f->get_32();
@@ -128,8 +127,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
if (magic != DDS_MAGIC || hsize != 124 || !(flags & DDSD_PIXELFORMAT) || !(flags & DDSD_CAPS)) {
- ERR_EXPLAIN("Invalid or Unsupported DDS texture file: " + p_path);
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Invalid or unsupported DDS texture file: " + p_path + ".");
}
/* uint32_t format_size = */ f->get_32();
@@ -218,9 +216,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
} else {
printf("unrecognized fourcc %x format_flags: %x - rgbbits %i - red_mask %x green mask %x blue mask %x alpha mask %x\n", format_fourcc, format_flags, format_rgb_bits, format_red_mask, format_green_mask, format_blue_mask, format_alpha_mask);
- ERR_EXPLAIN("Unrecognized or Unsupported color layout in DDS: " + p_path);
-
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Unrecognized or unsupported color layout in DDS: " + p_path + ".");
}
if (!(flags & DDSD_MIPMAPCOUNT))
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index a5a356ced2..44f69ca261 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -543,10 +543,7 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
if (target_peer != 0) {
E = peer_map.find(ABS(target_peer));
- if (!E) {
- ERR_EXPLAIN("Invalid Target Peer: " + itos(target_peer));
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
+ ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, "Invalid target peer: " + itos(target_peer) + ".");
}
ENetPacket *packet = enet_packet_create(NULL, p_buffer_size + 8, packet_flags);
@@ -794,11 +791,7 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
ERR_FAIL_COND(p_channel < -1 || p_channel >= channel_count);
-
- if (p_channel == SYSCH_CONFIG) {
- ERR_EXPLAIN("Channel " + itos(SYSCH_CONFIG) + " is reserved");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, "Channel " + itos(SYSCH_CONFIG) + " is reserved.");
transfer_channel = p_channel;
}
diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp
index ff925480b8..3337460dfc 100644
--- a/modules/etc/texture_loader_pkm.cpp
+++ b/modules/etc/texture_loader_pkm.cpp
@@ -56,8 +56,7 @@ RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path,
if (r_error)
*r_error = ERR_FILE_CORRUPT;
- ERR_EXPLAIN("Unable to open PKM texture file: " + p_path);
- ERR_FAIL_COND_V(err != OK, RES());
+ ERR_FAIL_COND_V_MSG(err != OK, RES(), "Unable to open PKM texture file: " + p_path + ".");
// big endian
f->set_endian_swap(true);
diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py
index 7ab0e01108..20c1a2233c 100644
--- a/modules/gdnative/gdnative_builders.py
+++ b/modules/gdnative/gdnative_builders.py
@@ -185,7 +185,7 @@ def _build_gdnative_api_struct_source(api):
'extern const godot_gdnative_core_' + ('{0}_{1}_api_struct api_{0}_{1}'.format(core['version']['major'], core['version']['minor'])) + ' = {',
'\tGDNATIVE_' + core['type'] + ',',
'\t{' + str(core['version']['major']) + ', ' + str(core['version']['minor']) + '},',
- '\t' + ('NULL' if not core['next'] else ('(const godot_gdnative_api_struct *)& api_{0}_{1}'.format(core['version']['major'], core['version']['minor']))) + ','
+ '\t' + ('NULL' if not core['next'] else ('(const godot_gdnative_api_struct *)& api_{0}_{1}'.format(core['next']['version']['major'], core['next']['version']['minor']))) + ','
]
for funcdef in core['api']:
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index b8a13ed91b..62117dcaf3 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -32,6 +32,7 @@
#include "core/io/file_access_encrypted.h"
#include "core/io/resource_loader.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "editor/gdscript_highlighter.h"
#include "gdscript.h"
@@ -117,6 +118,9 @@ public:
file = FileAccess::get_file_as_array(tmp_path);
add_file(p_path.get_basename() + ".gde", file, true);
+ // Clean up temporary file.
+ DirAccess::remove_file_or_error(tmp_path);
+
} else {
add_file(p_path.get_basename() + ".gdc", file, true);
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index bdecbbdbad..b36afd4386 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -196,16 +196,14 @@ bool GridMap::get_collision_layer_bit(int p_bit) const {
#ifndef DISABLE_DEPRECATED
void GridMap::set_theme(const Ref<MeshLibrary> &p_theme) {
- ERR_EXPLAIN("GridMap.theme/set_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/set_mesh_library() instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("GridMap.theme/set_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/set_mesh_library() instead.");
set_mesh_library(p_theme);
}
Ref<MeshLibrary> GridMap::get_theme() const {
- ERR_EXPLAIN("GridMap.theme/get_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/get_mesh_library() instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("GridMap.theme/get_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/get_mesh_library() instead.");
return get_mesh_library();
}
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 5a21833ffa..07b4f7f596 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -863,19 +863,21 @@ void GridMapEditor::_icon_size_changed(float p_value) {
void GridMapEditor::update_palette() {
int selected = mesh_library_palette->get_current();
+ float min_size = EDITOR_DEF("editors/grid_map/preview_size", 64);
+ min_size *= EDSCALE;
+
mesh_library_palette->clear();
if (display_mode == DISPLAY_THUMBNAIL) {
mesh_library_palette->set_max_columns(0);
mesh_library_palette->set_icon_mode(ItemList::ICON_MODE_TOP);
+ mesh_library_palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1.5));
} else if (display_mode == DISPLAY_LIST) {
mesh_library_palette->set_max_columns(1);
mesh_library_palette->set_icon_mode(ItemList::ICON_MODE_LEFT);
+ mesh_library_palette->set_fixed_column_width(0);
}
- float min_size = EDITOR_DEF("editors/grid_map/preview_size", 64);
- min_size *= EDSCALE;
mesh_library_palette->set_fixed_icon_size(Size2(min_size, min_size));
- mesh_library_palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1.5));
mesh_library_palette->set_max_text_lines(2);
Ref<MeshLibrary> mesh_library = node->get_mesh_library();
@@ -1269,7 +1271,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
options->get_popup()->add_item(TTR("Fill Selection"), MENU_OPTION_SELECTION_FILL, KEY_MASK_CTRL + KEY_F);
options->get_popup()->add_separator();
- options->get_popup()->add_item(TTR("Settings"), MENU_OPTION_GRIDMAP_SETTINGS);
+ options->get_popup()->add_item(TTR("Settings..."), MENU_OPTION_GRIDMAP_SETTINGS);
settings_dialog = memnew(ConfirmationDialog);
settings_dialog->set_title(TTR("GridMap Settings"));
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index b9be925ff7..d174ac1035 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -35,9 +35,6 @@
#include "editor/editor_plugin.h"
#include "editor/pane_drag.h"
#include "grid_map.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class SpatialEditorPlugin;
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index f75a4a926a..e610619b54 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -102,10 +102,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
len <<= 8;
len |= f->get_8();
- if (len != width) {
- ERR_EXPLAIN("invalid decoded scanline length, corrupt HDR");
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- }
+ ERR_FAIL_COND_V_MSG(len != width, ERR_FILE_CORRUPT, "Invalid decoded scanline length, corrupt HDR.");
for (int k = 0; k < 4; ++k) {
int i = 0;
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index 8ebf52def7..e9575ee4fb 100644
--- a/modules/hdr/image_loader_hdr.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderHDR : public ImageFormatLoader {
public:
diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h
index 9a96fe008d..e9016ce43e 100644
--- a/modules/jpg/image_loader_jpegd.h
+++ b/modules/jpg/image_loader_jpegd.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderJPG : public ImageFormatLoader {
public:
diff --git a/modules/mono/.gitignore b/modules/mono/.gitignore
new file mode 100644
index 0000000000..fa6d00cbbb
--- /dev/null
+++ b/modules/mono/.gitignore
@@ -0,0 +1,2 @@
+# Do not ignore solution files inside the mono module. Overrides Godot's global gitignore.
+!*.sln
diff --git a/modules/mono/build_scripts/godot_tools_build.py b/modules/mono/build_scripts/godot_tools_build.py
index c47cfc8a38..35daa6d307 100644
--- a/modules/mono/build_scripts/godot_tools_build.py
+++ b/modules/mono/build_scripts/godot_tools_build.py
@@ -84,10 +84,16 @@ def build(env_mono):
source_filenames = ['GodotSharp.dll', 'GodotSharpEditor.dll']
sources = [os.path.join(editor_api_dir, filename) for filename in source_filenames]
- target_filenames = ['GodotTools.dll', 'GodotTools.BuildLogger.dll', 'GodotTools.ProjectEditor.dll', 'DotNet.Glob.dll', 'GodotTools.Core.dll']
+ target_filenames = [
+ 'GodotTools.dll', 'GodotTools.IdeConnection.dll', 'GodotTools.BuildLogger.dll',
+ 'GodotTools.ProjectEditor.dll', 'DotNet.Glob.dll', 'GodotTools.Core.dll'
+ ]
if env_mono['target'] == 'debug':
- target_filenames += ['GodotTools.pdb', 'GodotTools.BuildLogger.pdb', 'GodotTools.ProjectEditor.pdb', 'GodotTools.Core.pdb']
+ target_filenames += [
+ 'GodotTools.pdb', 'GodotTools.IdeConnection.pdb', 'GodotTools.BuildLogger.pdb',
+ 'GodotTools.ProjectEditor.pdb', 'GodotTools.Core.pdb'
+ ]
targets = [os.path.join(editor_tools_dir, filename) for filename in target_filenames]
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 9f0eb58896..f751719531 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -113,8 +113,8 @@ def configure(env, env_mono):
else:
env.Append(LINKFLAGS=os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix))
- env.Append(LIBS='psapi')
- env.Append(LIBS='version')
+ env.Append(LIBS=['psapi'])
+ env.Append(LIBS=['version'])
else:
mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib')
@@ -124,7 +124,7 @@ def configure(env, env_mono):
if env.msvc:
env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX'])
else:
- env.Append(LIBS=mono_lib_name)
+ env.Append(LIBS=[mono_lib_name])
mono_bin_path = os.path.join(mono_root, 'bin')
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs
new file mode 100644
index 0000000000..7a2ff2ca56
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace GodotTools.IdeConnection
+{
+ public class ConsoleLogger : ILogger
+ {
+ public void LogDebug(string message)
+ {
+ Console.WriteLine("DEBUG: " + message);
+ }
+
+ public void LogInfo(string message)
+ {
+ Console.WriteLine("INFO: " + message);
+ }
+
+ public void LogWarning(string message)
+ {
+ Console.WriteLine("WARN: " + message);
+ }
+
+ public void LogError(string message)
+ {
+ Console.WriteLine("ERROR: " + message);
+ }
+
+ public void LogError(string message, Exception e)
+ {
+ Console.WriteLine("EXCEPTION: " + message);
+ Console.WriteLine(e);
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs
new file mode 100644
index 0000000000..be89638241
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs
@@ -0,0 +1,94 @@
+using System;
+using Path = System.IO.Path;
+
+namespace GodotTools.IdeConnection
+{
+ public class GodotIdeBase : IDisposable
+ {
+ private ILogger logger;
+
+ public ILogger Logger
+ {
+ get => logger ?? (logger = new ConsoleLogger());
+ set => logger = value;
+ }
+
+ private readonly string projectMetadataDir;
+
+ protected const string MetaFileName = "ide_server_meta.txt";
+ protected string MetaFilePath => Path.Combine(projectMetadataDir, MetaFileName);
+
+ private GodotIdeConnection connection;
+ protected readonly object ConnectionLock = new object();
+
+ public bool IsDisposed { get; private set; } = false;
+
+ public bool IsConnected => connection != null && !connection.IsDisposed && connection.IsConnected;
+
+ public event Action Connected
+ {
+ add
+ {
+ if (connection != null && !connection.IsDisposed)
+ connection.Connected += value;
+ }
+ remove
+ {
+ if (connection != null && !connection.IsDisposed)
+ connection.Connected -= value;
+ }
+ }
+
+ protected GodotIdeConnection Connection
+ {
+ get => connection;
+ set
+ {
+ connection?.Dispose();
+ connection = value;
+ }
+ }
+
+ protected GodotIdeBase(string projectMetadataDir)
+ {
+ this.projectMetadataDir = projectMetadataDir;
+ }
+
+ protected void DisposeConnection()
+ {
+ lock (ConnectionLock)
+ {
+ connection?.Dispose();
+ }
+ }
+
+ ~GodotIdeBase()
+ {
+ Dispose(disposing: false);
+ }
+
+ public void Dispose()
+ {
+ if (IsDisposed)
+ return;
+
+ lock (ConnectionLock)
+ {
+ if (IsDisposed) // lock may not be fair
+ return;
+ IsDisposed = true;
+ }
+
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ connection?.Dispose();
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
new file mode 100644
index 0000000000..4f56a8d71b
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
@@ -0,0 +1,219 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+namespace GodotTools.IdeConnection
+{
+ public abstract class GodotIdeClient : GodotIdeBase
+ {
+ protected GodotIdeMetadata GodotIdeMetadata;
+
+ private readonly FileSystemWatcher fsWatcher;
+
+ protected GodotIdeClient(string projectMetadataDir) : base(projectMetadataDir)
+ {
+ messageHandlers = InitializeMessageHandlers();
+
+ // FileSystemWatcher requires an existing directory
+ if (!File.Exists(projectMetadataDir))
+ Directory.CreateDirectory(projectMetadataDir);
+
+ fsWatcher = new FileSystemWatcher(projectMetadataDir, MetaFileName);
+ }
+
+ private void OnMetaFileChanged(object sender, FileSystemEventArgs e)
+ {
+ if (IsDisposed)
+ return;
+
+ lock (ConnectionLock)
+ {
+ if (IsDisposed)
+ return;
+
+ if (!File.Exists(MetaFilePath))
+ return;
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null && metadata != GodotIdeMetadata)
+ {
+ GodotIdeMetadata = metadata.Value;
+ ConnectToServer();
+ }
+ }
+ }
+
+ private void OnMetaFileDeleted(object sender, FileSystemEventArgs e)
+ {
+ if (IsDisposed)
+ return;
+
+ if (IsConnected)
+ DisposeConnection();
+
+ // The file may have been re-created
+
+ lock (ConnectionLock)
+ {
+ if (IsDisposed)
+ return;
+
+ if (IsConnected || !File.Exists(MetaFilePath))
+ return;
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null)
+ {
+ GodotIdeMetadata = metadata.Value;
+ ConnectToServer();
+ }
+ }
+ }
+
+ private GodotIdeMetadata? ReadMetadataFile()
+ {
+ using (var reader = File.OpenText(MetaFilePath))
+ {
+ string portStr = reader.ReadLine();
+
+ if (portStr == null)
+ return null;
+
+ string editorExecutablePath = reader.ReadLine();
+
+ if (editorExecutablePath == null)
+ return null;
+
+ if (!int.TryParse(portStr, out int port))
+ return null;
+
+ return new GodotIdeMetadata(port, editorExecutablePath);
+ }
+ }
+
+ private void ConnectToServer()
+ {
+ var tcpClient = new TcpClient();
+
+ Connection = new GodotIdeConnectionClient(tcpClient, HandleMessage);
+ Connection.Logger = Logger;
+
+ try
+ {
+ Logger.LogInfo("Connecting to Godot Ide Server");
+
+ tcpClient.Connect(IPAddress.Loopback, GodotIdeMetadata.Port);
+
+ Logger.LogInfo("Connection open with Godot Ide Server");
+
+ var clientThread = new Thread(Connection.Start)
+ {
+ IsBackground = true,
+ Name = "Godot Ide Connection Client"
+ };
+ clientThread.Start();
+ }
+ catch (SocketException e)
+ {
+ if (e.SocketErrorCode == SocketError.ConnectionRefused)
+ Logger.LogError("The connection to the Godot Ide Server was refused");
+ else
+ throw;
+ }
+ }
+
+ public void Start()
+ {
+ Logger.LogInfo("Starting Godot Ide Client");
+
+ fsWatcher.Changed += OnMetaFileChanged;
+ fsWatcher.Deleted += OnMetaFileDeleted;
+ fsWatcher.EnableRaisingEvents = true;
+
+ lock (ConnectionLock)
+ {
+ if (IsDisposed)
+ return;
+
+ if (!File.Exists(MetaFilePath))
+ {
+ Logger.LogInfo("There is no Godot Ide Server running");
+ return;
+ }
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null)
+ {
+ GodotIdeMetadata = metadata.Value;
+ ConnectToServer();
+ }
+ else
+ {
+ Logger.LogError("Failed to read Godot Ide metadata file");
+ }
+ }
+ }
+
+ public bool WriteMessage(Message message)
+ {
+ return Connection.WriteMessage(message);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ fsWatcher?.Dispose();
+ }
+ }
+
+ protected virtual bool HandleMessage(Message message)
+ {
+ if (messageHandlers.TryGetValue(message.Id, out var action))
+ {
+ action(message.Arguments);
+ return true;
+ }
+
+ return false;
+ }
+
+ private readonly Dictionary<string, Action<string[]>> messageHandlers;
+
+ private Dictionary<string, Action<string[]>> InitializeMessageHandlers()
+ {
+ return new Dictionary<string, Action<string[]>>
+ {
+ ["OpenFile"] = args =>
+ {
+ switch (args.Length)
+ {
+ case 1:
+ OpenFile(file: args[0]);
+ return;
+ case 2:
+ OpenFile(file: args[0], line: int.Parse(args[1]));
+ return;
+ case 3:
+ OpenFile(file: args[0], line: int.Parse(args[1]), column: int.Parse(args[2]));
+ return;
+ default:
+ throw new ArgumentException();
+ }
+ }
+ };
+ }
+
+ protected abstract void OpenFile(string file);
+ protected abstract void OpenFile(string file, int line);
+ protected abstract void OpenFile(string file, int line, int column);
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
new file mode 100644
index 0000000000..e7e81f175e
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
@@ -0,0 +1,207 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Net.Sockets;
+using System.Text;
+
+namespace GodotTools.IdeConnection
+{
+ public abstract class GodotIdeConnection : IDisposable
+ {
+ protected const string Version = "1.0";
+
+ protected static readonly string ClientHandshake = $"Godot Ide Client Version {Version}";
+ protected static readonly string ServerHandshake = $"Godot Ide Server Version {Version}";
+
+ private const int ClientWriteTimeout = 8000;
+ private readonly TcpClient tcpClient;
+
+ private TextReader clientReader;
+ private TextWriter clientWriter;
+
+ private readonly object writeLock = new object();
+
+ private readonly Func<Message, bool> messageHandler;
+
+ public event Action Connected;
+
+ private ILogger logger;
+
+ public ILogger Logger
+ {
+ get => logger ?? (logger = new ConsoleLogger());
+ set => logger = value;
+ }
+
+ public bool IsDisposed { get; private set; } = false;
+
+ public bool IsConnected => tcpClient.Client != null && tcpClient.Client.Connected;
+
+ protected GodotIdeConnection(TcpClient tcpClient, Func<Message, bool> messageHandler)
+ {
+ this.tcpClient = tcpClient;
+ this.messageHandler = messageHandler;
+ }
+
+ public void Start()
+ {
+ try
+ {
+ if (!StartConnection())
+ return;
+
+ string messageLine;
+ while ((messageLine = ReadLine()) != null)
+ {
+ if (!MessageParser.TryParse(messageLine, out Message msg))
+ {
+ Logger.LogError($"Received message with invalid format: {messageLine}");
+ continue;
+ }
+
+ Logger.LogDebug($"Received message: {msg}");
+
+ if (msg.Id == "close")
+ {
+ Logger.LogInfo("Closing connection");
+ return;
+ }
+
+ try
+ {
+ try
+ {
+ Debug.Assert(messageHandler != null);
+
+ if (!messageHandler(msg))
+ Logger.LogError($"Received unknown message: {msg}");
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Message handler for '{msg}' failed with exception", e);
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Exception thrown from message handler. Message: {msg}", e);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Unhandled exception in the Godot Ide Connection thread", e);
+ }
+ finally
+ {
+ Dispose();
+ }
+ }
+
+ private bool StartConnection()
+ {
+ NetworkStream clientStream = tcpClient.GetStream();
+
+ clientReader = new StreamReader(clientStream, Encoding.UTF8);
+
+ lock (writeLock)
+ clientWriter = new StreamWriter(clientStream, Encoding.UTF8);
+
+ clientStream.WriteTimeout = ClientWriteTimeout;
+
+ if (!WriteHandshake())
+ {
+ Logger.LogError("Could not write handshake");
+ return false;
+ }
+
+ if (!IsValidResponseHandshake(ReadLine()))
+ {
+ Logger.LogError("Received invalid handshake");
+ return false;
+ }
+
+ Connected?.Invoke();
+
+ Logger.LogInfo("Godot Ide connection started");
+
+ return true;
+ }
+
+ private string ReadLine()
+ {
+ try
+ {
+ return clientReader?.ReadLine();
+ }
+ catch (Exception e)
+ {
+ if (IsDisposed)
+ {
+ var se = e as SocketException ?? e.InnerException as SocketException;
+ if (se != null && se.SocketErrorCode == SocketError.Interrupted)
+ return null;
+ }
+
+ throw;
+ }
+ }
+
+ public bool WriteMessage(Message message)
+ {
+ Logger.LogDebug($"Sending message {message}");
+
+ var messageComposer = new MessageComposer();
+
+ messageComposer.AddArgument(message.Id);
+ foreach (string argument in message.Arguments)
+ messageComposer.AddArgument(argument);
+
+ return WriteLine(messageComposer.ToString());
+ }
+
+ protected bool WriteLine(string text)
+ {
+ if (clientWriter == null || IsDisposed || !IsConnected)
+ return false;
+
+ lock (writeLock)
+ {
+ try
+ {
+ clientWriter.WriteLine(text);
+ clientWriter.Flush();
+ }
+ catch (Exception e)
+ {
+ if (!IsDisposed)
+ {
+ var se = e as SocketException ?? e.InnerException as SocketException;
+ if (se != null && se.SocketErrorCode == SocketError.Shutdown)
+ Logger.LogInfo("Client disconnected ungracefully");
+ else
+ Logger.LogError("Exception thrown when trying to write to client", e);
+
+ Dispose();
+ }
+ }
+ }
+
+ return true;
+ }
+
+ protected abstract bool WriteHandshake();
+ protected abstract bool IsValidResponseHandshake(string handshakeLine);
+
+ public void Dispose()
+ {
+ if (IsDisposed)
+ return;
+
+ IsDisposed = true;
+
+ clientReader?.Dispose();
+ clientWriter?.Dispose();
+ ((IDisposable) tcpClient)?.Dispose();
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs
new file mode 100644
index 0000000000..1b11a14358
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+
+namespace GodotTools.IdeConnection
+{
+ public class GodotIdeConnectionClient : GodotIdeConnection
+ {
+ public GodotIdeConnectionClient(TcpClient tcpClient, Func<Message, bool> messageHandler)
+ : base(tcpClient, messageHandler)
+ {
+ }
+
+ protected override bool WriteHandshake()
+ {
+ return WriteLine(ClientHandshake);
+ }
+
+ protected override bool IsValidResponseHandshake(string handshakeLine)
+ {
+ return handshakeLine == ServerHandshake;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs
new file mode 100644
index 0000000000..aa98dc7ca3
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+
+namespace GodotTools.IdeConnection
+{
+ public class GodotIdeConnectionServer : GodotIdeConnection
+ {
+ public GodotIdeConnectionServer(TcpClient tcpClient, Func<Message, bool> messageHandler)
+ : base(tcpClient, messageHandler)
+ {
+ }
+
+ protected override bool WriteHandshake()
+ {
+ return WriteLine(ServerHandshake);
+ }
+
+ protected override bool IsValidResponseHandshake(string handshakeLine)
+ {
+ return handshakeLine == ClientHandshake;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs
new file mode 100644
index 0000000000..d16daba0e2
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs
@@ -0,0 +1,45 @@
+namespace GodotTools.IdeConnection
+{
+ public struct GodotIdeMetadata
+ {
+ public int Port { get; }
+ public string EditorExecutablePath { get; }
+
+ public GodotIdeMetadata(int port, string editorExecutablePath)
+ {
+ Port = port;
+ EditorExecutablePath = editorExecutablePath;
+ }
+
+ public static bool operator ==(GodotIdeMetadata a, GodotIdeMetadata b)
+ {
+ return a.Port == b.Port && a.EditorExecutablePath == b.EditorExecutablePath;
+ }
+
+ public static bool operator !=(GodotIdeMetadata a, GodotIdeMetadata b)
+ {
+ return !(a == b);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is GodotIdeMetadata metadata)
+ return metadata == this;
+
+ return false;
+ }
+
+ public bool Equals(GodotIdeMetadata other)
+ {
+ return Port == other.Port && EditorExecutablePath == other.EditorExecutablePath;
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return (Port * 397) ^ (EditorExecutablePath != null ? EditorExecutablePath.GetHashCode() : 0);
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
new file mode 100644
index 0000000000..84c08251ab
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{92600954-25F0-4291-8E11-1FEE9FC4BE20}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>GodotTools.IdeConnection</RootNamespace>
+ <AssemblyName>GodotTools.IdeConnection</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>portable</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>portable</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConsoleLogger.cs" />
+ <Compile Include="GodotIdeMetadata.cs" />
+ <Compile Include="GodotIdeBase.cs" />
+ <Compile Include="GodotIdeClient.cs" />
+ <Compile Include="GodotIdeConnection.cs" />
+ <Compile Include="GodotIdeConnectionClient.cs" />
+ <Compile Include="GodotIdeConnectionServer.cs" />
+ <Compile Include="ILogger.cs" />
+ <Compile Include="Message.cs" />
+ <Compile Include="MessageComposer.cs" />
+ <Compile Include="MessageParser.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs
new file mode 100644
index 0000000000..614bb30271
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace GodotTools.IdeConnection
+{
+ public interface ILogger
+ {
+ void LogDebug(string message);
+ void LogInfo(string message);
+ void LogWarning(string message);
+ void LogError(string message);
+ void LogError(string message, Exception e);
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs
new file mode 100644
index 0000000000..f24d324ae3
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs
@@ -0,0 +1,21 @@
+using System.Linq;
+
+namespace GodotTools.IdeConnection
+{
+ public struct Message
+ {
+ public string Id { get; set; }
+ public string[] Arguments { get; set; }
+
+ public Message(string id, params string[] arguments)
+ {
+ Id = id;
+ Arguments = arguments;
+ }
+
+ public override string ToString()
+ {
+ return $"(Id: '{Id}', Arguments: '{string.Join(",", Arguments)}')";
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
new file mode 100644
index 0000000000..9e4cd6ec1a
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
@@ -0,0 +1,46 @@
+using System.Linq;
+using System.Text;
+
+namespace GodotTools.IdeConnection
+{
+ public class MessageComposer
+ {
+ private readonly StringBuilder stringBuilder = new StringBuilder();
+
+ private static readonly char[] CharsToEscape = { '\\', '"' };
+
+ public void AddArgument(string argument)
+ {
+ AddArgument(argument, quoted: argument.Contains(","));
+ }
+
+ public void AddArgument(string argument, bool quoted)
+ {
+ if (stringBuilder.Length > 0)
+ stringBuilder.Append(',');
+
+ if (quoted)
+ {
+ stringBuilder.Append('"');
+
+ foreach (char @char in argument)
+ {
+ if (CharsToEscape.Contains(@char))
+ stringBuilder.Append('\\');
+ stringBuilder.Append(@char);
+ }
+
+ stringBuilder.Append('"');
+ }
+ else
+ {
+ stringBuilder.Append(argument);
+ }
+ }
+
+ public override string ToString()
+ {
+ return stringBuilder.ToString();
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
new file mode 100644
index 0000000000..ed691e481f
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
@@ -0,0 +1,88 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GodotTools.IdeConnection
+{
+ public static class MessageParser
+ {
+ public static bool TryParse(string messageLine, out Message message)
+ {
+ var arguments = new List<string>();
+ var stringBuilder = new StringBuilder();
+
+ bool expectingArgument = true;
+
+ for (int i = 0; i < messageLine.Length; i++)
+ {
+ char @char = messageLine[i];
+
+ if (@char == ',')
+ {
+ if (expectingArgument)
+ arguments.Add(string.Empty);
+
+ expectingArgument = true;
+ continue;
+ }
+
+ bool quoted = false;
+
+ if (messageLine[i] == '"')
+ {
+ quoted = true;
+ i++;
+ }
+
+ while (i < messageLine.Length)
+ {
+ @char = messageLine[i];
+
+ if (quoted && @char == '"')
+ {
+ i++;
+ break;
+ }
+
+ if (@char == '\\')
+ {
+ i++;
+ if (i < messageLine.Length)
+ break;
+
+ stringBuilder.Append(messageLine[i]);
+ }
+ else if (!quoted && @char == ',')
+ {
+ break; // We don't increment the counter to allow the colon to be parsed after this
+ }
+ else
+ {
+ stringBuilder.Append(@char);
+ }
+
+ i++;
+ }
+
+ arguments.Add(stringBuilder.ToString());
+ stringBuilder.Clear();
+
+ expectingArgument = false;
+ }
+
+ if (arguments.Count == 0)
+ {
+ message = new Message();
+ return false;
+ }
+
+ message = new Message
+ {
+ Id = arguments[0],
+ Arguments = arguments.Skip(1).ToArray()
+ };
+
+ return true;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..c7c00e66a2
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GodotTools.IdeConnection")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Godot Engine contributors")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("92600954-25F0-4291-8E11-1FEE9FC4BE20")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/modules/mono/editor/GodotTools/GodotTools.sln b/modules/mono/editor/GodotTools/GodotTools.sln
index 6f7d44bec2..a3438ea5f3 100644
--- a/modules/mono/editor/GodotTools/GodotTools.sln
+++ b/modules/mono/editor/GodotTools/GodotTools.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.Core", "GodotToo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.BuildLogger", "GodotTools.BuildLogger\GodotTools.BuildLogger.csproj", "{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.IdeConnection", "GodotTools.IdeConnection\GodotTools.IdeConnection.csproj", "{92600954-25F0-4291-8E11-1FEE9FC4BE20}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -31,5 +33,9 @@ Global
{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {92600954-25F0-4291-8E11-1FEE9FC4BE20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {92600954-25F0-4291-8E11-1FEE9FC4BE20}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {92600954-25F0-4291-8E11-1FEE9FC4BE20}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {92600954-25F0-4291-8E11-1FEE9FC4BE20}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
index 53ff0891d5..44813f962c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
@@ -9,7 +9,7 @@ using Path = System.IO.Path;
namespace GodotTools
{
- public class MonoBottomPanel : VBoxContainer
+ public class BottomPanel : VBoxContainer
{
private EditorInterface editorInterface;
@@ -34,7 +34,7 @@ namespace GodotTools
for (int i = 0; i < buildTabs.GetChildCount(); i++)
{
- var tab = (MonoBuildTab) buildTabs.GetChild(i);
+ var tab = (BuildTab) buildTabs.GetChild(i);
if (tab == null)
continue;
@@ -49,11 +49,11 @@ namespace GodotTools
itemTooltip += "\nStatus: ";
if (tab.BuildExited)
- itemTooltip += tab.BuildResult == MonoBuildTab.BuildResults.Success ? "Succeeded" : "Errored";
+ itemTooltip += tab.BuildResult == BuildTab.BuildResults.Success ? "Succeeded" : "Errored";
else
itemTooltip += "Running";
- if (!tab.BuildExited || tab.BuildResult == MonoBuildTab.BuildResults.Error)
+ if (!tab.BuildExited || tab.BuildResult == BuildTab.BuildResults.Error)
itemTooltip += $"\nErrors: {tab.ErrorCount}";
itemTooltip += $"\nWarnings: {tab.WarningCount}";
@@ -68,15 +68,15 @@ namespace GodotTools
}
}
- public MonoBuildTab GetBuildTabFor(MonoBuildInfo buildInfo)
+ public BuildTab GetBuildTabFor(BuildInfo buildInfo)
{
- foreach (var buildTab in new Array<MonoBuildTab>(buildTabs.GetChildren()))
+ foreach (var buildTab in new Array<BuildTab>(buildTabs.GetChildren()))
{
if (buildTab.BuildInfo.Equals(buildInfo))
return buildTab;
}
- var newBuildTab = new MonoBuildTab(buildInfo);
+ var newBuildTab = new BuildTab(buildInfo);
AddBuildTab(newBuildTab);
return newBuildTab;
@@ -120,7 +120,7 @@ namespace GodotTools
if (currentTab < 0 || currentTab >= buildTabs.GetTabCount())
throw new InvalidOperationException("No tab selected");
- var buildTab = (MonoBuildTab) buildTabs.GetChild(currentTab);
+ var buildTab = (BuildTab) buildTabs.GetChild(currentTab);
buildTab.WarningsVisible = pressed;
buildTab.UpdateIssuesList();
}
@@ -132,7 +132,7 @@ namespace GodotTools
if (currentTab < 0 || currentTab >= buildTabs.GetTabCount())
throw new InvalidOperationException("No tab selected");
- var buildTab = (MonoBuildTab) buildTabs.GetChild(currentTab);
+ var buildTab = (BuildTab) buildTabs.GetChild(currentTab);
buildTab.ErrorsVisible = pressed;
buildTab.UpdateIssuesList();
}
@@ -145,7 +145,7 @@ namespace GodotTools
string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor");
string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player");
- CSharpProject.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
+ CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
if (File.Exists(editorScriptsMetadataPath))
{
@@ -166,7 +166,7 @@ namespace GodotTools
Internal.GodotIs32Bits() ? "32" : "64"
};
- bool buildSuccess = GodotSharpBuilds.BuildProjectBlocking("Tools", godotDefines);
+ bool buildSuccess = BuildManager.BuildProjectBlocking("Tools", godotDefines);
if (!buildSuccess)
return;
@@ -193,9 +193,9 @@ namespace GodotTools
int selectedItem = selectedItems[0];
- var buildTab = (MonoBuildTab) buildTabs.GetTabControl(selectedItem);
+ var buildTab = (BuildTab) buildTabs.GetTabControl(selectedItem);
- OS.ShellOpen(Path.Combine(buildTab.BuildInfo.LogsDirPath, GodotSharpBuilds.MsBuildLogFileName));
+ OS.ShellOpen(Path.Combine(buildTab.BuildInfo.LogsDirPath, BuildManager.MsBuildLogFileName));
}
public override void _Notification(int what)
@@ -211,13 +211,13 @@ namespace GodotTools
}
}
- public void AddBuildTab(MonoBuildTab buildTab)
+ public void AddBuildTab(BuildTab buildTab)
{
buildTabs.AddChild(buildTab);
RaiseBuildTab(buildTab);
}
- public void RaiseBuildTab(MonoBuildTab buildTab)
+ public void RaiseBuildTab(BuildTab buildTab)
{
if (buildTab.GetParent() != buildTabs)
throw new InvalidOperationException("Build tab is not in the tabs list");
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
index d8cb9024c3..9a2b2e3a26 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
@@ -46,8 +46,8 @@ namespace GodotTools.Build
{
if (OS.IsWindows())
{
- return (GodotSharpBuilds.BuildTool) EditorSettings.GetSetting("mono/builds/build_tool")
- == GodotSharpBuilds.BuildTool.MsBuildMono;
+ return (BuildManager.BuildTool) EditorSettings.GetSetting("mono/builds/build_tool")
+ == BuildManager.BuildTool.MsBuildMono;
}
return false;
@@ -103,16 +103,16 @@ namespace GodotTools.Build
return process;
}
- public static int Build(MonoBuildInfo monoBuildInfo)
+ public static int Build(BuildInfo buildInfo)
{
- return Build(monoBuildInfo.Solution, monoBuildInfo.Configuration,
- monoBuildInfo.LogsDirPath, monoBuildInfo.CustomProperties);
+ return Build(buildInfo.Solution, buildInfo.Configuration,
+ buildInfo.LogsDirPath, buildInfo.CustomProperties);
}
- public static async Task<int> BuildAsync(MonoBuildInfo monoBuildInfo)
+ public static async Task<int> BuildAsync(BuildInfo buildInfo)
{
- return await BuildAsync(monoBuildInfo.Solution, monoBuildInfo.Configuration,
- monoBuildInfo.LogsDirPath, monoBuildInfo.CustomProperties);
+ return await BuildAsync(buildInfo.Solution, buildInfo.Configuration,
+ buildInfo.LogsDirPath, buildInfo.CustomProperties);
}
public static int Build(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index 926aabdf89..4c1e47ecad 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -19,13 +19,13 @@ namespace GodotTools.Build
public static string FindMsBuild()
{
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
- var buildTool = (GodotSharpBuilds.BuildTool) editorSettings.GetSetting("mono/builds/build_tool");
+ var buildTool = (BuildManager.BuildTool) editorSettings.GetSetting("mono/builds/build_tool");
if (OS.IsWindows())
{
switch (buildTool)
{
- case GodotSharpBuilds.BuildTool.MsBuildVs:
+ case BuildManager.BuildTool.MsBuildVs:
{
if (_msbuildToolsPath.Empty() || !File.Exists(_msbuildToolsPath))
{
@@ -34,7 +34,7 @@ namespace GodotTools.Build
if (_msbuildToolsPath.Empty())
{
- throw new FileNotFoundException($"Cannot find executable for '{GodotSharpBuilds.PropNameMsbuildVs}'. Tried with path: {_msbuildToolsPath}");
+ throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMsbuildVs}'. Tried with path: {_msbuildToolsPath}");
}
}
@@ -43,13 +43,13 @@ namespace GodotTools.Build
return Path.Combine(_msbuildToolsPath, "MSBuild.exe");
}
- case GodotSharpBuilds.BuildTool.MsBuildMono:
+ case BuildManager.BuildTool.MsBuildMono:
{
string msbuildPath = Path.Combine(Internal.MonoWindowsInstallRoot, "bin", "msbuild.bat");
if (!File.Exists(msbuildPath))
{
- throw new FileNotFoundException($"Cannot find executable for '{GodotSharpBuilds.PropNameMsbuildMono}'. Tried with path: {msbuildPath}");
+ throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMsbuildMono}'. Tried with path: {msbuildPath}");
}
return msbuildPath;
@@ -61,7 +61,7 @@ namespace GodotTools.Build
if (OS.IsUnix())
{
- if (buildTool == GodotSharpBuilds.BuildTool.MsBuildMono)
+ if (buildTool == BuildManager.BuildTool.MsBuildMono)
{
if (_msbuildUnixPath.Empty() || !File.Exists(_msbuildUnixPath))
{
@@ -71,7 +71,7 @@ namespace GodotTools.Build
if (_msbuildUnixPath.Empty())
{
- throw new FileNotFoundException($"Cannot find binary for '{GodotSharpBuilds.PropNameMsbuildMono}'");
+ throw new FileNotFoundException($"Cannot find binary for '{BuildManager.PropNameMsbuildMono}'");
}
return _msbuildUnixPath;
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs
index 858e852392..70bd552f2f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs
@@ -7,7 +7,7 @@ using Path = System.IO.Path;
namespace GodotTools
{
[Serializable]
- public sealed class MonoBuildInfo : Reference // TODO Remove Reference once we have proper serialization
+ public sealed class BuildInfo : Reference // TODO Remove Reference once we have proper serialization
{
public string Solution { get; }
public string Configuration { get; }
@@ -17,7 +17,7 @@ namespace GodotTools
public override bool Equals(object obj)
{
- if (obj is MonoBuildInfo other)
+ if (obj is BuildInfo other)
return other.Solution == Solution && other.Configuration == Configuration;
return false;
@@ -34,11 +34,11 @@ namespace GodotTools
}
}
- private MonoBuildInfo()
+ private BuildInfo()
{
}
- public MonoBuildInfo(string solution, string configuration)
+ public BuildInfo(string solution, string configuration)
{
Solution = solution;
Configuration = configuration;
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
index de3a4d9a6e..417032da54 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
@@ -6,15 +6,13 @@ using GodotTools.Build;
using GodotTools.Internals;
using GodotTools.Utils;
using static GodotTools.Internals.Globals;
-using Error = Godot.Error;
using File = GodotTools.Utils.File;
-using Directory = GodotTools.Utils.Directory;
namespace GodotTools
{
- public static class GodotSharpBuilds
+ public static class BuildManager
{
- private static readonly List<MonoBuildInfo> BuildsInProgress = new List<MonoBuildInfo>();
+ private static readonly List<BuildInfo> BuildsInProgress = new List<BuildInfo>();
public const string PropNameMsbuildMono = "MSBuild (Mono)";
public const string PropNameMsbuildVs = "MSBuild (VS Build Tools)";
@@ -28,7 +26,7 @@ namespace GodotTools
MsBuildVs
}
- private static void RemoveOldIssuesFile(MonoBuildInfo buildInfo)
+ private static void RemoveOldIssuesFile(BuildInfo buildInfo)
{
var issuesFile = GetIssuesFilePath(buildInfo);
@@ -38,29 +36,21 @@ namespace GodotTools
File.Delete(issuesFile);
}
- private static string _ApiFolderName(ApiAssemblyType apiType)
- {
- ulong apiHash = apiType == ApiAssemblyType.Core ?
- Internal.GetCoreApiHash() :
- Internal.GetEditorApiHash();
- return $"{apiHash}_{BindingsGenerator.Version}_{BindingsGenerator.CsGlueVersion}";
- }
-
private static void ShowBuildErrorDialog(string message)
{
GodotSharpEditor.Instance.ShowErrorDialog(message, "Build error");
- GodotSharpEditor.Instance.MonoBottomPanel.ShowBuildTab();
+ GodotSharpEditor.Instance.BottomPanel.ShowBuildTab();
}
- public static void RestartBuild(MonoBuildTab buildTab) => throw new NotImplementedException();
- public static void StopBuild(MonoBuildTab buildTab) => throw new NotImplementedException();
+ public static void RestartBuild(BuildTab buildTab) => throw new NotImplementedException();
+ public static void StopBuild(BuildTab buildTab) => throw new NotImplementedException();
- private static string GetLogFilePath(MonoBuildInfo buildInfo)
+ private static string GetLogFilePath(BuildInfo buildInfo)
{
return Path.Combine(buildInfo.LogsDirPath, MsBuildLogFileName);
}
- private static string GetIssuesFilePath(MonoBuildInfo buildInfo)
+ private static string GetIssuesFilePath(BuildInfo buildInfo)
{
return Path.Combine(buildInfo.LogsDirPath, MsBuildIssuesFileName);
}
@@ -71,7 +61,7 @@ namespace GodotTools
Godot.GD.Print(text);
}
- public static bool Build(MonoBuildInfo buildInfo)
+ public static bool Build(BuildInfo buildInfo)
{
if (BuildsInProgress.Contains(buildInfo))
throw new InvalidOperationException("A build is already in progress");
@@ -80,7 +70,7 @@ namespace GodotTools
try
{
- MonoBuildTab buildTab = GodotSharpEditor.Instance.MonoBottomPanel.GetBuildTabFor(buildInfo);
+ BuildTab buildTab = GodotSharpEditor.Instance.BottomPanel.GetBuildTabFor(buildInfo);
buildTab.OnBuildStart();
// Required in order to update the build tasks list
@@ -103,7 +93,7 @@ namespace GodotTools
if (exitCode != 0)
PrintVerbose($"MSBuild exited with code: {exitCode}. Log file: {GetLogFilePath(buildInfo)}");
- buildTab.OnBuildExit(exitCode == 0 ? MonoBuildTab.BuildResults.Success : MonoBuildTab.BuildResults.Error);
+ buildTab.OnBuildExit(exitCode == 0 ? BuildTab.BuildResults.Success : BuildTab.BuildResults.Error);
return exitCode == 0;
}
@@ -120,7 +110,7 @@ namespace GodotTools
}
}
- public static async Task<bool> BuildAsync(MonoBuildInfo buildInfo)
+ public static async Task<bool> BuildAsync(BuildInfo buildInfo)
{
if (BuildsInProgress.Contains(buildInfo))
throw new InvalidOperationException("A build is already in progress");
@@ -129,7 +119,7 @@ namespace GodotTools
try
{
- MonoBuildTab buildTab = GodotSharpEditor.Instance.MonoBottomPanel.GetBuildTabFor(buildInfo);
+ BuildTab buildTab = GodotSharpEditor.Instance.BottomPanel.GetBuildTabFor(buildInfo);
try
{
@@ -148,7 +138,7 @@ namespace GodotTools
if (exitCode != 0)
PrintVerbose($"MSBuild exited with code: {exitCode}. Log file: {GetLogFilePath(buildInfo)}");
- buildTab.OnBuildExit(exitCode == 0 ? MonoBuildTab.BuildResults.Success : MonoBuildTab.BuildResults.Error);
+ buildTab.OnBuildExit(exitCode == 0 ? BuildTab.BuildResults.Success : BuildTab.BuildResults.Error);
return exitCode == 0;
}
@@ -165,32 +155,6 @@ namespace GodotTools
}
}
- public static bool BuildApiSolution(string apiSlnDir, string config)
- {
- string apiSlnFile = Path.Combine(apiSlnDir, $"{ApiAssemblyNames.SolutionName}.sln");
-
- string coreApiAssemblyDir = Path.Combine(apiSlnDir, ApiAssemblyNames.Core, "bin", config);
- string coreApiAssemblyFile = Path.Combine(coreApiAssemblyDir, $"{ApiAssemblyNames.Core}.dll");
-
- string editorApiAssemblyDir = Path.Combine(apiSlnDir, ApiAssemblyNames.Editor, "bin", config);
- string editorApiAssemblyFile = Path.Combine(editorApiAssemblyDir, $"{ApiAssemblyNames.Editor}.dll");
-
- if (File.Exists(coreApiAssemblyFile) && File.Exists(editorApiAssemblyFile))
- return true; // The assemblies are in the output folder; assume the solution is already built
-
- var apiBuildInfo = new MonoBuildInfo(apiSlnFile, config);
-
- // TODO Replace this global NoWarn with '#pragma warning' directives on generated files,
- // once we start to actively document manually maintained C# classes
- apiBuildInfo.CustomProperties.Add("NoWarn=1591"); // Ignore missing documentation warnings
-
- if (Build(apiBuildInfo))
- return true;
-
- ShowBuildErrorDialog($"Failed to build {ApiAssemblyNames.SolutionName} solution.");
- return false;
- }
-
public static bool BuildProjectBlocking(string config, IEnumerable<string> godotDefines)
{
if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
@@ -201,13 +165,13 @@ namespace GodotTools
Internal.UpdateApiAssembliesFromPrebuilt();
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
- var buildTool = (BuildTool)editorSettings.GetSetting("mono/builds/build_tool");
+ var buildTool = (BuildTool) editorSettings.GetSetting("mono/builds/build_tool");
using (var pr = new EditorProgress("mono_project_debug_build", "Building project solution...", 1))
{
pr.Step("Building project solution", 0);
- var buildInfo = new MonoBuildInfo(GodotSharpDirs.ProjectSlnPath, config);
+ var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, config);
// Add Godot defines
string constants = buildTool == BuildTool.MsBuildVs ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
@@ -240,11 +204,28 @@ namespace GodotTools
string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor");
string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player");
- CSharpProject.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
+ CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
if (File.Exists(editorScriptsMetadataPath))
File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath);
+ var currentPlayRequest = GodotSharpEditor.Instance.GodotIdeManager.GodotIdeServer.CurrentPlayRequest;
+
+ if (currentPlayRequest != null)
+ {
+ if (currentPlayRequest.Value.HasDebugger)
+ {
+ // Set the environment variable that will tell the player to connect to the IDE debugger
+ // TODO: We should probably add a better way to do this
+ Environment.SetEnvironmentVariable("GODOT_MONO_DEBUGGER_AGENT",
+ "--debugger-agent=transport=dt_socket" +
+ $",address={currentPlayRequest.Value.DebuggerHost}:{currentPlayRequest.Value.DebuggerPort}" +
+ ",server=n");
+ }
+
+ return true; // Requested play from an external editor/IDE which already built the project
+ }
+
var godotDefines = new[]
{
Godot.OS.GetName(),
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
index 3a74fa2f66..807a20d9a1 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
@@ -7,7 +7,7 @@ using Path = System.IO.Path;
namespace GodotTools
{
- public class MonoBuildTab : VBoxContainer
+ public class BuildTab : VBoxContainer
{
public enum BuildResults
{
@@ -55,7 +55,7 @@ namespace GodotTools
}
}
- public MonoBuildInfo BuildInfo { get; private set; }
+ public BuildInfo BuildInfo { get; private set; }
private void _LoadIssuesFromFile(string csvFile)
{
@@ -199,7 +199,7 @@ namespace GodotTools
ErrorCount = 0;
UpdateIssuesList();
- GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this);
+ GodotSharpEditor.Instance.BottomPanel.RaiseBuildTab(this);
}
public void OnBuildExit(BuildResults result)
@@ -207,10 +207,10 @@ namespace GodotTools
BuildExited = true;
BuildResult = result;
- _LoadIssuesFromFile(Path.Combine(BuildInfo.LogsDirPath, GodotSharpBuilds.MsBuildIssuesFileName));
+ _LoadIssuesFromFile(Path.Combine(BuildInfo.LogsDirPath, BuildManager.MsBuildIssuesFileName));
UpdateIssuesList();
- GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this);
+ GodotSharpEditor.Instance.BottomPanel.RaiseBuildTab(this);
}
public void OnBuildExecFailed(string cause)
@@ -227,7 +227,7 @@ namespace GodotTools
UpdateIssuesList();
- GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this);
+ GodotSharpEditor.Instance.BottomPanel.RaiseBuildTab(this);
}
public void RestartBuild()
@@ -235,7 +235,7 @@ namespace GodotTools
if (!BuildExited)
throw new InvalidOperationException("Build already started");
- GodotSharpBuilds.RestartBuild(this);
+ BuildManager.RestartBuild(this);
}
public void StopBuild()
@@ -243,7 +243,7 @@ namespace GodotTools
if (!BuildExited)
throw new InvalidOperationException("Build is not in progress");
- GodotSharpBuilds.StopBuild(this);
+ BuildManager.StopBuild(this);
}
public override void _Ready()
@@ -255,11 +255,11 @@ namespace GodotTools
AddChild(issuesList);
}
- private MonoBuildTab()
+ private BuildTab()
{
}
- public MonoBuildTab(MonoBuildInfo buildInfo)
+ public BuildTab(BuildInfo buildInfo)
{
BuildInfo = buildInfo;
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
index 4535ed7247..c021a9051e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
@@ -9,7 +9,7 @@ using Directory = GodotTools.Utils.Directory;
namespace GodotTools
{
- public static class CSharpProject
+ public static class CsProjOperations
{
public static string GenerateGameProject(string dir, string name)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs b/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs
new file mode 100644
index 0000000000..4312ca0230
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs
@@ -0,0 +1,11 @@
+namespace GodotTools
+{
+ public enum ExternalEditorId
+ {
+ None,
+ VisualStudio, // TODO (Windows-only)
+ VisualStudioForMac, // Mac-only
+ MonoDevelop,
+ VsCode
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 9b5afb94a3..099c7fcb56 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -2,16 +2,18 @@ using Godot;
using GodotTools.Utils;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
+using GodotTools.Ides;
using GodotTools.Internals;
using GodotTools.ProjectEditor;
using static GodotTools.Internals.Globals;
using File = GodotTools.Utils.File;
-using Path = System.IO.Path;
using OS = GodotTools.Utils.OS;
namespace GodotTools
{
+ [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
public class GodotSharpEditor : EditorPlugin, ISerializationListener
{
private EditorSettings editorSettings;
@@ -24,12 +26,11 @@ namespace GodotTools
private ToolButton bottomPanelBtn;
- private MonoDevelopInstance monoDevelopInstance;
- private MonoDevelopInstance visualStudioForMacInstance;
+ public GodotIdeManager GodotIdeManager { get; private set; }
private WeakRef exportPluginWeak; // TODO Use WeakReference once we have proper serialization
- public MonoBottomPanel MonoBottomPanel { get; private set; }
+ public BottomPanel BottomPanel { get; private set; }
private bool CreateProjectSolution()
{
@@ -44,7 +45,7 @@ namespace GodotTools
if (name.Empty())
name = "UnnamedProject";
- string guid = CSharpProject.GenerateGameProject(path, name);
+ string guid = CsProjOperations.GenerateGameProject(path, name);
if (guid.Length > 0)
{
@@ -133,7 +134,7 @@ namespace GodotTools
return; // Failed to create solution
}
- Instance.MonoBottomPanel.BuildProjectPressed();
+ Instance.BottomPanel.BuildProjectPressed();
}
public override void _Notification(int what)
@@ -153,21 +154,12 @@ namespace GodotTools
}
}
- public enum MenuOptions
+ private enum MenuOptions
{
CreateSln,
AboutCSharp,
}
- public enum ExternalEditor
- {
- None,
- VisualStudio, // TODO (Windows-only)
- VisualStudioForMac, // Mac-only
- MonoDevelop,
- VsCode
- }
-
public void ShowErrorDialog(string message, string title = "Error")
{
errorDialog.WindowTitle = title;
@@ -184,11 +176,30 @@ namespace GodotTools
public Error OpenInExternalEditor(Script script, int line, int col)
{
- var editor = (ExternalEditor) editorSettings.GetSetting("mono/editor/external_editor");
+ var editor = (ExternalEditorId) editorSettings.GetSetting("mono/editor/external_editor");
switch (editor)
{
- case ExternalEditor.VsCode:
+ case ExternalEditorId.None:
+ // Tells the caller to fallback to the global external editor settings or the built-in editor
+ return Error.Unavailable;
+ case ExternalEditorId.VisualStudio:
+ throw new NotSupportedException();
+ case ExternalEditorId.VisualStudioForMac:
+ goto case ExternalEditorId.MonoDevelop;
+ case ExternalEditorId.MonoDevelop:
+ {
+ string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
+
+ if (line >= 0)
+ GodotIdeManager.SendOpenFile(scriptPath, line + 1, col);
+ else
+ GodotIdeManager.SendOpenFile(scriptPath);
+
+ break;
+ }
+
+ case ExternalEditorId.VsCode:
{
if (_vsCodePath.Empty() || !File.Exists(_vsCodePath))
{
@@ -273,47 +284,6 @@ namespace GodotTools
break;
}
- case ExternalEditor.VisualStudioForMac:
- goto case ExternalEditor.MonoDevelop;
- case ExternalEditor.MonoDevelop:
- {
- MonoDevelopInstance GetMonoDevelopInstance(string solutionPath)
- {
- if (OS.IsOSX() && editor == ExternalEditor.VisualStudioForMac)
- {
- if (visualStudioForMacInstance == null)
- visualStudioForMacInstance = new MonoDevelopInstance(solutionPath, MonoDevelopInstance.EditorId.VisualStudioForMac);
-
- return visualStudioForMacInstance;
- }
-
- if (monoDevelopInstance == null)
- monoDevelopInstance = new MonoDevelopInstance(solutionPath, MonoDevelopInstance.EditorId.MonoDevelop);
-
- return monoDevelopInstance;
- }
-
- string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
-
- if (line >= 0)
- scriptPath += $";{line + 1};{col}";
-
- try
- {
- GetMonoDevelopInstance(GodotSharpDirs.ProjectSlnPath).Execute(scriptPath);
- }
- catch (FileNotFoundException)
- {
- string editorName = editor == ExternalEditor.VisualStudioForMac ? "Visual Studio" : "MonoDevelop";
- GD.PushError($"Cannot find code editor: {editorName}");
- return Error.FileNotFound;
- }
-
- break;
- }
-
- case ExternalEditor.None:
- return Error.Unavailable;
default:
throw new ArgumentOutOfRangeException();
}
@@ -323,12 +293,12 @@ namespace GodotTools
public bool OverridesExternalEditor()
{
- return (ExternalEditor) editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditor.None;
+ return (ExternalEditorId) editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditorId.None;
}
public override bool Build()
{
- return GodotSharpBuilds.EditorBuildCallback();
+ return BuildManager.EditorBuildCallback();
}
public override void EnablePlugin()
@@ -347,9 +317,9 @@ namespace GodotTools
errorDialog = new AcceptDialog();
editorBaseControl.AddChild(errorDialog);
- MonoBottomPanel = new MonoBottomPanel();
+ BottomPanel = new BottomPanel();
- bottomPanelBtn = AddControlToBottomPanel(MonoBottomPanel, "Mono".TTR());
+ bottomPanelBtn = AddControlToBottomPanel(BottomPanel, "Mono".TTR());
AddChild(new HotReloadAssemblyWatcher {Name = "HotReloadAssemblyWatcher"});
@@ -407,7 +377,7 @@ namespace GodotTools
if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath))
{
// Make sure the existing project has Api assembly references configured correctly
- CSharpProject.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath);
+ CsProjOperations.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath);
}
else
{
@@ -427,25 +397,25 @@ namespace GodotTools
AddControlToContainer(CustomControlContainer.Toolbar, buildButton);
// External editor settings
- EditorDef("mono/editor/external_editor", ExternalEditor.None);
+ EditorDef("mono/editor/external_editor", ExternalEditorId.None);
string settingsHintStr = "Disabled";
if (OS.IsWindows())
{
- settingsHintStr += $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditor.VsCode}";
+ settingsHintStr += $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
}
else if (OS.IsOSX())
{
- settingsHintStr += $",Visual Studio:{(int) ExternalEditor.VisualStudioForMac}" +
- $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditor.VsCode}";
+ settingsHintStr += $",Visual Studio:{(int) ExternalEditorId.VisualStudioForMac}" +
+ $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
}
else if (OS.IsUnix())
{
- settingsHintStr += $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditor.VsCode}";
+ settingsHintStr += $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
}
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
@@ -461,7 +431,10 @@ namespace GodotTools
AddExportPlugin(exportPlugin);
exportPluginWeak = WeakRef(exportPlugin);
- GodotSharpBuilds.Initialize();
+ BuildManager.Initialize();
+
+ GodotIdeManager = new GodotIdeManager();
+ AddChild(GodotIdeManager);
}
protected override void Dispose(bool disposing)
@@ -478,6 +451,8 @@ namespace GodotTools
exportPluginWeak.Dispose();
}
+
+ GodotIdeManager?.Dispose();
}
public void OnBeforeSerialize()
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
index b80fe1fab7..aefc51545e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
@@ -65,14 +65,14 @@ namespace GodotTools
string buildConfig = isDebug ? "Debug" : "Release";
string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}");
- CSharpProject.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath);
+ CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath);
AddFile(scriptsMetadataPath, scriptsMetadataPath);
// Turn export features into defines
var godotDefines = features;
- if (!GodotSharpBuilds.BuildProjectBlocking(buildConfig, godotDefines))
+ if (!BuildManager.BuildProjectBlocking(buildConfig, godotDefines))
{
GD.PushError("Failed to build project");
return;
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
index 01e8c87d14..e2d576caef 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
@@ -39,26 +39,31 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Build\MsBuildFinder.cs" />
+ <Compile Include="ExternalEditorId.cs" />
+ <Compile Include="Ides\GodotIdeManager.cs" />
+ <Compile Include="Ides\GodotIdeServer.cs" />
+ <Compile Include="Ides\MonoDevelop\EditorId.cs" />
+ <Compile Include="Ides\MonoDevelop\Instance.cs" />
<Compile Include="Internals\BindingsGenerator.cs" />
<Compile Include="Internals\EditorProgress.cs" />
<Compile Include="Internals\GodotSharpDirs.cs" />
<Compile Include="Internals\Internal.cs" />
<Compile Include="Internals\ScriptClassParser.cs" />
<Compile Include="Internals\Globals.cs" />
- <Compile Include="MonoDevelopInstance.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Build\BuildSystem.cs" />
<Compile Include="Utils\Directory.cs" />
<Compile Include="Utils\File.cs" />
+ <Compile Include="Utils\NotifyAwaiter.cs" />
<Compile Include="Utils\OS.cs" />
<Compile Include="GodotSharpEditor.cs" />
- <Compile Include="GodotSharpBuilds.cs" />
+ <Compile Include="BuildManager.cs" />
<Compile Include="HotReloadAssemblyWatcher.cs" />
- <Compile Include="MonoBuildInfo.cs" />
- <Compile Include="MonoBuildTab.cs" />
- <Compile Include="MonoBottomPanel.cs" />
+ <Compile Include="BuildInfo.cs" />
+ <Compile Include="BuildTab.cs" />
+ <Compile Include="BottomPanel.cs" />
<Compile Include="GodotSharpExport.cs" />
- <Compile Include="CSharpProject.cs" />
+ <Compile Include="CsProjOperations.cs" />
<Compile Include="Utils\CollectionExtensions.cs" />
</ItemGroup>
<ItemGroup>
@@ -66,6 +71,10 @@
<Project>{6ce9a984-37b1-4f8a-8fe9-609f05f071b3}</Project>
<Name>GodotTools.BuildLogger</Name>
</ProjectReference>
+ <ProjectReference Include="..\GodotTools.IdeConnection\GodotTools.IdeConnection.csproj">
+ <Project>{92600954-25f0-4291-8e11-1fee9fc4be20}</Project>
+ <Name>GodotTools.IdeConnection</Name>
+ </ProjectReference>
<ProjectReference Include="..\GodotTools.ProjectEditor\GodotTools.ProjectEditor.csproj">
<Project>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</Project>
<Name>GodotTools.ProjectEditor</Name>
@@ -75,8 +84,5 @@
<Name>GodotTools.Core</Name>
</ProjectReference>
</ItemGroup>
- <ItemGroup>
- <Folder Include="Editor" />
- </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
new file mode 100644
index 0000000000..9e24138143
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
@@ -0,0 +1,166 @@
+using System;
+using System.IO;
+using Godot;
+using GodotTools.IdeConnection;
+using GodotTools.Internals;
+
+namespace GodotTools.Ides
+{
+ public class GodotIdeManager : Node, ISerializationListener
+ {
+ public GodotIdeServer GodotIdeServer { get; private set; }
+
+ private MonoDevelop.Instance monoDevelInstance;
+ private MonoDevelop.Instance vsForMacInstance;
+
+ private GodotIdeServer GetRunningServer()
+ {
+ if (GodotIdeServer != null && !GodotIdeServer.IsDisposed)
+ return GodotIdeServer;
+ StartServer();
+ return GodotIdeServer;
+ }
+
+ public override void _Ready()
+ {
+ StartServer();
+ }
+
+ public void OnBeforeSerialize()
+ {
+ GodotIdeServer?.Dispose();
+ }
+
+ public void OnAfterDeserialize()
+ {
+ StartServer();
+ }
+
+ private ILogger logger;
+
+ protected ILogger Logger
+ {
+ get => logger ?? (logger = new ConsoleLogger());
+ set => logger = value;
+ }
+
+ private void StartServer()
+ {
+ GodotIdeServer?.Dispose();
+ GodotIdeServer = new GodotIdeServer(LaunchIde,
+ OS.GetExecutablePath(),
+ ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir));
+
+ GodotIdeServer.Logger = Logger;
+
+ GodotIdeServer.StartServer();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ GodotIdeServer?.Dispose();
+ }
+
+ private void LaunchIde()
+ {
+ var editor = (ExternalEditorId) GodotSharpEditor.Instance.GetEditorInterface()
+ .GetEditorSettings().GetSetting("mono/editor/external_editor");
+
+ switch (editor)
+ {
+ case ExternalEditorId.None:
+ case ExternalEditorId.VisualStudio:
+ case ExternalEditorId.VsCode:
+ throw new NotSupportedException();
+ case ExternalEditorId.VisualStudioForMac:
+ goto case ExternalEditorId.MonoDevelop;
+ case ExternalEditorId.MonoDevelop:
+ {
+ MonoDevelop.Instance GetMonoDevelopInstance(string solutionPath)
+ {
+ if (Utils.OS.IsOSX() && editor == ExternalEditorId.VisualStudioForMac)
+ {
+ vsForMacInstance = vsForMacInstance ??
+ new MonoDevelop.Instance(solutionPath, MonoDevelop.EditorId.VisualStudioForMac);
+ return vsForMacInstance;
+ }
+
+ monoDevelInstance = monoDevelInstance ??
+ new MonoDevelop.Instance(solutionPath, MonoDevelop.EditorId.MonoDevelop);
+ return monoDevelInstance;
+ }
+
+ try
+ {
+ var instance = GetMonoDevelopInstance(GodotSharpDirs.ProjectSlnPath);
+
+ if (!instance.IsRunning)
+ instance.Execute();
+ }
+ catch (FileNotFoundException)
+ {
+ string editorName = editor == ExternalEditorId.VisualStudioForMac ? "Visual Studio" : "MonoDevelop";
+ GD.PushError($"Cannot find code editor: {editorName}");
+ }
+
+ break;
+ }
+
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private void WriteMessage(string id, params string[] arguments)
+ {
+ GetRunningServer().WriteMessage(new Message(id, arguments));
+ }
+
+ public void SendOpenFile(string file)
+ {
+ WriteMessage("OpenFile", file);
+ }
+
+ public void SendOpenFile(string file, int line)
+ {
+ WriteMessage("OpenFile", file, line.ToString());
+ }
+
+ public void SendOpenFile(string file, int line, int column)
+ {
+ WriteMessage("OpenFile", file, line.ToString(), column.ToString());
+ }
+
+ private class GodotLogger : ILogger
+ {
+ public void LogDebug(string message)
+ {
+ if (OS.IsStdoutVerbose())
+ Console.WriteLine(message);
+ }
+
+ public void LogInfo(string message)
+ {
+ if (OS.IsStdoutVerbose())
+ Console.WriteLine(message);
+ }
+
+ public void LogWarning(string message)
+ {
+ GD.PushWarning(message);
+ }
+
+ public void LogError(string message)
+ {
+ GD.PushError(message);
+ }
+
+ public void LogError(string message, Exception e)
+ {
+ GD.PushError(message + "\n" + e);
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
new file mode 100644
index 0000000000..d515254e65
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
@@ -0,0 +1,208 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using GodotTools.IdeConnection;
+using GodotTools.Internals;
+using GodotTools.Utils;
+using File = System.IO.File;
+using Thread = System.Threading.Thread;
+
+namespace GodotTools.Ides
+{
+ public class GodotIdeServer : GodotIdeBase
+ {
+ private readonly TcpListener listener;
+ private readonly FileStream metaFile;
+ private readonly Action launchIdeAction;
+ private readonly NotifyAwaiter<bool> clientConnectedAwaiter = new NotifyAwaiter<bool>();
+
+ private async Task<bool> AwaitClientConnected()
+ {
+ return await clientConnectedAwaiter.Reset();
+ }
+
+ public GodotIdeServer(Action launchIdeAction, string editorExecutablePath, string projectMetadataDir)
+ : base(projectMetadataDir)
+ {
+ messageHandlers = InitializeMessageHandlers();
+
+ this.launchIdeAction = launchIdeAction;
+
+ // The Godot editor's file system thread can keep the file open for writing, so we are forced to allow write sharing...
+ const FileShare metaFileShare = FileShare.ReadWrite;
+
+ metaFile = File.Open(MetaFilePath, FileMode.Create, FileAccess.Write, metaFileShare);
+
+ listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, port: 0));
+ listener.Start();
+
+ int port = ((IPEndPoint) listener.Server.LocalEndPoint).Port;
+ using (var metaFileWriter = new StreamWriter(metaFile, Encoding.UTF8))
+ {
+ metaFileWriter.WriteLine(port);
+ metaFileWriter.WriteLine(editorExecutablePath);
+ }
+
+ StartServer();
+ }
+
+ public void StartServer()
+ {
+ var serverThread = new Thread(RunServerThread) {Name = "Godot Ide Connection Server"};
+ serverThread.Start();
+ }
+
+ private void RunServerThread()
+ {
+ SynchronizationContext.SetSynchronizationContext(Godot.Dispatcher.SynchronizationContext);
+
+ try
+ {
+ while (!IsDisposed)
+ {
+ TcpClient tcpClient = listener.AcceptTcpClient();
+
+ Logger.LogInfo("Connection open with Ide Client");
+
+ lock (ConnectionLock)
+ {
+ Connection = new GodotIdeConnectionServer(tcpClient, HandleMessage);
+ Connection.Logger = Logger;
+ }
+
+ Connected += () => clientConnectedAwaiter.SetResult(true);
+
+ Connection.Start();
+ }
+ }
+ catch (Exception e)
+ {
+ if (!IsDisposed && !(e is SocketException se && se.SocketErrorCode == SocketError.Interrupted))
+ throw;
+ }
+ }
+
+ public async void WriteMessage(Message message)
+ {
+ async Task LaunchIde()
+ {
+ if (IsConnected)
+ return;
+
+ launchIdeAction();
+ await Task.WhenAny(Task.Delay(10000), AwaitClientConnected());
+ }
+
+ await LaunchIde();
+
+ if (!IsConnected)
+ {
+ Logger.LogError("Cannot write message: Godot Ide Server not connected");
+ return;
+ }
+
+ Connection.WriteMessage(message);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ listener?.Stop();
+
+ metaFile?.Dispose();
+
+ File.Delete(MetaFilePath);
+ }
+ }
+
+ protected virtual bool HandleMessage(Message message)
+ {
+ if (messageHandlers.TryGetValue(message.Id, out var action))
+ {
+ action(message.Arguments);
+ return true;
+ }
+
+ return false;
+ }
+
+ private readonly Dictionary<string, Action<string[]>> messageHandlers;
+
+ private Dictionary<string, Action<string[]>> InitializeMessageHandlers()
+ {
+ return new Dictionary<string, Action<string[]>>
+ {
+ ["Play"] = args =>
+ {
+ switch (args.Length)
+ {
+ case 0:
+ Play();
+ return;
+ case 2:
+ Play(debuggerHost: args[0], debuggerPort: int.Parse(args[1]));
+ return;
+ default:
+ throw new ArgumentException();
+ }
+ },
+ ["ReloadScripts"] = args => ReloadScripts()
+ };
+ }
+
+ private void DispatchToMainThread(Action action)
+ {
+ var d = new SendOrPostCallback(state => action());
+ Godot.Dispatcher.SynchronizationContext.Post(d, null);
+ }
+
+ private void Play()
+ {
+ DispatchToMainThread(() =>
+ {
+ CurrentPlayRequest = new PlayRequest();
+ Internal.EditorRunPlay();
+ CurrentPlayRequest = null;
+ });
+ }
+
+ private void Play(string debuggerHost, int debuggerPort)
+ {
+ DispatchToMainThread(() =>
+ {
+ CurrentPlayRequest = new PlayRequest(debuggerHost, debuggerPort);
+ Internal.EditorRunPlay();
+ CurrentPlayRequest = null;
+ });
+ }
+
+ private void ReloadScripts()
+ {
+ DispatchToMainThread(Internal.ScriptEditorDebugger_ReloadScripts);
+ }
+
+ public PlayRequest? CurrentPlayRequest { get; private set; }
+
+ public struct PlayRequest
+ {
+ public bool HasDebugger { get; }
+ public string DebuggerHost { get; }
+ public int DebuggerPort { get; }
+
+ public PlayRequest(string debuggerHost, int debuggerPort)
+ {
+ HasDebugger = true;
+ DebuggerHost = debuggerHost;
+ DebuggerPort = debuggerPort;
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/EditorId.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/EditorId.cs
new file mode 100644
index 0000000000..1dfc91d6d1
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/EditorId.cs
@@ -0,0 +1,8 @@
+namespace GodotTools.Ides.MonoDevelop
+{
+ public enum EditorId
+ {
+ MonoDevelop = 0,
+ VisualStudioForMac = 1
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
index 61a0a992ce..1fdccf5bbd 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
@@ -1,4 +1,3 @@
-using GodotTools.Core;
using System;
using System.IO;
using System.Collections.Generic;
@@ -6,22 +5,18 @@ using System.Diagnostics;
using GodotTools.Internals;
using GodotTools.Utils;
-namespace GodotTools
+namespace GodotTools.Ides.MonoDevelop
{
- public class MonoDevelopInstance
+ public class Instance
{
- public enum EditorId
- {
- MonoDevelop = 0,
- VisualStudioForMac = 1
- }
-
private readonly string solutionFile;
private readonly EditorId editorId;
private Process process;
- public void Execute(params string[] files)
+ public bool IsRunning => process != null && !process.HasExited;
+
+ public void Execute()
{
bool newWindow = process == null || process.HasExited;
@@ -29,7 +24,7 @@ namespace GodotTools
string command;
- if (Utils.OS.IsOSX())
+ if (OS.IsOSX())
{
string bundleId = BundleIds[editorId];
@@ -61,16 +56,6 @@ namespace GodotTools
if (newWindow)
args.Add("\"" + Path.GetFullPath(solutionFile) + "\"");
- foreach (var file in files)
- {
- int semicolonIndex = file.IndexOf(';');
-
- string filePath = semicolonIndex < 0 ? file : file.Substring(0, semicolonIndex);
- string cursor = semicolonIndex < 0 ? string.Empty : file.Substring(semicolonIndex);
-
- args.Add("\"" + Path.GetFullPath(filePath.NormalizePath()) + cursor + "\"");
- }
-
if (command == null)
throw new FileNotFoundException();
@@ -80,7 +65,7 @@ namespace GodotTools
{
FileName = command,
Arguments = string.Join(" ", args),
- UseShellExecute = false
+ UseShellExecute = true
});
}
else
@@ -89,14 +74,14 @@ namespace GodotTools
{
FileName = command,
Arguments = string.Join(" ", args),
- UseShellExecute = false
+ UseShellExecute = true
})?.Dispose();
}
}
- public MonoDevelopInstance(string solutionFile, EditorId editorId)
+ public Instance(string solutionFile, EditorId editorId)
{
- if (editorId == EditorId.VisualStudioForMac && !Utils.OS.IsOSX())
+ if (editorId == EditorId.VisualStudioForMac && !OS.IsOSX())
throw new InvalidOperationException($"{nameof(EditorId.VisualStudioForMac)} not supported on this platform");
this.solutionFile = solutionFile;
@@ -106,9 +91,9 @@ namespace GodotTools
private static readonly IReadOnlyDictionary<EditorId, string> ExecutableNames;
private static readonly IReadOnlyDictionary<EditorId, string> BundleIds;
- static MonoDevelopInstance()
+ static Instance()
{
- if (Utils.OS.IsOSX())
+ if (OS.IsOSX())
{
ExecutableNames = new Dictionary<EditorId, string>
{
@@ -122,7 +107,7 @@ namespace GodotTools
{EditorId.VisualStudioForMac, "com.microsoft.visual-studio"}
};
}
- else if (Utils.OS.IsWindows())
+ else if (OS.IsWindows())
{
ExecutableNames = new Dictionary<EditorId, string>
{
@@ -133,7 +118,7 @@ namespace GodotTools
{EditorId.MonoDevelop, "MonoDevelop.exe"}
};
}
- else if (Utils.OS.IsUnix())
+ else if (OS.IsUnix())
{
ExecutableNames = new Dictionary<EditorId, string>
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
index 9526dd3c6f..7783576910 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
@@ -46,6 +46,12 @@ namespace GodotTools.Internals
public static string MonoWindowsInstallRoot => internal_MonoWindowsInstallRoot();
+ public static void EditorRunPlay() => internal_EditorRunPlay();
+
+ public static void EditorRunStop() => internal_EditorRunStop();
+
+ public static void ScriptEditorDebugger_ReloadScripts() => internal_ScriptEditorDebugger_ReloadScripts();
+
// Internal Calls
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -95,5 +101,14 @@ namespace GodotTools.Internals
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_MonoWindowsInstallRoot();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void internal_EditorRunPlay();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void internal_EditorRunStop();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void internal_ScriptEditorDebugger_ReloadScripts();
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
index 288c65de74..e3c2c822a5 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
namespace GodotTools.Utils
{
@@ -17,5 +18,12 @@ namespace GodotTools.Utils
return orElse;
}
+
+ public static IEnumerable<string> EnumerateLines(this TextReader textReader)
+ {
+ string line;
+ while ((line = textReader.ReadLine()) != null)
+ yield return line;
+ }
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs
new file mode 100644
index 0000000000..a3490fa89f
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace GodotTools.Utils
+{
+ public sealed class NotifyAwaiter<T> : INotifyCompletion
+ {
+ private Action continuation;
+ private Exception exception;
+ private T result;
+
+ public bool IsCompleted { get; private set; }
+
+ public T GetResult()
+ {
+ if (exception != null)
+ throw exception;
+ return result;
+ }
+
+ public void OnCompleted(Action continuation)
+ {
+ if (this.continuation != null)
+ throw new InvalidOperationException("This awaiter has already been listened");
+ this.continuation = continuation;
+ }
+
+ public void SetResult(T result)
+ {
+ if (IsCompleted)
+ throw new InvalidOperationException("This awaiter is already completed");
+
+ IsCompleted = true;
+ this.result = result;
+
+ continuation?.Invoke();
+ }
+
+ public void SetException(Exception exception)
+ {
+ if (IsCompleted)
+ throw new InvalidOperationException("This awaiter is already completed");
+
+ IsCompleted = true;
+ this.exception = exception;
+
+ continuation?.Invoke();
+ }
+
+ public NotifyAwaiter<T> Reset()
+ {
+ continuation = null;
+ exception = null;
+ result = default;
+ IsCompleted = false;
+ return this;
+ }
+
+ public NotifyAwaiter<T> GetAwaiter()
+ {
+ return this;
+ }
+ }
+}
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index 0014aaca70..7db1090e2a 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -350,6 +350,21 @@ MonoString *godot_icall_Internal_MonoWindowsInstallRoot() {
#endif
}
+void godot_icall_Internal_EditorRunPlay() {
+ EditorNode::get_singleton()->run_play();
+}
+
+void godot_icall_Internal_EditorRunStop() {
+ EditorNode::get_singleton()->run_stop();
+}
+
+void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() {
+ ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
+ if (sed) {
+ sed->reload_scripts();
+ }
+}
+
MonoString *godot_icall_Utils_OS_GetPlatformName() {
String os_name = OS::get_singleton()->get_name();
return GDMonoMarshal::mono_string_from_godot(os_name);
@@ -414,7 +429,9 @@ void register_editor_internal_calls() {
mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", (void *)godot_icall_Internal_ScriptEditorEdit);
mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", (void *)godot_icall_Internal_EditorNodeShowScriptScreen);
mono_add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", (void *)godot_icall_Internal_GetScriptsMetadataOrNothing);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", (void *)godot_icall_Internal_MonoWindowsInstallRoot);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", (void *)godot_icall_Internal_EditorRunPlay);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", (void *)godot_icall_Internal_EditorRunStop);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebugger_ReloadScripts", (void *)godot_icall_Internal_ScriptEditorDebugger_ReloadScripts);
// Globals
mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorScale", (void *)godot_icall_Globals_EditorScale);
diff --git a/modules/mono/glue/Managed/Files/Basis.cs b/modules/mono/glue/Managed/Files/Basis.cs
index 421532b68f..0eb76e9c63 100644
--- a/modules/mono/glue/Managed/Files/Basis.cs
+++ b/modules/mono/glue/Managed/Files/Basis.cs
@@ -12,40 +12,6 @@ namespace Godot
[StructLayout(LayoutKind.Sequential)]
public struct Basis : IEquatable<Basis>
{
- private static readonly Basis identity = new Basis
- (
- 1f, 0f, 0f,
- 0f, 1f, 0f,
- 0f, 0f, 1f
- );
-
- private static readonly Basis[] orthoBases = {
- new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f),
- new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f),
- new Basis(-1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f),
- new Basis(0f, 1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f),
- new Basis(1f, 0f, 0f, 0f, 0f, -1f, 0f, 1f, 0f),
- new Basis(0f, 0f, 1f, 1f, 0f, 0f, 0f, 1f, 0f),
- new Basis(-1f, 0f, 0f, 0f, 0f, 1f, 0f, 1f, 0f),
- new Basis(0f, 0f, -1f, -1f, 0f, 0f, 0f, 1f, 0f),
- new Basis(1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, -1f),
- new Basis(0f, 1f, 0f, 1f, 0f, 0f, 0f, 0f, -1f),
- new Basis(-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, -1f),
- new Basis(0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, -1f),
- new Basis(1f, 0f, 0f, 0f, 0f, 1f, 0f, -1f, 0f),
- new Basis(0f, 0f, -1f, 1f, 0f, 0f, 0f, -1f, 0f),
- new Basis(-1f, 0f, 0f, 0f, 0f, -1f, 0f, -1f, 0f),
- new Basis(0f, 0f, 1f, -1f, 0f, 0f, 0f, -1f, 0f),
- new Basis(0f, 0f, 1f, 0f, 1f, 0f, -1f, 0f, 0f),
- new Basis(0f, -1f, 0f, 0f, 0f, 1f, -1f, 0f, 0f),
- new Basis(0f, 0f, -1f, 0f, -1f, 0f, -1f, 0f, 0f),
- new Basis(0f, 1f, 0f, 0f, 0f, -1f, -1f, 0f, 0f),
- new Basis(0f, 0f, 1f, 0f, -1f, 0f, 1f, 0f, 0f),
- new Basis(0f, 1f, 0f, 0f, 0f, 1f, 1f, 0f, 0f),
- new Basis(0f, 0f, -1f, 0f, 1f, 0f, 1f, 0f, 0f),
- new Basis(0f, -1f, 0f, 0f, 0f, -1f, 1f, 0f, 0f)
- };
-
// NOTE: x, y and z are public-only. Use Column0, Column1 and Column2 internally.
/// <summary>
@@ -64,7 +30,6 @@ namespace Godot
/// </summary>
public Vector3 y
{
-
get => Column1;
set => Column1 = value;
}
@@ -75,7 +40,6 @@ namespace Godot
/// </summary>
public Vector3 z
{
-
get => Column2;
set => Column2 = value;
}
@@ -115,8 +79,6 @@ namespace Godot
}
}
- public static Basis Identity => identity;
-
public Vector3 Scale
{
get
@@ -361,7 +323,7 @@ namespace Godot
for (int i = 0; i < 24; i++)
{
- if (orthoBases[i] == orth)
+ if (orth == _orthoBases[i])
return i;
}
@@ -531,6 +493,43 @@ namespace Godot
}
}
+ private static readonly Basis[] _orthoBases = {
+ new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f),
+ new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f),
+ new Basis(-1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f),
+ new Basis(0f, 1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f),
+ new Basis(1f, 0f, 0f, 0f, 0f, -1f, 0f, 1f, 0f),
+ new Basis(0f, 0f, 1f, 1f, 0f, 0f, 0f, 1f, 0f),
+ new Basis(-1f, 0f, 0f, 0f, 0f, 1f, 0f, 1f, 0f),
+ new Basis(0f, 0f, -1f, -1f, 0f, 0f, 0f, 1f, 0f),
+ new Basis(1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, -1f),
+ new Basis(0f, 1f, 0f, 1f, 0f, 0f, 0f, 0f, -1f),
+ new Basis(-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, -1f),
+ new Basis(0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, -1f),
+ new Basis(1f, 0f, 0f, 0f, 0f, 1f, 0f, -1f, 0f),
+ new Basis(0f, 0f, -1f, 1f, 0f, 0f, 0f, -1f, 0f),
+ new Basis(-1f, 0f, 0f, 0f, 0f, -1f, 0f, -1f, 0f),
+ new Basis(0f, 0f, 1f, -1f, 0f, 0f, 0f, -1f, 0f),
+ new Basis(0f, 0f, 1f, 0f, 1f, 0f, -1f, 0f, 0f),
+ new Basis(0f, -1f, 0f, 0f, 0f, 1f, -1f, 0f, 0f),
+ new Basis(0f, 0f, -1f, 0f, -1f, 0f, -1f, 0f, 0f),
+ new Basis(0f, 1f, 0f, 0f, 0f, -1f, -1f, 0f, 0f),
+ new Basis(0f, 0f, 1f, 0f, -1f, 0f, 1f, 0f, 0f),
+ new Basis(0f, 1f, 0f, 0f, 0f, 1f, 1f, 0f, 0f),
+ new Basis(0f, 0f, -1f, 0f, 1f, 0f, 1f, 0f, 0f),
+ new Basis(0f, -1f, 0f, 0f, 0f, -1f, 1f, 0f, 0f)
+ };
+
+ private static readonly Basis _identity = new Basis(1, 0, 0, 0, 1, 0, 0, 0, 1);
+ private static readonly Basis _flipX = new Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1);
+ private static readonly Basis _flipY = new Basis(1, 0, 0, 0, -1, 0, 0, 0, 1);
+ private static readonly Basis _flipZ = new Basis(1, 0, 0, 0, 1, 0, 0, 0, -1);
+
+ public static Basis Identity { get { return _identity; } }
+ public static Basis FlipX { get { return _flipX; } }
+ public static Basis FlipY { get { return _flipY; } }
+ public static Basis FlipZ { get { return _flipZ; } }
+
public Basis(Quat quat)
{
real_t s = 2.0f / quat.LengthSquared;
diff --git a/modules/mono/glue/Managed/Files/Dispatcher.cs b/modules/mono/glue/Managed/Files/Dispatcher.cs
new file mode 100644
index 0000000000..072e0f20ff
--- /dev/null
+++ b/modules/mono/glue/Managed/Files/Dispatcher.cs
@@ -0,0 +1,13 @@
+using System.Runtime.CompilerServices;
+
+namespace Godot
+{
+ public static class Dispatcher
+ {
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern GodotTaskScheduler godot_icall_DefaultGodotTaskScheduler();
+
+ public static GodotSynchronizationContext SynchronizationContext =>
+ godot_icall_DefaultGodotTaskScheduler().Context;
+ }
+}
diff --git a/modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs b/modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs
index e727781d63..4b5e3f8761 100644
--- a/modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs
+++ b/modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs
@@ -6,17 +6,16 @@ namespace Godot
{
public class GodotSynchronizationContext : SynchronizationContext
{
- private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> queue = new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
+ private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue = new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
public override void Post(SendOrPostCallback d, object state)
{
- queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state));
+ _queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state));
}
public void ExecutePendingContinuations()
{
- KeyValuePair<SendOrPostCallback, object> workItem;
- while (queue.TryTake(out workItem))
+ while (_queue.TryTake(out var workItem))
{
workItem.Key(workItem.Value);
}
diff --git a/modules/mono/glue/Managed/Files/GodotTaskScheduler.cs b/modules/mono/glue/Managed/Files/GodotTaskScheduler.cs
index 9a40fef5a9..8eaeea50dc 100644
--- a/modules/mono/glue/Managed/Files/GodotTaskScheduler.cs
+++ b/modules/mono/glue/Managed/Files/GodotTaskScheduler.cs
@@ -8,7 +8,7 @@ namespace Godot
{
public class GodotTaskScheduler : TaskScheduler
{
- private GodotSynchronizationContext Context { get; set; }
+ internal GodotSynchronizationContext Context { get; }
private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
public GodotTaskScheduler()
@@ -28,14 +28,10 @@ namespace Godot
protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
if (SynchronizationContext.Current != Context)
- {
return false;
- }
if (taskWasPreviouslyQueued)
- {
TryDequeue(task);
- }
return TryExecuteTask(task);
}
@@ -52,7 +48,8 @@ namespace Godot
{
lock (_tasks)
{
- return _tasks.ToArray();
+ foreach (Task task in _tasks)
+ yield return task;
}
}
diff --git a/modules/mono/glue/Managed/Managed.csproj b/modules/mono/glue/Managed/Managed.csproj
index 61f738922b..ad55fe9539 100644
--- a/modules/mono/glue/Managed/Managed.csproj
+++ b/modules/mono/glue/Managed/Managed.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -37,4 +37,4 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index 27fd715f60..8b9a1380d8 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -210,6 +210,10 @@ MonoString *godot_icall_GD_var2str(MonoObject *p_var) {
return GDMonoMarshal::mono_string_from_godot(vars);
}
+MonoObject *godot_icall_DefaultGodotTaskScheduler() {
+ return GDMonoUtils::mono_cache.task_scheduler_handle->get_target();
+}
+
void godot_register_gd_icalls() {
mono_add_internal_call("Godot.GD::godot_icall_GD_bytes2var", (void *)godot_icall_GD_bytes2var);
mono_add_internal_call("Godot.GD::godot_icall_GD_convert", (void *)godot_icall_GD_convert);
@@ -233,6 +237,9 @@ void godot_register_gd_icalls() {
mono_add_internal_call("Godot.GD::godot_icall_GD_type_exists", (void *)godot_icall_GD_type_exists);
mono_add_internal_call("Godot.GD::godot_icall_GD_var2bytes", (void *)godot_icall_GD_var2bytes);
mono_add_internal_call("Godot.GD::godot_icall_GD_var2str", (void *)godot_icall_GD_var2str);
+
+ // Dispatcher
+ mono_add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", (void *)godot_icall_DefaultGodotTaskScheduler);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/gd_glue.h b/modules/mono/glue/gd_glue.h
index d4e20e2887..a34c0bc50f 100644
--- a/modules/mono/glue/gd_glue.h
+++ b/modules/mono/glue/gd_glue.h
@@ -75,6 +75,8 @@ MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_object
MonoString *godot_icall_GD_var2str(MonoObject *p_var);
+MonoObject *godot_icall_DefaultGodotTaskScheduler();
+
// Register internal calls
void godot_register_gd_icalls();
diff --git a/modules/mono/icons/icon_c_#.svg b/modules/mono/icons/icon_c_#.svg
new file mode 100644
index 0000000000..69664ca553
--- /dev/null
+++ b/modules/mono/icons/icon_c_#.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path d="m6 1046.4c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3h1v-2h-1c-0.55228 0-1-0.4478-1-1 0-0.5523 0.44772-1 1-1h1v-2zm1-9-0.56445 2.2578c-0.23643 0.076-0.46689 0.1692-0.68945 0.2793l-1.9883-1.1933-1.4141 1.414 1.1953 1.9942c-0.11191 0.2211-0.20723 0.4502-0.28516 0.6855l-2.2539 0.5625v2h5.2715c-0.17677-0.3037-0.27041-0.6486-0.27148-1 9.6e-6 -1.1046 0.89543-2 2-2s2 0.8954 2 2c-4.817e-4 0.3512-0.093442 0.6961-0.26953 1h5.2695v-2l-2.2578-0.5645c-0.07594-0.2357-0.1693-0.4655-0.2793-0.6875l1.1934-1.9902-1.4141-1.414-1.9941 1.1953c-0.22113-0.1119-0.45028-0.2073-0.68555-0.2852l-0.5625-2.2539zm4 9c-0.71466-1e-4 -1.3751 0.3811-1.7324 1-0.35727 0.6188-0.35727 1.3812 0 2 0.35733 0.6189 1.0178 1.0001 1.7324 1h-2v2h2c0.71466 1e-4 1.3751-0.3811 1.7324-1 0.35727-0.6188 0.35727-1.3812 0-2-0.35733-0.6189-1.0178-1.0001-1.7324-1h2v-2z" fill="#e0e0e0"/>
+</g>
+</svg>
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index ee1ecf3be7..eed8812305 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -556,14 +556,14 @@ bool GDMono::_load_corlib_assembly() {
}
#ifdef TOOLS_ENABLED
-bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type) {
+bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type, const String &p_config) {
bool &api_assembly_out_of_sync = (p_api_type == APIAssembly::API_CORE) ?
GDMono::get_singleton()->core_api_assembly_out_of_sync :
GDMono::get_singleton()->editor_api_assembly_out_of_sync;
- String src_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
- String dst_dir = GodotSharpDirs::get_res_assemblies_dir();
+ String src_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
+ String dst_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config);
String assembly_name = p_api_type == APIAssembly::API_CORE ? CORE_API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME;
@@ -626,18 +626,28 @@ String GDMono::update_api_assemblies_from_prebuilt() {
if (!api_assembly_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path))
return String(); // No update needed
- print_verbose("Updating API assemblies");
+ const int CONFIGS_LEN = 2;
+ String configs[CONFIGS_LEN] = { String("Debug"), String("Release") };
- String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
- String prebuilt_core_dll_path = prebuilt_api_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
- String prebuilt_editor_dll_path = prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
+ for (int i = 0; i < CONFIGS_LEN; i++) {
+ String config = configs[i];
- if (!FileAccess::exists(prebuilt_core_dll_path) || !FileAccess::exists(prebuilt_editor_dll_path))
- return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ false);
+ print_verbose("Updating '" + config + "' API assemblies");
- // Copy the prebuilt Api
- if (!copy_prebuilt_api_assembly(APIAssembly::API_CORE) || !copy_prebuilt_api_assembly(APIAssembly::API_EDITOR))
- return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ true);
+ String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(config);
+ String prebuilt_core_dll_path = prebuilt_api_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
+ String prebuilt_editor_dll_path = prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
+
+ if (!FileAccess::exists(prebuilt_core_dll_path) || !FileAccess::exists(prebuilt_editor_dll_path)) {
+ return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ false);
+ }
+
+ // Copy the prebuilt Api
+ if (!copy_prebuilt_api_assembly(APIAssembly::API_CORE, config) ||
+ !copy_prebuilt_api_assembly(APIAssembly::API_EDITOR, config)) {
+ return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ true);
+ }
+ }
return String(); // Updated successfully
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index c5bcce4fa1..4f7d3791f7 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -165,7 +165,7 @@ public:
#endif
#ifdef TOOLS_ENABLED
- bool copy_prebuilt_api_assembly(APIAssembly::Type p_api_type);
+ bool copy_prebuilt_api_assembly(APIAssembly::Type p_api_type, const String &p_config);
String update_api_assemblies_from_prebuilt();
#endif
diff --git a/modules/opus/audio_stream_opus.cpp b/modules/opus/audio_stream_opus.cpp
index 615081d818..d3e8d3c9bb 100644
--- a/modules/opus/audio_stream_opus.cpp
+++ b/modules/opus/audio_stream_opus.cpp
@@ -287,8 +287,7 @@ int AudioStreamPlaybackOpus::mix(int16_t *p_buffer, int p_frames) {
int ret = op_read(opus_file, (opus_int16 *)p_buffer, todo * stream_channels, &current_section);
if (ret < 0) {
playing = false;
- ERR_EXPLAIN("Error reading Opus File: " + file);
- ERR_BREAK(ret < 0);
+ ERR_BREAK_MSG(ret < 0, "Error reading Opus file: " + file + ".");
} else if (ret == 0) { // end of song, reload?
op_free(opus_file);
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index 8b1f21d95d..cf6b396180 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -149,8 +149,7 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
format = Image::FORMAT_ETC;
break;
default:
- ERR_EXPLAIN("Unsupported format in PVR texture: " + itos(flags & 0xFF));
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Unsupported format in PVR texture: " + itos(flags & 0xFF) + ".");
}
w.release();
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index 64f4c169cb..9b0a55eae3 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -57,8 +57,7 @@ void image_decompress_squish(Image *p_image) {
} else if (p_image->get_format() == Image::FORMAT_RGTC_RG) {
squish_flags = squish::kBc5;
} else {
- ERR_EXPLAIN("Squish: Can't decompress unknown format: " + itos(p_image->get_format()));
- ERR_FAIL_COND(true);
+ ERR_FAIL_MSG("Squish: Can't decompress unknown format: " + itos(p_image->get_format()) + ".");
return;
}
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index b0cd648734..a2ef88d130 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -109,12 +109,10 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
float upscale = upsample ? 2.0 : 1.0;
int w = (int)(svg_image->width * p_scale * upscale);
- ERR_EXPLAIN(vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale)));
- ERR_FAIL_COND_V(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR);
+ ERR_FAIL_COND_V_MSG(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale)));
int h = (int)(svg_image->height * p_scale * upscale);
- ERR_EXPLAIN(vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale)));
- ERR_FAIL_COND_V(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR);
+ ERR_FAIL_COND_V_MSG(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale)));
PoolVector<uint8_t> dst_image;
dst_image.resize(w * h * 4);
diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h
index 4003fdc802..ee8479b1b4 100644
--- a/modules/tinyexr/image_loader_tinyexr.h
+++ b/modules/tinyexr/image_loader_tinyexr.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderTinyEXR : public ImageFormatLoader {
public:
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 4425565afa..3f8b2b1831 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -328,8 +328,7 @@ void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<Visual
if (Object::cast_to<VisualScriptFunction>(*p_node)) {
//the function indeed
- ERR_EXPLAIN("A function node already has been set here.");
- ERR_FAIL_COND(func.function_id >= 0);
+ ERR_FAIL_COND_MSG(func.function_id >= 0, "A function node has already been set here.");
func.function_id = p_id;
}
@@ -1917,8 +1916,7 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
if (!E) {
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- ERR_EXPLAIN("No VisualScriptFunction node in function!");
- ERR_FAIL_V(Variant());
+ ERR_FAIL_V_MSG(Variant(), "No VisualScriptFunction node in function.");
}
VisualScriptNodeInstance *node = E->get();
@@ -1974,8 +1972,7 @@ String VisualScriptInstance::to_string(bool *r_valid) {
if (ret.get_type() != Variant::STRING) {
if (r_valid)
*r_valid = false;
- ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
- ERR_FAIL_V(String());
+ ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
}
if (r_valid)
*r_valid = true;
@@ -2262,15 +2259,10 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
- if (instance_id && !ObjectDB::get_instance(instance_id)) {
- ERR_EXPLAIN("Resumed after yield, but class instance is gone");
- ERR_FAIL_V(Variant());
- }
- if (script_id && !ObjectDB::get_instance(script_id)) {
- ERR_EXPLAIN("Resumed after yield, but script is gone");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
+ ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
+
#endif
r_error.error = Variant::CallError::CALL_OK;
@@ -2329,15 +2321,10 @@ Variant VisualScriptFunctionState::resume(Array p_args) {
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
- if (instance_id && !ObjectDB::get_instance(instance_id)) {
- ERR_EXPLAIN("Resumed after yield, but class instance is gone");
- ERR_FAIL_V(Variant());
- }
- if (script_id && !ObjectDB::get_instance(script_id)) {
- ERR_EXPLAIN("Resumed after yield, but script is gone");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
+ ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
+
#endif
Variant::CallError r_error;
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
index 2f4a45f108..2f56e778b9 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp
@@ -116,8 +116,7 @@ int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_buffer, int p_frames) {
if (ret < 0) {
playing = false;
- ERR_EXPLAIN("Error reading OGG Vorbis File: " + file);
- ERR_BREAK(ret < 0);
+ ERR_BREAK_MSG(ret < 0, "Error reading OGG Vorbis file: " + file + ".");
} else if (ret == 0) { // end of song, reload?
ov_clear(&vf);
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index 3670edc9ea..fa3602ad27 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -53,8 +53,7 @@ public:
file = FileAccess::open(p_file, FileAccess::READ);
- ERR_EXPLAIN("Failed loading resource: '" + p_file + "';");
- ERR_FAIL_COND(!file);
+ ERR_FAIL_COND_MSG(!file, "Failed loading resource: '" + p_file + "'.");
}
~MkvReader() {
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 630c15f140..8986e49cf0 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -84,8 +84,7 @@ static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
ERR_FAIL_COND_V(r[0] != 'W' || r[1] != 'E' || r[2] != 'B' || r[3] != 'P', Ref<Image>());
WebPBitstreamFeatures features;
if (WebPGetFeatures(&r[4], size, &features) != VP8_STATUS_OK) {
- ERR_EXPLAIN("Error unpacking WEBP image:");
- ERR_FAIL_V(Ref<Image>());
+ ERR_FAIL_V_MSG(Ref<Image>(), "Error unpacking WEBP image.");
}
/*
diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h
index 0c4e54df09..5a5c038017 100644
--- a/modules/webp/image_loader_webp.h
+++ b/modules/webp/image_loader_webp.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderWEBP : public ImageFormatLoader {
public:
diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp
index 069918cc9c..996db35cba 100644
--- a/modules/webrtc/webrtc_data_channel_js.cpp
+++ b/modules/webrtc/webrtc_data_channel_js.cpp
@@ -68,10 +68,8 @@ void WebRTCDataChannelJS::_on_error() {
}
void WebRTCDataChannelJS::_on_message(uint8_t *p_data, uint32_t p_size, bool p_is_string) {
- if (in_buffer.space_left() < (int)(p_size + 5)) {
- ERR_EXPLAIN("Buffer full! Dropping data");
- ERR_FAIL();
- }
+
+ ERR_FAIL_COND_MSG(in_buffer.space_left() < (int)(p_size + 5), "Buffer full! Dropping data.");
uint8_t is_string = p_is_string ? 1 : 0;
in_buffer.write((uint8_t *)&p_size, 4);
diff --git a/modules/webrtc/webrtc_multiplayer.cpp b/modules/webrtc/webrtc_multiplayer.cpp
index 17dafff93a..a759b17b83 100644
--- a/modules/webrtc/webrtc_multiplayer.cpp
+++ b/modules/webrtc/webrtc_multiplayer.cpp
@@ -321,10 +321,8 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size)
if (target_peer > 0) {
E = peer_map.find(target_peer);
- if (!E) {
- ERR_EXPLAIN("Invalid Target Peer: " + itos(target_peer));
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
+ ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, "Invalid target peer: " + itos(target_peer) + ".");
+
ERR_FAIL_COND_V(E->value()->channels.size() <= ch, ERR_BUG);
ERR_FAIL_COND_V(!E->value()->channels[ch].is_valid(), ERR_BUG);
return E->value()->channels[ch]->put_packet(p_buffer, p_buffer_size);
diff --git a/modules/webrtc/webrtc_peer_connection_gdnative.cpp b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
index af98aa750a..5e9dcb5366 100644
--- a/modules/webrtc/webrtc_peer_connection_gdnative.cpp
+++ b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
@@ -51,13 +51,11 @@ Error WebRTCPeerConnectionGDNative::set_default_library(const godot_net_webrtc_l
WebRTCPeerConnection *WebRTCPeerConnectionGDNative::_create() {
WebRTCPeerConnectionGDNative *obj = memnew(WebRTCPeerConnectionGDNative);
- ERR_EXPLAIN("Default GDNative WebRTC implementation not defined.");
- ERR_FAIL_COND_V(!default_library, obj);
+ ERR_FAIL_COND_V_MSG(!default_library, obj, "Default GDNative WebRTC implementation not defined.");
// Call GDNative constructor
Error err = (Error)default_library->create_peer_connection(obj);
- ERR_EXPLAIN("GDNative default library constructor returned an error");
- ERR_FAIL_COND_V(err != OK, obj);
+ ERR_FAIL_COND_V_MSG(err != OK, obj, "GDNative default library constructor returned an error.");
return obj;
}
diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp
index a9f38f1a82..58d4c52688 100644
--- a/modules/websocket/emws_peer.cpp
+++ b/modules/websocket/emws_peer.cpp
@@ -131,14 +131,12 @@ void EMWSPeer::close(int p_code, String p_reason) {
IP_Address EMWSPeer::get_connected_host() const {
- ERR_EXPLAIN("Not supported in HTML5 export");
- ERR_FAIL_V(IP_Address());
+ ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export.");
};
uint16_t EMWSPeer::get_connected_port() const {
- ERR_EXPLAIN("Not supported in HTML5 export");
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "Not supported in HTML5 export.");
};
EMWSPeer::EMWSPeer() {
diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp
index e24cb850ec..62f09bfbf9 100644
--- a/modules/websocket/websocket_multiplayer_peer.cpp
+++ b/modules/websocket/websocket_multiplayer_peer.cpp
@@ -98,16 +98,14 @@ void WebSocketMultiplayerPeer::_bind_methods() {
//
int WebSocketMultiplayerPeer::get_available_packet_count() const {
- ERR_EXPLAIN("Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI.");
return _incoming_packets.size();
}
Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- ERR_EXPLAIN("Please use get_peer(ID).get_packet/var to communicate with peers when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).get_packet/var to communicate with peers when not using the MultiplayerAPI.");
r_buffer_size = 0;
@@ -127,8 +125,7 @@ Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buff
Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_EXPLAIN("Please use get_peer(ID).put_packet/var to communicate with peers when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).put_packet/var to communicate with peers when not using the MultiplayerAPI.");
PoolVector<uint8_t> buffer = _make_pkt(SYS_NONE, get_unique_id(), _target_peer, p_buffer, p_buffer_size);
@@ -160,8 +157,7 @@ void WebSocketMultiplayerPeer::set_target_peer(int p_target_peer) {
int WebSocketMultiplayerPeer::get_packet_peer() const {
- ERR_EXPLAIN("This function is not available when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(!_is_multiplayer, 1);
+ ERR_FAIL_COND_V_MSG(!_is_multiplayer, 1, "This function is not available when not using the MultiplayerAPI.");
ERR_FAIL_COND_V(_incoming_packets.size() == 0, 1);
return _incoming_packets.front()->get().source;
@@ -354,8 +350,7 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u
_peer_id = id;
break;
default:
- ERR_EXPLAIN("Invalid multiplayer message");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid multiplayer message.");
break;
}
}
diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp
index af75f2a320..cf2ad55b4a 100644
--- a/modules/websocket/wsl_client.cpp
+++ b/modules/websocket/wsl_client.cpp
@@ -53,8 +53,7 @@ void WSLClient::_do_handshake() {
// Header is too big
disconnect_from_host();
_on_error();
- ERR_EXPLAIN("Response headers too big");
- ERR_FAIL();
+ ERR_FAIL_MSG("Response headers too big.");
}
Error err = _connection->get_partial_data(&_resp_buf[_resp_pos], 1, read);
if (err == ERR_FILE_EOF) {
@@ -81,8 +80,7 @@ void WSLClient::_do_handshake() {
if (!_verify_headers(protocol)) {
disconnect_from_host();
_on_error();
- ERR_EXPLAIN("Invalid response headers");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid response headers.");
}
// Create peer.
WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData);
@@ -103,29 +101,18 @@ bool WSLClient::_verify_headers(String &r_protocol) {
String s = (char *)_resp_buf;
Vector<String> psa = s.split("\r\n");
int len = psa.size();
- if (len < 4) {
- ERR_EXPLAIN("Not enough response headers.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4.");
Vector<String> req = psa[0].split(" ", false);
- if (req.size() < 2) {
- ERR_EXPLAIN("Invalid protocol or status code.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code.");
+
// Wrong protocol
- if (req[0] != "HTTP/1.1" || req[1] != "101") {
- ERR_EXPLAIN("Invalid protocol or status code.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(req[0] != "HTTP/1.1" || req[1] != "101", false, "Invalid protocol or status code.");
Map<String, String> headers;
for (int i = 1; i < len; i++) {
Vector<String> header = psa[i].split(":", false, 1);
- if (header.size() != 2) {
- ERR_EXPLAIN("Invalid header -> " + psa[i]);
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i] + ".");
String name = header[0].to_lower();
String value = header[1].strip_edges();
if (headers.has(name))
@@ -251,8 +238,7 @@ void WSLClient::poll() {
if (_connection == _tcp) {
// Start SSL handshake
ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create());
- ERR_EXPLAIN("SSL is not available in this build");
- ERR_FAIL_COND(ssl.is_null());
+ ERR_FAIL_COND_MSG(ssl.is_null(), "SSL is not available in this build.");
ssl->set_blocking_handshake_enabled(false);
if (ssl->connect_to_stream(_tcp, verify_ssl, _host) != OK) {
disconnect_from_host();
@@ -332,8 +318,7 @@ uint16_t WSLClient::get_connected_port() const {
}
Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) {
- ERR_EXPLAIN("Buffers sizes can only be set before listening or connecting");
- ERR_FAIL_COND_V(_connection.is_valid(), FAILED);
+ ERR_FAIL_COND_V_MSG(_connection.is_valid(), FAILED, "Buffers sizes can only be set before listening or connecting.");
_in_buf_size = nearest_shift(p_in_buffer - 1) + 10;
_in_pkt_size = nearest_shift(p_in_packets - 1);
diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp
index 0d09a4d74e..1feae420b9 100644
--- a/modules/websocket/wsl_server.cpp
+++ b/modules/websocket/wsl_server.cpp
@@ -45,29 +45,18 @@ WSLServer::PendingPeer::PendingPeer() {
bool WSLServer::PendingPeer::_parse_request(const PoolStringArray p_protocols) {
Vector<String> psa = String((char *)req_buf).split("\r\n");
int len = psa.size();
- if (len < 4) {
- ERR_EXPLAIN("Not enough response headers.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4.");
Vector<String> req = psa[0].split(" ", false);
- if (req.size() < 2) {
- ERR_EXPLAIN("Invalid protocol or status code.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code.");
+
// Wrong protocol
- if (req[0] != "GET" || req[2] != "HTTP/1.1") {
- ERR_EXPLAIN("Invalid method or HTTP version.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", false, "Invalid method or HTTP version.");
Map<String, String> headers;
for (int i = 1; i < len; i++) {
Vector<String> header = psa[i].split(":", false, 1);
- if (header.size() != 2) {
- ERR_EXPLAIN("Invalid header -> " + psa[i]);
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i]);
String name = header[0].to_lower();
String value = header[1].strip_edges();
if (headers.has(name))
@@ -115,11 +104,7 @@ Error WSLServer::PendingPeer::do_handshake(PoolStringArray p_protocols) {
if (!has_request) {
int read = 0;
while (true) {
- if (req_pos >= WSL_MAX_HEADER_SIZE) {
- // Header is too big
- ERR_EXPLAIN("Response headers too big");
- ERR_FAIL_V(ERR_OUT_OF_MEMORY);
- }
+ ERR_FAIL_COND_V_MSG(req_pos >= WSL_MAX_HEADER_SIZE, ERR_OUT_OF_MEMORY, "Response headers too big.");
Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
if (err != OK) // Got an error
return FAILED;
@@ -277,8 +262,7 @@ void WSLServer::disconnect_peer(int p_peer_id, int p_code, String p_reason) {
}
Error WSLServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) {
- ERR_EXPLAIN("Buffers sizes can only be set before listening or connecting");
- ERR_FAIL_COND_V(_server->is_listening(), FAILED);
+ ERR_FAIL_COND_V_MSG(_server->is_listening(), FAILED, "Buffers sizes can only be set before listening or connecting.");
_in_buf_size = nearest_shift(p_in_buffer - 1) + 10;
_in_pkt_size = nearest_shift(p_in_packets - 1);
diff --git a/platform/SCsub b/platform/SCsub
index 20c89ae8c6..38bab59d74 100644
--- a/platform/SCsub
+++ b/platform/SCsub
@@ -29,4 +29,4 @@ with open_utf8('register_platform_apis.gen.cpp', 'w') as f:
env.add_source_files(env.platform_sources, 'register_platform_apis.gen.cpp')
lib = env.add_library('platform', env.platform_sources)
-env.Prepend(LIBS=lib)
+env.Prepend(LIBS=[lib])
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index dc0a63d171..16e49e8a38 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -32,6 +32,7 @@
#include "core/io/marshalls.h"
#include "core/io/zip_io.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/project_settings.h"
@@ -1398,8 +1399,9 @@ public:
return ERR_UNCONFIGURED;
}
- //export_temp
+ // Export_temp APK.
if (ep.step("Exporting APK", 0)) {
+ device_lock->unlock();
return ERR_SKIP;
}
@@ -1409,11 +1411,20 @@ public:
if (use_reverse)
p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST;
- String export_to = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk");
- Error err = export_project(p_preset, true, export_to, p_debug_flags);
- if (err) {
- device_lock->unlock();
- return err;
+ String tmp_export_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk");
+
+#define CLEANUP_AND_RETURN(m_err) \
+ { \
+ DirAccess::remove_file_or_error(tmp_export_path); \
+ device_lock->unlock(); \
+ return m_err; \
+ }
+
+ // Export to temporary APK before sending to device.
+ Error err = export_project(p_preset, true, tmp_export_path, p_debug_flags);
+
+ if (err != OK) {
+ CLEANUP_AND_RETURN(err);
}
List<String> args;
@@ -1425,7 +1436,7 @@ public:
if (remove_prev) {
if (ep.step("Uninstalling...", 1)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
print_line("Uninstalling previous version: " + devices[p_device].name);
@@ -1440,7 +1451,7 @@ public:
print_line("Installing to device (please wait...): " + devices[p_device].name);
if (ep.step("Installing to device (please wait...)", 2)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
args.clear();
@@ -1448,13 +1459,12 @@ public:
args.push_back(devices[p_device].id);
args.push_back("install");
args.push_back("-r");
- args.push_back(export_to);
+ args.push_back(tmp_export_path);
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
if (err || rv != 0) {
EditorNode::add_io_error("Could not install to device.");
- device_lock->unlock();
- return ERR_CANT_CREATE;
+ CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
if (use_remote) {
@@ -1508,7 +1518,7 @@ public:
}
if (ep.step("Running on Device...", 3)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
args.clear();
args.push_back("-s");
@@ -1528,11 +1538,11 @@ public:
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
if (err || rv != 0) {
EditorNode::add_io_error("Could not execute on device.");
- device_lock->unlock();
- return ERR_CANT_CREATE;
+ CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
- device_lock->unlock();
- return OK;
+
+ CLEANUP_AND_RETURN(OK);
+#undef CLEANUP_AND_RETURN
}
virtual Ref<Texture> get_run_icon() const {
@@ -2023,8 +2033,16 @@ public:
zlib_filefunc_def io2 = io;
FileAccess *dst_f = NULL;
io2.opaque = &dst_f;
- String unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned.apk");
- zipFile unaligned_apk = zipOpen2(unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2);
+
+ String tmp_unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned.apk");
+
+#define CLEANUP_AND_RETURN(m_err) \
+ { \
+ DirAccess::remove_file_or_error(tmp_unaligned_path); \
+ return m_err; \
+ }
+
+ zipFile unaligned_apk = zipOpen2(tmp_unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2);
bool use_32_fb = p_preset->get("graphics/32_bits_framebuffer");
bool immersive = p_preset->get("screen/immersive_mode");
@@ -2152,7 +2170,7 @@ public:
}
if (ep.step("Adding Files...", 1)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
Error err = OK;
Vector<String> cl = cmdline.strip_edges().split(" ");
@@ -2184,7 +2202,7 @@ public:
unzClose(pkg);
EditorNode::add_io_error("Could not write expansion package file: " + apkfname);
- return OK;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
cl.push_back("--use_apk_expansion");
@@ -2271,8 +2289,8 @@ public:
zipClose(unaligned_apk, NULL);
unzClose(pkg);
- if (err) {
- return err;
+ if (err != OK) {
+ CLEANUP_AND_RETURN(err);
}
if (_signed) {
@@ -2280,7 +2298,7 @@ public:
String jarsigner = EditorSettings::get_singleton()->get("export/android/jarsigner");
if (!FileAccess::exists(jarsigner)) {
EditorNode::add_io_error("'jarsigner' could not be found.\nPlease supply a path in the Editor Settings.\nThe resulting APK is unsigned.");
- return OK;
+ CLEANUP_AND_RETURN(OK);
}
String keystore;
@@ -2300,7 +2318,7 @@ public:
}
if (ep.step("Signing debug APK...", 103)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
} else {
@@ -2309,13 +2327,13 @@ public:
user = release_username;
if (ep.step("Signing release APK...", 103)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
}
if (!FileAccess::exists(keystore)) {
EditorNode::add_io_error("Could not find keystore, unable to export.");
- return ERR_FILE_CANT_OPEN;
+ CLEANUP_AND_RETURN(ERR_FILE_CANT_OPEN);
}
List<String> args;
@@ -2333,30 +2351,30 @@ public:
args.push_back(keystore);
args.push_back("-storepass");
args.push_back(password);
- args.push_back(unaligned_path);
+ args.push_back(tmp_unaligned_path);
args.push_back(user);
int retval;
OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval);
if (retval) {
EditorNode::add_io_error("'jarsigner' returned with error #" + itos(retval));
- return ERR_CANT_CREATE;
+ CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
if (ep.step("Verifying APK...", 104)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
args.clear();
args.push_back("-verify");
args.push_back("-keystore");
args.push_back(keystore);
- args.push_back(unaligned_path);
+ args.push_back(tmp_unaligned_path);
args.push_back("-verbose");
OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval);
if (retval) {
EditorNode::add_io_error("'jarsigner' verification of APK failed. Make sure to use a jarsigner from OpenJDK 8.");
- return ERR_CANT_CREATE;
+ CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
}
@@ -2365,14 +2383,14 @@ public:
static const int ZIP_ALIGNMENT = 4;
if (ep.step("Aligning APK...", 105)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
- unzFile tmp_unaligned = unzOpen2(unaligned_path.utf8().get_data(), &io);
+ unzFile tmp_unaligned = unzOpen2(tmp_unaligned_path.utf8().get_data(), &io);
if (!tmp_unaligned) {
- EditorNode::add_io_error("Could not find temp unaligned APK.");
- return ERR_FILE_NOT_FOUND;
+ EditorNode::add_io_error("Could not unzip temporary unaligned APK.");
+ CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
}
ret = unzGoToFirstFile(tmp_unaligned);
@@ -2442,7 +2460,7 @@ public:
zipClose(final_apk, NULL);
unzClose(tmp_unaligned);
- return OK;
+ CLEANUP_AND_RETURN(OK);
}
virtual void get_platform_features(List<String> *r_features) {
diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h
index 1e1c00ab39..0b6e1f4b4a 100644
--- a/platform/android/thread_jandroid.h
+++ b/platform/android/thread_jandroid.h
@@ -31,10 +31,6 @@
#ifndef THREAD_POSIX_H
#define THREAD_POSIX_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/os/thread.h"
#include <jni.h>
#include <pthread.h>
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index ac43392700..a0d6ac9214 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -141,3 +141,6 @@ def configure(env):
# TODO: Reevaluate usage of this setting now that engine.js manages engine runtime.
env.Append(LINKFLAGS=['-s', 'NO_EXIT_RUNTIME=1'])
+
+ #adding flag due to issue with emscripten 1.38.41 callMain method https://github.com/emscripten-core/emscripten/blob/incoming/ChangeLog.md#v13841-08072019
+ env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["callMain"]'])
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index c68b420c61..69dd038709 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -362,12 +362,21 @@ int EditorExportPlatformJavaScript::get_device_count() const {
Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) {
- String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_export.html");
+ String basepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export");
+ String path = basepath + ".html";
Error err = export_project(p_preset, true, path, p_debug_flags);
- if (err) {
+ if (err != OK) {
+ // Export generates several files, clean them up on failure.
+ DirAccess::remove_file_or_error(basepath + ".html");
+ DirAccess::remove_file_or_error(basepath + ".js");
+ DirAccess::remove_file_or_error(basepath + ".pck");
+ DirAccess::remove_file_or_error(basepath + ".png");
+ DirAccess::remove_file_or_error(basepath + ".wasm");
return err;
}
OS::get_singleton()->shell_open(String("file://") + path);
+ // FIXME: Find out how to clean up export files after running the successfully
+ // exported game. Might not be trivial.
return OK;
}
diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h
index e1aa038c61..c5951a570e 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/osx/dir_access_osx.h
@@ -41,9 +41,6 @@
#include "core/os/dir_access.h"
#include "drivers/unix/dir_access_unix.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class DirAccessOSX : public DirAccessUnix {
protected:
virtual String fix_unicode_name(const char *p_name) const;
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 8cabc45250..56b0a44dbc 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -29,9 +29,11 @@
/*************************************************************************/
#include "export.h"
+
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
#include "core/io/zip_io.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/project_settings.h"
@@ -244,13 +246,17 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
copy->resize(icon_infos[i].size, icon_infos[i].size);
if (icon_infos[i].is_png) {
- //encode png icon
+ // Encode PNG icon.
it->create_from_image(copy);
String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png");
ResourceSaver::save(path, it);
FileAccess *f = FileAccess::open(path, FileAccess::READ);
- ERR_FAIL_COND(!f);
+ if (!f) {
+ // Clean up generated file.
+ DirAccess::remove_file_or_error(path);
+ ERR_FAIL();
+ }
int ofs = data.size();
uint32_t len = f->get_len();
@@ -261,6 +267,10 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
len = BSWAP32(len);
copymem(&data.write[ofs], icon_infos[i].name, 4);
encode_uint32(len, &data.write[ofs + 4]);
+
+ // Clean up generated file.
+ DirAccess::remove_file_or_error(path);
+
} else {
PoolVector<uint8_t> src_data = copy->get_data();
@@ -561,7 +571,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
}
}
- //bleh?
}
if (data.size() > 0) {
@@ -687,7 +696,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
// Clean up temporary .app dir
OS::get_singleton()->move_to_trash(tmp_app_path_name);
- } else {
+
+ } else { // pck
String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck");
@@ -747,6 +757,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
zipCloseFileInZip(dst_pkg_zip);
}
}
+
+ // Clean up generated file.
+ DirAccess::remove_file_or_error(pack_path);
}
}
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index a83d5084ed..9cb2915701 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -51,9 +51,6 @@
#include <CoreVideo/CoreVideo.h>
#undef CursorShape
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class OS_OSX : public OS_Unix {
public:
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index dbdae6afb1..b8119288ff 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -47,9 +47,6 @@
#include "servers/visual_server.h"
#undef CursorShape
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class OS_Server : public OS_Unix {
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index 024e7f1916..662ee49935 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -34,6 +34,7 @@
#include "core/io/zip_io.h"
#include "core/math/crypto_core.h"
#include "core/object.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
#include "core/version.h"
@@ -133,8 +134,6 @@ class AppxPackager {
String progress_task;
FileAccess *package;
- String tmp_blockmap_file_path;
- String tmp_content_types_file_path;
Set<String> mime_types;
@@ -146,8 +145,8 @@ class AppxPackager {
String hash_block(const uint8_t *p_block_data, size_t p_block_len);
- void make_block_map();
- void make_content_types();
+ void make_block_map(const String &p_path);
+ void make_content_types(const String &p_path);
_FORCE_INLINE_ unsigned int buf_put_int16(uint16_t p_val, uint8_t *p_buf) {
for (int i = 0; i < 2; i++) {
@@ -208,9 +207,9 @@ String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len)
return String(base64);
}
-void AppxPackager::make_block_map() {
+void AppxPackager::make_block_map(const String &p_path) {
- FileAccess *tmp_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::WRITE);
+ FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE);
tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
tmp_file->store_string("<BlockMap xmlns=\"http://schemas.microsoft.com/appx/2010/blockmap\" HashMethod=\"http://www.w3.org/2001/04/xmlenc#sha256\">");
@@ -253,9 +252,9 @@ String AppxPackager::content_type(String p_extension) {
return "application/octet-stream";
}
-void AppxPackager::make_content_types() {
+void AppxPackager::make_content_types(const String &p_path) {
- FileAccess *tmp_file = FileAccess::open(tmp_content_types_file_path, FileAccess::WRITE);
+ FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE);
tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
tmp_file->store_string("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">");
@@ -458,8 +457,6 @@ void AppxPackager::init(FileAccess *p_fa) {
package = p_fa;
central_dir_offset = 0;
end_of_central_dir_offset = 0;
- tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml");
- tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml");
}
Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) {
@@ -591,7 +588,9 @@ void AppxPackager::finish() {
// Create and add block map file
EditorNode::progress_task_step("export", "Creating block map...", 4);
- make_block_map();
+ const String &tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml");
+ make_block_map(tmp_blockmap_file_path);
+
FileAccess *blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ);
Vector<uint8_t> blockmap_buffer;
blockmap_buffer.resize(blockmap_file->get_len());
@@ -604,8 +603,11 @@ void AppxPackager::finish() {
memdelete(blockmap_file);
// Add content types
+
EditorNode::progress_task_step("export", "Setting content types...", 5);
- make_content_types();
+
+ const String &tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml");
+ make_content_types(tmp_content_types_file_path);
FileAccess *types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ);
Vector<uint8_t> types_buffer;
@@ -618,6 +620,10 @@ void AppxPackager::finish() {
types_file->close();
memdelete(types_file);
+ // Cleanup generated files.
+ DirAccess::remove_file_or_error(tmp_blockmap_file_path);
+ DirAccess::remove_file_or_error(tmp_content_types_file_path);
+
// Pre-process central directory before signing
for (int i = 0; i < file_metadata.size(); i++) {
store_central_dir_header(file_metadata[i]);
@@ -909,7 +915,8 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
if (err != OK) {
String err_string = "Couldn't open temp logo file.";
-
+ // Cleanup generated file.
+ DirAccess::remove_file_or_error(tmp_path);
EditorNode::add_io_error(err_string);
ERR_FAIL_V_MSG(data, err_string);
}
@@ -919,29 +926,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
f->close();
memdelete(f);
-
- // Delete temp file
- DirAccess *dir = DirAccess::open(tmp_path.get_base_dir(), &err);
-
- if (err != OK) {
-
- String err_string = "Couldn't open temp path to remove temp logo file.";
-
- EditorNode::add_io_error(err_string);
- ERR_FAIL_V_MSG(data, err_string);
- }
-
- err = dir->remove(tmp_path);
-
- memdelete(dir);
-
- if (err != OK) {
-
- String err_string = "Couldn't remove temp logo file.";
-
- EditorNode::add_io_error(err_string);
- ERR_FAIL_V_MSG(data, err_string);
- }
+ DirAccess::remove_file_or_error(tmp_path);
return data;
}
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index b7a7248f19..370cab6a9b 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -50,9 +50,6 @@
#include <stdio.h>
#include <windows.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class OS_UWP : public OS {
public:
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index ce55328173..915d025e3b 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -56,10 +56,6 @@
#include <windows.h>
#include <windowsx.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef struct {
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h
index 46420df48b..095ce2154b 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/x11/context_gl_x11.h
@@ -31,9 +31,6 @@
#ifndef CONTEXT_GL_X11_H
#define CONTEXT_GL_X11_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
#ifdef X11_ENABLED
#if defined(OPENGL_ENABLED)
diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h
index 853fe7954a..4e25d6a6ed 100644
--- a/platform/x11/key_mapping_x11.h
+++ b/platform/x11/key_mapping_x11.h
@@ -31,9 +31,6 @@
#ifndef KEY_MAPPING_X11_H
#define KEY_MAPPING_X11_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
#include <X11/XF86keysym.h>
#include <X11/Xlib.h>
#define XK_MISCELLANY
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index a4c22cf08a..e6c2effacf 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -77,9 +77,6 @@ typedef struct _xrr_monitor_info {
} xrr_monitor_info;
#undef CursorShape
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class OS_X11 : public OS_Unix {
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 1cd22df9e7..da668664b9 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -35,10 +35,6 @@
#include "scene/2d/node_2d.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CPUParticles2D : public Node2D {
private:
GDCLASS(CPUParticles2D, Node2D);
diff --git a/scene/3d/camera.h b/scene/3d/camera.h
index 6460f17e85..22223880c1 100644
--- a/scene/3d/camera.h
+++ b/scene/3d/camera.h
@@ -35,9 +35,7 @@
#include "scene/3d/spatial_velocity_tracker.h"
#include "scene/main/viewport.h"
#include "scene/resources/environment.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Camera : public Spatial {
GDCLASS(Camera, Spatial);
diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h
index 71de56f59e..66b37f359a 100644
--- a/scene/3d/cpu_particles.h
+++ b/scene/3d/cpu_particles.h
@@ -34,10 +34,6 @@
#include "core/rid.h"
#include "scene/3d/visual_instance.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CPUParticles : public GeometryInstance {
private:
GDCLASS(CPUParticles, GeometryInstance);
diff --git a/scene/3d/light.h b/scene/3d/light.h
index 5d365758b5..cc8675ead1 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -35,10 +35,6 @@
#include "scene/resources/texture.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Light : public VisualInstance {
GDCLASS(Light, VisualInstance);
diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h
index 022ef15aad..8b690b0c21 100644
--- a/scene/3d/mesh_instance.h
+++ b/scene/3d/mesh_instance.h
@@ -34,9 +34,6 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/mesh.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class MeshInstance : public GeometryInstance {
GDCLASS(MeshInstance, GeometryInstance);
diff --git a/scene/3d/multimesh_instance.h b/scene/3d/multimesh_instance.h
index 8f41aa8fd2..ca69c73251 100644
--- a/scene/3d/multimesh_instance.h
+++ b/scene/3d/multimesh_instance.h
@@ -34,10 +34,6 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/multimesh.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MultiMeshInstance : public GeometryInstance {
GDCLASS(MultiMeshInstance, GeometryInstance);
diff --git a/scene/3d/particles.h b/scene/3d/particles.h
index 42c68010db..391491e8b8 100644
--- a/scene/3d/particles.h
+++ b/scene/3d/particles.h
@@ -35,10 +35,6 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/material.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Particles : public GeometryInstance {
private:
GDCLASS(Particles, GeometryInstance);
diff --git a/scene/3d/portal.h b/scene/3d/portal.h
index f053867917..04af3a750c 100644
--- a/scene/3d/portal.h
+++ b/scene/3d/portal.h
@@ -32,9 +32,6 @@
#define PORTAL_H
#include "scene/3d/visual_instance.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
/* Portal Logic:
If a portal is placed next (very close to) a similar, opposing portal, they automatically connect,
diff --git a/scene/3d/room_instance.h b/scene/3d/room_instance.h
index 9ee140d522..01efde53c9 100644
--- a/scene/3d/room_instance.h
+++ b/scene/3d/room_instance.h
@@ -34,10 +34,6 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/room.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
/* RoomInstance Logic:
a) Instances that belong to the room are drawn only if the room is visible (seen through portal, or player inside)
b) Instances that don't belong to any room are considered to belong to the root room (RID empty)
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 5f43b3c6c3..5b55dffbc8 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -34,10 +34,6 @@
#include "core/rid.h"
#include "scene/3d/spatial.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifndef _3D_DISABLED
typedef int BoneId;
diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h
index 18a4a5b54d..eea2696767 100644
--- a/scene/3d/spatial.h
+++ b/scene/3d/spatial.h
@@ -34,10 +34,6 @@
#include "scene/main/node.h"
#include "scene/main/scene_tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class SpatialGizmo : public Reference {
GDCLASS(SpatialGizmo, Reference);
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index 3b924e0454..63d15680aa 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -35,9 +35,7 @@
#include "core/rid.h"
#include "scene/3d/spatial.h"
#include "scene/resources/material.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class VisualInstance : public Spatial {
GDCLASS(VisualInstance, Spatial);
diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h
index bf36a0a532..656e16371f 100644
--- a/scene/3d/world_environment.h
+++ b/scene/3d/world_environment.h
@@ -33,10 +33,6 @@
#include "scene/3d/spatial.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class WorldEnvironment : public Node {
GDCLASS(WorldEnvironment, Node);
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index f3d38110c6..320fd2084c 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -35,9 +35,6 @@
#include "scene/3d/skeleton.h"
#include "scene/3d/spatial.h"
#include "scene/resources/animation.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
#ifdef TOOLS_ENABLED
// To save/restore animated values
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index ffccdd69d6..2773f024df 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -32,9 +32,6 @@
#define BASE_BUTTON_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ButtonGroup;
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 6ba3475e5a..370809060e 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -32,9 +32,6 @@
#define BUTTON_H
#include "scene/gui/base_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Button : public BaseButton {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index eae889a667..7305b3ce93 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -38,9 +38,6 @@
#include "scene/main/node.h"
#include "scene/main/timer.h"
#include "scene/resources/theme.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Viewport;
class Label;
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index c1a7f26a85..1a0350ba18 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -37,9 +37,6 @@
#include "scene/gui/panel.h"
#include "scene/gui/popup.h"
#include "scene/gui/texture_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class WindowDialog : public Popup {
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 191af5fef3..4fd6d0d13c 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -38,9 +38,7 @@
#include "scene/gui/option_button.h"
#include "scene/gui/tool_button.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class FileDialog : public ConfirmationDialog {
GDCLASS(FileDialog, ConfirmationDialog);
diff --git a/scene/gui/label.h b/scene/gui/label.h
index 561c42ef9e..2cc55a47ef 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -32,9 +32,7 @@
#define LABEL_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Label : public Control {
GDCLASS(Label, Control);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 60a74066a4..4a763844f8 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1368,18 +1368,28 @@ void LineEdit::set_editable(bool p_editable) {
// Reorganize context menu.
menu->clear();
- if (editable)
+
+ if (editable) {
+ menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
+ menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
+ }
+
+ if (editable) {
+ menu->add_separator();
menu->add_item(RTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X);
+ }
+
menu->add_item(RTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C);
- if (editable)
+
+ if (editable) {
menu->add_item(RTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V);
+ }
+
menu->add_separator();
menu->add_item(RTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A);
+
if (editable) {
menu->add_item(RTR("Clear"), MENU_CLEAR);
- menu->add_separator();
- menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
- menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
}
update();
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 3002f6f637..1d33f7d4ce 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -34,9 +34,6 @@
#include "scene/gui/control.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class LineEdit : public Control {
GDCLASS(LineEdit, Control);
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 42e909d991..5448ff13f2 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -33,9 +33,7 @@
#include "scene/gui/button.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class MenuButton : public Button {
GDCLASS(MenuButton, Button);
diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h
index ac17e52fc1..f31a09a482 100644
--- a/scene/gui/nine_patch_rect.h
+++ b/scene/gui/nine_patch_rect.h
@@ -32,9 +32,7 @@
#define NINE_PATCH_RECT_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class NinePatchRect : public Control {
GDCLASS(NinePatchRect, Control);
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 51d5fd6947..7210708042 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -33,9 +33,7 @@
#include "scene/gui/button.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class OptionButton : public Button {
GDCLASS(OptionButton, Button);
diff --git a/scene/gui/panel.h b/scene/gui/panel.h
index f8d15e4261..84bf6e75f5 100644
--- a/scene/gui/panel.h
+++ b/scene/gui/panel.h
@@ -32,9 +32,7 @@
#define PANEL_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Panel : public Control {
GDCLASS(Panel, Control);
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 3e003af396..32380b6457 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -74,7 +74,7 @@ void Popup::_fix_size() {
Point2 pos = get_global_position();
Size2 size = get_size() * get_scale();
- Point2 window_size = get_viewport_rect().size;
+ Point2 window_size = get_viewport_rect().size - get_viewport_transform().get_origin();
if (pos.x + size.width > window_size.width)
pos.x = window_size.width - size.width;
@@ -207,6 +207,7 @@ bool Popup::is_exclusive() const {
void Popup::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_as_minsize"), &Popup::set_as_minsize);
ClassDB::bind_method(D_METHOD("popup_centered", "size"), &Popup::popup_centered, DEFVAL(Size2()));
ClassDB::bind_method(D_METHOD("popup_centered_ratio", "ratio"), &Popup::popup_centered_ratio, DEFVAL(0.75));
ClassDB::bind_method(D_METHOD("popup_centered_minsize", "minsize"), &Popup::popup_centered_minsize, DEFVAL(Size2()));
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index d6d96dfe64..925760984e 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -33,9 +33,6 @@
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Popup : public Control {
GDCLASS(Popup, Control);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index babdd21281..8bfe8fc607 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -33,10 +33,6 @@
#include "scene/gui/popup.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class PopupMenu : public Popup {
GDCLASS(PopupMenu, Popup);
diff --git a/scene/gui/range.h b/scene/gui/range.h
index cf0add8c89..8ce450f8fc 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -32,9 +32,7 @@
#define RANGE_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Range : public Control {
GDCLASS(Range, Control);
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index 5ceabfc06b..cbcee1dae3 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -33,10 +33,6 @@
#include "scene/gui/range.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ScrollBar : public Range {
GDCLASS(ScrollBar, Range);
diff --git a/scene/gui/separator.h b/scene/gui/separator.h
index 54ad9b5bb5..89039f3112 100644
--- a/scene/gui/separator.h
+++ b/scene/gui/separator.h
@@ -31,10 +31,6 @@
#ifndef SEPARATOR_H
#define SEPARATOR_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "scene/gui/control.h"
class Separator : public Control {
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index db277d3705..6ada0cba97 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -170,6 +170,10 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
void SpinBox::_line_edit_focus_exit() {
+ // discontinue because the focus_exit was caused by right-click context menu
+ if (line_edit->get_menu()->is_visible())
+ return;
+
_text_entered(line_edit->get_text());
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index ff0c723141..6e5f8de3b5 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -4450,18 +4450,28 @@ void TextEdit::set_readonly(bool p_readonly) {
// Reorganize context menu.
menu->clear();
- if (!readonly)
+
+ if (!readonly) {
+ menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
+ menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
+ }
+
+ if (!readonly) {
+ menu->add_separator();
menu->add_item(RTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X);
+ }
+
menu->add_item(RTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C);
- if (!readonly)
+
+ if (!readonly) {
menu->add_item(RTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V);
+ }
+
menu->add_separator();
menu->add_item(RTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A);
+
if (!readonly) {
menu->add_item(RTR("Clear"), MENU_CLEAR);
- menu->add_separator();
- menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
- menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
}
update();
@@ -6592,8 +6602,6 @@ TextEdit::TextEdit() {
indent_size = 4;
text.set_indent_size(indent_size);
text.clear();
- //text.insert(1,"Mongolia...");
- //text.insert(2,"PAIS GENEROSO!!");
text.set_color_regions(&color_regions);
h_scroll = memnew(HScrollBar);
diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h
index 3ab35324e5..1c5bd9d99c 100644
--- a/scene/gui/texture_rect.h
+++ b/scene/gui/texture_rect.h
@@ -32,9 +32,7 @@
#define TEXTURE_FRAME_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class TextureRect : public Control {
GDCLASS(TextureRect, Control);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index b6cdab766f..b57923e24b 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -37,10 +37,6 @@
#include "scene/gui/scroll_bar.h"
#include "scene/gui/slider.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Tree;
class TreeItem : public Object {
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 98f2fe5e35..afb653e242 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -39,10 +39,6 @@
#include "scene/resources/world.h"
#include "scene/resources/world_2d.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class PackedScene;
class Node;
class Viewport;
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index b7160d5139..6393785b22 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -36,9 +36,6 @@
#include "scene/resources/texture.h"
#include "scene/resources/world_2d.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Camera;
class Camera2D;
diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h
index 3645f88807..b551ad2ac4 100644
--- a/scene/register_scene_types.h
+++ b/scene/register_scene_types.h
@@ -31,10 +31,6 @@
#ifndef REGISTER_SCENE_TYPES_H
#define REGISTER_SCENE_TYPES_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
void register_scene_types();
void unregister_scene_types();
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 6fff77d746..d59dfab2c8 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -32,9 +32,7 @@
#define ANIMATION_H
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Animation : public Resource {
GDCLASS(Animation, Resource);
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index cbf0cc1b79..e7d80ffb3d 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -32,9 +32,6 @@
#define DEFAULT_THEME_H
#include "scene/resources/theme.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(bool p_hidpi, Ref<Font> p_font);
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 436ed43c42..9b99b85d22 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -34,9 +34,6 @@
#include "core/map.h"
#include "core/resource.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Font : public Resource {
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 17e52527b3..4c368b3f8b 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -37,9 +37,6 @@
#include "scene/resources/texture.h"
#include "servers/visual/shader_language.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Material : public Resource {
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index b38791b9a6..6b6ee8a209 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -37,9 +37,6 @@
#include "scene/resources/material.h"
#include "scene/resources/shape.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Mesh : public Resource {
GDCLASS(Mesh, Resource);
diff --git a/scene/resources/room.h b/scene/resources/room.h
index 8990056f46..2c53ea1aed 100644
--- a/scene/resources/room.h
+++ b/scene/resources/room.h
@@ -33,9 +33,6 @@
#include "core/math/bsp_tree.h"
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
// FIXME: left for reference but will be removed when portals are reimplemented using Area
#if 0
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index c3965fe076..d02e107480 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -34,9 +34,7 @@
#include "core/resource.h"
#include "scene/resources/texture.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class CanvasItem;
class StyleBox : public Resource {
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index eb7a9ff25c..e535f7544a 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -42,10 +42,6 @@
#include "servers/camera_server.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Texture : public Resource {
GDCLASS(Texture, Resource);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index d27180e9eb..187694de65 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -38,9 +38,6 @@
#include "scene/resources/style_box.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Theme : public Resource {
GDCLASS(Theme, Resource);
diff --git a/servers/physics/gjk_epa.h b/servers/physics/gjk_epa.h
index 0b7885c9a5..d3fa192804 100644
--- a/servers/physics/gjk_epa.h
+++ b/servers/physics/gjk_epa.h
@@ -31,11 +31,8 @@
#ifndef GJK_EPA_H
#define GJK_EPA_H
-#include "shape_sw.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
#include "collision_solver_sw.h"
+#include "shape_sw.h"
bool gjk_epa_calculate_penetration(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, CollisionSolverSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false);
bool gjk_epa_calculate_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B);
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 5f39d3ff49..1dd6699851 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -3862,14 +3862,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
return ERR_PARSE_ERROR;
}
+ decl.size = ((uint32_t)tk.constant);
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
return ERR_PARSE_ERROR;
}
-
- decl.size = ((uint32_t)tk.constant);
var.array_size = decl.size;
}
@@ -4022,6 +4021,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
_set_error("Expected array initialization");
return ERR_PARSE_ERROR;
}
+ if (is_const) {
+ _set_error("Expected initialization of constant");
+ return ERR_PARSE_ERROR;
+ }
}
node->declarations.push_back(decl);
@@ -4051,6 +4054,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
tk = _get_token();
node->declarations.push_back(decl);
} else {
+ if (is_const) {
+ _set_error("Expected initialization of constant");
+ return ERR_PARSE_ERROR;
+ }
+
VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>();
node->datatype = type;
node->precision = precision;
@@ -4124,16 +4132,40 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
_set_tkpos(pos); //rollback
}
- } else if (tk.type == TK_CF_WHILE) {
- //if () {}
+ } else if (tk.type == TK_CF_DO || tk.type == TK_CF_WHILE) {
+ // do {} while()
+ // while() {}
+ bool is_do = tk.type == TK_CF_DO;
+
+ BlockNode *do_block = NULL;
+ if (is_do) {
+
+ do_block = alloc_node<BlockNode>();
+ do_block->parent_block = p_block;
+
+ Error err = _parse_block(do_block, p_builtin_types, true, true, true);
+ if (err)
+ return err;
+
+ tk = _get_token();
+ if (tk.type != TK_CF_WHILE) {
+ _set_error("Expected while after do");
+ return ERR_PARSE_ERROR;
+ }
+ }
tk = _get_token();
+
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '(' after while");
return ERR_PARSE_ERROR;
}
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
- cf->flow_op = FLOW_OP_WHILE;
+ if (is_do) {
+ cf->flow_op = FLOW_OP_DO;
+ } else {
+ cf->flow_op = FLOW_OP_WHILE;
+ }
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
if (!n)
return ERR_PARSE_ERROR;
@@ -4143,18 +4175,30 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
_set_error("Expected ')' after expression");
return ERR_PARSE_ERROR;
}
+ if (!is_do) {
+ BlockNode *block = alloc_node<BlockNode>();
+ block->parent_block = p_block;
+ cf->expressions.push_back(n);
+ cf->blocks.push_back(block);
+ p_block->statements.push_back(cf);
- BlockNode *block = alloc_node<BlockNode>();
- block->parent_block = p_block;
- cf->expressions.push_back(n);
- cf->blocks.push_back(block);
- p_block->statements.push_back(cf);
+ Error err = _parse_block(block, p_builtin_types, true, true, true);
+ if (err)
+ return err;
+ } else {
- Error err = _parse_block(block, p_builtin_types, true, true, true);
- if (err)
- return err;
+ cf->expressions.push_back(n);
+ cf->blocks.push_back(do_block);
+ p_block->statements.push_back(cf);
+
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';'");
+ return ERR_PARSE_ERROR;
+ }
+ }
} else if (tk.type == TK_CF_FOR) {
- //if () {}
+ // for() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '(' after for");
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index f37d651dee..dcfbd28dd6 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -38,9 +38,6 @@
#include "visual_server_globals.h"
#include "visual_server_scene.h"
#include "visual_server_viewport.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class VisualServerRaster : public VisualServer {
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 24e50eb99e..41993d7c88 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -35,9 +35,6 @@
#include "core/os/thread.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class VisualServerWrapMT : public VisualServer {
// the real visual server
diff --git a/servers/visual_server.h b/servers/visual_server.h
index a84d395e3f..1b0164e5ca 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -39,9 +39,6 @@
#include "core/rid.h"
#include "core/variant.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class VisualServer : public Object {
GDCLASS(VisualServer, Object);