diff options
Diffstat (limited to 'modules')
59 files changed, 406 insertions, 196 deletions
diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h index 57c3300b3d..ba36331d07 100644 --- a/modules/bullet/bullet_types_converter.h +++ b/modules/bullet/bullet_types_converter.h @@ -31,7 +31,7 @@ #ifndef BULLET_TYPES_CONVERTER_H #define BULLET_TYPES_CONVERTER_H -#include "core/math/matrix3.h" +#include "core/math/basis.h" #include "core/math/transform.h" #include "core/math/vector3.h" #include "core/typedefs.h" diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index 91a5ed095a..ef5f21fc21 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -69,8 +69,12 @@ void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_s CollisionObjectBullet::CollisionObjectBullet(Type p_type) : RIDBullet(), type(p_type), + instance_id(0), + collisionLayer(0), + collisionMask(0), collisionsEnabled(true), m_isStatic(false), + ray_pickable(false), bt_collision_object(NULL), body_scale(1., 1., 1.), force_shape_reset(false), diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 12282b4730..a0be0138d3 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -32,7 +32,7 @@ #include "core/math/face3.h" #include "core/math/geometry.h" #include "core/os/os.h" -#include "core/sort.h" +#include "core/sort_array.h" #include "thirdparty/misc/triangulator.h" void CSGBrush::clear() { diff --git a/modules/csg/csg.h b/modules/csg/csg.h index ac16575e82..4fa1a945cc 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -31,7 +31,6 @@ #ifndef CSG_H #define CSG_H -#include "core/dvector.h" #include "core/map.h" #include "core/math/aabb.h" #include "core/math/plane.h" @@ -39,6 +38,7 @@ #include "core/math/transform.h" #include "core/math/vector3.h" #include "core/oa_hash_map.h" +#include "core/pool_vector.h" #include "scene/resources/material.h" struct CSGBrush { diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index f62e6f5c40..f274fff3f3 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -531,6 +531,13 @@ void CSGShape::_notification(int p_what) { } } + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + + if (parent) { + parent->_make_dirty(); + } + } + if (p_what == NOTIFICATION_EXIT_TREE) { if (parent) diff --git a/modules/csg/doc_classes/CSGShape.xml b/modules/csg/doc_classes/CSGShape.xml index 56087cbb82..d304d0179f 100644 --- a/modules/csg/doc_classes/CSGShape.xml +++ b/modules/csg/doc_classes/CSGShape.xml @@ -29,6 +29,12 @@ Returns an individual bit on the collision mask. </description> </method> + <method name="get_meshes" qualifiers="const"> + <return type="Array"> + </return> + <description> + </description> + </method> <method name="is_root_shape" qualifiers="const"> <return type="bool"> </return> diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp index 01fbc316cf..11509fc20a 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp +++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp @@ -31,7 +31,7 @@ #include "arvr_interface_gdnative.h" #include "main/input_default.h" #include "servers/arvr/arvr_positional_tracker.h" -#include "servers/visual/visual_server_global.h" +#include "servers/visual/visual_server_globals.h" ARVRInterfaceGDNative::ARVRInterfaceGDNative() { // testing diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp index 18da9d811e..6849ff03d7 100644 --- a/modules/gdnative/gdnative/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -34,7 +34,7 @@ #include "core/os/memory.h" #include "core/color.h" -#include "core/dvector.h" +#include "core/pool_vector.h" #include "core/variant.h" diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index 4441a03ca1..d77c7d91ac 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -30,7 +30,7 @@ #include "gdnative/basis.h" -#include "core/math/matrix3.h" +#include "core/math/basis.h" #include "core/variant.h" #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp index 68e064d829..74c540ca14 100644 --- a/modules/gdnative/gdnative/pool_arrays.cpp +++ b/modules/gdnative/gdnative/pool_arrays.cpp @@ -31,7 +31,7 @@ #include "gdnative/pool_arrays.h" #include "core/array.h" -#include "core/dvector.h" +#include "core/pool_vector.h" #include "core/variant.h" #include "core/color.h" diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 4b8d79305c..913c57eb56 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -30,7 +30,7 @@ #include "gdnative/string.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/ustring.h" #include "core/variant.h" diff --git a/modules/gdnative/gdnative/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp index d2862c5980..dcbb773c25 100644 --- a/modules/gdnative/gdnative/string_name.cpp +++ b/modules/gdnative/gdnative/string_name.cpp @@ -30,7 +30,7 @@ #include "gdnative/string_name.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/ustring.h" #include <string.h> diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py index cd356ce513..5fd5971fd1 100644 --- a/modules/gdnative/gdnative_builders.py +++ b/modules/gdnative/gdnative_builders.py @@ -213,7 +213,7 @@ def _build_gdnative_api_struct_source(api): 'extern const godot_gdnative_core_api_struct api_struct = {', '\tGDNATIVE_' + api['core']['type'] + ',', '\t{' + str(api['core']['version']['major']) + ', ' + str(api['core']['version']['minor']) + '},', - '\tNULL,', + '\t(const godot_gdnative_api_struct *)&api_1_1,', '\t' + str(len(api['extensions'])) + ',', '\tgdnative_extensions_pointers,', ] diff --git a/modules/gdnative/include/videodecoder/godot_videodecoder.h b/modules/gdnative/include/videodecoder/godot_videodecoder.h index 360fc0f5f5..1b08be30f0 100644 --- a/modules/gdnative/include/videodecoder/godot_videodecoder.h +++ b/modules/gdnative/include/videodecoder/godot_videodecoder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 0370060937..9fd0a2e8ec 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -39,7 +39,7 @@ #include "core/project_settings.h" #include "scene/main/scene_tree.h" -#include "scene/resources/scene_format_text.h" +#include "scene/resources/resource_format_text.h" #include <stdlib.h> diff --git a/modules/gdnative/videodecoder/register_types.cpp b/modules/gdnative/videodecoder/register_types.cpp index ea78cb1970..0a0b2f64d5 100644 --- a/modules/gdnative/videodecoder/register_types.cpp +++ b/modules/gdnative/videodecoder/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/videodecoder/register_types.h b/modules/gdnative/videodecoder/register_types.h index dd1943fc47..f082343d8c 100644 --- a/modules/gdnative/videodecoder/register_types.h +++ b/modules/gdnative/videodecoder/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index a1590cef43..8c2a84f60b 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h index f9dec46b72..aafd02f33d 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.h +++ b/modules/gdnative/videodecoder/video_stream_gdnative.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 6d85eb3c90..f29432666e 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -483,7 +483,7 @@ bool GDScript::_update_exports() { placeholder_fallback_enabled = true; return false; } - } else if (!valid || placeholder_fallback_enabled) { + } else if (placeholder_fallback_enabled) { return false; } diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index f69bd6c08a..af770ac533 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -618,6 +618,9 @@ static GDScriptCompletionIdentifier _type_from_gdtype(const GDScriptDataType &p_ ci.type.script_type = p_gdtype.script_type; switch (p_gdtype.kind) { + case GDScriptDataType::UNINITIALIZED: { + ERR_EXPLAIN("Uninitialized completion. Please report a bug."); + } break; case GDScriptDataType::BUILTIN: { ci.type.kind = GDScriptParser::DataType::BUILTIN; } break; diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index f4058664ff..cefc28d77f 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -36,7 +36,7 @@ #include "core/reference.h" #include "core/script_language.h" #include "core/self_list.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/variant.h" class GDScriptInstance; @@ -45,10 +45,11 @@ class GDScript; struct GDScriptDataType { bool has_type; enum { + UNINITIALIZED, BUILTIN, NATIVE, SCRIPT, - GDSCRIPT + GDSCRIPT, } kind; Variant::Type builtin_type; StringName native_type; @@ -58,6 +59,8 @@ struct GDScriptDataType { if (!has_type) return true; // Can't type check switch (kind) { + case UNINITIALIZED: + break; case BUILTIN: { Variant::Type var_type = p_variant.get_type(); bool valid = builtin_type == var_type; @@ -113,6 +116,8 @@ struct GDScriptDataType { PropertyInfo info; if (has_type) { switch (kind) { + case UNINITIALIZED: + break; case BUILTIN: { info.type = builtin_type; } break; @@ -134,7 +139,9 @@ struct GDScriptDataType { } GDScriptDataType() : - has_type(false) {} + has_type(false), + kind(UNINITIALIZED), + builtin_type(Variant::NIL) {} }; class GDScriptFunction { diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index af189fdb7e..b53d37226c 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3494,16 +3494,20 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); if ((tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING)) { - Variant constant = tokenizer->get_token_constant(); - String icon_path = constant.operator String(); +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + Variant constant = tokenizer->get_token_constant(); + String icon_path = constant.operator String(); - String abs_icon_path = icon_path.is_rel_path() ? self_path.get_base_dir().plus_file(icon_path).simplify_path() : icon_path; - if (!FileAccess::exists(abs_icon_path)) { - _set_error("No class icon found at: " + abs_icon_path); - return; - } + String abs_icon_path = icon_path.is_rel_path() ? self_path.get_base_dir().plus_file(icon_path).simplify_path() : icon_path; + if (!FileAccess::exists(abs_icon_path)) { + _set_error("No class icon found at: " + abs_icon_path); + return; + } - p_class->icon_path = icon_path; + p_class->icon_path = icon_path; + } +#endif tokenizer->advance(); } else { @@ -4553,6 +4557,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { //variale declaration and (eventual) initialization ClassNode::Member member; + bool autoexport = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_EXPORT; if (current_export.type != Variant::NIL) { member._export = current_export; @@ -4720,6 +4725,25 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { _set_error("Type-less export needs a constant expression assigned to infer type."); return; } + + if (member._export.type != Variant::NIL) { + IdentifierNode *id = alloc_node<IdentifierNode>(); + id->name = member.identifier; + + ConstantNode *cn = alloc_node<ConstantNode>(); + + Variant::CallError ce; + cn->value = Variant::construct(member._export.type, NULL, 0, ce); + + OperatorNode *op = alloc_node<OperatorNode>(); + op->op = OperatorNode::OP_INIT_ASSIGN; + op->arguments.push_back(id); + op->arguments.push_back(cn); + + p_class->initializer->statements.push_back(op); + + member.initial_assignment = op; + } } if (autoexport && member.data_type.has_type) { @@ -5594,6 +5618,9 @@ GDScriptParser::DataType GDScriptParser::_type_from_gdtype(const GDScriptDataTyp result.script_type = p_gdtype.script_type; switch (p_gdtype.kind) { + case GDScriptDataType::UNINITIALIZED: { + ERR_EXPLAIN("Uninitialized datatype. Please report a bug."); + } break; case GDScriptDataType::BUILTIN: { result.kind = DataType::BUILTIN; } break; @@ -6795,7 +6822,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat return_type = original_type; return_type.is_meta_type = false; - valid = true; // There's always an initializer, we can asume this is true + valid = true; // There's always an initializer, we can assume this is true } if (!valid) { diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index b4a705c9e7..d1ddf9aa12 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -95,6 +95,7 @@ public: } DataType() : + kind(UNRESOLVED), has_type(false), is_constant(false), is_meta_type(false), @@ -168,6 +169,7 @@ public: MultiplayerAPI::RPCMode rpc_mode; int usages; }; + struct Constant { Node *expression; DataType type; diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index abacdf0322..e4315f7969 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -32,7 +32,7 @@ #define GDSCRIPT_TOKENIZER_H #include "core/pair.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/ustring.h" #include "core/variant.h" #include "core/vmap.h" diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbed_tls.cpp index 973713f500..e4050b1af8 100755 --- a/modules/mbedtls/stream_peer_mbed_tls.cpp +++ b/modules/mbedtls/stream_peer_mbed_tls.cpp @@ -313,7 +313,7 @@ void StreamPeerMbedTLS::disconnect_from_stream() { Ref<StreamPeerTCP> tcp = base; if (tcp.is_valid() && tcp->get_status() == StreamPeerTCP::STATUS_CONNECTED) { - // We are still connected on the socket, try to send close notity. + // We are still connected on the socket, try to send close notify. mbedtls_ssl_close_notify(&ssl); } diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 78cc667718..b4fbd417d7 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -31,7 +31,7 @@ #include "mobile_vr_interface.h" #include "core/os/input.h" #include "core/os/os.h" -#include "servers/visual/visual_server_global.h" +#include "servers/visual/visual_server_globals.h" StringName MobileVRInterface::get_name() const { return "Native mobile"; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 5da1344595..9c127b837d 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1113,19 +1113,23 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) { + SCOPED_MUTEX_LOCK(language_bind_mutex); + + Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object); + if (match) + return (void *)match; + CSharpScriptBinding script_binding; if (!setup_csharp_script_binding(script_binding, p_object)) return NULL; - void *data; + return (void *)insert_script_binding(p_object, script_binding); +} - { - SCOPED_MUTEX_LOCK(language_bind_mutex); - data = (void *)script_bindings.insert(p_object, script_binding); - } +Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding) { - return data; + return script_bindings.insert(p_object, p_script_binding); } void CSharpLanguage::free_instance_binding_data(void *p_data) { @@ -2279,17 +2283,18 @@ void CSharpScript::_bind_methods() { ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &CSharpScript::_new, MethodInfo(Variant::OBJECT, "new")); } -Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class) { +Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native) { // This method should not fail CRASH_COND(!p_class); + // TODO: Cache the 'CSharpScript' associated with this 'p_class' instead of allocating a new one every time Ref<CSharpScript> script = memnew(CSharpScript); script->name = p_class->get_name(); script->script_class = p_class; - script->native = GDMonoUtils::get_class_native_base(script->script_class); + script->native = p_native; CRASH_COND(script->native == NULL); diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index db9d6a73a2..8b1a4b5f7e 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -135,7 +135,7 @@ class CSharpScript : public Script { // Do not use unless you know what you are doing friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *); - static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class); + static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native); protected: static void _bind_methods(); @@ -312,6 +312,8 @@ class CSharpLanguage : public ScriptLanguage { public: StringNameCache string_names; + Mutex *get_language_bind_mutex() { return language_bind_mutex; } + _FORCE_INLINE_ int get_language_index() { return lang_idx; } void set_language_index(int p_idx); @@ -406,6 +408,7 @@ public: virtual void refcount_incremented_instance_binding(Object *p_object); virtual bool refcount_decremented_instance_binding(Object *p_object); + Map<Object *, CSharpScriptBinding>::Element *insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding); bool setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object); #ifdef DEBUG_ENABLED diff --git a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs index 4137f5eaef..e7d0486c76 100644 --- a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs +++ b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs @@ -18,8 +18,6 @@ namespace GodotSharpTools.Build [MethodImpl(MethodImplOptions.InternalCall)] private extern static string godot_icall_BuildInstance_get_MSBuildPath(); [MethodImpl(MethodImplOptions.InternalCall)] - private extern static string godot_icall_BuildInstance_get_FrameworkPath(); - [MethodImpl(MethodImplOptions.InternalCall)] private extern static string godot_icall_BuildInstance_get_MonoWindowsBinDir(); [MethodImpl(MethodImplOptions.InternalCall)] private extern static bool godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows(); @@ -34,11 +32,6 @@ namespace GodotSharpTools.Build return msbuildPath; } - private static string GetFrameworkPath() - { - return godot_icall_BuildInstance_get_FrameworkPath(); - } - private static string MonoWindowsBinDir { get @@ -85,11 +78,6 @@ namespace GodotSharpTools.Build if (customProperties != null) customPropertiesList.AddRange(customProperties); - string frameworkPath = GetFrameworkPath(); - - if (!string.IsNullOrEmpty(frameworkPath)) - customPropertiesList.Add("FrameworkPathOverride=" + frameworkPath); - string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList); ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); @@ -145,11 +133,6 @@ namespace GodotSharpTools.Build if (customProperties != null) customPropertiesList.AddRange(customProperties); - string frameworkPath = GetFrameworkPath(); - - if (!string.IsNullOrEmpty(frameworkPath)) - customPropertiesList.Add("FrameworkPathOverride=" + frameworkPath); - string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList); ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj index f9e9f41977..9a5dd24bb1 100644 --- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj +++ b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj @@ -8,6 +8,7 @@ <RootNamespace>GodotSharpTools</RootNamespace> <AssemblyName>GodotSharpTools</AssemblyName> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <BaseIntermediateOutputPath>obj</BaseIntermediateOutputPath> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 0b6a6a327c..77e9b1f1f4 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -849,6 +849,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } } + // TODO: BINDINGS_NATIVE_NAME_FIELD should be StringName, once we support it in C# + if (itype.is_singleton) { // Add the type name and the singleton pointer as static fields diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index a040e4a344..5e1c9875f0 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -100,22 +100,24 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() { if (msbuild_tools_path.empty() || !FileAccess::exists(msbuild_tools_path)) { // Try to search it again if it wasn't found last time or if it was removed from its location msbuild_tools_path = MonoRegUtils::find_msbuild_tools_path(); - } - - if (msbuild_tools_path.length()) { - if (!msbuild_tools_path.ends_with("\\")) - msbuild_tools_path += "\\"; - return GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe"); + if (msbuild_tools_path.empty()) { + ERR_PRINTS("Cannot find executable for '" PROP_NAME_MSBUILD_VS "'. Tried with path: " + msbuild_tools_path); + return NULL; + } } - print_verbose("Cannot find executable for '" PROP_NAME_MSBUILD_VS "'. Trying with '" PROP_NAME_MSBUILD_MONO "'..."); - } // FALL THROUGH + if (!msbuild_tools_path.ends_with("\\")) + msbuild_tools_path += "\\"; + + return GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe"); + } break; case GodotSharpBuilds::MSBUILD_MONO: { String msbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("msbuild.bat"); if (!FileAccess::exists(msbuild_path)) { - WARN_PRINTS("Cannot find executable for '" PROP_NAME_MSBUILD_MONO "'. Tried with path: " + msbuild_path); + ERR_PRINTS("Cannot find executable for '" PROP_NAME_MSBUILD_MONO "'. Tried with path: " + msbuild_path); + return NULL; } return GDMonoMarshal::mono_string_from_godot(msbuild_path); @@ -124,7 +126,8 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() { String xbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("xbuild.bat"); if (!FileAccess::exists(xbuild_path)) { - WARN_PRINTS("Cannot find executable for '" PROP_NAME_XBUILD "'. Tried with path: " + xbuild_path); + ERR_PRINTS("Cannot find executable for '" PROP_NAME_XBUILD "'. Tried with path: " + xbuild_path); + return NULL; } return GDMonoMarshal::mono_string_from_godot(xbuild_path); @@ -144,7 +147,7 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() { } if (xbuild_path.empty()) { - WARN_PRINT("Cannot find binary for '" PROP_NAME_XBUILD "'"); + ERR_PRINT("Cannot find binary for '" PROP_NAME_XBUILD "'"); return NULL; } } else { @@ -154,7 +157,7 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() { } if (msbuild_path.empty()) { - WARN_PRINT("Cannot find binary for '" PROP_NAME_MSBUILD_MONO "'"); + ERR_PRINT("Cannot find binary for '" PROP_NAME_MSBUILD_MONO "'"); return NULL; } } @@ -168,22 +171,6 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() { #endif } -MonoString *godot_icall_BuildInstance_get_FrameworkPath() { - -#if defined(WINDOWS_ENABLED) - const MonoRegInfo &mono_reg_info = GDMono::get_singleton()->get_mono_reg_info(); - if (mono_reg_info.assembly_dir.length()) { - String framework_path = path_join(mono_reg_info.assembly_dir, "mono", "4.5"); - return GDMonoMarshal::mono_string_from_godot(framework_path); - } - - ERR_EXPLAIN("Cannot find Mono's assemblies directory in the registry"); - ERR_FAIL_V(NULL); -#else - return NULL; -#endif -} - MonoString *godot_icall_BuildInstance_get_MonoWindowsBinDir() { #if defined(WINDOWS_ENABLED) @@ -216,7 +203,6 @@ void GodotSharpBuilds::register_internal_calls() { mono_add_internal_call("GodotSharpTools.Build.BuildSystem::godot_icall_BuildInstance_ExitCallback", (void *)godot_icall_BuildInstance_ExitCallback); mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MSBuildPath", (void *)godot_icall_BuildInstance_get_MSBuildPath); - mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_FrameworkPath", (void *)godot_icall_BuildInstance_get_FrameworkPath); mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MonoWindowsBinDir", (void *)godot_icall_BuildInstance_get_MonoWindowsBinDir); mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows", (void *)godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows); } @@ -459,7 +445,11 @@ GodotSharpBuilds::GodotSharpBuilds() { // Build tool settings EditorSettings *ed_settings = EditorSettings::get_singleton(); +#ifdef WINDOWS_ENABLED + EDITOR_DEF("mono/builds/build_tool", MSBUILD_VS); +#else EDITOR_DEF("mono/builds/build_tool", MSBUILD_MONO); +#endif ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/builds/build_tool", PROPERTY_HINT_ENUM, PROP_NAME_MSBUILD_MONO diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index ee93229700..17e29fba19 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -272,19 +272,50 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int static String vscode_path; if (vscode_path.empty() || !FileAccess::exists(vscode_path)) { - static List<String> vscode_name; - vscode_name.push_back("code"); - vscode_name.push_back("code-oss"); - vscode_name.push_back("vscode"); - vscode_name.push_back("vscode-oss"); - vscode_name.push_back("visual-studio-code"); - vscode_name.push_back("visual-studio-code-oss"); // Try to search it again if it wasn't found last time or if it was removed from its location - for (int i = 0; i < vscode_name.size(); i++) { - vscode_path = path_which(vscode_name[i]); - if (!vscode_path.empty() || FileAccess::exists(vscode_path)) + bool found = false; + + // TODO: Use initializer lists once C++11 is allowed + + // Try with hint paths + static Vector<String> hint_paths; +#ifdef WINDOWS_ENABLED + if (hint_paths.empty()) { + hint_paths.push_back(OS::get_singleton()->get_environment("ProgramFiles") + "\\Microsoft VS Code\\Code.exe"); + if (sizeof(size_t) == 8) { + hint_paths.push_back(OS::get_singleton()->get_environment("ProgramFiles(x86)") + "\\Microsoft VS Code\\Code.exe"); + } + } +#endif + for (int i = 0; i < hint_paths.size(); i++) { + vscode_path = hint_paths[i]; + if (FileAccess::exists(vscode_path)) { + found = true; break; + } + } + + if (!found) { + static Vector<String> vscode_names; + if (vscode_names.empty()) { + vscode_names.push_back("code"); + vscode_names.push_back("code-oss"); + vscode_names.push_back("vscode"); + vscode_names.push_back("vscode-oss"); + vscode_names.push_back("visual-studio-code"); + vscode_names.push_back("visual-studio-code-oss"); + } + for (int i = 0; i < vscode_names.size(); i++) { + vscode_path = path_which(vscode_names[i]); + if (!vscode_path.empty()) { + found = true; + break; + } + } } + + if (!found) + vscode_path.clear(); // Not found, clear so next time the empty() check is enough } List<String> args; diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp index 47341e3555..7e2487a6e7 100644 --- a/modules/mono/editor/godotsharp_export.cpp +++ b/modules/mono/editor/godotsharp_export.cpp @@ -124,7 +124,7 @@ void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug ERR_FAIL_COND(!load_success); Vector<String> search_dirs; - GDMonoAssembly::fill_search_dirs(search_dirs); + GDMonoAssembly::fill_search_dirs(search_dirs, build_config); Error depend_error = _get_assembly_dependencies(scripts_assembly, search_dirs, dependencies); ERR_FAIL_COND(depend_error != OK); } diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp index d3efa288e9..cc9822e319 100644 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ b/modules/mono/editor/mono_bottom_panel.cpp @@ -156,10 +156,20 @@ void MonoBottomPanel::_build_project_pressed() { if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path())) return; // No solution to build - String scripts_metadata_path = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata.editor"); - Error metadata_err = CSharpProject::generate_scripts_metadata(GodotSharpDirs::get_project_csproj_path(), scripts_metadata_path); + String scripts_metadata_path_editor = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata.editor"); + String scripts_metadata_path_player = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata.editor_player"); + + Error metadata_err = CSharpProject::generate_scripts_metadata(GodotSharpDirs::get_project_csproj_path(), scripts_metadata_path_editor); ERR_FAIL_COND(metadata_err != OK); + if (FileAccess::exists(scripts_metadata_path_editor)) { + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Error copy_err = da->copy(scripts_metadata_path_editor, scripts_metadata_path_player); + + ERR_EXPLAIN("Failed to copy scripts metadata file"); + ERR_FAIL_COND(copy_err != OK); + } + bool build_success = GodotSharpBuilds::get_singleton()->build_project_blocking("Tools"); if (build_success) { diff --git a/modules/mono/glue/Managed/Files/Transform2D.cs b/modules/mono/glue/Managed/Files/Transform2D.cs index c9e5b560b2..df7ba3402d 100644 --- a/modules/mono/glue/Managed/Files/Transform2D.cs +++ b/modules/mono/glue/Managed/Files/Transform2D.cs @@ -13,21 +13,44 @@ namespace Godot { public Vector2 x; public Vector2 y; - public Vector2 o; - - public Vector2 Origin - { - get { return o; } - } + public Vector2 origin; public real_t Rotation { - get { return Mathf.Atan2(y.x, o.y); } + get + { + real_t det = BasisDeterminant(); + Transform2D t = Orthonormalized(); + if (det < 0) + { + t.ScaleBasis(new Vector2(1, -1)); + } + return Mathf.Atan2(t.x.y, t.x.x); + } + set + { + Vector2 scale = Scale; + x.x = y.y = Mathf.Cos(value); + x.y = y.x = Mathf.Sin(value); + y.x *= -1; + Scale = scale; + } } public Vector2 Scale { - get { return new Vector2(x.Length(), y.Length()); } + get + { + real_t detSign = Mathf.Sign(BasisDeterminant()); + return new Vector2(x.Length(), detSign * y.Length()); + } + set + { + x = x.Normalized(); + y = y.Normalized(); + x *= value.x; + y *= value.y; + } } public Vector2 this[int index] @@ -41,7 +64,7 @@ namespace Godot case 1: return y; case 2: - return o; + return origin; default: throw new IndexOutOfRangeException(); } @@ -57,7 +80,7 @@ namespace Godot y = value; return; case 2: - o = value; + origin = value; return; default: throw new IndexOutOfRangeException(); @@ -100,32 +123,37 @@ namespace Godot { var inv = this; - real_t det = this[0, 0] * this[1, 1] - this[1, 0] * this[0, 1]; + real_t det = BasisDeterminant(); if (det == 0) { return new Transform2D ( - float.NaN, float.NaN, - float.NaN, float.NaN, - float.NaN, float.NaN + real_t.NaN, real_t.NaN, + real_t.NaN, real_t.NaN, + real_t.NaN, real_t.NaN ); } - real_t idet = 1.0f / det; + real_t detInv = 1.0f / det; real_t temp = this[0, 0]; this[0, 0] = this[1, 1]; this[1, 1] = temp; - this[0] *= new Vector2(idet, -idet); - this[1] *= new Vector2(-idet, idet); + this[0] *= new Vector2(detInv, -detInv); + this[1] *= new Vector2(-detInv, detInv); this[2] = BasisXform(-this[2]); return inv; } + private real_t BasisDeterminant() + { + return x.x * y.y - x.y * y.x; + } + public Vector2 BasisXform(Vector2 v) { return new Vector2(Tdotx(v), Tdoty(v)); @@ -168,8 +196,8 @@ namespace Godot } // Extract parameters - Vector2 p1 = Origin; - Vector2 p2 = m.Origin; + Vector2 p1 = origin; + Vector2 p2 = m.origin; // Construct matrix var res = new Transform2D(Mathf.Atan2(v.y, v.x), p1.LinearInterpolate(p2, c)); @@ -189,7 +217,7 @@ namespace Godot inv.x.y = inv.y.x; inv.y.x = temp; - inv.o = inv.BasisXform(-inv.o); + inv.origin = inv.BasisXform(-inv.origin); return inv; } @@ -221,10 +249,18 @@ namespace Godot var copy = this; copy.x *= scale; copy.y *= scale; - copy.o *= scale; + copy.origin *= scale; return copy; } + private void ScaleBasis(Vector2 scale) + { + x.x *= scale.x; + x.y *= scale.y; + y.x *= scale.x; + y.y *= scale.y; + } + private real_t Tdotx(Vector2 with) { return this[0, 0] * with[0] + this[1, 0] * with[1]; @@ -238,59 +274,56 @@ namespace Godot public Transform2D Translated(Vector2 offset) { var copy = this; - copy.o += copy.BasisXform(offset); + copy.origin += copy.BasisXform(offset); return copy; } public Vector2 Xform(Vector2 v) { - return new Vector2(Tdotx(v), Tdoty(v)) + o; + return new Vector2(Tdotx(v), Tdoty(v)) + origin; } public Vector2 XformInv(Vector2 v) { - Vector2 vInv = v - o; + Vector2 vInv = v - origin; return new Vector2(x.Dot(vInv), y.Dot(vInv)); } // Constants - private static readonly Transform2D _identity = new Transform2D(new Vector2(1f, 0f), new Vector2(0f, 1f), Vector2.Zero); - private static readonly Transform2D _flipX = new Transform2D(new Vector2(-1f, 0f), new Vector2(0f, 1f), Vector2.Zero); - private static readonly Transform2D _flipY = new Transform2D(new Vector2(1f, 0f), new Vector2(0f, -1f), Vector2.Zero); + private static readonly Transform2D _identity = new Transform2D(1, 0, 0, 1, 0, 0); + private static readonly Transform2D _flipX = new Transform2D(-1, 0, 0, 1, 0, 0); + private static readonly Transform2D _flipY = new Transform2D(1, 0, 0, -1, 0, 0); public static Transform2D Identity { get { return _identity; } } public static Transform2D FlipX { get { return _flipX; } } public static Transform2D FlipY { get { return _flipY; } } // Constructors - public Transform2D(Vector2 xAxis, Vector2 yAxis, Vector2 origin) + public Transform2D(Vector2 xAxis, Vector2 yAxis, Vector2 originPos) { x = xAxis; y = yAxis; - o = origin; + origin = originPos; } public Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) { x = new Vector2(xx, xy); y = new Vector2(yx, yy); - o = new Vector2(ox, oy); + origin = new Vector2(ox, oy); } public Transform2D(real_t rot, Vector2 pos) { - real_t cr = Mathf.Cos(rot); - real_t sr = Mathf.Sin(rot); - x.x = cr; - y.y = cr; - x.y = -sr; - y.x = sr; - o = pos; + x.x = y.y = Mathf.Cos(rot); + x.y = y.x = Mathf.Sin(rot); + y.x *= -1; + origin = pos; } public static Transform2D operator *(Transform2D left, Transform2D right) { - left.o = left.Xform(right.o); + left.origin = left.Xform(right.origin); real_t x0, x1, y0, y1; @@ -329,12 +362,12 @@ namespace Godot public bool Equals(Transform2D other) { - return x.Equals(other.x) && y.Equals(other.y) && o.Equals(other.o); + return x.Equals(other.x) && y.Equals(other.y) && origin.Equals(other.origin); } public override int GetHashCode() { - return x.GetHashCode() ^ y.GetHashCode() ^ o.GetHashCode(); + return x.GetHashCode() ^ y.GetHashCode() ^ origin.GetHashCode(); } public override string ToString() @@ -343,7 +376,7 @@ namespace Godot { x.ToString(), y.ToString(), - o.ToString() + origin.ToString() }); } @@ -353,7 +386,7 @@ namespace Godot { x.ToString(format), y.ToString(format), - o.ToString(format) + origin.ToString(format) }); } } diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 2963619b79..fad02b01d3 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -33,7 +33,7 @@ #ifdef MONO_GLUE_ENABLED #include "core/reference.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "../csharp_script.h" #include "../mono_gd/gd_mono_internals.h" diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index 3943c0c7d7..09a1fc6fbc 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -99,7 +99,6 @@ public: String sln_filepath; String csproj_filepath; - String data_mono_bin_dir; String data_editor_tools_dir; String data_editor_prebuilt_api_dir; #endif @@ -107,6 +106,10 @@ public: String data_mono_etc_dir; String data_mono_lib_dir; +#ifdef WINDOWS_ENABLED + String data_mono_bin_dir; +#endif + private: _GodotSharpDirs() { res_data_dir = "res://.mono"; @@ -146,10 +149,13 @@ private: data_editor_prebuilt_api_dir = data_dir_root.plus_file("Api"); String data_mono_root_dir = data_dir_root.plus_file("Mono"); - data_mono_bin_dir = data_mono_root_dir.plus_file("bin"); data_mono_etc_dir = data_mono_root_dir.plus_file("etc"); data_mono_lib_dir = data_mono_root_dir.plus_file("lib"); +#ifdef WINDOWS_ENABLED + data_mono_bin_dir = data_mono_root_dir.plus_file("bin"); +#endif + #ifdef OSX_ENABLED if (!DirAccess::exists(data_editor_tools_dir)) { data_editor_tools_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Tools"); @@ -160,7 +166,6 @@ private: } if (!DirAccess::exists(data_mono_root_dir)) { - data_mono_bin_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/bin"); data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc"); data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib"); } @@ -178,6 +183,10 @@ private: data_mono_etc_dir = data_mono_root_dir.plus_file("etc"); data_mono_lib_dir = data_mono_root_dir.plus_file("lib"); +#ifdef WINDOWS_ENABLED + data_mono_bin_dir = data_mono_root_dir.plus_file("bin"); +#endif + #ifdef OSX_ENABLED if (!DirAccess::exists(data_mono_root_dir)) { data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc"); @@ -251,10 +260,6 @@ String get_project_csproj_path() { return _GodotSharpDirs::get_singleton().csproj_filepath; } -String get_data_mono_bin_dir() { - return _GodotSharpDirs::get_singleton().data_mono_bin_dir; -} - String get_data_editor_tools_dir() { return _GodotSharpDirs::get_singleton().data_editor_tools_dir; } @@ -272,4 +277,10 @@ String get_data_mono_lib_dir() { return _GodotSharpDirs::get_singleton().data_mono_lib_dir; } +#ifdef WINDOWS_ENABLED +String get_data_mono_bin_dir() { + return _GodotSharpDirs::get_singleton().data_mono_bin_dir; +} +#endif + } // namespace GodotSharpDirs diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h index a038e6486c..556df959e2 100644 --- a/modules/mono/godotsharp_dirs.h +++ b/modules/mono/godotsharp_dirs.h @@ -53,7 +53,6 @@ String get_build_logs_dir(); String get_project_sln_path(); String get_project_csproj_path(); -String get_data_mono_bin_dir(); String get_data_editor_tools_dir(); String get_data_editor_prebuilt_api_dir(); #endif @@ -61,6 +60,10 @@ String get_data_editor_prebuilt_api_dir(); String get_data_mono_etc_dir(); String get_data_mono_lib_dir(); +#ifdef WINDOWS_ENABLED +String get_data_mono_bin_dir(); +#endif + } // namespace GodotSharpDirs #endif // GODOTSHARP_DIRS_H diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index ca1ff9f9ff..bba8b1050f 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -157,7 +157,17 @@ void GDMono::add_mono_shared_libs_dir_to_path() { path_value += ';'; String bundled_bin_dir = GodotSharpDirs::get_data_mono_bin_dir(); - path_value += DirAccess::exists(bundled_bin_dir) ? bundled_bin_dir : mono_reg_info.bin_dir; +#ifdef TOOLS_ENABLED + if (DirAccess::exists(bundled_bin_dir)) { + path_value += bundled_bin_dir; + } else { + path_value += mono_reg_info.bin_dir; + } +#else + if (DirAccess::exists(bundled_bin_dir)) + path_value += bundled_bin_dir; +#endif // TOOLS_ENABLED + #else path_value += ':'; @@ -167,10 +177,10 @@ void GDMono::add_mono_shared_libs_dir_to_path() { } else { // TODO: Do we need to add the lib dir when using the system installed Mono on Unix platforms? } -#endif +#endif // WINDOWS_ENABLED OS::get_singleton()->set_environment(path_var, path_value); -#endif +#endif // WINDOWS_ENABLED || UNIX_ENABLED } void GDMono::initialize() { @@ -231,11 +241,21 @@ void GDMono::initialize() { assembly_rootdir = bundled_assembly_rootdir; config_dir = bundled_config_dir; } + +#ifdef WINDOWS_ENABLED + if (assembly_rootdir.empty() || config_dir.empty()) { + // Assertion: if they are not set, then they weren't found in the registry + CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0); + + ERR_PRINT("Cannot find Mono in the registry"); + } +#endif // WINDOWS_ENABLED + #else // These are always the directories in export templates assembly_rootdir = bundled_assembly_rootdir; config_dir = bundled_config_dir; -#endif +#endif // TOOLS_ENABLED // Leak if we call mono_set_dirs more than once mono_set_dirs(assembly_rootdir.length() ? assembly_rootdir.utf8().get_data() : NULL, @@ -253,6 +273,29 @@ void GDMono::initialize() { mono_install_unhandled_exception_hook(&unhandled_exception_hook, NULL); +#ifdef TOOLS_ENABLED + if (!DirAccess::exists("res://.mono")) { + // 'res://.mono/' is missing so there is nothing to load. We don't need to initialize mono, but + // we still do so unless mscorlib is missing (which is the case for projects that don't use C#). + + String mscorlib_fname("mscorlib.dll"); + + Vector<String> search_dirs; + GDMonoAssembly::fill_search_dirs(search_dirs); + + bool found = false; + for (int i = 0; i < search_dirs.size(); i++) { + if (FileAccess::exists(search_dirs[i].plus_file(mscorlib_fname))) { + found = true; + break; + } + } + + if (!found) + return; // mscorlib is missing, do not initialize mono + } +#endif + root_domain = mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319"); ERR_EXPLAIN("Mono: Failed to initialize runtime"); diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h index a3244101d8..e348583370 100644 --- a/modules/mono/mono_gd/gd_mono_field.h +++ b/modules/mono/mono_gd/gd_mono_field.h @@ -32,8 +32,8 @@ #define GDMONOFIELD_H #include "gd_mono.h" -#include "gd_mono_class_member.h" #include "gd_mono_header.h" +#include "i_mono_class_member.h" class GDMonoField : public IMonoClassMember { diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index 0daa394e63..14ec24466b 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -34,6 +34,8 @@ #include "../mono_gc_handle.h" #include "../utils/macros.h" #include "../utils/thread_local.h" +#include "gd_mono_class.h" +#include "gd_mono_marshal.h" #include "gd_mono_utils.h" #include <mono/metadata/exception.h> @@ -55,10 +57,49 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { CRASH_COND(!klass); + GDMonoClass *native = GDMonoUtils::get_class_native_base(klass); + + CRASH_COND(native == NULL); + + if (native == klass) { + // If it's just a wrapper Godot class and not a custom inheriting class, then attach a + // script binding instead. One of the advantages of this is that if a script is attached + // later and it's not a C# script, then the managed object won't have to be disposed. + // Another reason for doing this is that this instance could outlive CSharpLanguage, which would + // be problematic when using a script. See: https://github.com/godotengine/godot/issues/25621 + + CSharpScriptBinding script_binding; + + script_binding.inited = true; + script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass); + script_binding.wrapper_class = klass; + script_binding.gchandle = MonoGCHandle::create_strong(managed); + + Reference *ref = Object::cast_to<Reference>(unmanaged); + if (ref) { + // Unsafe refcount increment. The managed instance also counts as a reference. + // This way if the unmanaged world has no references to our owner + // but the managed instance is alive, the refcount will be 1 instead of 0. + // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr) + + ref->reference(); + } + + // The object was just created, no script instance binding should have been attached + CRASH_COND(unmanaged->has_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index())); + + void *data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding); + + // Should be thread safe because the object was just created and nothing else should be referencing it + unmanaged->set_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index(), data); + + return; + } + Ref<MonoGCHandle> gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed); - Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass); + Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass, native); CRASH_COND(script.is_null()); diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h index fc035d387c..f74cef438d 100644 --- a/modules/mono/mono_gd/gd_mono_method.h +++ b/modules/mono/mono_gd/gd_mono_method.h @@ -32,8 +32,8 @@ #define GD_MONO_METHOD_H #include "gd_mono.h" -#include "gd_mono_class_member.h" #include "gd_mono_header.h" +#include "i_mono_class_member.h" class GDMonoMethod : public IMonoClassMember { diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h index d8a9f69ffb..2700c460b0 100644 --- a/modules/mono/mono_gd/gd_mono_property.h +++ b/modules/mono/mono_gd/gd_mono_property.h @@ -32,8 +32,8 @@ #define GD_MONO_PROPERTY_H #include "gd_mono.h" -#include "gd_mono_class_member.h" #include "gd_mono_header.h" +#include "i_mono_class_member.h" class GDMonoProperty : public IMonoClassMember { diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index ac6ccac3a7..3b97339fea 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -39,6 +39,7 @@ #include "../csharp_script.h" #include "../utils/macros.h" +#include "../utils/mutex_utils.h" #include "gd_mono.h" #include "gd_mono_class.h" #include "gd_mono_marshal.h" @@ -281,17 +282,19 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { void *data = unmanaged->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index()); - if (!data) - return NULL; + ERR_FAIL_NULL_V(data, NULL); CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value(); if (!script_binding.inited) { - // Already had a binding that needs to be setup - CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, unmanaged); + SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex()); + + if (!script_binding.inited) { // Other thread may have set it up + // Already had a binding that needs to be setup + CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, unmanaged); - if (!script_binding.inited) - return NULL; + ERR_FAIL_COND_V(!script_binding.inited, NULL); + } } Ref<MonoGCHandle> &gchandle = script_binding.gchandle; diff --git a/modules/mono/mono_gd/gd_mono_class_member.h b/modules/mono/mono_gd/i_mono_class_member.h index 3058b18c05..553d9edc72 100644 --- a/modules/mono/mono_gd/gd_mono_class_member.h +++ b/modules/mono/mono_gd/i_mono_class_member.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_mono_class_member.h */ +/* i_mono_class_member.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GD_MONO_CLASS_MEMBER_H -#define GD_MONO_CLASS_MEMBER_H +#ifndef I_MONO_CLASS_MEMBER_H +#define I_MONO_CLASS_MEMBER_H #include "gd_mono_header.h" @@ -65,4 +65,4 @@ public: virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) = 0; }; -#endif // GD_MONO_CLASS_MEMBER_H +#endif // I_MONO_CLASS_MEMBER_H diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h index 87295a98f2..e44f254e1c 100644 --- a/modules/mono/utils/macros.h +++ b/modules/mono/utils/macros.h @@ -31,10 +31,6 @@ #ifndef UTIL_MACROS_H #define UTIL_MACROS_H -#ifndef __has_cpp_attribute -#define __has_cpp_attribute(attr_token) 0 -#endif - #define _GD_VARNAME_CONCAT_B_(m_ignore, m_name) m_name #define _GD_VARNAME_CONCAT_A_(m_a, m_b, m_c) _GD_VARNAME_CONCAT_B_(hello there, m_a##m_b##m_c) #define _GD_VARNAME_CONCAT_(m_a, m_b, m_c) _GD_VARNAME_CONCAT_A_(m_a, m_b, m_c) @@ -61,7 +57,7 @@ // noreturn // TODO: Get rid of this macro once we upgrade to C++11 -#if __has_cpp_attribute(deprecated) +#if (__cplusplus >= 201103L) #define GD_NORETURN [[noreturn]] #elif defined(__GNUC__) #define GD_NORETURN __attribute__((noreturn)) diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp index 76b250e038..0eb4b3b8b3 100644 --- a/modules/mono/utils/mono_reg_utils.cpp +++ b/modules/mono/utils/mono_reg_utils.cpp @@ -158,8 +158,6 @@ MonoRegInfo find_mono() { if (_find_mono_in_reg_old("Software\\Novell\\Mono", info) == ERROR_SUCCESS) return info; - ERR_PRINT("Cannot find mono in the registry"); - return MonoRegInfo(); } diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.h b/modules/stb_vorbis/resource_importer_ogg_vorbis.h index ca2d662e61..f61fc91cda 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.h +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.h @@ -32,7 +32,7 @@ #define RESOURCEIMPORTEROGGVORBIS_H #include "audio_stream_ogg_vorbis.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class ResourceImporterOGGVorbis : public ResourceImporter { GDCLASS(ResourceImporterOGGVorbis, ResourceImporter) diff --git a/modules/upnp/register_types.cpp b/modules/upnp/register_types.cpp index abb73a3605..fbf0ee8b97 100644 --- a/modules/upnp/register_types.cpp +++ b/modules/upnp/register_types.cpp @@ -33,7 +33,7 @@ #include "core/error_macros.h" #include "upnp.h" -#include "upnpdevice.h" +#include "upnp_device.h" void register_upnp_types() { diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h index b73908724d..011b6d44b3 100644 --- a/modules/upnp/upnp.h +++ b/modules/upnp/upnp.h @@ -33,7 +33,7 @@ #include "core/reference.h" -#include "upnpdevice.h" +#include "upnp_device.h" #include <miniupnpc/miniupnpc.h> diff --git a/modules/upnp/upnpdevice.cpp b/modules/upnp/upnp_device.cpp index 2fb2102df9..4d67e3ddc8 100644 --- a/modules/upnp/upnpdevice.cpp +++ b/modules/upnp/upnp_device.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* upnpdevice.cpp */ +/* upnp_device.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "upnpdevice.h" +#include "upnp_device.h" #include "upnp.h" diff --git a/modules/upnp/upnpdevice.h b/modules/upnp/upnp_device.h index 20fe5c62fe..09fce6af89 100644 --- a/modules/upnp/upnpdevice.h +++ b/modules/upnp/upnp_device.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* upnpdevice.h */ +/* upnp_device.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_UPNPDEVICE_H -#define GODOT_UPNPDEVICE_H +#ifndef GODOT_UPNP_DEVICE_H +#define GODOT_UPNP_DEVICE_H #include "core/reference.h" @@ -92,4 +92,4 @@ private: VARIANT_ENUM_CAST(UPNPDevice::IGDStatus) -#endif // GODOT_UPNPDEVICE_H +#endif // GODOT_UPNP_DEVICE_H diff --git a/modules/visual_script/doc_classes/VisualScriptCondition.xml b/modules/visual_script/doc_classes/VisualScriptCondition.xml index 4657436c8f..a7b1028c0c 100644 --- a/modules/visual_script/doc_classes/VisualScriptCondition.xml +++ b/modules/visual_script/doc_classes/VisualScriptCondition.xml @@ -4,7 +4,7 @@ A Visual Script node which branches the flow. </brief_description> <description> - A Visual Script node that checks a [bool] input port. If [code]true[/code], it will exit via the “true” sequence port. If [code]false[/code], it will exit via the "false" sequence port. After exiting either, it exits via the “done” port. Sequence ports may be left disconnected. + A Visual Script node that checks a [bool] input port. If [code]true[/code], it will exit via the "true" sequence port. If [code]false[/code], it will exit via the "false" sequence port. After exiting either, it exits via the "done" port. Sequence ports may be left disconnected. [b]Input Ports:[/b] - Sequence: [code]if (cond) is[/code] - Data (boolean): [code]cond[/code] diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h index 32db719435..c464d97c7f 100644 --- a/modules/websocket/websocket_client.h +++ b/modules/websocket/websocket_client.h @@ -32,7 +32,7 @@ #define WEBSOCKET_CLIENT_H #include "core/error_list.h" -#include "websocket_multiplayer.h" +#include "websocket_multiplayer_peer.h" #include "websocket_peer.h" class WebSocketClient : public WebSocketMultiplayerPeer { diff --git a/modules/websocket/websocket_multiplayer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index 11caac944b..a48738b6a4 100644 --- a/modules/websocket/websocket_multiplayer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* websocket_multiplayer.cpp */ +/* websocket_multiplayer_peer.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "websocket_multiplayer.h" +#include "websocket_multiplayer_peer.h" + #include "core/os/os.h" WebSocketMultiplayerPeer::WebSocketMultiplayerPeer() { diff --git a/modules/websocket/websocket_multiplayer.h b/modules/websocket/websocket_multiplayer_peer.h index 1aecad97a0..b050449ee0 100644 --- a/modules/websocket/websocket_multiplayer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* websocket_multiplayer.h */ +/* websocket_multiplayer_peer.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index 3f3e46db5a..7a94c4047b 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -32,7 +32,7 @@ #define WEBSOCKET_H #include "core/reference.h" -#include "websocket_multiplayer.h" +#include "websocket_multiplayer_peer.h" #include "websocket_peer.h" class WebSocketServer : public WebSocketMultiplayerPeer { |