Example #1
0
        public static void TieManagedToUnmanaged(Object managed, IntPtr unmanaged,
                                                 StringName nativeName, bool refCounted, Type type, Type nativeType)
        {
            var gcHandle = refCounted ?
                           CustomGCHandle.AllocWeak(managed) :
                           CustomGCHandle.AllocStrong(managed, type);

            if (type == nativeType)
            {
                var nativeNameSelf = (godot_string_name)nativeName.NativeValue;
                NativeFuncs.godotsharp_internal_tie_native_managed_to_unmanaged(
                    GCHandle.ToIntPtr(gcHandle), unmanaged, nativeNameSelf, refCounted.ToGodotBool());
            }
            else
            {
                unsafe
                {
                    // We don't dispose `script` ourselves here.
                    // `tie_user_managed_to_unmanaged` does it for us to avoid another P/Invoke call.
                    godot_ref script;
                    ScriptManagerBridge.GetOrLoadOrCreateScriptForType(type, &script);

                    // IMPORTANT: This must be called after GetOrCreateScriptBridgeForType
                    NativeFuncs.godotsharp_internal_tie_user_managed_to_unmanaged(
                        GCHandle.ToIntPtr(gcHandle), unmanaged, &script, refCounted.ToGodotBool());
                }
            }
        }
Example #2
0
        public static void TieManagedToUnmanagedWithPreSetup(Object managed, IntPtr unmanaged,
                                                             Type type, Type nativeType)
        {
            if (type == nativeType)
            {
                return;
            }

            var strongGCHandle = CustomGCHandle.AllocStrong(managed);

            NativeFuncs.godotsharp_internal_tie_managed_to_unmanaged_with_pre_setup(
                GCHandle.ToIntPtr(strongGCHandle), unmanaged);
        }
Example #3
0
        public static void LogUnhandledException(Exception e)
        {
            try
            {
                if (NativeFuncs.godotsharp_internal_script_debugger_is_active())
                {
                    SendToScriptDebugger(e);
                }

                // In this case, print it as well in addition to sending it to the script debugger
                GD.PushError("Unhandled exception\n" + e);
            }
            catch (Exception unexpected)
            {
                OnExceptionLoggerException(unexpected, e);
            }
        }
Example #4
0
        public static Object UnmanagedGetManaged(IntPtr unmanaged)
        {
            // The native pointer may be null
            if (unmanaged == IntPtr.Zero)
            {
                return(null);
            }

            IntPtr     gcHandlePtr;
            godot_bool hasCsScriptInstance;

            // First try to get the tied managed instance from a CSharpInstance script instance

            gcHandlePtr = NativeFuncs.godotsharp_internal_unmanaged_get_script_instance_managed(
                unmanaged, out hasCsScriptInstance);

            if (gcHandlePtr != IntPtr.Zero)
            {
                return((Object)GCHandle.FromIntPtr(gcHandlePtr).Target);
            }

            // Otherwise, if the object has a CSharpInstance script instance, return null

            if (hasCsScriptInstance.ToBool())
            {
                return(null);
            }

            // If it doesn't have a CSharpInstance script instance, try with native instance bindings

            gcHandlePtr = NativeFuncs.godotsharp_internal_unmanaged_get_instance_binding_managed(unmanaged);

            object target = gcHandlePtr != IntPtr.Zero ? GCHandle.FromIntPtr(gcHandlePtr).Target : null;

            if (target != null)
            {
                return((Object)target);
            }

            // If the native instance binding GC handle target was collected, create a new one

            gcHandlePtr = NativeFuncs.godotsharp_internal_unmanaged_instance_binding_create_managed(
                unmanaged, gcHandlePtr);

            return(gcHandlePtr != IntPtr.Zero ? (Object)GCHandle.FromIntPtr(gcHandlePtr).Target : null);
        }
