diff --git a/Flax.sln.DotSettings b/Flax.sln.DotSettings index e8af1461c..6a22f211b 100644 --- a/Flax.sln.DotSettings +++ b/Flax.sln.DotSettings @@ -291,6 +291,8 @@ True True True + True + True True True True diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index a2647dd10..9cc5a1f1c 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -853,7 +853,7 @@ namespace FlaxEngine.Interop { object fieldOwner = fieldOwnerHandle.Target; FieldHolder field = Unsafe.As(fieldHandle.Target); - field.toNativeMarshaller(field.fieldOffset, fieldOwner, valuePtr, out int fieldSize); + field.toNativeMarshaller(field.field, field.fieldOffset, fieldOwner, valuePtr, out int fieldSize); } [UnmanagedCallersOnly] diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index 0b6aa2320..500636290 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -363,7 +363,7 @@ namespace FlaxEngine.Interop internal delegate object MarshalToManagedDelegate(IntPtr nativePtr, bool byRef); internal delegate void MarshalToNativeDelegate(object managedObject, IntPtr nativePtr); - internal delegate void MarshalToNativeFieldDelegate(int fieldOffset, object fieldOwner, IntPtr nativePtr, out int fieldSize); + internal delegate void MarshalToNativeFieldDelegate(FieldInfo field, int fieldOffset, object fieldOwner, IntPtr nativePtr, out int fieldSize); internal static ConcurrentDictionary toManagedMarshallers = new ConcurrentDictionary(1, 3); internal static ConcurrentDictionary toNativeMarshallers = new ConcurrentDictionary(1, 3); @@ -471,7 +471,7 @@ namespace FlaxEngine.Interop { private delegate void MarshalToNativeTypedDelegate(ref T managedValue, IntPtr nativePtr); private delegate void MarshalToManagedTypedDelegate(ref T managedValue, IntPtr nativePtr, bool byRef); - internal delegate void MarshalFieldTypedDelegate(int managedFieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize); + internal delegate void MarshalFieldTypedDelegate(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize); internal delegate void* GetBasePointer(ref T fieldOwner); internal static FieldInfo[] marshallableFields; @@ -605,7 +605,6 @@ namespace FlaxEngine.Interop methodName = nameof(MarshalHelperValueType.ToManagedWithMarshallableFields); else methodName = nameof(MarshalHelperValueType.ToManaged); - toManagedMethod = typeof(MarshalHelperValueType<>).MakeGenericType(type).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic); } else if (type.IsArray) @@ -716,7 +715,7 @@ namespace FlaxEngine.Interop toNativeTypedMarshaller(ref managedValue, nativePtr); } - internal static void ToNativeField(int fieldOffset, ref T fieldOwner, IntPtr nativePtr, out int fieldSize) + internal static void ToNativeField(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativePtr, out int fieldSize) { if (marshallableFields != null) { @@ -724,7 +723,7 @@ namespace FlaxEngine.Interop { if (marshallableFieldOffsets[i] == fieldOffset) { - toNativeFieldMarshallers[i](fieldOffset, ref fieldOwner, nativePtr, out fieldSize); + toNativeFieldMarshallers[i](field, fieldOffset, ref fieldOwner, nativePtr, out fieldSize); return; } } @@ -732,28 +731,28 @@ namespace FlaxEngine.Interop throw new NativeInteropException($"Invalid field with offset {fieldOffset} to marshal for type {typeof(T).Name}"); } - private static void ToManagedFieldPointerValueType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct + private static void ToManagedFieldPointerValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct { ref IntPtr fieldValueRef = ref FieldHelper.GetValueTypeFieldReference(fieldOffset, ref fieldOwner); fieldValueRef = Unsafe.Read(nativeFieldPtr.ToPointer()); fieldSize = IntPtr.Size; } - private static void ToManagedFieldPointerReferenceType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class + private static void ToManagedFieldPointerReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class { ref IntPtr fieldValueRef = ref FieldHelper.GetReferenceTypeFieldReference(fieldOffset, ref fieldOwner); fieldValueRef = Unsafe.Read(nativeFieldPtr.ToPointer()); fieldSize = IntPtr.Size; } - private static void ToNativeFieldPointerValueType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct + private static void ToNativeFieldPointerValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct { ref IntPtr fieldValueRef = ref FieldHelper.GetValueTypeFieldReference(fieldOffset, ref fieldOwner); Unsafe.Write(nativeFieldPtr.ToPointer(), fieldValueRef); fieldSize = IntPtr.Size; } - private static void ToNativeFieldPointerReferenceType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class + private static void ToNativeFieldPointerReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class { ref IntPtr fieldValueRef = ref FieldHelper.GetReferenceTypeFieldReference(fieldOffset, ref fieldOwner); Unsafe.Write(nativeFieldPtr.ToPointer(), fieldValueRef); @@ -788,7 +787,7 @@ namespace FlaxEngine.Interop fieldAlignment = GetTypeSize(fieldType); } - internal static void ToManagedFieldValueType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct + internal static void ToManagedFieldValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct { fieldSize = Unsafe.SizeOf(); if (fieldAlignment > 1) @@ -802,7 +801,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToManaged(ref fieldValueRef, nativeFieldPtr, false); } - internal static void ToManagedFieldReferenceType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class + internal static void ToManagedFieldReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class { fieldSize = Unsafe.SizeOf(); if (fieldAlignment > 1) @@ -816,7 +815,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToManaged(ref fieldValueRef, nativeFieldPtr, false); } - internal static void ToManagedFieldArrayValueType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct + internal static void ToManagedFieldArrayValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct { // Follows the same marshalling semantics with reference types fieldSize = Unsafe.SizeOf(); @@ -828,7 +827,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToManaged(ref fieldValueRef, Unsafe.Read(nativeFieldPtr.ToPointer()), false); } - internal static void ToManagedFieldArrayReferenceType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class + internal static void ToManagedFieldArrayReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class { // Follows the same marshalling semantics with reference types fieldSize = Unsafe.SizeOf(); @@ -840,7 +839,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToManaged(ref fieldValueRef, Unsafe.Read(nativeFieldPtr.ToPointer()), false); } - internal static void ToNativeFieldValueType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct + internal static void ToNativeFieldValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct { fieldSize = Unsafe.SizeOf(); if (fieldAlignment > 1) @@ -858,7 +857,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToNative(ref fieldValueRef, nativeFieldPtr); } - internal static void ToNativeFieldReferenceType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class + internal static void ToNativeFieldReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class { fieldSize = Unsafe.SizeOf(); if (fieldAlignment > 1) @@ -883,12 +882,12 @@ namespace FlaxEngine.Interop { } - internal static void ToManagedField(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) + internal static void ToManagedField(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) { fieldSize = 0; } - internal static void ToNativeField(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) + internal static void ToNativeField(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) { fieldSize = 0; } @@ -896,7 +895,7 @@ namespace FlaxEngine.Interop private static class ReferenceTypeField where TField : class { - internal static void ToManagedFieldValueType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct + internal static void ToManagedFieldValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct { fieldSize = Unsafe.SizeOf(); IntPtr fieldStartPtr = nativeFieldPtr; @@ -907,7 +906,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToManaged(ref fieldValueRef, Unsafe.Read(nativeFieldPtr.ToPointer()), false); } - internal static void ToManagedFieldReferenceType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class + internal static void ToManagedFieldReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class { fieldSize = Unsafe.SizeOf(); IntPtr fieldStartPtr = nativeFieldPtr; @@ -918,7 +917,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToManaged(ref fieldValueRef, Unsafe.Read(nativeFieldPtr.ToPointer()), false); } - internal static void ToManagedFieldArrayValueType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct + internal static void ToManagedFieldArrayValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct { fieldSize = Unsafe.SizeOf(); IntPtr fieldStartPtr = nativeFieldPtr; @@ -929,7 +928,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToManaged(ref fieldValueRef, Unsafe.Read(nativeFieldPtr.ToPointer()), false); } - internal static void ToManagedFieldArrayReferenceType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class + internal static void ToManagedFieldArrayReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class { fieldSize = Unsafe.SizeOf(); IntPtr fieldStartPtr = nativeFieldPtr; @@ -940,7 +939,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToManaged(ref fieldValueRef, Unsafe.Read(nativeFieldPtr.ToPointer()), false); } - internal static void ToNativeFieldValueType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct + internal static void ToNativeFieldValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct { fieldSize = Unsafe.SizeOf(); IntPtr fieldStartPtr = nativeFieldPtr; @@ -951,7 +950,7 @@ namespace FlaxEngine.Interop MarshalHelper.ToNative(ref fieldValueRef, nativeFieldPtr); } - internal static void ToNativeFieldReferenceType(int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class + internal static void ToNativeFieldReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class { fieldSize = Unsafe.SizeOf(); IntPtr fieldStartPtr = nativeFieldPtr; @@ -971,9 +970,9 @@ namespace FlaxEngine.Interop MarshalHelper.ToNative(ref Unsafe.Unbox(managedObject), nativePtr); } - internal static void ToNativeFieldWrapper(int fieldOffset, object fieldOwner, IntPtr nativePtr, out int fieldSize) + internal static void ToNativeFieldWrapper(FieldInfo field, int fieldOffset, object fieldOwner, IntPtr nativePtr, out int fieldSize) { - MarshalHelper.ToNativeField(fieldOffset, ref Unsafe.Unbox(fieldOwner), nativePtr, out fieldSize); + MarshalHelper.ToNativeField(field, fieldOffset, ref Unsafe.Unbox(fieldOwner), nativePtr, out fieldSize); } internal static void ToManagedPointer(ref IntPtr managedValue, IntPtr nativePtr, bool byRef) @@ -982,7 +981,6 @@ namespace FlaxEngine.Interop byRef |= type.IsByRef; // Is this needed? if (type.IsByRef) Assert.IsTrue(type.GetElementType().IsValueType); - managedValue = byRef ? nativePtr : Unsafe.Read(nativePtr.ToPointer()); } @@ -994,9 +992,12 @@ namespace FlaxEngine.Interop internal static void ToManagedWithMarshallableFields(ref T managedValue, IntPtr nativePtr, bool byRef) { IntPtr fieldPtr = nativePtr; - for (int i = 0; i < MarshalHelper.marshallableFields.Length; i++) + var fields = MarshalHelper.marshallableFields; + var offsets = MarshalHelper.marshallableFieldOffsets; + var marshallers = MarshalHelper.toManagedFieldMarshallers; + for (int i = 0; i < fields.Length; i++) { - MarshalHelper.toManagedFieldMarshallers[i](MarshalHelper.marshallableFieldOffsets[i], ref managedValue, fieldPtr, out int fieldSize); + marshallers[i](fields[i], offsets[i], ref managedValue, fieldPtr, out int fieldSize); fieldPtr += fieldSize; } Assert.IsTrue((fieldPtr - nativePtr) <= Unsafe.SizeOf()); @@ -1038,9 +1039,12 @@ namespace FlaxEngine.Interop internal static void ToNativeWithMarshallableFields(ref T managedValue, IntPtr nativePtr) { IntPtr fieldPtr = nativePtr; + var fields = MarshalHelper.marshallableFields; + var offsets = MarshalHelper.marshallableFieldOffsets; + var marshallers = MarshalHelper.toNativeFieldMarshallers; for (int i = 0; i < MarshalHelper.marshallableFields.Length; i++) { - MarshalHelper.toNativeFieldMarshallers[i](MarshalHelper.marshallableFieldOffsets[i], ref managedValue, nativePtr, out int fieldSize); + marshallers[i](fields[i], offsets[i], ref managedValue, nativePtr, out int fieldSize); nativePtr += fieldSize; } Assert.IsTrue((nativePtr - fieldPtr) <= Unsafe.SizeOf()); @@ -1060,10 +1064,10 @@ namespace FlaxEngine.Interop MarshalHelper.ToNative(ref managedValue, nativePtr); } - internal static void ToNativeFieldWrapper(int fieldOffset, object managedObject, IntPtr nativePtr, out int fieldSize) + internal static void ToNativeFieldWrapper(FieldInfo field, int fieldOffset, object fieldOwner, IntPtr nativePtr, out int fieldSize) { - T managedValue = Unsafe.As(managedObject); - MarshalHelper.ToNativeField(fieldOffset, ref managedValue, nativePtr, out fieldSize); + T managedValue = Unsafe.As(fieldOwner); + MarshalHelper.ToNativeField(field, fieldOffset, ref managedValue, nativePtr, out fieldSize); } internal static void ToManagedString(ref string managedValue, IntPtr nativePtr, bool byRef) diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index 047423994..1d01a8ea3 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -614,6 +614,18 @@ bool MCore::Type::IsReference(MType* type) return CallStaticMethod(GetTypeIsReferencePtr, type); } +void MCore::ScriptingObject::SetInternalValues(MClass* klass, MObject* object, void* unmanagedPtr, const Guid* id) +{ + static void* ScriptingObjectSetInternalValuesPtr = GetStaticMethodPointer(TEXT("ScriptingObjectSetInternalValues")); + CallStaticMethod(ScriptingObjectSetInternalValuesPtr, object, unmanagedPtr, id); +} + +MObject* MCore::ScriptingObject::CreateScriptingObject(MClass* klass, void* unmanagedPtr, const Guid* id) +{ + static void* ScriptingObjectSetInternalValuesPtr = GetStaticMethodPointer(TEXT("ScriptingObjectCreate")); + return CallStaticMethod(ScriptingObjectSetInternalValuesPtr, klass->_handle, unmanagedPtr, id); +} + const MAssembly::ClassesDictionary& MAssembly::GetClasses() const { if (_hasCachedClasses || !IsLoaded()) @@ -1737,18 +1749,6 @@ void* GetStaticMethodPointer(const String& methodName) return fun; } -void MCore::ScriptingObject::SetInternalValues(MClass* klass, MObject* object, void* unmanagedPtr, const Guid* id) -{ - static void* ScriptingObjectSetInternalValuesPtr = GetStaticMethodPointer(TEXT("ScriptingObjectSetInternalValues")); - CallStaticMethod(ScriptingObjectSetInternalValuesPtr, object, unmanagedPtr, id); -} - -MObject* MCore::ScriptingObject::CreateScriptingObject(MClass* klass, void* unmanagedPtr, const Guid* id) -{ - static void* ScriptingObjectSetInternalValuesPtr = GetStaticMethodPointer(TEXT("ScriptingObjectCreate")); - return CallStaticMethod(ScriptingObjectSetInternalValuesPtr, klass->_handle, unmanagedPtr, id); -} - #elif DOTNET_HOST_MONO #ifdef USE_MONO_AOT_MODULE