internal static unsafe void InvokeWithVariantArgs(IntPtr delegateGCHandle, godot_variant **args, uint argc, godot_variant *outRet) { try { // TODO: Optimize var @delegate = (Delegate)GCHandle.FromIntPtr(delegateGCHandle).Target !; var managedArgs = new object?[argc]; var parameterInfos = @delegate.Method.GetParameters(); var paramsLength = parameterInfos.Length; if (argc != paramsLength) { throw new InvalidOperationException( $"The delegate expects {paramsLength} arguments, but received {argc}."); } for (uint i = 0; i < argc; i++) { managedArgs[i] = Marshaling.ConvertVariantToManagedObjectOfType( *args[i], parameterInfos[i].ParameterType); } object?invokeRet = @delegate.DynamicInvoke(managedArgs); *outRet = Marshaling.ConvertManagedObjectToVariant(invokeRet); } catch (Exception e) { ExceptionUtils.LogException(e); *outRet = default; } }
/// <summary> /// Returns the item at the given <paramref name="index"/>. /// </summary> /// <value>The <see cref="Variant"/> item at the given <paramref name="index"/>.</value> public unsafe Variant this[int index] { get { GetVariantBorrowElementAt(index, out godot_variant borrowElem); return(Variant.CreateCopyingBorrowed(borrowElem)); } set { if (index < 0 || index >= Count) { throw new ArgumentOutOfRangeException(nameof(index)); } var self = (godot_array)NativeValue; godot_variant *ptrw = NativeFuncs.godotsharp_array_ptrw(ref self); godot_variant *itemPtr = &ptrw[index]; (*itemPtr).Dispose(); *itemPtr = value.CopyNativeVariant(); } }
internal static unsafe godot_bool Get(IntPtr godotObjectGCHandle, godot_string_name *name, godot_variant *outRet) { try { var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) { throw new InvalidOperationException(); } if (godotObject.GetGodotClassPropertyValue(CustomUnsafe.AsRef(name), out godot_variant outRetValue)) { *outRet = outRetValue; return(godot_bool.True); } var nameManaged = StringName.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(name))); Variant ret = godotObject._Get(nameManaged); if (ret.VariantType == Variant.Type.Nil) { *outRet = default; return(godot_bool.False); } *outRet = Marshaling.ConvertManagedObjectToVariant(ret); return(godot_bool.True); } catch (Exception e) { ExceptionUtils.LogException(e); *outRet = default; return(godot_bool.False); } }
internal static unsafe godot_bool Call(IntPtr godotObjectGCHandle, godot_string_name *method, godot_variant **args, int argCount, godot_variant_call_error *refCallError, godot_variant *ret) { try { var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) { *ret = default; (*refCallError).Error = godot_variant_call_error_error.GODOT_CALL_ERROR_CALL_ERROR_INSTANCE_IS_NULL; return(godot_bool.False); } bool methodInvoked = godotObject.InvokeGodotClassMethod(CustomUnsafe.AsRef(method), new NativeVariantPtrArgs(args), argCount, out godot_variant retValue); if (!methodInvoked) { *ret = default; // This is important, as it tells Object::call that no method was called. // Otherwise, it would prevent Object::call from calling native methods. (*refCallError).Error = godot_variant_call_error_error.GODOT_CALL_ERROR_CALL_ERROR_INVALID_METHOD; return(godot_bool.False); } *ret = retValue; return(godot_bool.True); } catch (Exception e) { ExceptionUtils.LogException(e); *ret = default; return(godot_bool.False); } }
internal static unsafe godot_bool Set(IntPtr godotObjectGCHandle, godot_string_name *name, godot_variant *value) { try { var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) { throw new InvalidOperationException(); } if (godotObject.SetGodotClassPropertyValue(CustomUnsafe.AsRef(name), CustomUnsafe.AsRef(value))) { return(godot_bool.True); } var nameManaged = StringName.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(name))); Variant valueManaged = Variant.CreateCopyingBorrowed(*value); return(godotObject._Set(nameManaged, valueManaged).ToGodotBool()); } catch (Exception e) { ExceptionUtils.LogException(e); return(godot_bool.False); } }