some
This commit is contained in:
@@ -269,7 +269,7 @@ namespace FlaxEngine
|
||||
internal static partial bool Internal_HasConnection(ref AnimationGraph.CustomNode.Context context, int boxId);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "AnimGraphInternal_GetInputValue")]
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.ManagedHandleMarshaller))]
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.AsManagedHandleMarshaller))]
|
||||
internal static partial object Internal_GetInputValue(ref AnimationGraph.CustomNode.Context context, int boxId);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "AnimGraphInternal_GetOutputImpulseData")]
|
||||
|
||||
@@ -17,16 +17,16 @@ namespace FlaxEngine.Interop
|
||||
#if FLAX_EDITOR
|
||||
[HideInEditor]
|
||||
#endif
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedHandleMarshaller.ManagedToNativeState))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedOut, typeof(ManagedHandleMarshaller.ManagedToNativeState))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ElementIn, typeof(ManagedHandleMarshaller.ManagedToNative))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedOut, typeof(ManagedHandleMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedIn, typeof(ManagedHandleMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ElementOut, typeof(ManagedHandleMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedRef, typeof(ManagedHandleMarshaller.Bidirectional))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedRef, typeof(ManagedHandleMarshaller.Bidirectional))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ElementRef, typeof(ManagedHandleMarshaller))]
|
||||
public static class ManagedHandleMarshaller
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedIn, typeof(AsManagedHandleMarshaller.ManagedToNativeState))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedOut, typeof(AsManagedHandleMarshaller.ManagedToNativeState))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ElementIn, typeof(AsManagedHandleMarshaller.ManagedToNative))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedOut, typeof(AsManagedHandleMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedIn, typeof(AsManagedHandleMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ElementOut, typeof(AsManagedHandleMarshaller.NativeToManaged))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedRef, typeof(AsManagedHandleMarshaller.Bidirectional))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedRef, typeof(AsManagedHandleMarshaller.Bidirectional))]
|
||||
[CustomMarshaller(typeof(object), MarshalMode.ElementRef, typeof(AsManagedHandleMarshaller))]
|
||||
public static class AsManagedHandleMarshaller
|
||||
{
|
||||
#if FLAX_EDITOR
|
||||
[HideInEditor]
|
||||
@@ -132,7 +132,7 @@ namespace FlaxEngine.Interop
|
||||
|
||||
public IntPtr ToUnmanaged()
|
||||
{
|
||||
unmanaged = ManagedHandleMarshaller.ToNative(managed);
|
||||
unmanaged = AsManagedHandleMarshaller.ToNative(managed);
|
||||
return unmanaged;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace FlaxEngine.Interop
|
||||
|
||||
public object ToManaged()
|
||||
{
|
||||
managed = ManagedHandleMarshaller.ToManaged(unmanaged);
|
||||
managed = AsManagedHandleMarshaller.ToManaged(unmanaged);
|
||||
unmanaged = IntPtr.Zero;
|
||||
return managed;
|
||||
}
|
||||
@@ -177,7 +177,7 @@ namespace FlaxEngine.Interop
|
||||
[CustomMarshaller(typeof(Type), MarshalMode.Default, typeof(SystemTypeMarshaller))]
|
||||
public static class SystemTypeMarshaller
|
||||
{
|
||||
public static Type ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As<FlaxEngine.Interop.NativeInterop.TypeHolder>(ManagedHandleMarshaller.ConvertToManaged(unmanaged)).type : null;
|
||||
public static Type ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As<FlaxEngine.Interop.NativeInterop.TypeHolder>(AsManagedHandleMarshaller.ConvertToManaged(unmanaged)).type : null;
|
||||
|
||||
public static IntPtr ConvertToUnmanaged(Type managed)
|
||||
{
|
||||
@@ -199,9 +199,9 @@ namespace FlaxEngine.Interop
|
||||
[CustomMarshaller(typeof(Exception), MarshalMode.Default, typeof(ExceptionMarshaller))]
|
||||
public static class ExceptionMarshaller
|
||||
{
|
||||
public static Exception ConvertToManaged(IntPtr unmanaged) => Unsafe.As<Exception>(ManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
public static IntPtr ConvertToUnmanaged(Exception managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed);
|
||||
public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged);
|
||||
public static Exception ConvertToManaged(IntPtr unmanaged) => Unsafe.As<Exception>(AsManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
public static IntPtr ConvertToUnmanaged(Exception managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed);
|
||||
public static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged);
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
@@ -225,9 +225,9 @@ namespace FlaxEngine.Interop
|
||||
[CustomMarshaller(typeof(CultureInfo), MarshalMode.Default, typeof(CultureInfoMarshaller))]
|
||||
public static class CultureInfoMarshaller
|
||||
{
|
||||
public static CultureInfo ConvertToManaged(IntPtr unmanaged) => Unsafe.As<CultureInfo>(ManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
public static IntPtr ConvertToUnmanaged(CultureInfo managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed);
|
||||
public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged);
|
||||
public static CultureInfo ConvertToManaged(IntPtr unmanaged) => Unsafe.As<CultureInfo>(AsManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
public static IntPtr ConvertToUnmanaged(CultureInfo managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed);
|
||||
public static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged);
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
@@ -236,9 +236,9 @@ namespace FlaxEngine.Interop
|
||||
[CustomMarshaller(typeof(Version), MarshalMode.Default, typeof(VersionMarshaller))]
|
||||
public static class VersionMarshaller
|
||||
{
|
||||
public static Version ConvertToManaged(IntPtr unmanaged) => Unsafe.As<Version>(ManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
public static IntPtr ConvertToUnmanaged(Version managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed);
|
||||
public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged);
|
||||
public static Version ConvertToManaged(IntPtr unmanaged) => Unsafe.As<Version>(AsManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
public static IntPtr ConvertToUnmanaged(Version managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed);
|
||||
public static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged);
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
|
||||
@@ -785,7 +785,7 @@ namespace FlaxEngine.Interop
|
||||
for (int i = 0; i < numParams; i++)
|
||||
{
|
||||
IntPtr nativePtr = Unsafe.Read<IntPtr>((IntPtr.Add(paramPtr, sizeof(IntPtr) * i)).ToPointer());
|
||||
methodParameters[i] = MarshalToManaged(nativePtr, methodHolder.parameterTypes[i]);
|
||||
methodParameters[i] = MarshalToManaged2(nativePtr, methodHolder.parameterTypes[i]);
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
@@ -19,6 +19,8 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Buffers;
|
||||
using System.Runtime.InteropServices.Marshalling;
|
||||
using FlaxEngine.Utilities;
|
||||
|
||||
namespace FlaxEngine.Interop
|
||||
{
|
||||
@@ -410,6 +412,164 @@ namespace FlaxEngine.Interop
|
||||
internal static ConcurrentDictionary<Type, MarshalToNativeDelegate> toNativeMarshallers = new ConcurrentDictionary<Type, MarshalToNativeDelegate>(1, 3);
|
||||
internal static ConcurrentDictionary<Type, MarshalToNativeFieldDelegate> toNativeFieldMarshallers = new ConcurrentDictionary<Type, MarshalToNativeFieldDelegate>(1, 3);
|
||||
|
||||
internal static ConcurrentDictionary<Type, (Type, Func<object, object>)> _marshallers = new(1, 3);
|
||||
|
||||
internal static object MarshalToManaged2(IntPtr nativePtr, Type type)
|
||||
{
|
||||
static MarshalToManagedDelegate Factory(Type type)
|
||||
{
|
||||
Type marshalType = type;
|
||||
if (marshalType.IsByRef)
|
||||
marshalType = marshalType.GetElementType();
|
||||
else if (marshalType.IsPointer)
|
||||
marshalType = typeof(IntPtr);
|
||||
|
||||
MethodInfo method = typeof(MarshalHelper<>).MakeGenericType(marshalType).GetMethod(nameof(MarshalHelper<ReferenceTypePlaceholder>.ToManagedWrapper), BindingFlags.Static | BindingFlags.NonPublic);
|
||||
return method.CreateDelegate<MarshalToManagedDelegate>();
|
||||
}
|
||||
|
||||
static Type GetCustomMarshaller(Type type)
|
||||
{
|
||||
if (type == typeof(bool))
|
||||
return typeof(BooleanMarshaller);
|
||||
else if (type.IsArray)
|
||||
return null;
|
||||
|
||||
Type marshallerType = type.GetCustomAttribute<NativeMarshallingAttribute>()?.NativeType;
|
||||
//if (marshallerType == null && marshallerType != type)
|
||||
// marshallerType = type.GetCustomAttribute<NativeMarshallingAttribute>()?.NativeType;
|
||||
|
||||
return marshallerType;
|
||||
}
|
||||
static (Type, Func<object, object>) Factory2(Type type)
|
||||
{
|
||||
Type marshalType = type;
|
||||
if (marshalType.IsByRef)
|
||||
marshalType = marshalType.GetElementType();
|
||||
else if (marshalType == typeof(byte*) || marshalType == typeof(char*))
|
||||
{
|
||||
}
|
||||
else if (marshalType.IsPointer)
|
||||
marshalType = typeof(IntPtr);
|
||||
|
||||
Type marshallerType = GetCustomMarshaller(marshalType);
|
||||
if (marshalType.IsArray)
|
||||
{
|
||||
Type elementType = marshalType.GetElementType();
|
||||
Type elementMarshallerType = GetCustomMarshaller(elementType);
|
||||
if (elementMarshallerType == null)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MethodInfo method2 = elementMarshallerType.GetMethod("ConvertToManaged", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
var elementInternalType = method2.GetParameters()[0].ParameterType;
|
||||
var types2 = new Type[] { elementType, elementInternalType };
|
||||
marshallerType = typeof(NativeArrayMarshaller<,>).MakeGenericType(types2);
|
||||
}
|
||||
}
|
||||
if (marshallerType == null)
|
||||
{
|
||||
if (marshalType == typeof(IntPtr))
|
||||
{
|
||||
Func<object, object> func = (obj) => obj;
|
||||
return (typeof(IntPtr), func);
|
||||
}
|
||||
else if (marshalType == typeof(ManagedHandle))
|
||||
{
|
||||
Func<object, object> func = (obj) => ManagedHandle.FromIntPtr((IntPtr)obj);
|
||||
return (typeof(IntPtr), func);
|
||||
}
|
||||
}
|
||||
if (marshallerType == null)
|
||||
return (null, null);
|
||||
|
||||
MethodInfo method = marshallerType.GetMethod("ConvertToManaged", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (method == null)
|
||||
{
|
||||
// [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.ManagedToUnmanagedOut, typeof(NativeArrayMarshaller<,>.NativeToManaged))]
|
||||
// [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.UnmanagedToManagedIn, typeof(NativeArrayMarshaller<,>.NativeToManaged))]
|
||||
|
||||
var customMarshallerAttributes = marshallerType.GetCustomAttributes<CustomMarshallerAttribute>();
|
||||
foreach (var attrib in customMarshallerAttributes)
|
||||
{
|
||||
if (attrib.MarshalMode == MarshalMode.ManagedToUnmanagedOut)
|
||||
{
|
||||
var asdf = typeof(NativeArrayMarshaller<,>.NativeToManaged);
|
||||
marshallerType = attrib.MarshallerType;
|
||||
//method = marshallerType.GetMethod("ConvertToManaged", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
}
|
||||
}
|
||||
|
||||
return (null, null);
|
||||
}
|
||||
|
||||
var internalType = method.GetParameters()[0].ParameterType;
|
||||
var types = new Type[] { marshalType, internalType };
|
||||
var convertDelegate = method.CreateDelegate(typeof(ToManagedDelegate<,>).MakeGenericType(types));
|
||||
if (internalType.IsStructure())
|
||||
{
|
||||
Func<object, object> func =
|
||||
(obj) => convertDelegate.DynamicInvoke(obj);
|
||||
return (internalType, func);
|
||||
}
|
||||
else
|
||||
{
|
||||
Func<object, object> func =
|
||||
(obj) => convertDelegate.DynamicInvoke(obj);
|
||||
return (internalType, func);
|
||||
}
|
||||
}
|
||||
|
||||
var type2 = type.IsByRef ? type.GetElementType() : type;
|
||||
if (!_marshallers.TryGetValue(type, out var marsh))
|
||||
marsh = _marshallers.GetOrAdd(type, Factory2);
|
||||
if (!toManagedMarshallers.TryGetValue(type, out var deleg))
|
||||
deleg = toManagedMarshallers.GetOrAdd(type, Factory);
|
||||
|
||||
if (marsh.Item2 != null)
|
||||
{
|
||||
object conv1 = deleg(nativePtr, type.IsByRef && false);
|
||||
if (type.IsByRef && marsh.Item1 == typeof(IntPtr))
|
||||
nativePtr = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
object value = marsh.Item1 == typeof(IntPtr) ? nativePtr : Marshal.PtrToStructure(nativePtr, marsh.Item1);//Unsafe.Read<byte>(nativePtr.ToPointer());
|
||||
object conv2 = marsh.Item2(value);
|
||||
if (conv1 is null && conv2 is null)
|
||||
{ }
|
||||
else if (!conv1.Equals(conv2))
|
||||
Assert.IsTrue(conv1.Equals(conv2));
|
||||
return conv2;
|
||||
}
|
||||
else if (type2 == typeof(bool))
|
||||
{
|
||||
//object conv1 = deleg(nativePtr, type.IsByRef && false);
|
||||
byte value = Unsafe.Read<byte>(nativePtr.ToPointer());
|
||||
object conv2 = BooleanMarshaller.ConvertToManaged(value);
|
||||
//Assert.IsTrue(conv1.Equals(conv2));
|
||||
return conv2;
|
||||
}
|
||||
else if (type2 == typeof(ManagedHandle))
|
||||
{
|
||||
//ManagedHandle conv1 = (ManagedHandle)deleg(nativePtr, type.IsByRef && false);
|
||||
ManagedHandle conv2 = ManagedHandle.FromIntPtr(nativePtr);
|
||||
//Assert.IsTrue(conv1.Equals(conv2));
|
||||
return conv2;
|
||||
}
|
||||
else if (type2 == typeof(int) || type2.IsEnum ||
|
||||
type2 == typeof(IntPtr) || type2 == typeof(Float2) || type2 == typeof(Float3) || type2 == typeof(Guid))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
return deleg(nativePtr, type.IsByRef && false);
|
||||
}
|
||||
|
||||
internal static object MarshalToManaged(IntPtr nativePtr, Type type)
|
||||
{
|
||||
static MarshalToManagedDelegate Factory(Type type)
|
||||
@@ -583,9 +743,6 @@ namespace FlaxEngine.Interop
|
||||
MethodInfo toManagedFieldMethod;
|
||||
MethodInfo toNativeFieldMethod;
|
||||
|
||||
if (fieldType == typeof(string))
|
||||
fieldType = fieldType;
|
||||
|
||||
if (fieldType == typeof(SoftTypeReference))
|
||||
{
|
||||
if (type.IsValueType)
|
||||
@@ -1409,12 +1566,6 @@ namespace FlaxEngine.Interop
|
||||
var offsets = MarshalHelper<T>.marshallableFieldOffsets;
|
||||
var marshallers = MarshalHelper<T>.toNativeFieldMarshallers;
|
||||
|
||||
for (int i = 1; i < offsets.Length; i++)
|
||||
{
|
||||
if (offsets[i - 1] > offsets[i])
|
||||
fieldPtr = fieldPtr;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
marshallers[i](fields[i], offsets[i], ref managedValue, nativePtr, out int fieldSize);
|
||||
|
||||
@@ -37,7 +37,7 @@ DEFINE_INTERNAL_CALL(MObject*) UtilsInternal_ExtractArrayFromList(MObject* obj)
|
||||
|
||||
//#if USE_NETCORE
|
||||
//APgI_TYPEDEF() typedef MString* ManagedString;
|
||||
API_TYPEDEF() typedef String* ManagedString;
|
||||
API_TYPEDEF() typedef const String& ManagedString;
|
||||
//#endif
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryCopy(void* dst, const void* src, uint64 size)
|
||||
@@ -58,11 +58,14 @@ DEFINE_INTERNAL_CALL(int32) PlatformInternal_MemoryCompare(const void* buf1, con
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, ManagedString msgObj)
|
||||
{
|
||||
#if LOG_ENABLE
|
||||
|
||||
#if USE_NETCORE
|
||||
if (msgObj.IsEmpty())
|
||||
return;
|
||||
StringView msg(msgObj);
|
||||
#else
|
||||
if (msgObj == nullptr)
|
||||
return;
|
||||
#if USE_NETCORE
|
||||
StringView msg(*msgObj);
|
||||
#else
|
||||
StringView msg;
|
||||
MUtils::ToString(msgObj, msg);
|
||||
#endif
|
||||
@@ -73,11 +76,15 @@ DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, Manag
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, ManagedString msgObj, ScriptingObject* obj, ManagedString stackTrace)
|
||||
{
|
||||
#if LOG_ENABLE
|
||||
|
||||
#if USE_NETCORE
|
||||
if (msgObj.IsEmpty())
|
||||
return;
|
||||
StringView msg(msgObj);
|
||||
#else
|
||||
if (msgObj == nullptr)
|
||||
return;
|
||||
#if USE_NETCORE
|
||||
StringView msg(*msgObj);
|
||||
#else
|
||||
|
||||
// Get info
|
||||
StringView msg;
|
||||
MUtils::ToString(msgObj, msg);
|
||||
@@ -135,11 +142,13 @@ namespace
|
||||
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(ManagedString nameObj)
|
||||
{
|
||||
#if COMPILE_WITH_PROFILER
|
||||
#if USE_NETCORE
|
||||
if (nameObj.IsEmpty())
|
||||
return;
|
||||
StringView name(nameObj);
|
||||
#else
|
||||
if (nameObj == nullptr)
|
||||
return;
|
||||
#if USE_NETCORE
|
||||
StringView name(*nameObj);
|
||||
#else
|
||||
StringView name;
|
||||
MUtils::ToString(nameObj, name);
|
||||
#endif
|
||||
@@ -198,10 +207,12 @@ DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(ManagedString nameObj)
|
||||
{
|
||||
#if COMPILE_WITH_PROFILER
|
||||
#if USE_NETCORE
|
||||
if (nameObj.IsEmpty())
|
||||
return;
|
||||
const StringView nameChars(nameObj);
|
||||
#else
|
||||
if (nameObj == nullptr)
|
||||
return;
|
||||
const StringView nameChars(*nameObj);
|
||||
#else
|
||||
const StringView nameChars = MCore::String::GetChars(nameObj);
|
||||
#endif
|
||||
const auto index = ProfilerGPU::BeginEvent(nameChars.Get());
|
||||
|
||||
Reference in New Issue
Block a user