Example #5
0
 public static void LogException(Exception e)
 {
     try
     {
         if (NativeFuncs.godotsharp_internal_script_debugger_is_active())
         {
             SendToScriptDebugger(e);
         }
         else
         {
             GD.PushError(e.ToString());
         }
     }
     catch (Exception unexpected)
     {
         OnExceptionLoggerException(unexpected, e);
     }
 }
Example #6
0
        private static void SendToScriptDebugger(Exception e)
        {
            var globalFrames = new List <StackInfoTuple>();

            var excMsg = new StringBuilder();

            CollectExceptionInfo(e, globalFrames, excMsg);

            string file     = globalFrames.Count > 0 ? globalFrames[0].File ?? "" : "";
            string func     = globalFrames.Count > 0 ? globalFrames[0].Func : "";
            int    line     = globalFrames.Count > 0 ? globalFrames[0].Line : 0;
            string errorMsg = "Exception";

            using godot_string nFile     = Marshaling.ConvertStringToNative(file);
            using godot_string nFunc     = Marshaling.ConvertStringToNative(func);
            using godot_string nErrorMsg = Marshaling.ConvertStringToNative(errorMsg);
            using godot_string nExcMsg   = Marshaling.ConvertStringToNative(excMsg.ToString());

            using DebuggingUtils.godot_stack_info_vector stackInfoVector = default;

            stackInfoVector.Resize(globalFrames.Count);

            unsafe
            {
                for (int i = 0; i < globalFrames.Count; i++)
                {
                    DebuggingUtils.godot_stack_info *stackInfo = &stackInfoVector.Elements[i];

                    var globalFrame = globalFrames[i];

                    // Assign directly to element in Vector. This way we don't need to worry
                    // about disposal if an exception is thrown. The Vector takes care of it.
                    stackInfo->File = Marshaling.ConvertStringToNative(globalFrame.File);
                    stackInfo->Func = Marshaling.ConvertStringToNative(globalFrame.Func);
                    stackInfo->Line = globalFrame.Line;
                }

                NativeFuncs.godotsharp_internal_script_debugger_send_error(nFunc, nFile, line,
                                                                           nErrorMsg, nExcMsg, p_warning: godot_bool.False, stackInfoVector);
            }
        }
Example #7
0
 public static Object EngineGetSingleton(string name)
 {
     using godot_string src = Marshaling.ConvertStringToNative(name);
     return(UnmanagedGetManaged(NativeFuncs.godotsharp_engine_get_singleton(src)));
 }
