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/image.cpp21
-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/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.h4
-rw-r--r--core/method_bind.h4
-rw-r--r--core/node_path.h4
-rw-r--r--core/os/dir_access.h4
-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/safe_refcount.h16
-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--doc/classes/Node.xml6
-rw-r--r--doc/classes/Popup.xml7
-rw-r--r--doc/classes/VisualShaderNode.xml15
-rw-r--r--doc/classes/VisualShaderNodeCustom.xml148
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp14
-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.cpp80
-rw-r--r--editor/code_editor.h4
-rw-r--r--editor/create_dialog.h3
-rw-r--r--editor/editor_about.h3
-rw-r--r--editor/editor_file_dialog.h3
-rw-r--r--editor/editor_fonts.cpp26
-rw-r--r--editor/editor_node.cpp9
-rw-r--r--editor/editor_node.h7
-rw-r--r--editor/editor_plugin.h4
-rw-r--r--editor/editor_settings.cpp4
-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.cpp6
-rw-r--r--editor/plugins/camera_editor_plugin.h4
-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.cpp21
-rw-r--r--editor/plugins/particles_editor_plugin.h6
-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/spatial_editor_plugin.h3
-rw-r--r--editor/plugins/tile_map_editor_plugin.h4
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp116
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h8
-rw-r--r--editor/project_manager.cpp6
-rw-r--r--editor/property_editor.h4
-rw-r--r--editor/scene_tree_editor.h4
-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/gridmap/grid_map_editor_plugin.h3
-rw-r--r--modules/hdr/image_loader_hdr.h3
-rw-r--r--modules/jpg/image_loader_jpegd.h3
-rw-r--r--modules/mono/build_scripts/godot_tools_build.py10
-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/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/mono_gd/gd_mono.cpp34
-rw-r--r--modules/mono/mono_gd/gd_mono.h2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h3
-rw-r--r--modules/visual_script/visual_script_nodes.cpp2
-rw-r--r--modules/webp/image_loader_webp.h3
-rw-r--r--platform/android/thread_jandroid.h4
-rw-r--r--platform/osx/dir_access_osx.h3
-rw-r--r--platform/osx/os_osx.h3
-rw-r--r--platform/server/os_server.h3
-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/2d/parallax_layer.cpp3
-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.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/text_edit.cpp4
-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.cpp1
-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--scene/resources/visual_shader.cpp154
-rw-r--r--scene/resources/visual_shader.h40
-rw-r--r--servers/physics/gjk_epa.h5
-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
204 files changed, 2248 insertions, 837 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/image.cpp b/core/image.cpp
index 5ce744f709..6211c06ebe 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -754,15 +754,14 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
for (int32_t buffer_x = 0; buffer_x < dst_width; buffer_x++) {
- float src_real_x = buffer_x * x_scale;
- int32_t src_x = src_real_x;
-
- int32_t start_x = MAX(0, src_x - half_kernel + 1);
- int32_t end_x = MIN(src_width - 1, src_x + half_kernel);
+ // The corresponding point on the source image
+ float src_x = (buffer_x + 0.5f) * x_scale; // Offset by 0.5 so it uses the pixel's center
+ int32_t start_x = MAX(0, int32_t(src_x) - half_kernel + 1);
+ int32_t end_x = MIN(src_width - 1, int32_t(src_x) + half_kernel);
// Create the kernel used by all the pixels of the column
for (int32_t target_x = start_x; target_x <= end_x; target_x++)
- kernel[target_x - start_x] = _lanczos((src_real_x - target_x) / scale_factor);
+ kernel[target_x - start_x] = _lanczos((target_x + 0.5f - src_x) / scale_factor);
for (int32_t buffer_y = 0; buffer_y < src_height; buffer_y++) {
@@ -805,14 +804,12 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
for (int32_t dst_y = 0; dst_y < dst_height; dst_y++) {
- float buffer_real_y = dst_y * y_scale;
- int32_t buffer_y = buffer_real_y;
-
- int32_t start_y = MAX(0, buffer_y - half_kernel + 1);
- int32_t end_y = MIN(src_height - 1, buffer_y + half_kernel);
+ float buffer_y = (dst_y + 0.5f) * y_scale;
+ int32_t start_y = MAX(0, int32_t(buffer_y) - half_kernel + 1);
+ int32_t end_y = MIN(src_height - 1, int32_t(buffer_y) + half_kernel);
for (int32_t target_y = start_y; target_y <= end_y; target_y++)
- kernel[target_y - start_y] = _lanczos((buffer_real_y - target_y) / scale_factor);
+ kernel[target_y - start_y] = _lanczos((target_y + 0.5f - buffer_y) / scale_factor);
for (int32_t dst_x = 0; dst_x < dst_width; dst_x++) {
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/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.h b/core/math/transform.h
index df0a036218..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;
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 3c0528112b..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:
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/safe_refcount.h b/core/safe_refcount.h
index 54f540b0c7..0b65ffb9ca 100644
--- a/core/safe_refcount.h
+++ b/core/safe_refcount.h
@@ -97,8 +97,8 @@ static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V v
/* Implementation for GCC & Clang */
-// GCC guarantees atomic intrinsics for sizes of 1, 2, 4 and 8 bytes.
-// Clang states it supports GCC atomic builtins.
+#include <stdbool.h>
+#include <atomic>
template <class T>
static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
@@ -107,7 +107,7 @@ static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
T tmp = static_cast<T const volatile &>(*pw);
if (tmp == 0)
return 0; // if zero, can't add to it anymore
- if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp)
+ if (__atomic_compare_exchange_n(pw, &tmp, tmp + 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) == true)
return tmp + 1;
}
}
@@ -115,25 +115,25 @@ static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
template <class T>
static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) {
- return __sync_sub_and_fetch(pw, 1);
+ return __atomic_sub_fetch(pw, 1, __ATOMIC_SEQ_CST);
}
template <class T>
static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) {
- return __sync_add_and_fetch(pw, 1);
+ return __atomic_add_fetch(pw, 1, __ATOMIC_SEQ_CST);
}
template <class T, class V>
static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) {
- return __sync_sub_and_fetch(pw, val);
+ return __atomic_sub_fetch(pw, val, __ATOMIC_SEQ_CST);
}
template <class T, class V>
static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) {
- return __sync_add_and_fetch(pw, val);
+ return __atomic_add_fetch(pw, val, __ATOMIC_SEQ_CST);
}
template <class T, class V>
@@ -143,7 +143,7 @@ static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V v
T tmp = static_cast<T const volatile &>(*pw);
if (tmp >= val)
return tmp; // already greater, or equal
- if (__sync_val_compare_and_swap(pw, tmp, val) == tmp)
+ if (__atomic_compare_exchange_n(pw, &tmp, val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) == true)
return val;
}
}
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/doc/classes/Node.xml b/doc/classes/Node.xml
index 889ce4d3eb..097fa1f6e5 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -122,6 +122,12 @@
<description>
Adds a child node. Nodes can have any number of children, but every child must have a unique name. Child nodes are automatically deleted when the parent node is deleted, so an entire scene can be removed by deleting its topmost node.
If [code]legible_unique_name[/code] is [code]true[/code], the child node will have an human-readable name based on the name of the node being instanced instead of its type.
+ [b]Note:[/b] If the child node already has a parent, the function will fail. Use [method remove_child] first to remove the node from its current parent. For example:
+ [codeblock]
+ if child_node.get_parent():
+ child_node.get_parent().remove_child(child_node)
+ add_child(child_node)
+ [/codeblock]
</description>
</method>
<method name="add_child_below_node">
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/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml
index 19495a8859..3e80349b13 100644
--- a/doc/classes/VisualShaderNode.xml
+++ b/doc/classes/VisualShaderNode.xml
@@ -39,5 +39,20 @@
</signal>
</signals>
<constants>
+ <constant name="PORT_TYPE_SCALAR" value="0" enum="PortType">
+ Floating-point scalar. Translated to [code]float[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_VECTOR" value="1" enum="PortType">
+ 3D vector of floating-point values. Translated to [code]vec3[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_BOOLEAN" value="2" enum="PortType">
+ Boolean type. Translated to [code]bool[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_TRANSFORM" value="3" enum="PortType">
+ Transform type. Translated to [code]mat4[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_ICON_COLOR" value="4" enum="PortType">
+ Color type. Can be used for return icon type in members dialog (see [method VisualShaderNodeCustom._get_return_icon_type]) - do not use it in other cases!
+ </constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml
new file mode 100644
index 0000000000..d4a1732364
--- /dev/null
+++ b/doc/classes/VisualShaderNodeCustom.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeCustom" inherits="VisualShaderNode" category="Core" version="3.2">
+ <brief_description>
+ Virtual class to define custom [VisualShaderNode]s for use in the Visual Shader Editor.
+ </brief_description>
+ <description>
+ By inheriting this class you can create a custom [VisualShader] script addon which will be automatically added to the Visual Shader Editor. The [VisualShaderNode]'s behavior is defined by overriding the provided virtual methods.
+ In order for the node to be registered as an editor addon, you must use the [code]tool[/code] keyword and provide a [code]class_name[/code] for your custom script. For example:
+ [codeblock]
+ tool
+ extends VisualShaderNodeCustom
+ class_name VisualShaderNodeNoise
+ [/codeblock]
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="_get_category" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to define the category of the associated custom node in the Visual Shader Editor's members dialog.
+ Defining this method is [b]optional[/b]. If not overridden, the node will be filed under the "Custom" category.
+ </description>
+ </method>
+ <method name="_get_description" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to define the description of the associated custom node in the Visual Shader Editor's members dialog.
+ Defining this method is [b]optional[/b].
+ </description>
+ </method>
+ <method name="_get_code" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="input_vars" type="Array">
+ </argument>
+ <argument index="1" name="output_vars" type="Array">
+ </argument>
+ <argument index="2" name="mode" type="int" enum="Shader.Mode">
+ </argument>
+ <argument index="3" name="type" type="int" enum="VisualShader.Type">
+ </argument>
+ <description>
+ Override this method to define the actual shader code of the associated custom node. The shader code should be returned as a string, which can have multiple lines (the [code]"""[/code] multiline string construct can be used for convenience).
+ The [code]input_vars[/code] and [code]output_vars[/code] arrays contain the string names of the various input and output variables, as defined by [code]_get_input_*[/code] and [code]_get_output_*[/code] virtual methods in this class.
+ The output ports can be assigned values in the shader code. For example, [code]return output_vars[0] + " = " + input_vars[0] + ";"[/code].
+ You can customize the generated code based on the shader [code]mode[/code] (see [enum Shader.Mode]) and/or [code]type[/code] (see [enum VisualShader.Type]).
+ Defining this method is [b]required[/b].
+ </description>
+ </method>
+ <method name="_get_global_code" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Shader.Mode">
+ </argument>
+ <description>
+ Override this method to add shader code on top of the global shader, to define your own standard library of reusable methods, varyings, constants, uniforms, etc. The shader code should be returned as a string, which can have multiple lines (the [code]"""[/code] multiline string construct can be used for convenience).
+ Be careful with this functionality as it can cause name conflicts with other custom nodes, so be sure to give the defined entities unique names.
+ You can customize the generated code based on the shader [code]mode[/code] (see [enum Shader.Mode]).
+ Defining this method is [b]optional[/b].
+ </description>
+ </method>
+ <method name="_get_input_port_count" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <description>
+ Override this method to define the amount of input ports of the associated custom node.
+ Defining this method is [b]required[/b]. If not overridden, the node has no input ports.
+ </description>
+ </method>
+ <method name="_get_input_port_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="port" type="int">
+ </argument>
+ <description>
+ Override this method to define the names of input ports of the associated custom node. The names are used both for the input slots in the editor and as identifiers in the shader code, and are passed in the [code]input_vars[/code] array in [method _get_code].
+ Defining this method is [b]optional[/b], but recommended. If not overridden, input ports are named as [code]"in" + str(port)[/code].
+ </description>
+ </method>
+ <method name="_get_input_port_type" qualifiers="virtual">
+ <return type="int" enum="VisualShaderNode.PortType">
+ </return>
+ <argument index="0" name="port" type="int">
+ </argument>
+ <description>
+ Override this method to define the returned type of each input port of the associated custom node (see [enum VisualShaderNode.PortType] for possible types).
+ Defining this method is [b]optional[/b], but recommended. If not overridden, input ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] type.
+ </description>
+ </method>
+ <method name="_get_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to define the name of the associated custom node in the Visual Shader Editor's members dialog and graph.
+ Defining this method is [b]optional[/b], but recommended. If not overridden, the node will be named as "Unnamed".
+ </description>
+ </method>
+ <method name="_get_output_port_count" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <description>
+ Override this method to define the amount of output ports of the associated custom node.
+ Defining this method is [b]required[/b]. If not overridden, the node has no output ports.
+ </description>
+ </method>
+ <method name="_get_output_port_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="port" type="int">
+ </argument>
+ <description>
+ Override this method to define the names of output ports of the associated custom node. The names are used both for the output slots in the editor and as identifiers in the shader code, and are passed in the [code]output_vars[/code] array in [method _get_code].
+ Defining this method is [b]optional[/b], but recommended. If not overridden, output ports are named as [code]"out" + str(port)[/code].
+ </description>
+ </method>
+ <method name="_get_output_port_type" qualifiers="virtual">
+ <return type="int" enum="VisualShaderNode.PortType">
+ </return>
+ <argument index="0" name="port" type="int">
+ </argument>
+ <description>
+ Override this method to define the returned type of each output port of the associated custom node (see [enum VisualShaderNode.PortType] for possible types).
+ Defining this method is [b]optional[/b], but recommended. If not overridden, output ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] type.
+ </description>
+ </method>
+ <method name="_get_return_icon_type" qualifiers="virtual">
+ <return type="int" enum="VisualShaderNode.PortType">
+ </return>
+ <description>
+ Override this method to define the return icon of the associated custom node in the Visual Shader Editor's members dialog.
+ Defining this method is [b]optional[/b]. If not overridden, no return icon is shown.
+ </description>
+ </method>
+ <method name="_get_subcategory" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to define the subcategory of the associated custom node in the Visual Shader Editor's members dialog.
+ Defining this method is [b]optional[/b]. If not overridden, the node will be filed under the root of the main category (see [method _get_category]).
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 30ca07aa28..048f3c114e 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1121,13 +1121,23 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
if (state.current_depth_draw != p_material->shader->spatial.depth_draw_mode) {
switch (p_material->shader->spatial.depth_draw_mode) {
- case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS:
+ case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS: {
+ glDepthMask(GL_TRUE);
+ // If some transparent objects write to depth, we need to re-copy depth texture when we need it
+ if (p_alpha_pass && !state.used_depth_prepass) {
+ state.prepared_depth_texture = false;
+ }
+ } break;
case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_OPAQUE: {
glDepthMask(!p_alpha_pass);
} break;
case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALWAYS: {
glDepthMask(GL_TRUE);
+ // If some transparent objects write to depth, we need to re-copy depth texture when we need it
+ if (p_alpha_pass) {
+ state.prepared_depth_texture = false;
+ }
} break;
case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER: {
glDepthMask(GL_FALSE);
@@ -4616,6 +4626,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
return;
}
+ if (env && (env->dof_blur_far_enabled || env->dof_blur_near_enabled) && storage->frame.current_rt && storage->frame.current_rt->buffers.active)
+ _prepare_depth_texture();
_post_process(env, p_cam_projection);
// Needed only for debugging
/* if (shadow_atlas && storage->frame.current_rt) {
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 1a529a4764..33af5927b3 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -164,6 +164,7 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
_update_results_count();
} else {
+ results_count = 0;
result_line = -1;
result_col = -1;
text_edit->set_search_text("");
@@ -196,7 +197,7 @@ void FindReplaceBar::_replace() {
void FindReplaceBar::_replace_all() {
text_edit->disconnect("text_changed", this, "_editor_text_changed");
- // line as x so it gets priority in comparison, column as y
+ // Line as x so it gets priority in comparison, column as y.
Point2i orig_cursor(text_edit->cursor_get_line(), text_edit->cursor_get_column());
Point2i prev_match = Point2(-1, -1);
@@ -228,7 +229,7 @@ void FindReplaceBar::_replace_all() {
Point2i match_to(result_line, result_col + search_text_len);
if (match_from < prev_match) {
- break; // done
+ break; // Done.
}
prev_match = Point2i(result_line, result_col + replace_text.length());
@@ -241,14 +242,14 @@ void FindReplaceBar::_replace_all() {
continue;
}
- // replace but adjust selection bounds
+ // Replace but adjust selection bounds.
text_edit->insert_text_at_cursor(replace_text);
if (match_to.x == selection_end.x) {
selection_end.y += replace_text.length() - search_text_len;
}
} else {
- // just replace
+ // Just replace.
text_edit->insert_text_at_cursor(replace_text);
}
@@ -260,12 +261,12 @@ void FindReplaceBar::_replace_all() {
replace_all_mode = false;
- // restore editor state (selection, cursor, scroll)
+ // Restore editor state (selection, cursor, scroll).
text_edit->cursor_set_line(orig_cursor.x);
text_edit->cursor_set_column(orig_cursor.y);
if (selection_enabled && is_selection_only()) {
- // reselect
+ // Reselect.
text_edit->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y);
} else {
text_edit->deselect();
@@ -283,20 +284,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;
}
@@ -361,6 +348,9 @@ bool FindReplaceBar::search_current() {
bool FindReplaceBar::search_prev() {
+ if (!is_visible())
+ popup_search(true);
+
uint32_t flags = 0;
String text = get_search_text();
@@ -373,6 +363,8 @@ bool FindReplaceBar::search_prev() {
int line, col;
_get_search_from(line, col);
+ if (text_edit->is_selection_active())
+ col--; // Skip currently selected word.
if (line == result_line && col == result_col) {
col -= text.length();
@@ -389,6 +381,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)
@@ -428,34 +423,51 @@ void FindReplaceBar::_hide_bar() {
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();
@@ -463,7 +475,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) {
@@ -740,7 +752,7 @@ void CodeTextEditor::_zoom_changed() {
}
void CodeTextEditor::_reset_zoom() {
- Ref<DynamicFont> font = text_editor->get_font("font"); // reset source font size to default
+ Ref<DynamicFont> font = text_editor->get_font("font"); // Reset source font size to default.
if (font.is_valid()) {
EditorSettings::get_singleton()->set("interface/editor/code_font_size", 14);
@@ -1250,7 +1262,7 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
int col_to = text_editor->get_selection_to_column();
int cursor_pos = text_editor->cursor_get_column();
- // Check if all lines in the selected block are commented
+ // Check if all lines in the selected block are commented.
bool is_commented = true;
for (int i = begin; i <= end; i++) {
if (!text_editor->get_line(i).begins_with(delimiter)) {
@@ -1445,14 +1457,14 @@ void CodeTextEditor::_on_settings_change() {
font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size");
- // AUTO BRACE COMPLETION
+ // Auto brace completion.
text_editor->set_auto_brace_completion(
EDITOR_GET("text_editor/completion/auto_brace_complete"));
code_complete_timer->set_wait_time(
EDITOR_GET("text_editor/completion/code_complete_delay"));
- // call hint settings
+ // Call hint settings.
text_editor->set_callhint_settings(
EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line"),
EDITOR_GET("text_editor/completion/callhint_tooltip_offset"));
diff --git a/editor/code_editor.h b/editor/code_editor.h
index a4b3aa312f..f2a55cfb70 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -93,7 +93,7 @@ class FindReplaceBar : public HBoxContainer {
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();
@@ -125,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_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_fonts.cpp b/editor/editor_fonts.cpp
index 73438ffc0c..55cae35a4a 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -94,7 +94,31 @@ void editor_register_fonts(Ref<Theme> p_theme) {
/* Custom font */
bool font_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/font_antialiased");
- DynamicFontData::Hinting font_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/font_hinting");
+ int font_hinting_setting = (int)EditorSettings::get_singleton()->get("interface/editor/font_hinting");
+
+ DynamicFontData::Hinting font_hinting;
+ switch (font_hinting_setting) {
+ case 0:
+ // The "Auto" setting uses the setting that best matches the OS' font rendering:
+ // - macOS doesn't use font hinting.
+ // - Windows uses ClearType, which is in between "Light" and "Normal" hinting.
+ // - Linux has configurable font hinting, but most distributions including Ubuntu default to "Light".
+#ifdef OSX_ENABLED
+ font_hinting = DynamicFontData::HINTING_NONE;
+#else
+ font_hinting = DynamicFontData::HINTING_LIGHT;
+#endif
+ break;
+ case 1:
+ font_hinting = DynamicFontData::HINTING_NONE;
+ break;
+ case 2:
+ font_hinting = DynamicFontData::HINTING_LIGHT;
+ break;
+ default:
+ font_hinting = DynamicFontData::HINTING_NORMAL;
+ break;
+ }
String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font");
Ref<DynamicFontData> CustomFont;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 10737d9f3a..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();
}
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_settings.cpp b/editor/editor_settings.cpp
index e3f2a888d6..2d2e53370d 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -324,8 +324,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/code_font_size", 14);
hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,48,1", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/font_antialiased", true);
- _initial_set("interface/editor/font_hinting", 2);
- hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT);
+ _initial_set("interface/editor/font_hinting", 0);
+ hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto,None,Light,Normal", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/main_font", "");
hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/main_font_bold", "");
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 5679426eb5..132bf3973e 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -270,10 +270,10 @@ void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, cons
if (!p_video) {
preview.image = get_icon("ThumbnailWait", "EditorIcons");
}
- if (preview_images.size() == 0 && !p_video) {
+ preview_images.push_back(preview);
+ if (preview_images.size() == 1 && !p_video) {
_preview_click(p_id);
}
- preview_images.push_back(preview);
}
EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
@@ -758,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.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.cpp b/editor/plugins/particles_editor_plugin.cpp
index 75d31459e8..31b0539bfe 100644
--- a/editor/plugins/particles_editor_plugin.cpp
+++ b/editor/plugins/particles_editor_plugin.cpp
@@ -55,8 +55,7 @@ bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vect
if (!triangle_area_map.size() || area_accum == 0) {
- err_dialog->set_text(TTR("Faces contain no area!"));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(TTR("The geometry's faces don't contain any area."));
return false;
}
@@ -90,8 +89,7 @@ bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vect
if (gcount == 0) {
- err_dialog->set_text(TTR("No faces!"));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(TTR("The geometry doesn't contain any faces."));
return false;
}
@@ -169,11 +167,16 @@ void ParticlesEditorBase::_node_selected(const NodePath &p_path) {
if (!sel)
return;
+ if (!sel->is_class("Spatial")) {
+
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't inherit from Spatial."), sel->get_name()));
+ return;
+ }
+
VisualInstance *vi = Object::cast_to<VisualInstance>(sel);
if (!vi) {
- err_dialog->set_text(TTR("Node does not contain geometry."));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain geometry."), sel->get_name()));
return;
}
@@ -181,8 +184,7 @@ void ParticlesEditorBase::_node_selected(const NodePath &p_path) {
if (geometry.size() == 0) {
- err_dialog->set_text(TTR("Node does not contain geometry (faces)."));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain face geometry."), sel->get_name()));
return;
}
@@ -231,9 +233,6 @@ ParticlesEditorBase::ParticlesEditorBase() {
emission_dialog->get_ok()->set_text(TTR("Create"));
emission_dialog->connect("confirmed", this, "_generate_emission_points");
- err_dialog = memnew(ConfirmationDialog);
- add_child(err_dialog);
-
emission_file_dialog = memnew(EditorFileDialog);
add_child(emission_file_dialog);
emission_file_dialog->connect("file_selected", this, "_resource_seleted");
diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h
index 5d05fbd4ac..1b3a1877a4 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);
@@ -53,8 +49,6 @@ protected:
EditorFileDialog *emission_file_dialog;
SceneTreeDialog *emission_tree_dialog;
- ConfirmationDialog *err_dialog;
-
ConfirmationDialog *emission_dialog;
SpinBox *emission_amount;
OptionButton *emission_fill;
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/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/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/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 863cf75a93..e193e237de 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -79,6 +79,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
} else {
if (changed) { // to avoid tree collapse
_clear_buffer();
+ _update_custom_nodes();
_update_options_menu();
}
_update_graph();
@@ -95,31 +96,36 @@ void VisualShaderEditor::remove_plugin(const Ref<VisualShaderNodePlugin> &p_plug
plugins.erase(p_plugin);
}
-void VisualShaderEditor::add_custom_type(const String &p_name, const String &p_category, const Ref<Script> &p_script) {
-
+void VisualShaderEditor::clear_custom_types() {
for (int i = 0; i < add_options.size(); i++) {
- ERR_FAIL_COND(add_options[i].script == p_script);
+ if (add_options[i].is_custom) {
+ add_options.remove(i);
+ }
}
-
- AddOption ao;
- ao.name = p_name;
- ao.script = p_script;
- ao.category = p_category;
- add_options.push_back(ao);
-
- _update_options_menu();
}
-void VisualShaderEditor::remove_custom_type(const Ref<Script> &p_script) {
+void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_sub_category) {
+
+ ERR_FAIL_COND(!p_name.is_valid_identifier());
+ ERR_FAIL_COND(!p_script.is_valid());
for (int i = 0; i < add_options.size(); i++) {
- if (add_options[i].script == p_script) {
- add_options.remove(i);
- return;
+ if (add_options[i].is_custom) {
+ if (add_options[i].script == p_script)
+ return;
}
}
- _update_options_menu();
+ AddOption ao;
+ ao.name = p_name;
+ ao.script = p_script;
+ ao.return_type = p_return_icon_type;
+ ao.description = p_description;
+ ao.category = p_category;
+ ao.sub_category = p_sub_category;
+ ao.is_custom = true;
+
+ add_options.push_back(ao);
}
bool VisualShaderEditor::_is_available(int p_mode) {
@@ -162,6 +168,58 @@ bool VisualShaderEditor::_is_available(int p_mode) {
return (p_mode == -1 || (p_mode & current_mode) != 0);
}
+void VisualShaderEditor::_update_custom_nodes() {
+ clear_custom_types();
+ List<StringName> class_list;
+ ScriptServer::get_global_class_list(&class_list);
+ for (int i = 0; i < class_list.size(); i++) {
+ if (ScriptServer::get_global_class_native_base(class_list[i]) == "VisualShaderNodeCustom") {
+
+ String script_path = ScriptServer::get_global_class_path(class_list[i]);
+ Ref<Resource> res = ResourceLoader::load(script_path);
+ ERR_FAIL_COND(res.is_null());
+ ERR_FAIL_COND(!res->is_class("Script"));
+ Ref<Script> script = Ref<Script>(res);
+
+ Ref<VisualShaderNodeCustom> ref;
+ ref.instance();
+ ref->set_script(script.get_ref_ptr());
+
+ String name;
+ if (ref->has_method("_get_name")) {
+ name = (String)ref->call("_get_name");
+ } else {
+ name = "Unnamed";
+ }
+
+ String description = "";
+ if (ref->has_method("_get_description")) {
+ description = (String)ref->call("_get_description");
+ }
+
+ int return_icon_type = -1;
+ if (ref->has_method("_get_return_icon_type")) {
+ return_icon_type = (int)ref->call("_get_return_icon_type");
+ }
+
+ String category = "";
+ if (ref->has_method("_get_category")) {
+ category = (String)ref->call("_get_category");
+ }
+ if (category == "") {
+ category = "Custom";
+ }
+
+ String sub_category = "";
+ if (ref->has_method("_get_subcategory")) {
+ sub_category = (String)ref->call("_get_subcategory");
+ }
+
+ add_custom_type(name, script, description, return_icon_type, category, sub_category);
+ }
+ }
+}
+
void VisualShaderEditor::_update_options_menu() {
node_desc->set_text("");
@@ -284,7 +342,7 @@ void VisualShaderEditor::_update_options_menu() {
case VisualShaderNode::PORT_TYPE_TRANSFORM:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
break;
- case VisualShaderNode::PORT_TYPE_COLOR:
+ case VisualShaderNode::PORT_TYPE_ICON_COLOR:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Color", "EditorIcons"));
break;
default:
@@ -942,8 +1000,10 @@ void VisualShaderEditor::_expression_focus_out(Object *text_edit, int p_node) {
}
void VisualShaderEditor::_rebuild() {
- EditorNode::get_singleton()->get_log()->clear();
- visual_shader->rebuild();
+ if (visual_shader != NULL) {
+ EditorNode::get_singleton()->get_log()->clear();
+ visual_shader->rebuild();
+ }
}
void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p_size) {
@@ -1139,7 +1199,9 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
Ref<VisualShaderNode> vsnode;
- if (add_options[p_idx].type != String()) {
+ bool is_custom = add_options[p_idx].is_custom;
+
+ if (!is_custom && add_options[p_idx].type != String()) {
VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type));
ERR_FAIL_COND(!vsn);
@@ -2164,8 +2226,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), VisualShaderNodeColorOp::OP_SCREEN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), VisualShaderNodeColorOp::OP_SOFT_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."), -1, VisualShaderNode::PORT_TYPE_COLOR));
- add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), -1, VisualShaderNode::PORT_TYPE_COLOR));
+ add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
// CONDITIONAL
@@ -2368,12 +2430,12 @@ VisualShaderEditor::VisualShaderEditor() {
// TEXTURES
- add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubeMap", TTR("Perform the cubic texture lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR));
- add_options.push_back(AddOption("Texture", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR));
+ add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubeMap", TTR("Perform the cubic texture lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("Texture", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
- add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubeMapUniform", TTR("Cubic texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR));
- add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR));
- add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, VisualShaderNode::PORT_TYPE_COLOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubeMapUniform", TTR("Cubic texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
// TRANSFORM
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index d2b1e8bc45..b5b00f2b5e 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -104,6 +104,7 @@ class VisualShaderEditor : public VBoxContainer {
int func;
float value;
bool highend;
+ bool is_custom;
AddOption(const String &p_name = String(), const String &p_category = String(), const String &p_sub_category = String(), const String &p_type = String(), const String &p_description = String(), int p_sub_func = -1, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
name = p_name;
@@ -117,6 +118,7 @@ class VisualShaderEditor : public VBoxContainer {
func = p_func;
value = p_value;
highend = p_highend;
+ is_custom = false;
}
AddOption(const String &p_name, const String &p_category, const String &p_sub_category, const String &p_type, const String &p_description, const String &p_sub_func, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
@@ -131,6 +133,7 @@ class VisualShaderEditor : public VBoxContainer {
func = p_func;
value = p_value;
highend = p_highend;
+ is_custom = false;
}
};
@@ -140,6 +143,7 @@ class VisualShaderEditor : public VBoxContainer {
void _draw_color_over_button(Object *obj, Color p_color);
void _add_node(int p_idx, int p_op_idx = -1);
+ void _update_custom_nodes();
void _update_options_menu();
static VisualShaderEditor *singleton;
@@ -240,8 +244,8 @@ public:
static VisualShaderEditor *get_singleton() { return singleton; }
- void add_custom_type(const String &p_name, const String &p_category, const Ref<Script> &p_script);
- void remove_custom_type(const Ref<Script> &p_script);
+ void clear_custom_types();
+ void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_sub_category);
virtual Size2 get_minimum_size() const;
void edit(VisualShader *p_visual_shader);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index feb2cdd071..0f3c4c924a 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();
}
}
@@ -2075,10 +2075,12 @@ void ProjectManager::_rename_project() {
void ProjectManager::_erase_project_confirm() {
_project_list->erase_selected_projects();
+ _update_project_buttons();
}
void ProjectManager::_erase_missing_projects_confirm() {
_project_list->erase_missing_projects();
+ _update_project_buttons();
}
void ProjectManager::_erase_project() {
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/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/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/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.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/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/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/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/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/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_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 3b0210597b..65820b4c15 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -2530,7 +2530,7 @@ String VisualScriptCustomNode::get_category() const {
if (get_script_instance() && get_script_instance()->has_method("_get_category")) {
return get_script_instance()->call("_get_category");
}
- return "custom";
+ return "Custom";
}
class VisualScriptNodeInstanceCustomNode : public VisualScriptNodeInstance {
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/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/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/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/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/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index 9a6b63b9a3..0823e09110 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -69,6 +69,9 @@ Size2 ParallaxLayer::get_motion_offset() const {
void ParallaxLayer::_update_mirroring() {
+ if (!is_inside_tree())
+ return;
+
ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent());
if (pb) {
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.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/text_edit.cpp b/scene/gui/text_edit.cpp
index 6e5f8de3b5..c0eaf21215 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1403,7 +1403,7 @@ void TextEdit::_notification(int p_what) {
}
int line_from = CLAMP(completion_index - lines / 2, 0, completion_options.size() - lines);
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(completion_rect.position.x, completion_rect.position.y + (completion_index - line_from) * get_row_height()), Size2(completion_rect.size.width, get_row_height())), cache.completion_selected_color);
- draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(nofs, completion_rect.size.height)), cache.completion_existing_color);
+ draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(nofs, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color);
for (int i = 0; i < lines; i++) {
@@ -1430,7 +1430,7 @@ void TextEdit::_notification(int p_what) {
}
title_pos.x = icon_area.position.x + icon_area.size.width + icon_hsep;
- draw_string(cache.font, title_pos, completion_options[l].display, text_color, completion_rect.size.width);
+ draw_string(cache.font, title_pos, completion_options[l].display, text_color, completion_rect.size.width - (icon_area_size.x + icon_hsep));
}
if (scrollw) {
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.cpp b/scene/register_scene_types.cpp
index fd7cd3c17b..6c858e9d9a 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -475,6 +475,7 @@ void register_scene_types() {
ClassDB::register_class<Shader>();
ClassDB::register_class<VisualShader>();
ClassDB::register_virtual_class<VisualShaderNode>();
+ ClassDB::register_class<VisualShaderNodeCustom>();
ClassDB::register_class<VisualShaderNodeInput>();
ClassDB::register_virtual_class<VisualShaderNodeOutput>();
ClassDB::register_class<VisualShaderNodeGroupBase>();
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/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index cd0c1b5b07..389011c095 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -117,6 +117,12 @@ void VisualShaderNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_default_input_values", "_get_default_input_values");
ADD_SIGNAL(MethodInfo("editor_refresh_request"));
+
+ BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN);
+ BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM);
+ BIND_ENUM_CONSTANT(PORT_TYPE_ICON_COLOR);
}
VisualShaderNode::VisualShaderNode() {
@@ -125,6 +131,147 @@ VisualShaderNode::VisualShaderNode() {
/////////////////////////////////////////////////////////
+void VisualShaderNodeCustom::update_ports() {
+ ERR_FAIL_COND(!get_script_instance());
+
+ input_ports.clear();
+ if (get_script_instance()->has_method("_get_input_port_count")) {
+ int input_port_count = (int)get_script_instance()->call("_get_input_port_count");
+ bool has_name = get_script_instance()->has_method("_get_input_port_name");
+ bool has_type = get_script_instance()->has_method("_get_input_port_type");
+ for (int i = 0; i < input_port_count; i++) {
+ Port port;
+ if (has_name) {
+ port.name = (String)get_script_instance()->call("_get_input_port_name", i);
+ } else {
+ port.name = "in" + itos(i);
+ }
+ if (has_type) {
+ port.type = (int)get_script_instance()->call("_get_input_port_type", i);
+ } else {
+ port.type = (int)PortType::PORT_TYPE_SCALAR;
+ }
+ input_ports.push_back(port);
+ }
+ }
+ output_ports.clear();
+ if (get_script_instance()->has_method("_get_output_port_count")) {
+ int output_port_count = (int)get_script_instance()->call("_get_output_port_count");
+ bool has_name = get_script_instance()->has_method("_get_output_port_name");
+ bool has_type = get_script_instance()->has_method("_get_output_port_type");
+ for (int i = 0; i < output_port_count; i++) {
+ Port port;
+ if (has_name) {
+ port.name = (String)get_script_instance()->call("_get_output_port_name", i);
+ } else {
+ port.name = "out" + itos(i);
+ }
+ if (has_type) {
+ port.type = (int)get_script_instance()->call("_get_output_port_type", i);
+ } else {
+ port.type = (int)PortType::PORT_TYPE_SCALAR;
+ }
+ output_ports.push_back(port);
+ }
+ }
+}
+
+String VisualShaderNodeCustom::get_caption() const {
+ ERR_FAIL_COND_V(!get_script_instance(), "");
+ if (get_script_instance()->has_method("_get_name")) {
+ return (String)get_script_instance()->call("_get_name");
+ }
+ return "Unnamed";
+}
+
+int VisualShaderNodeCustom::get_input_port_count() const {
+ return input_ports.size();
+}
+
+VisualShaderNodeCustom::PortType VisualShaderNodeCustom::get_input_port_type(int p_port) const {
+ ERR_FAIL_INDEX_V(p_port, input_ports.size(), PORT_TYPE_SCALAR);
+ return (PortType)input_ports[p_port].type;
+}
+
+String VisualShaderNodeCustom::get_input_port_name(int p_port) const {
+ ERR_FAIL_INDEX_V(p_port, input_ports.size(), "");
+ return input_ports[p_port].name;
+}
+
+int VisualShaderNodeCustom::get_output_port_count() const {
+ return output_ports.size();
+}
+
+VisualShaderNodeCustom::PortType VisualShaderNodeCustom::get_output_port_type(int p_port) const {
+ ERR_FAIL_INDEX_V(p_port, output_ports.size(), PORT_TYPE_SCALAR);
+ return (PortType)output_ports[p_port].type;
+}
+
+String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
+ ERR_FAIL_INDEX_V(p_port, output_ports.size(), "");
+ return output_ports[p_port].name;
+}
+
+String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+
+ ERR_FAIL_COND_V(!get_script_instance(), "");
+ ERR_FAIL_COND_V(!get_script_instance()->has_method("_get_code"), "");
+ Array input_vars;
+ for (int i = 0; i < get_input_port_count(); i++) {
+ input_vars.push_back(p_input_vars[i]);
+ }
+ Array output_vars;
+ for (int i = 0; i < get_output_port_count(); i++) {
+ output_vars.push_back(p_output_vars[i]);
+ }
+ String code = "\t{\n";
+ String _code = (String)get_script_instance()->call("_get_code", input_vars, output_vars, (int)p_mode, (int)p_type);
+ bool nend = _code.ends_with("\n");
+ _code = _code.insert(0, "\t\t");
+ _code = _code.replace("\n", "\n\t\t");
+ code += _code;
+ if (!nend) {
+ code += "\n\t}";
+ } else {
+ code.remove(code.size() - 1);
+ code += "}";
+ }
+ return code;
+}
+
+String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ ERR_FAIL_COND_V(!get_script_instance(), "");
+ if (get_script_instance()->has_method("_get_global_code")) {
+ String code = "// " + get_caption() + "\n";
+ code += (String)get_script_instance()->call("_get_global_code", (int)p_mode);
+ code += "\n";
+ return code;
+ }
+ return "";
+}
+
+void VisualShaderNodeCustom::_bind_methods() {
+
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description"));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_subcategory"));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type"));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count"));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_port_name", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_count"));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_type", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_port_name", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_code", PropertyInfo(Variant::ARRAY, "input_vars"), PropertyInfo(Variant::ARRAY, "output_vars"), PropertyInfo(Variant::INT, "mode"), PropertyInfo(Variant::INT, "type")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_global_code", PropertyInfo(Variant::INT, "mode")));
+}
+
+VisualShaderNodeCustom::VisualShaderNodeCustom() {
+}
+
+/////////////////////////////////////////////////////////
+
void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id) {
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(p_id < 2);
@@ -150,6 +297,11 @@ void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, co
n.node->connect("changed", this, "_queue_update");
+ Ref<VisualShaderNodeCustom> custom = n.node;
+ if (custom.is_valid()) {
+ custom->update_ports();
+ }
+
g->nodes[p_id] = n;
_queue_update();
@@ -965,6 +1117,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
bool skip_global = input.is_valid() && for_preview;
if (!skip_global) {
+
global_code += vsnode->generate_global(get_mode(), type, node);
if (!r_classes.has(vsnode->get_class_name())) {
@@ -976,7 +1129,6 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
}
}
- //handle normally
code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview);
code += "\n"; //
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index b3c0ab6e0b..a89e3295fc 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -183,7 +183,7 @@ public:
PORT_TYPE_VECTOR,
PORT_TYPE_BOOLEAN,
PORT_TYPE_TRANSFORM,
- PORT_TYPE_COLOR // just a hint for node tree icons, do not use it as actual port type !
+ PORT_TYPE_ICON_COLOR // just a hint for node tree icons, do not use it as actual port type !
};
virtual String get_caption() const = 0;
@@ -216,6 +216,44 @@ public:
VisualShaderNode();
};
+
+VARIANT_ENUM_CAST(VisualShaderNode::PortType)
+
+class VisualShaderNodeCustom : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeCustom, VisualShaderNode);
+
+ struct Port {
+ String name;
+ int type;
+ };
+
+ List<Port> input_ports;
+ List<Port> output_ports;
+
+ friend class VisualShaderEditor;
+
+protected:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+protected:
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+ virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+
+ static void _bind_methods();
+
+public:
+ VisualShaderNodeCustom();
+ void update_ports();
+};
+
/////
class VisualShaderNodeInput : public VisualShaderNode {
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/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);