diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs deleted file mode 100644 index 0c21bcaa3f..0000000000 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Dynamic; -using System.Linq.Expressions; -using System.Runtime.CompilerServices; - -namespace Godot -{ - /// - /// Represents an whose members can be dynamically accessed at runtime through the Variant API. - /// - /// - /// - /// The class enables access to the Variant - /// members of a instance at runtime. - /// - /// - /// This allows accessing the class members using their original names in the engine as well as the members from the - /// script attached to the , regardless of the scripting language it was written in. - /// - /// - /// - /// This sample shows how to use to dynamically access the engine members of a . - /// - /// dynamic sprite = GetNode("Sprite2D").DynamicGodotObject; - /// sprite.add_child(this); - /// - /// if ((sprite.hframes * sprite.vframes) > 0) - /// sprite.frame = 0; - /// - /// - /// - /// This sample shows how to use to dynamically access the members of the script attached to a . - /// - /// dynamic childNode = GetNode("ChildNode").DynamicGodotObject; - /// - /// if (childNode.print_allowed) - /// { - /// childNode.message = "Hello from C#"; - /// childNode.print_message(3); - /// } - /// - /// The ChildNode node has the following GDScript script attached: - /// - /// // # ChildNode.gd - /// // var print_allowed = true - /// // var message = "" - /// // - /// // func print_message(times): - /// // for i in times: - /// // print(message) - /// - /// - public class DynamicGodotObject : DynamicObject - { - /// - /// Gets the associated with this . - /// - public Object Value { get; } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The that will be associated with this . - /// - /// - /// Thrown when the parameter is null. - /// - public DynamicGodotObject(Object godotObject) - { - if (godotObject == null) - throw new ArgumentNullException(nameof(godotObject)); - - this.Value = godotObject; - } - - public override IEnumerable GetDynamicMemberNames() - { - return godot_icall_DynamicGodotObject_SetMemberList(Object.GetPtr(Value)); - } - - public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result) - { - switch (binder.Operation) - { - case ExpressionType.Equal: - case ExpressionType.NotEqual: - if (binder.ReturnType == typeof(bool) || binder.ReturnType.IsAssignableFrom(typeof(bool))) - { - if (arg == null) - { - bool boolResult = Object.IsInstanceValid(Value); - - if (binder.Operation == ExpressionType.Equal) - boolResult = !boolResult; - - result = boolResult; - return true; - } - - if (arg is Object other) - { - bool boolResult = (Value == other); - - if (binder.Operation == ExpressionType.NotEqual) - boolResult = !boolResult; - - result = boolResult; - return true; - } - } - - break; - default: - // We're not implementing operators <, <=, >, and >= (LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual). - // These are used on the actual pointers in variant_op.cpp. It's better to let the user do that explicitly. - break; - } - - return base.TryBinaryOperation(binder, arg, out result); - } - - public override bool TryConvert(ConvertBinder binder, out object result) - { - if (binder.Type == typeof(Object)) - { - result = Value; - return true; - } - - if (typeof(Object).IsAssignableFrom(binder.Type)) - { - // Throws InvalidCastException when the cast fails - result = Convert.ChangeType(Value, binder.Type); - return true; - } - - return base.TryConvert(binder, out result); - } - - public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) - { - if (indexes.Length == 1) - { - if (indexes[0] is string name) - { - return godot_icall_DynamicGodotObject_GetMember(Object.GetPtr(Value), name, out result); - } - } - - return base.TryGetIndex(binder, indexes, out result); - } - - public override bool TryGetMember(GetMemberBinder binder, out object result) - { - return godot_icall_DynamicGodotObject_GetMember(Object.GetPtr(Value), binder.Name, out result); - } - - public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) - { - return godot_icall_DynamicGodotObject_InvokeMember(Object.GetPtr(Value), binder.Name, args, out result); - } - - public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) - { - if (indexes.Length == 1) - { - if (indexes[0] is string name) - { - return godot_icall_DynamicGodotObject_SetMember(Object.GetPtr(Value), name, value); - } - } - - return base.TrySetIndex(binder, indexes, value); - } - - public override bool TrySetMember(SetMemberBinder binder, object value) - { - return godot_icall_DynamicGodotObject_SetMember(Object.GetPtr(Value), binder.Name, value); - } - - [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static string[] godot_icall_DynamicGodotObject_SetMemberList(IntPtr godotObject); - - [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static bool godot_icall_DynamicGodotObject_InvokeMember(IntPtr godotObject, string name, object[] args, out object result); - - [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static bool godot_icall_DynamicGodotObject_GetMember(IntPtr godotObject, string name, out object result); - - [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static bool godot_icall_DynamicGodotObject_SetMember(IntPtr godotObject, string name, object value); - - #region We don't override these methods - - // Looks like this is not usable from C# - //public override bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result); - - // Object members cannot be deleted - //public override bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes); - //public override bool TryDeleteMember(DeleteMemberBinder binder); - - // Invocation on the object itself, e.g.: obj(param) - //public override bool TryInvoke(InvokeBinder binder, object[] args, out object result); - - // No unnary operations to handle - //public override bool TryUnaryOperation(UnaryOperationBinder binder, out object result); - - #endregion - } -} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs index 8587748d03..a52707edfb 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs @@ -118,11 +118,6 @@ namespace Godot return new SignalAwaiter(source, signal, this); } - /// - /// Gets a new associated with this instance. - /// - public dynamic DynamicObject => new DynamicGodotObject(this); - internal static unsafe IntPtr ClassDB_get_method(StringName type, string method) { IntPtr methodBind; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index 6cd0539ac4..7cafa1ce07 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -39,7 +39,6 @@ - diff --git a/modules/mono/glue/arguments_vector.h b/modules/mono/glue/arguments_vector.h deleted file mode 100644 index 9ba6a05ac6..0000000000 --- a/modules/mono/glue/arguments_vector.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************/ -/* arguments_vector.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ARGUMENTS_VECTOR_H -#define ARGUMENTS_VECTOR_H - -#include "core/os/memory.h" - -template -struct ArgumentsVector { -private: - T pool[POOL_SIZE]; - T *_ptr; - int size; - - ArgumentsVector() = delete; - ArgumentsVector(const ArgumentsVector &) = delete; - -public: - T *ptr() { return _ptr; } - T &get(int p_idx) { return _ptr[p_idx]; } - void set(int p_idx, const T &p_value) { _ptr[p_idx] = p_value; } - - explicit ArgumentsVector(int p_size) : - size(p_size) { - if (p_size <= POOL_SIZE) { - _ptr = pool; - } else { - _ptr = memnew_arr(T, p_size); - } - } - - ~ArgumentsVector() { - if (size > POOL_SIZE) { - memdelete_arr(_ptr); - } - } -}; - -#endif // ARGUMENTS_VECTOR_H diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 40886ddbea..9d153bdbf8 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -39,7 +39,6 @@ #include "../mono_gd/gd_mono_marshal.h" #include "../mono_gd/gd_mono_utils.h" #include "../signal_awaiter_utils.h" -#include "arguments_vector.h" void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) { #ifdef DEBUG_ENABLED @@ -154,67 +153,6 @@ int32_t godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal return (int32_t)gd_mono_connect_signal_awaiter(p_source, signal, p_target, p_awaiter); } -MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) { - List property_list; - p_ptr->get_property_list(&property_list); - - MonoArray *result = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), property_list.size()); - - int i = 0; - for (const PropertyInfo &E : property_list) { - MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E.name); - mono_array_setref(result, i, boxed); - i++; - } - - return result; -} - -MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoString *p_name, MonoArray *p_args, MonoObject **r_result) { - String name = GDMonoMarshal::mono_string_to_godot(p_name); - - int argc = mono_array_length(p_args); - - ArgumentsVector arg_store(argc); - ArgumentsVector args(argc); - - for (int i = 0; i < argc; i++) { - MonoObject *elem = mono_array_get(p_args, MonoObject *, i); - arg_store.set(i, GDMonoMarshal::mono_object_to_variant(elem)); - args.set(i, &arg_store.get(i)); - } - - Callable::CallError error; - Variant result = p_ptr->call(StringName(name), args.ptr(), argc, error); - - *r_result = GDMonoMarshal::variant_to_mono_object(result); - - return error.error == Callable::CallError::CALL_OK; -} - -MonoBoolean godot_icall_DynamicGodotObject_GetMember(Object *p_ptr, MonoString *p_name, MonoObject **r_result) { - String name = GDMonoMarshal::mono_string_to_godot(p_name); - - bool valid; - Variant value = p_ptr->get(StringName(name), &valid); - - if (valid) { - *r_result = GDMonoMarshal::variant_to_mono_object(value); - } - - return valid; -} - -MonoBoolean godot_icall_DynamicGodotObject_SetMember(Object *p_ptr, MonoString *p_name, MonoObject *p_value) { - String name = GDMonoMarshal::mono_string_to_godot(p_name); - Variant value = GDMonoMarshal::mono_object_to_variant(p_value); - - bool valid; - p_ptr->set(StringName(name), value, &valid); - - return valid; -} - MonoString *godot_icall_Object_ToString(Object *p_ptr) { #ifdef DEBUG_ENABLED // Cannot happen in C#; would get an ObjectDisposedException instead. @@ -232,8 +170,4 @@ void godot_register_object_icalls() { GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ToString", godot_icall_Object_ToString); GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_weakref", godot_icall_Object_weakref); GDMonoUtils::add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", godot_icall_SignalAwaiter_connect); - GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMemberList", godot_icall_DynamicGodotObject_SetMemberList); - GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_InvokeMember", godot_icall_DynamicGodotObject_InvokeMember); - GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_GetMember", godot_icall_DynamicGodotObject_GetMember); - GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMember", godot_icall_DynamicGodotObject_SetMember); }