Example #8
0
        public static godot_variant ConvertManagedObjectToVariant(object?p_obj)
        {
            if (p_obj == null)
            {
                return(new godot_variant());
            }

            switch (p_obj)
            {
            case bool @bool:
                return(VariantUtils.CreateFromBool(@bool));

            case char @char:
                return(VariantUtils.CreateFromInt(@char));

            case sbyte @int8:
                return(VariantUtils.CreateFromInt(@int8));

            case short @int16:
                return(VariantUtils.CreateFromInt(@int16));

            case int @int32:
                return(VariantUtils.CreateFromInt(@int32));

            case long @int64:
                return(VariantUtils.CreateFromInt(@int64));

            case byte @uint8:
                return(VariantUtils.CreateFromInt(@uint8));

            case ushort @uint16:
                return(VariantUtils.CreateFromInt(@uint16));

            case uint @uint32:
                return(VariantUtils.CreateFromInt(@uint32));

            case ulong @uint64:
                return(VariantUtils.CreateFromInt(@uint64));

            case float @float:
                return(VariantUtils.CreateFromFloat(@float));

            case double @double:
                return(VariantUtils.CreateFromFloat(@double));

            case Vector2 @vector2:
                return(VariantUtils.CreateFromVector2(@vector2));

            case Vector2i @vector2i:
                return(VariantUtils.CreateFromVector2i(@vector2i));

            case Rect2 @rect2:
                return(VariantUtils.CreateFromRect2(@rect2));

            case Rect2i @rect2i:
                return(VariantUtils.CreateFromRect2i(@rect2i));

            case Transform2D @transform2D:
                return(VariantUtils.CreateFromTransform2D(@transform2D));

            case Vector3 @vector3:
                return(VariantUtils.CreateFromVector3(@vector3));

            case Vector3i @vector3i:
                return(VariantUtils.CreateFromVector3i(@vector3i));

            case Vector4 @vector4:
                return(VariantUtils.CreateFromVector4(@vector4));

            case Vector4i @vector4i:
                return(VariantUtils.CreateFromVector4i(@vector4i));

            case Basis @basis:
                return(VariantUtils.CreateFromBasis(@basis));

            case Quaternion @quaternion:
                return(VariantUtils.CreateFromQuaternion(@quaternion));

            case Transform3D @transform3d:
                return(VariantUtils.CreateFromTransform3D(@transform3d));

            case Projection @projection:
                return(VariantUtils.CreateFromProjection(@projection));

            case AABB @aabb:
                return(VariantUtils.CreateFromAABB(@aabb));

            case Color @color:
                return(VariantUtils.CreateFromColor(@color));

            case Plane @plane:
                return(VariantUtils.CreateFromPlane(@plane));

            case Callable @callable:
                return(VariantUtils.CreateFromCallable(@callable));

            case SignalInfo @signalInfo:
                return(VariantUtils.CreateFromSignalInfo(@signalInfo));

            case Enum @enum:
                return(VariantUtils.CreateFromInt(Convert.ToInt64(@enum)));

            case string @string:
                return(VariantUtils.CreateFromString(@string));

            case byte[] byteArray:
                return(VariantUtils.CreateFromPackedByteArray(byteArray));

            case int[] int32Array:
                return(VariantUtils.CreateFromPackedInt32Array(int32Array));

            case long[] int64Array:
                return(VariantUtils.CreateFromPackedInt64Array(int64Array));

            case float[] floatArray:
                return(VariantUtils.CreateFromPackedFloat32Array(floatArray));

            case double[] doubleArray:
                return(VariantUtils.CreateFromPackedFloat64Array(doubleArray));

            case string[] stringArray:
                return(VariantUtils.CreateFromPackedStringArray(stringArray));

            case Vector2[] vector2Array:
                return(VariantUtils.CreateFromPackedVector2Array(vector2Array));

            case Vector3[] vector3Array:
                return(VariantUtils.CreateFromPackedVector3Array(vector3Array));

            case Color[] colorArray:
                return(VariantUtils.CreateFromPackedColorArray(colorArray));

            case StringName[] stringNameArray:
                return(VariantUtils.CreateFromSystemArrayOfStringName(stringNameArray));

            case NodePath[] nodePathArray:
                return(VariantUtils.CreateFromSystemArrayOfNodePath(nodePathArray));

            case RID[] ridArray:
                return(VariantUtils.CreateFromSystemArrayOfRID(ridArray));

            case Godot.Object[] godotObjectArray:
                return(VariantUtils.CreateFromSystemArrayOfGodotObject(godotObjectArray));

            case Godot.Object godotObject:
                return(VariantUtils.CreateFromGodotObject(godotObject));

            case StringName stringName:
                return(VariantUtils.CreateFromStringName(stringName));

            case NodePath nodePath:
                return(VariantUtils.CreateFromNodePath(nodePath));

            case RID rid:
                return(VariantUtils.CreateFromRID(rid));

            case Collections.Dictionary godotDictionary:
                return(VariantUtils.CreateFromDictionary(godotDictionary));

            case Collections.Array godotArray:
                return(VariantUtils.CreateFromArray(godotArray));

            case Variant variant:
                return(NativeFuncs.godotsharp_variant_new_copy((godot_variant)variant.NativeVar));
            }

            GD.PushError("Attempted to convert an unmarshallable managed type to Variant. Name: '" +
                         p_obj.GetType().FullName + ".");
            return(new godot_variant());
        }