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()); } } }
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); }
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); } }
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); }
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); } }
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); } }
public static Object EngineGetSingleton(string name) { using godot_string src = Marshaling.ConvertStringToNative(name); return(UnmanagedGetManaged(NativeFuncs.godotsharp_engine_get_singleton(src))); }
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()); }