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