예제 #1
0
        internal static unsafe void SignalCallback(IntPtr awaiterGCHandlePtr, godot_variant **args, int argCount,
                                                   godot_bool *outAwaiterIsNull)
        {
            try
            {
                var awaiter = (SignalAwaiter)GCHandle.FromIntPtr(awaiterGCHandlePtr).Target;

                if (awaiter == null)
                {
                    *outAwaiterIsNull = godot_bool.True;
                    return;
                }

                *outAwaiterIsNull = godot_bool.False;

                awaiter._completed = true;

                Variant[] signalArgs = new Variant[argCount];

                for (int i = 0; i < argCount; i++)
                {
                    signalArgs[i] = Variant.CreateCopyingBorrowed(*args[i]);
                }

                awaiter._result = signalArgs;

                awaiter._continuation?.Invoke();
            }
            catch (Exception e)
            {
                ExceptionUtils.LogException(e);
                *outAwaiterIsNull = godot_bool.False;
            }
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
 internal NativeVariantPtrArgs(godot_variant **args) => _args = args;