diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gdscript/gdscript.cpp | 14 | ||||
-rw-r--r-- | modules/gdscript/gdscript_function.cpp | 9 | ||||
-rw-r--r-- | modules/gdscript/gdscript_function.h | 1 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs | 20 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs | 4 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs | 34 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs | 2 | ||||
-rw-r--r-- | modules/mono/glue/runtime_interop.cpp | 10 |
8 files changed, 90 insertions, 4 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 8324cb0fe0..a876229276 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1496,7 +1496,12 @@ GDScript::~GDScript() { // Order matters since clearing the stack may already cause // the GDScriptFunctionState to be destroyed and thus removed from the list. pending_func_states.remove(E); - E->self()->_clear_stack(); + GDScriptFunctionState *state = E->self(); + ObjectID state_id = state->get_instance_id(); + state->_clear_connections(); + if (ObjectDB::get_instance(state_id)) { + state->_clear_stack(); + } } } @@ -1920,7 +1925,12 @@ GDScriptInstance::~GDScriptInstance() { // Order matters since clearing the stack may already cause // the GDSCriptFunctionState to be destroyed and thus removed from the list. pending_func_states.remove(E); - E->self()->_clear_stack(); + GDScriptFunctionState *state = E->self(); + ObjectID state_id = state->get_instance_id(); + state->_clear_connections(); + if (ObjectDB::get_instance(state_id)) { + state->_clear_stack(); + } } if (script.is_valid() && owner) { diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 71831a3a97..a6b4dc7981 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -296,6 +296,15 @@ void GDScriptFunctionState::_clear_stack() { } } +void GDScriptFunctionState::_clear_connections() { + List<Object::Connection> conns; + get_signals_connected_to_this(&conns); + + for (Object::Connection &c : conns) { + c.signal.disconnect(c.callable); + } +} + void GDScriptFunctionState::_bind_methods() { ClassDB::bind_method(D_METHOD("resume", "arg"), &GDScriptFunctionState::resume, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("is_valid", "extended_check"), &GDScriptFunctionState::is_valid, DEFVAL(false)); diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 37416a734d..f45c1f9577 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -628,6 +628,7 @@ public: Variant resume(const Variant &p_arg = Variant()); void _clear_stack(); + void _clear_connections(); GDScriptFunctionState(); ~GDScriptFunctionState(); diff --git a/modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs b/modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs index 344b76a202..02d0226e90 100644 --- a/modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs +++ b/modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs @@ -21,6 +21,26 @@ namespace GodotPlugins _resolver = new AssemblyDependencyResolver(pluginPath); _sharedAssemblies = sharedAssemblies; _mainLoadContext = mainLoadContext; + + if (string.IsNullOrEmpty(AppContext.BaseDirectory)) + { + // See https://github.com/dotnet/runtime/blob/v6.0.0/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs#L17-L35 + // but Assembly.Location is unavailable, because we load assemblies from memory. + string? baseDirectory = Path.GetDirectoryName(pluginPath); + if (baseDirectory != null) + { + if (!Path.EndsInDirectorySeparator(baseDirectory)) + baseDirectory += Path.PathSeparator; + // This SetData call effectively sets AppContext.BaseDirectory + // See https://github.com/dotnet/runtime/blob/v6.0.0/src/libraries/System.Private.CoreLib/src/System/AppContext.cs#L21-L25 + AppDomain.CurrentDomain.SetData("APP_CONTEXT_BASE_DIRECTORY", baseDirectory); + } + else + { + // TODO: How to log from GodotPlugins? (delegate pointer?) + Console.Error.WriteLine("Failed to set AppContext.BaseDirectory. Dynamic loading of libraries may fail."); + } + } } protected override Assembly? Load(AssemblyName assemblyName) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs index 1e23689c95..8ac18c4314 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs @@ -459,6 +459,10 @@ namespace Godot.NativeInterop public static partial godot_bool godotsharp_node_path_is_absolute(in godot_node_path p_self); + public static partial godot_bool godotsharp_node_path_equals(in godot_node_path p_self, in godot_node_path p_other); + + public static partial int godotsharp_node_path_hash(in godot_node_path p_self); + // GD, etc internal static partial void godotsharp_bytes_to_var(in godot_packed_byte_array p_bytes, diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs index b02bd167a1..f216fb7ea3 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs @@ -39,7 +39,7 @@ namespace Godot /// new NodePath("/root/MyAutoload"); // If you have an autoloaded node or scene. /// </code> /// </example> - public sealed class NodePath : IDisposable + public sealed class NodePath : IDisposable, IEquatable<NodePath> { internal godot_node_path.movable NativeValue; @@ -288,5 +288,37 @@ namespace Godot /// </summary> /// <returns>If the <see cref="NodePath"/> is empty.</returns> public bool IsEmpty => NativeValue.DangerousSelfRef.IsEmpty; + + public static bool operator ==(NodePath left, NodePath right) + { + if (left is null) + return right is null; + return left.Equals(right); + } + + public static bool operator !=(NodePath left, NodePath right) + { + return !(left == right); + } + + public bool Equals(NodePath other) + { + if (other is null) + return false; + var self = (godot_node_path)NativeValue; + var otherNative = (godot_node_path)other.NativeValue; + return NativeFuncs.godotsharp_node_path_equals(self, otherNative).ToBool(); + } + + public override bool Equals(object obj) + { + return ReferenceEquals(this, obj) || (obj is NodePath other && Equals(other)); + } + + public override int GetHashCode() + { + var self = (godot_node_path)NativeValue; + return NativeFuncs.godotsharp_node_path_hash(self); + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs index b9ee0bc278..97d28f9ee9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs @@ -10,7 +10,7 @@ namespace Godot /// Comparing them is much faster than with regular strings, because only the pointers are compared, /// not the whole strings. /// </summary> - public sealed class StringName : IDisposable + public sealed class StringName : IDisposable, IEquatable<StringName> { internal godot_string_name.movable NativeValue; diff --git a/modules/mono/glue/runtime_interop.cpp b/modules/mono/glue/runtime_interop.cpp index d17fe3e75f..a90b07620c 100644 --- a/modules/mono/glue/runtime_interop.cpp +++ b/modules/mono/glue/runtime_interop.cpp @@ -1141,6 +1141,14 @@ bool godotsharp_node_path_is_absolute(const NodePath *p_self) { return p_self->is_absolute(); } +bool godotsharp_node_path_equals(const NodePath *p_self, const NodePath *p_other) { + return *p_self == *p_other; +} + +int godotsharp_node_path_hash(const NodePath *p_self) { + return p_self->hash(); +} + void godotsharp_randomize() { Math::randomize(); } @@ -1477,6 +1485,8 @@ static const void *unmanaged_callbacks[]{ (void *)godotsharp_node_path_get_subname, (void *)godotsharp_node_path_get_subname_count, (void *)godotsharp_node_path_is_absolute, + (void *)godotsharp_node_path_equals, + (void *)godotsharp_node_path_hash, (void *)godotsharp_bytes_to_var, (void *)godotsharp_convert, (void *)godotsharp_hash, |