Compare commits
4 Commits
c7326ea483
...
sdl_platfo
| Author | SHA1 | Date | |
|---|---|---|---|
| 43c4d45080 | |||
| 56a85f6ac0 | |||
| 1b8e25cb86 | |||
| 7088ce8742 |
@@ -139,7 +139,7 @@ namespace FlaxEditor.CustomEditors
|
||||
return new GenericEditor();
|
||||
}
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "CustomEditorsUtilInternal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "CustomEditorsUtilInternal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalUsing(typeof(SystemTypeMarshaller))]
|
||||
internal static partial Type Internal_GetCustomEditor([MarshalUsing(typeof(SystemTypeMarshaller))] Type targetType);
|
||||
}
|
||||
|
||||
@@ -69,18 +69,18 @@ namespace FlaxEditor
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this Editor is running a dev instance of the engine.
|
||||
/// </summary>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsDevInstance", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsDevInstance")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool IsDevInstance();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this Editor is running as official build (distributed via Flax services).
|
||||
/// </summary>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsOfficialBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsOfficialBuild")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool IsOfficialBuild();
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsPlayMode")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_IsPlayMode();
|
||||
|
||||
@@ -1647,96 +1647,103 @@ namespace FlaxEditor
|
||||
}
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ReadOutputLogs", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
internal static partial int Internal_ReadOutputLogs([MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref string[] outMessages, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref byte[] outLogTypes, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref long[] outLogTimes, int outCapacity);
|
||||
internal static partial int Internal_ReadOutputLogs([MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, FlaxEngine.Interop.NativeString>), CountElementName = "outCapacity")] ref string[] outMessages, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 3)] ref byte[] outLogTypes, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I8, SizeParamIndex = 3)] ref long[] outLogTimes, int outCapacity);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetPlayMode")]
|
||||
internal static partial void Internal_SetPlayMode([MarshalAs(UnmanagedType.U1)] bool value);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
internal static partial string Internal_GetProjectPath();
|
||||
internal static string Internal_GetProjectPath()
|
||||
{
|
||||
Internal_GetProjectPath(out string projectPath);
|
||||
return projectPath;
|
||||
}
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
internal static partial void Internal_GetProjectPath([MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller))] out string projectPath);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_CloneAssetFile(string dstPath, string srcPath, ref Guid dstId);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAudioClipMetadata", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAudioClipMetadata")]
|
||||
internal static partial void Internal_GetAudioClipMetadata(IntPtr obj, out int originalSize, out int importedSize);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_SaveJsonAsset(string outputPath, string data, string typename);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CopyCache", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CopyCache")]
|
||||
internal static partial void Internal_CopyCache(ref Guid dstId, ref Guid srcId);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_BakeLightmaps", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_BakeLightmaps")]
|
||||
internal static partial void Internal_BakeLightmaps([MarshalAs(UnmanagedType.U1)] bool cancel);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller))]
|
||||
internal static partial string Internal_GetShaderAssetSourceCode(IntPtr obj);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_CookMeshCollision(string path, CollisionDataType type, IntPtr model, int modelLodIndex, uint materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int convexVertexLimit);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetCollisionWires", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
internal static partial void Internal_GetCollisionWires(IntPtr collisionData, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "trianglesCount")] out Float3[] triangles, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "indicesCount")] out int[] indices, out int trianglesCount, out int indicesCount);
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetCollisionWires")]
|
||||
internal static partial void Internal_GetCollisionWires(IntPtr collisionData, [MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<,>), CountElementName = "trianglesCount")] out Float3[] triangles, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "indicesCount")] out int[] indices, out int trianglesCount, out int indicesCount);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetEditorBoxWithChildren", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetEditorBoxWithChildren")]
|
||||
internal static partial void Internal_GetEditorBoxWithChildren(IntPtr obj, out BoundingBox resultAsRef);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetOptions")]
|
||||
internal static partial void Internal_SetOptions(ref InternalOptions options);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DrawNavMesh", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DrawNavMesh")]
|
||||
internal static partial void Internal_DrawNavMesh();
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloseSplashScreen", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloseSplashScreen")]
|
||||
internal static partial void Internal_CloseSplashScreen();
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_CreateVisualScript(string outputPath, string baseTypename);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
internal static partial string Internal_CanImport(string extension);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_CanExport(string path);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_Export(string inputPath, string outputFolder);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsEveryAssemblyLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsEveryAssemblyLoaded")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_GetIsEveryAssemblyLoaded();
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetLastProjectOpenedEngineBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetLastProjectOpenedEngineBuild")]
|
||||
internal static partial int Internal_GetLastProjectOpenedEngineBuild();
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsCSGActive", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsCSGActive")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_GetIsCSGActive();
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_RunVisualScriptBreakpointLoopTick", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_RunVisualScriptBreakpointLoopTick")]
|
||||
internal static partial void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
internal static partial void Internal_DeserializeSceneObject(IntPtr sceneObject, string json);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_LoadAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_LoadAsset")]
|
||||
internal static partial void Internal_LoadAsset(ref Guid id);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanSetToRoot", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanSetToRoot")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime")]
|
||||
internal static partial float Internal_GetAnimationTime(IntPtr animatedModel);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetAnimationTime")]
|
||||
internal static partial void Internal_SetAnimationTime(IntPtr animatedModel, float time);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -58,22 +58,22 @@ void OnLogMessage(LogType type, const StringView& msg)
|
||||
{
|
||||
ScopeLock lock(CachedLogDataLocker);
|
||||
|
||||
CachedLogData.EnsureCapacity(4 + 8 + 4 + msg.Length() * 2);
|
||||
CachedLogData.EnsureCapacity(sizeof(int32) + sizeof(DateTime) + sizeof(int32) + msg.Length() * sizeof(Char));
|
||||
|
||||
// Log Type
|
||||
int32 buf = (int32)type;
|
||||
CachedLogData.Add((byte*)&buf, 4);
|
||||
CachedLogData.Add((byte*)&buf, sizeof(int32));
|
||||
|
||||
// Time
|
||||
auto time = DateTime::Now();
|
||||
CachedLogData.Add((byte*)&time.Ticks, 8);
|
||||
CachedLogData.Add((byte*)&time.Ticks, sizeof(DateTime));
|
||||
|
||||
// Message Length
|
||||
buf = msg.Length();
|
||||
CachedLogData.Add((byte*)&buf, 4);
|
||||
CachedLogData.Add((byte*)&buf, sizeof(int32));
|
||||
|
||||
// Message
|
||||
CachedLogData.Add((byte*)msg.Get(), msg.Length() * 2);
|
||||
CachedLogData.Add((byte*)msg.Get(), msg.Length() * sizeof(Char));
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) EditorInternal_IsDevInstance()
|
||||
@@ -99,7 +99,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_IsPlayMode()
|
||||
return Editor::IsPlayMode;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(MArray** outMessages, MArray** outLogTypes, MArray** outLogTimes, int outArraySize)
|
||||
DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(NativeArray<String>* outMessages, NativeArray<byte>* outLogTypes, NativeArray<int64>* outLogTimes, int outArraySize)
|
||||
{
|
||||
ScopeLock lock(CachedLogDataLocker);
|
||||
if (CachedLogData.IsEmpty() || CachedLogData.Get() == nullptr)
|
||||
@@ -108,27 +108,30 @@ DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(MArray** outMessages,
|
||||
int32 count = 0;
|
||||
const int32 maxCount = outArraySize;
|
||||
|
||||
String* messages = &outMessages->data[0];
|
||||
byte* ptr = CachedLogData.Get();
|
||||
byte* end = ptr + CachedLogData.Count();
|
||||
byte* outLogTypesPtr = MCore::Array::GetAddress<byte>(*outLogTypes);
|
||||
int64* outLogTimesPtr = MCore::Array::GetAddress<int64>(*outLogTimes);
|
||||
byte* outLogTypesPtr = outLogTypes->data;
|
||||
int64* outLogTimesPtr = outLogTimes->data;
|
||||
while (count < maxCount && ptr != end)
|
||||
{
|
||||
auto type = (byte)*(int32*)ptr;
|
||||
ptr += 4;
|
||||
ptr += sizeof(int32);
|
||||
|
||||
auto time = *(int64*)ptr;
|
||||
ptr += 8;
|
||||
ptr += sizeof(int64);
|
||||
|
||||
auto length = *(int32*)ptr;
|
||||
ptr += 4;
|
||||
ptr += sizeof(int32);
|
||||
|
||||
auto msg = (Char*)ptr;
|
||||
ptr += length * 2;
|
||||
ptr += length * sizeof(Char);
|
||||
|
||||
auto msgObj = MUtils::ToString(StringView(msg, length));
|
||||
auto msgObj = String(msg, length);
|
||||
|
||||
MCore::GC::WriteArrayRef(*outMessages, (MObject*)msgObj, count);
|
||||
String& str = messages[count];
|
||||
ASSERT(str.Get() == nullptr && str.Length() == 0);
|
||||
str = msgObj;
|
||||
outLogTypesPtr[count] = type;
|
||||
outLogTimesPtr[count] = time;
|
||||
|
||||
@@ -147,9 +150,9 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_SetPlayMode(bool value)
|
||||
Editor::IsPlayMode = value;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetProjectPath()
|
||||
DEFINE_INTERNAL_CALL(void) EditorInternal_GetProjectPath(StringView* projectPath)
|
||||
{
|
||||
return MUtils::ToString(Editor::Project->ProjectPath);
|
||||
*projectPath = Editor::Project->ProjectPath;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) EditorInternal_CloseSplashScreen()
|
||||
@@ -159,6 +162,7 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_CloseSplashScreen()
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) EditorInternal_CloneAssetFile(MString* dstPathObj, MString* srcPathObj, Guid* dstId)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
// Get normalized paths
|
||||
String dstPath, srcPath;
|
||||
MUtils::ToString(dstPathObj, dstPath);
|
||||
@@ -172,6 +176,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CloneAssetFile(MString* dstPathObj, MS
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MString* outputPathObj, MString* baseTypenameObj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
String outputPath;
|
||||
MUtils::ToString(outputPathObj, outputPath);
|
||||
FileSystem::NormalizePath(outputPath);
|
||||
@@ -182,6 +187,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MString* outputPath
|
||||
|
||||
DEFINE_INTERNAL_CALL(MString*) EditorInternal_CanImport(MString* extensionObj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
String extension;
|
||||
MUtils::ToString(extensionObj, extension);
|
||||
if (extension.Length() > 0 && extension[0] == '.')
|
||||
@@ -199,6 +205,7 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_GetAudioClipMetadata(AudioClip* clip,
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) EditorInternal_SaveJsonAsset(MString* outputPathObj, MString* dataObj, MString* dataTypeNameObj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
String outputPath;
|
||||
MUtils::ToString(outputPathObj, outputPath);
|
||||
FileSystem::NormalizePath(outputPath);
|
||||
@@ -216,6 +223,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_SaveJsonAsset(MString* outputPathObj,
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MString* pathObj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
#if COMPILE_WITH_ASSETS_EXPORTER
|
||||
String path;
|
||||
MUtils::ToString(pathObj, path);
|
||||
@@ -229,6 +237,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MString* pathObj)
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) EditorInternal_Export(MString* inputPathObj, MString* outputFolderObj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
#if COMPILE_WITH_ASSETS_EXPORTER
|
||||
String inputPath;
|
||||
MUtils::ToString(inputPathObj, inputPath);
|
||||
@@ -246,6 +255,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_Export(MString* inputPathObj, MString*
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) EditorInternal_CopyCache(Guid* dstId, Guid* srcId)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
ShaderCacheManager::CopyCache(*dstId, *srcId);
|
||||
}
|
||||
|
||||
@@ -260,6 +270,7 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_BakeLightmaps(bool cancel)
|
||||
|
||||
DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetShaderAssetSourceCode(BinaryAsset* obj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
|
||||
if (obj->WaitForLoaded())
|
||||
DebugLog::ThrowNullReference();
|
||||
@@ -287,6 +298,7 @@ DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetShaderAssetSourceCode(BinaryAss
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
#if COMPILE_WITH_PHYSICS_COOKING
|
||||
CollisionCooking::Argument arg;
|
||||
String path;
|
||||
@@ -307,6 +319,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MString* pathObj, Co
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* collisionData, MArray** triangles, MArray** indices, int* trianglesCount, int* indicesCount)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
if (!collisionData || collisionData->WaitForLoaded() || collisionData->GetOptions().Type == CollisionDataType::None)
|
||||
return;
|
||||
|
||||
@@ -332,6 +345,7 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* colli
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) EditorInternal_GetEditorBoxWithChildren(Actor* obj, BoundingBox* result)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
INTERNAL_CALL_CHECK(obj);
|
||||
*result = obj->GetEditorBoxChildren();
|
||||
}
|
||||
@@ -461,6 +475,7 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) EditorInternal_DeserializeSceneObject(SceneObject* sceneObject, MString* jsonObj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
PROFILE_CPU_NAMED("DeserializeSceneObject");
|
||||
|
||||
StringAnsi json;
|
||||
@@ -531,10 +546,9 @@ DEFINE_INTERNAL_CALL(MTypeObject*) CustomEditorsUtilInternal_GetCustomEditor(MTy
|
||||
return CustomEditorsUtil::GetCustomEditor(targetType);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MArray*) LayersAndTagsSettingsInternal_GetCurrentLayers(int* layersCount)
|
||||
DEFINE_INTERNAL_CALL(NativeSpan<String>) LayersAndTagsSettingsInternal_GetCurrentLayers()
|
||||
{
|
||||
*layersCount = Math::Max(1, Level::GetNonEmptyLayerNamesCount());
|
||||
return MUtils::ToArray(Span<String>(Level::Layers, *layersCount));
|
||||
return NativeSpan<String>::AsSpan(Level::Layers, Math::Max(1, Level::GetNonEmptyLayerNamesCount()));
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) GameSettingsInternal_Apply()
|
||||
|
||||
@@ -878,7 +878,7 @@ namespace FlaxEditor.Windows
|
||||
Message = _outMessages[i],
|
||||
};
|
||||
_entries.Add(entry);
|
||||
_outMessages[i] = null;
|
||||
_outMessages[i] = null; // Prevent passing old strings back to native side
|
||||
_isDirty = true;
|
||||
}
|
||||
} while (logCount != 0);
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -47,6 +47,7 @@ static_assert(sizeof(InternalImpulse) == sizeof(AnimGraphImpulse), "Please updat
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) AnimGraphInternal_HasConnection(InternalContext* context, int32 boxId)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
const auto box = context->Node->TryGetBox(boxId);
|
||||
if (box == nullptr)
|
||||
DebugLog::ThrowArgumentOutOfRange("boxId");
|
||||
@@ -55,6 +56,7 @@ DEFINE_INTERNAL_CALL(bool) AnimGraphInternal_HasConnection(InternalContext* cont
|
||||
|
||||
DEFINE_INTERNAL_CALL(MObject*) AnimGraphInternal_GetInputValue(InternalContext* context, int32 boxId)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
const auto box = context->Node->TryGetBox(boxId);
|
||||
if (box == nullptr)
|
||||
DebugLog::ThrowArgumentOutOfRange("boxId");
|
||||
@@ -72,6 +74,7 @@ DEFINE_INTERNAL_CALL(MObject*) AnimGraphInternal_GetInputValue(InternalContext*
|
||||
|
||||
DEFINE_INTERNAL_CALL(AnimGraphImpulse*) AnimGraphInternal_GetOutputImpulseData(InternalContext* context)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
const auto nodes = context->Node->GetNodes(context->GraphExecutor);
|
||||
context->GraphExecutor->InitNodes(nodes);
|
||||
return nodes;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace FlaxEditor.Content.Settings
|
||||
/// <returns>The layers.</returns>
|
||||
public static string[] GetCurrentLayers()
|
||||
{
|
||||
return GetCurrentLayers(out int _);
|
||||
return Internal_GetCurrentLayers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -56,7 +56,7 @@ namespace FlaxEditor.Content.Settings
|
||||
}
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "LayersAndTagsSettingsInternal_GetCurrentLayers", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "layerCount")]
|
||||
internal static partial string[] GetCurrentLayers(out int layerCount);
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.NativeSpanMarshaller<string, FlaxEngine.Interop.NativeString>), ConstantElementCount = FlaxEngine.Interop.MarshallerFlags.SkipDisposeElements)]
|
||||
internal static partial string[] Internal_GetCurrentLayers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,7 +678,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in BoundingBox other)
|
||||
{
|
||||
return Minimum == other.Minimum && Maximum == other.Maximum;
|
||||
return Minimum.Equals(other.Minimum) && Maximum.Equals(other.Maximum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in BoundingFrustum other)
|
||||
{
|
||||
return pMatrix == other.pMatrix;
|
||||
return pMatrix.Equals(other.pMatrix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -492,7 +492,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in BoundingSphere other)
|
||||
{
|
||||
return Center == other.Center && Radius == other.Radius;
|
||||
return Center.Equals(other.Center) && Radius.Equals(other.Radius);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Color other)
|
||||
{
|
||||
return R == other.R && G == other.G && B == other.B && A == other.A;
|
||||
return R.Equals(other.R) && G.Equals(other.G) && B.Equals(other.B) && A.Equals(other.A);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1582,7 +1582,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Double2 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1880,7 +1880,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Double3 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y && Z == other.Z;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1379,7 +1379,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Double4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(in Double4 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && W.Equals(other.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1658,7 +1658,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Float2 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1912,7 +1912,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Float3 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y && Z == other.Z;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1419,7 +1419,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Float4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(in Float4 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && W.Equals(other.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -198,7 +198,7 @@ namespace FlaxEngine
|
||||
/// <param name="value"></param>
|
||||
public static double InverseLerp(double a, double b, double value)
|
||||
{
|
||||
if (a == b)
|
||||
if (a.Equals(b))
|
||||
return 0d;
|
||||
return Saturate((value - a) / (b - a));
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace FlaxEngine
|
||||
/// <param name="value"></param>
|
||||
public static float InverseLerp(float a, float b, float value)
|
||||
{
|
||||
if (a == b)
|
||||
if (a.Equals(b))
|
||||
return 0f;
|
||||
return Saturate((value - a) / (b - a));
|
||||
}
|
||||
|
||||
@@ -3236,22 +3236,22 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Matrix" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(in Matrix other)
|
||||
{
|
||||
return other.M11 == M11 &&
|
||||
other.M12 == M12 &&
|
||||
other.M13 == M13 &&
|
||||
other.M14 == M14 &&
|
||||
other.M21 == M21 &&
|
||||
other.M22 == M22 &&
|
||||
other.M23 == M23 &&
|
||||
other.M24 == M24 &&
|
||||
other.M31 == M31 &&
|
||||
other.M32 == M32 &&
|
||||
other.M33 == M33 &&
|
||||
other.M34 == M34 &&
|
||||
other.M41 == M41 &&
|
||||
other.M42 == M42 &&
|
||||
other.M43 == M43 &&
|
||||
other.M44 == M44;
|
||||
return other.M11.Equals(M11) &&
|
||||
other.M12.Equals(M12) &&
|
||||
other.M13.Equals(M13) &&
|
||||
other.M14.Equals(M14) &&
|
||||
other.M21.Equals(M21) &&
|
||||
other.M22.Equals(M22) &&
|
||||
other.M23.Equals(M23) &&
|
||||
other.M24.Equals(M24) &&
|
||||
other.M31.Equals(M31) &&
|
||||
other.M32.Equals(M32) &&
|
||||
other.M33.Equals(M33) &&
|
||||
other.M34.Equals(M34) &&
|
||||
other.M41.Equals(M41) &&
|
||||
other.M42.Equals(M42) &&
|
||||
other.M43.Equals(M43) &&
|
||||
other.M44.Equals(M44);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -483,7 +483,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Matrix2x2"/> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(in Matrix2x2 other)
|
||||
{
|
||||
return M11 == other.M11 && M12 == other.M12 && M21 == other.M21 && M22 == other.M22;
|
||||
return M11.Equals(other.M11) && M12.Equals(other.M12) && M21.Equals(other.M21) && M22.Equals(other.M22);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2125,15 +2125,15 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Matrix3x3"/> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(in Matrix3x3 other)
|
||||
{
|
||||
return M11 == other.M11 &&
|
||||
M12 == other.M12 &&
|
||||
M13 == other.M13 &&
|
||||
M21 == other.M21 &&
|
||||
M22 == other.M22 &&
|
||||
M23 == other.M23 &&
|
||||
M31 == other.M31 &&
|
||||
M32 == other.M32 &&
|
||||
M33 == other.M33;
|
||||
return M11.Equals(other.M11) &&
|
||||
M12.Equals(other.M12) &&
|
||||
M13.Equals(other.M13) &&
|
||||
M21.Equals(other.M21) &&
|
||||
M22.Equals(other.M22) &&
|
||||
M23.Equals(other.M23) &&
|
||||
M31.Equals(other.M31) &&
|
||||
M32.Equals(other.M32) &&
|
||||
M33.Equals(other.M33);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -397,7 +397,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in OrientedBoundingBox value)
|
||||
{
|
||||
return Extents == value.Extents && Transformation == value.Transformation;
|
||||
return Extents.Equals(value.Extents) && Transformation.Equals(value.Transformation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -587,7 +587,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Plane other)
|
||||
{
|
||||
return Normal == other.Normal && D == other.D;
|
||||
return Normal.Equals(other.Normal) && D.Equals(other.D);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1714,7 +1714,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Quaternion other)
|
||||
{
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && W.Equals(other.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -433,7 +433,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Ray other)
|
||||
{
|
||||
return Position == other.Position && Direction == other.Direction;
|
||||
return Position.Equals(other.Position) && Direction.Equals(other.Direction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -499,7 +499,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Rectangle other)
|
||||
{
|
||||
return Location == other.Location && Size == other.Size;
|
||||
return Location.Equals(other.Location) && Size.Equals(other.Size);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -705,7 +705,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Transform other)
|
||||
{
|
||||
return Translation == other.Translation && Orientation == other.Orientation && Scale == other.Scale;
|
||||
return Translation.Equals(other.Translation) && Orientation.Equals(other.Orientation) && Scale.Equals(other.Scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1782,7 +1782,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Vector2 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2141,7 +2141,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(in Vector3 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y && Z == other.Z;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1493,7 +1493,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(in Vector4 other)
|
||||
{
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && W.Equals(other.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -183,11 +183,11 @@ namespace FlaxEngine.Interop
|
||||
if (returnType == typeof(string))
|
||||
return ManagedString.ToNative/*Weak*/(Unsafe.As<string>(returnObject));
|
||||
if (returnType == typeof(IntPtr))
|
||||
return (IntPtr)(object)returnObject;
|
||||
return (IntPtr)returnObject;
|
||||
if (returnType == typeof(ManagedHandle))
|
||||
return ManagedHandle.ToIntPtr((ManagedHandle)(object)returnObject);
|
||||
return ManagedHandle.ToIntPtr((ManagedHandle)returnObject);
|
||||
if (returnType == typeof(Type) || returnType == typeof(TypeHolder))
|
||||
return returnObject != null ? ManagedHandle.ToIntPtr(GetTypeManagedHandle(Unsafe.As<Type>(returnObject))) : IntPtr.Zero;
|
||||
return ManagedHandle.ToIntPtr(GetTypeManagedHandle(Unsafe.As<Type>(returnObject)));
|
||||
if (returnType.IsArray)
|
||||
{
|
||||
var elementType = returnType.GetElementType();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma warning disable CS0162
|
||||
#define USE_CONCURRENT_DICT
|
||||
#define USE_GCHANDLE
|
||||
//#define TRACK_HANDLES
|
||||
@@ -311,20 +311,24 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
internal static ManagedHandle EmptyStringHandle = ManagedHandle.Alloc(string.Empty);
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe IntPtr ToNative(string str)
|
||||
{
|
||||
if (str == null)
|
||||
return IntPtr.Zero;
|
||||
else if (str == string.Empty)
|
||||
return ManagedHandle.ToIntPtr(EmptyStringHandle);
|
||||
Assert.IsTrue(str.Length > 0);
|
||||
return ManagedHandle.ToIntPtr(str);
|
||||
//else if (str == string.Empty)
|
||||
// return ManagedHandle.ToIntPtr(EmptyStringHandle);
|
||||
//return ManagedHandle.ToIntPtr(str);
|
||||
|
||||
NativeString* nativeString = (NativeString*)NativeMemory.AlignedAlloc((UIntPtr)Unsafe.SizeOf<NativeString>(), 16);
|
||||
*nativeString = new NativeString(str);
|
||||
return (IntPtr)nativeString;
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe IntPtr ToNativeWeak(string str)
|
||||
{
|
||||
throw new Exception("not used");
|
||||
if (str == null)
|
||||
return IntPtr.Zero;
|
||||
else if (str == string.Empty)
|
||||
@@ -333,28 +337,39 @@ namespace FlaxEngine.Interop
|
||||
return ManagedHandle.ToIntPtr(str, GCHandleType.Weak);
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
public static string ToManaged(IntPtr ptr)
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe string ToManaged(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
return null;
|
||||
return Unsafe.As<string>(ManagedHandle.FromIntPtr(ptr).Target);
|
||||
//return Unsafe.As<string>(ManagedHandle.FromIntPtr(ptr).Target);
|
||||
NativeString* str = (NativeString*)ptr.ToPointer();
|
||||
return str->ToString();
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
public static void Free(IntPtr ptr)
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe void Free(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
return;
|
||||
ManagedHandle handle = ManagedHandle.FromIntPtr(ptr);
|
||||
if (handle == EmptyStringHandle)
|
||||
return;
|
||||
handle.Free();
|
||||
//ManagedHandle handle = ManagedHandle.FromIntPtr(ptr);
|
||||
//if (handle == EmptyStringHandle)
|
||||
// return;
|
||||
//handle.Free();
|
||||
Free((NativeString*)ptr.ToPointer());
|
||||
}
|
||||
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe void Free(NativeString* str)
|
||||
{
|
||||
if (str->Data != null)
|
||||
NativeMemory.AlignedFree(str->Data);
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
public static void Free(ManagedHandle handle)
|
||||
{
|
||||
throw new Exception("not used");
|
||||
if (handle == EmptyStringHandle)
|
||||
return;
|
||||
handle.Free();
|
||||
@@ -537,7 +552,8 @@ namespace FlaxEngine.Interop
|
||||
internal static class ManagedHandlePool
|
||||
{
|
||||
[ThreadStatic]
|
||||
private static List<(bool InUse, ManagedHandle Handle)> _pool;
|
||||
private static List<(bool InUse, ManagedHandle Handle)> __poolField;
|
||||
private static List<(bool InUse, ManagedHandle Handle)> _pool => __poolField ??= [];
|
||||
|
||||
internal static void TryCollectWeakHandles(bool force = false)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -527,34 +527,49 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle NewArray(ManagedHandle typeHandle, long size)
|
||||
internal static IntPtr NewArray(ManagedHandle typeHandle, long size)
|
||||
{
|
||||
Type elementType = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
Type marshalledType = ArrayFactory.GetMarshalledType(elementType);
|
||||
Type arrayType = ArrayFactory.GetArrayType(elementType);
|
||||
if (marshalledType.IsValueType)
|
||||
{
|
||||
ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, arrayType, marshalledType);
|
||||
return ManagedHandle.Alloc(managedArray);
|
||||
IntPtr arrayPtr = (IntPtr)NativeMemory.AlignedAlloc((UIntPtr)Unsafe.SizeOf<NativeArrayTypeless>(), 16);
|
||||
IntPtr dataPtr = (IntPtr)NativeMemory.AlignedAlloc((UIntPtr)(RuntimeHelpers.SizeOf(marshalledType.TypeHandle) * size), 16);
|
||||
Unsafe.Write<IntPtr>(arrayPtr.ToPointer(), dataPtr);
|
||||
Unsafe.Write<long>(IntPtr.Add(arrayPtr, Unsafe.SizeOf<IntPtr>()).ToPointer(), size);
|
||||
|
||||
return arrayPtr;
|
||||
//ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, arrayType, marshalledType);
|
||||
//return ManagedHandle.Alloc(managedArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array arr = ArrayFactory.CreateArray(elementType, size);
|
||||
/*Array arr = ArrayFactory.CreateArray(elementType, size);
|
||||
ManagedArray managedArray = ManagedArray.WrapNewArray(arr, arrayType);
|
||||
return ManagedHandle.Alloc(managedArray);
|
||||
return ManagedHandle.Alloc(managedArray);*/
|
||||
IntPtr arrayPtr = (IntPtr)NativeMemory.AlignedAlloc((UIntPtr)Unsafe.SizeOf<NativeArrayTypeless>(), 16);
|
||||
IntPtr dataPtr = (IntPtr)NativeMemory.AlignedAlloc((UIntPtr)(Unsafe.SizeOf<IntPtr>() * size), 16);
|
||||
Unsafe.Write<IntPtr>(arrayPtr.ToPointer(), dataPtr);
|
||||
Unsafe.Write<long>(IntPtr.Add(arrayPtr, Unsafe.SizeOf<IntPtr>()).ToPointer(), size);
|
||||
|
||||
return arrayPtr;
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void FreeArray(ManagedHandle handle)
|
||||
internal static void FreeArray(void* ptr)
|
||||
{
|
||||
if (!handle.IsAllocated)
|
||||
if (ptr == null)
|
||||
return;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(handle.Target);
|
||||
|
||||
NativeArrayTypeless* array = (NativeArrayTypeless*)ptr;
|
||||
array->Free();
|
||||
/*ManagedArray managedArray = Unsafe.As<ManagedArray>(handle.Target);
|
||||
if (managedArray.ElementType.IsValueType)
|
||||
managedArray.Free();
|
||||
else
|
||||
managedArray.FreePooled();
|
||||
managedArray.FreePooled();*/
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -575,14 +590,15 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static IntPtr GetArrayPointer(ManagedHandle arrayHandle)
|
||||
internal static IntPtr GetArrayPointer(void* ptr)
|
||||
{
|
||||
if (!arrayHandle.IsAllocated)
|
||||
if (ptr == null)
|
||||
return IntPtr.Zero;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||
if (managedArray.Length == 0)
|
||||
NativeArrayTypeless* array = (NativeArrayTypeless*)ptr;
|
||||
if (array->Length == 0)
|
||||
return IntPtr.Zero;
|
||||
return managedArray.Pointer;
|
||||
|
||||
return (IntPtr)array->Data;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -599,12 +615,16 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static int GetArrayLength(ManagedHandle arrayHandle)
|
||||
internal static int GetArrayLength(void* ptr)
|
||||
{
|
||||
if (!arrayHandle.IsAllocated)
|
||||
return 0;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||
return managedArray.Length;
|
||||
//if (ptr == null)
|
||||
// return 0;
|
||||
NativeArrayTypeless* array = (NativeArrayTypeless*)ptr;
|
||||
return array->Length;
|
||||
/* if (!arrayHandle.IsAllocated)
|
||||
return 0;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||
return managedArray.Length;*/
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -626,9 +646,9 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void FreeString(ManagedHandle handle)
|
||||
internal static void FreeString(NativeString* str)
|
||||
{
|
||||
ManagedString.Free(handle);
|
||||
ManagedString.Free(str);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -765,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
|
||||
@@ -787,8 +807,11 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
// The internal exception thrown in MethodInfo.Invoke is caught here
|
||||
Exception realException = exception;
|
||||
if (exception.InnerException != null && exception.TargetSite.ReflectedType.Name == "MethodInvoker")
|
||||
if (exception.InnerException != null &&
|
||||
(exception.TargetSite.ReflectedType.Name == "MethodInvoker" || exception.TargetSite.ReflectedType.Name == "MethodBaseInvoker"))
|
||||
{
|
||||
realException = exception.InnerException;
|
||||
}
|
||||
|
||||
if (exceptionPtr != IntPtr.Zero)
|
||||
Unsafe.Write<IntPtr>(exceptionPtr.ToPointer(), ManagedHandle.ToIntPtr(realException, GCHandleType.Weak));
|
||||
|
||||
@@ -19,6 +19,9 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Buffers;
|
||||
using System.Runtime.InteropServices.Marshalling;
|
||||
using FlaxEngine.Utilities;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace FlaxEngine.Interop
|
||||
{
|
||||
@@ -198,8 +201,8 @@ namespace FlaxEngine.Interop
|
||||
public static T[] GCHandleArrayToManagedArray<T>(NativeArray<IntPtr> ptrArray, T[] buffer = null) where T : class
|
||||
{
|
||||
ReadOnlySpan<IntPtr> span = ptrArray.AsReadOnlySpan();
|
||||
if (buffer != null)
|
||||
buffer = buffer;
|
||||
//if (buffer != null)
|
||||
// buffer = buffer;
|
||||
if (buffer == null || buffer.Length < ptrArray.Length)
|
||||
buffer = new T[ptrArray.Length];
|
||||
for (int i = 0; i < ptrArray.Length; i++)
|
||||
@@ -410,6 +413,339 @@ 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>, Func<IntPtr, object>)> _marshallers = new(1, 3);
|
||||
|
||||
internal static class NewMarshalHelperValueType<TDest, TSource> where TSource : struct
|
||||
{
|
||||
internal static object NativeToManaged9(object src)
|
||||
{
|
||||
return NewMarshalHelper<TDest, TSource>.NativeToManaged9(ref Unsafe.Unbox<TSource>(src));
|
||||
}
|
||||
}
|
||||
|
||||
internal static class NewMarshalHelperReferenceType<TDest, TSource> where TSource : class
|
||||
{
|
||||
internal static object NativeToManaged9(object src)
|
||||
{
|
||||
TSource tsrc = Unsafe.As<TSource>(src);
|
||||
return NewMarshalHelper<TDest, TSource>.NativeToManaged9(ref tsrc);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class NewMarshalHelper<TDest, TSource>
|
||||
{
|
||||
internal static Func<TSource, TDest> _nativeToManagedFunc;
|
||||
internal static Type _pointerType;
|
||||
|
||||
internal static void Init(MethodInfo nativeToManagedMethod)
|
||||
{
|
||||
//Assert.IsNull(_nativeToManagedFunc);
|
||||
|
||||
//var internalType = nativeToManagedMethod.GetParameters()[0].ParameterType;
|
||||
//var types = new Type[] { marshalType, internalType };
|
||||
//var convertDelegate = method.CreateDelegate(typeof(ToManagedDelegate<,>).MakeGenericType(types));
|
||||
|
||||
if (_nativeToManagedFunc == null && nativeToManagedMethod != null)
|
||||
_nativeToManagedFunc = nativeToManagedMethod.CreateDelegate<Func<TSource, TDest>>();
|
||||
|
||||
_pointerType = typeof(TDest).MakePointerType();
|
||||
}
|
||||
|
||||
internal static TDest NativeToManaged9(ref TSource src)
|
||||
{
|
||||
return _nativeToManagedFunc(src);
|
||||
}
|
||||
|
||||
internal static object NativeToManagedIntPtr(TSource src)
|
||||
{
|
||||
// typeof(TSource) == typeof(IntPtr)
|
||||
return _nativeToManagedFunc(src);
|
||||
}
|
||||
|
||||
internal static object NativeToManagedPointer(IntPtr src)
|
||||
{
|
||||
//byte* asd = null;
|
||||
//return asd;
|
||||
return Pointer.Box(src.ToPointer(), _pointerType);
|
||||
}
|
||||
|
||||
internal static object NativeToManagedByPass(TSource src) => src;
|
||||
|
||||
internal static object NativeToManaged(IntPtr src)
|
||||
{
|
||||
// typeof(TSource) != typeof(IntPtr)
|
||||
TSource native = Marshal.PtrToStructure<TSource>(src);
|
||||
return _nativeToManagedFunc(native);
|
||||
}
|
||||
|
||||
internal static object NativeToManagedDirect(IntPtr src)
|
||||
{
|
||||
// typeof(TSource) != typeof(IntPtr)
|
||||
TSource native = Unsafe.Read<TSource>(src.ToPointer());
|
||||
return native;
|
||||
}
|
||||
}
|
||||
|
||||
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 == typeof(string))
|
||||
return typeof(StringMarshaller); // UTF-16 strings via MMethod::Invoke
|
||||
else if (type == typeof(object))
|
||||
return typeof(AsManagedHandleMarshaller);
|
||||
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>, Func<IntPtr, object>) Factory2(Type type)
|
||||
{
|
||||
Type marshalType = type;
|
||||
if (marshalType.IsByRef)
|
||||
marshalType = marshalType.GetElementType();
|
||||
|
||||
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))
|
||||
{
|
||||
//var setup = typeof(NewMarshalHelper<,>).MakeGenericType([typeof(IntPtr), typeof(IntPtr)]).GetMethod(nameof(NewMarshalHelper<,>.Init), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
//setup.Invoke(null, [method]);
|
||||
var convdirect = typeof(NewMarshalHelper<,>).MakeGenericType([typeof(IntPtr), typeof(IntPtr)]).GetMethod(nameof(NewMarshalHelper<,>.NativeToManagedByPass), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdirectdel = convdirect.CreateDelegate<Func<IntPtr, object>>();
|
||||
|
||||
Func<object, object> func = (obj) => obj;
|
||||
return (typeof(IntPtr), func, convdirectdel);
|
||||
}
|
||||
else if (marshalType == typeof(ManagedHandle))
|
||||
{
|
||||
var methody = typeof(ManagedHandle).GetMethod(nameof(ManagedHandle.FromIntPtr), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var setup = typeof(NewMarshalHelper<,>).MakeGenericType([typeof(ManagedHandle), typeof(IntPtr)]).GetMethod(nameof(NewMarshalHelper<,>.Init), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
setup.Invoke(null, [methody]);
|
||||
var convdirect = typeof(NewMarshalHelper<,>).MakeGenericType([typeof(ManagedHandle), typeof(IntPtr)]).GetMethod(nameof(NewMarshalHelper<,>.NativeToManagedIntPtr), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdirectdel = convdirect.CreateDelegate<Func<IntPtr, object>>();
|
||||
|
||||
Func<object, object> func = (obj) => ManagedHandle.FromIntPtr((IntPtr)obj);
|
||||
return (typeof(IntPtr), func, convdirectdel);
|
||||
}
|
||||
else if (marshalType.IsPointer)
|
||||
{
|
||||
var convdirect = typeof(NewMarshalHelper<,>).MakeGenericType([typeof(IntPtr), typeof(IntPtr)]).GetMethod(nameof(NewMarshalHelper<,>.NativeToManagedDirect), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdirectdel = convdirect.CreateDelegate<Func<IntPtr, object>>();
|
||||
|
||||
Func<object, object> func = (obj) => obj;
|
||||
return (typeof(IntPtr), func, convdirectdel);
|
||||
//return (null, null, null);
|
||||
/*var setup = typeof(NewMarshalHelper<,>).MakeGenericType([marshalType.GetElementType(), typeof(IntPtr)]).GetMethod(nameof(NewMarshalHelper<,>.Init), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
setup.Invoke(null, [null]);
|
||||
var convdirect = typeof(NewMarshalHelper<,>).MakeGenericType([marshalType.GetElementType(), typeof(IntPtr)]).GetMethod(nameof(NewMarshalHelper<,>.NativeToManagedPointer), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdirectdel = convdirect.CreateDelegate<Func<IntPtr, object>>();
|
||||
return (marshalType, null, convdirectdel);*/
|
||||
}
|
||||
else if (marshalType.IsPrimitive || marshalType.IsEnum)
|
||||
{
|
||||
var convdirect = typeof(NewMarshalHelper<,>).MakeGenericType([marshalType, marshalType]).GetMethod(nameof(NewMarshalHelper<,>.NativeToManagedDirect), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdirectdel = convdirect.CreateDelegate<Func<IntPtr, object>>();
|
||||
return (marshalType, null, convdirectdel);
|
||||
}
|
||||
else if (!marshalType.IsArray && IsBlittable(marshalType))
|
||||
{
|
||||
var convdirect = typeof(NewMarshalHelper<,>).MakeGenericType([marshalType, marshalType]).GetMethod(nameof(NewMarshalHelper<,>.NativeToManagedDirect), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdirectdel = convdirect.CreateDelegate<Func<IntPtr, object>>();
|
||||
return (marshalType, null, convdirectdel);
|
||||
}
|
||||
|
||||
/*else if (marshalType == typeof(object))
|
||||
{
|
||||
var convdirect = typeof(NewMarshalHelper<,>).MakeGenericType([typeof(ManagedHandle), typeof(IntPtr)]).GetMethod(nameof(NewMarshalHelper<,>.NativeToManagedIntPtr), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdirectdel = convdirect.CreateDelegate<Func<IntPtr, object>>();
|
||||
|
||||
Func<object, object> func = (obj) => (IntPtr)obj != IntPtr.Zero ? ManagedHandle.FromIntPtr((IntPtr)obj).Target : null;
|
||||
return (typeof(IntPtr), func, null);
|
||||
}*/
|
||||
}
|
||||
if (marshallerType == null)
|
||||
return (null, 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, null);
|
||||
}
|
||||
|
||||
var internalType = method.GetParameters()[0].ParameterType;
|
||||
var types = new Type[] { marshalType, internalType };
|
||||
var convertDelegate = method.CreateDelegate(typeof(ToManagedDelegate<,>).MakeGenericType(types));
|
||||
|
||||
var minit = typeof(NewMarshalHelper<,>).MakeGenericType(types).GetMethod(nameof(NewMarshalHelper<,>.Init), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
minit.Invoke(null, [method]);
|
||||
var conv = typeof(NewMarshalHelper<,>).MakeGenericType(types).GetMethod(nameof(NewMarshalHelper<,>.NativeToManaged), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdel = conv.CreateDelegate<Func<IntPtr, object>>();
|
||||
|
||||
|
||||
if (internalType == typeof(IntPtr))
|
||||
{
|
||||
var convdirect = typeof(NewMarshalHelper<,>).MakeGenericType(types).GetMethod(nameof(NewMarshalHelper<,>.NativeToManagedIntPtr), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var convdirectdel = convdirect.CreateDelegate<Func<IntPtr, object>>();
|
||||
|
||||
Func<object, object> func =
|
||||
(obj) => convertDelegate.DynamicInvoke(obj);
|
||||
|
||||
return (internalType, func, convdirectdel);
|
||||
}
|
||||
else if (internalType.IsStructure())
|
||||
{
|
||||
Func<object, object> func =
|
||||
(obj) => convertDelegate.DynamicInvoke(obj);
|
||||
|
||||
return (internalType, func, convdel);
|
||||
}
|
||||
else
|
||||
{
|
||||
Func<object, object> func =
|
||||
(obj) => convertDelegate.DynamicInvoke(obj);
|
||||
return (internalType, func, convdel);
|
||||
}
|
||||
}
|
||||
|
||||
var type2 = type.IsByRef ? type.GetElementType() : type;
|
||||
/*if (type2.IsPrimitive)
|
||||
{
|
||||
if (type.IsByRef && type2 == typeof(IntPtr))
|
||||
nativePtr = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
|
||||
//ref byte src = ref Unsafe.AsRef<byte>(nativePtr.ToPointer());
|
||||
//var ret = RuntimeHelpers.Box(ref src, type.TypeHandle);
|
||||
var ret = Marshal.PtrToStructure(nativePtr, type2);
|
||||
return ret;
|
||||
}
|
||||
else if (type2.IsEnum)
|
||||
{
|
||||
if (type.IsByRef)
|
||||
type2 = type2;
|
||||
ref byte src = ref Unsafe.AsRef<byte>(nativePtr.ToPointer());
|
||||
var ret = RuntimeHelpers.Box(ref src, type2.TypeHandle);
|
||||
return ret;
|
||||
}*/
|
||||
if (!_marshallers.TryGetValue(type, out var marsh))
|
||||
marsh = _marshallers.GetOrAdd(type, Factory2);
|
||||
if (marsh.Item3 != null)
|
||||
{
|
||||
//object conv1 = deleg(nativePtr, type.IsByRef && false);
|
||||
if (type.IsByRef && marsh.Item1 == typeof(IntPtr))
|
||||
nativePtr = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
if (true && marsh.Item3 != null)
|
||||
{
|
||||
// TODO: CustomMarshaller.Free()
|
||||
return marsh.Item3(nativePtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
object value = marsh.Item1 == typeof(IntPtr) ? nativePtr : Marshal.PtrToStructure(nativePtr, marsh.Item1);
|
||||
object conv2 = marsh.Item2(value);
|
||||
|
||||
// TODO: CustomMarshaller.Free()
|
||||
return conv2;
|
||||
}
|
||||
/*if (conv1 is null && conv2 is null)
|
||||
{ }
|
||||
else if (!conv1.Equals(conv2))
|
||||
Assert.IsTrue(conv1.Equals(conv2));*/
|
||||
|
||||
|
||||
}
|
||||
if (type2.IsStructure())
|
||||
{
|
||||
var ret = Marshal.PtrToStructure(nativePtr, type2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (type2 == typeof(int) || type2.IsEnum
|
||||
|| type2 == typeof(IntPtr) || type2 == typeof(Float2) || type2 == typeof(Float3)
|
||||
|| type2 == typeof(long) || type2 == typeof(sbyte)
|
||||
|| type2 == typeof(uint) || type2 == typeof(ulong) || type2 == typeof(ushort) || type2 == typeof(byte)
|
||||
|| type2 == typeof(float) || type2 == typeof(double))
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
else if (type2 == typeof(byte*) || type2 == typeof(Guid) || type2.IsArray)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (!toManagedMarshallers.TryGetValue(type, out var deleg))
|
||||
deleg = toManagedMarshallers.GetOrAdd(type, Factory);
|
||||
return deleg(nativePtr, type.IsByRef && false);
|
||||
}
|
||||
|
||||
internal static object MarshalToManaged(IntPtr nativePtr, Type type)
|
||||
{
|
||||
static MarshalToManagedDelegate Factory(Type type)
|
||||
@@ -426,7 +762,7 @@ namespace FlaxEngine.Interop
|
||||
|
||||
if (!toManagedMarshallers.TryGetValue(type, out var deleg))
|
||||
deleg = toManagedMarshallers.GetOrAdd(type, Factory);
|
||||
return deleg(nativePtr, type.IsByRef);
|
||||
return deleg(nativePtr, type.IsByRef && false);
|
||||
}
|
||||
|
||||
internal static void MarshalToNative(object managedObject, IntPtr nativePtr, Type type)
|
||||
@@ -552,6 +888,7 @@ namespace FlaxEngine.Interop
|
||||
internal static int[] marshallableFieldOffsets;
|
||||
internal static MarshalFieldTypedDelegate[] toManagedFieldMarshallers;
|
||||
internal static MarshalFieldTypedDelegate[] toNativeFieldMarshallers;
|
||||
private static int marshalledSize;
|
||||
|
||||
private static MarshalToNativeTypedDelegate toNativeTypedMarshaller;
|
||||
private static MarshalToManagedTypedDelegate toManagedTypedMarshaller;
|
||||
@@ -582,7 +919,33 @@ namespace FlaxEngine.Interop
|
||||
MethodInfo toManagedFieldMethod;
|
||||
MethodInfo toNativeFieldMethod;
|
||||
|
||||
if (fieldType.IsPointer)
|
||||
if (fieldType == typeof(SoftTypeReference))
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
toManagedFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToManagedFieldSoftTypeReferenceValueType), bindingFlags);
|
||||
toNativeFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToNativeFieldSoftTypeReferenceValueType), bindingFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
toManagedFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToManagedFieldSoftTypeReferenceReferenceType), bindingFlags);
|
||||
toNativeFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToNativeFieldSoftTypeReferenceReferenceType), bindingFlags);
|
||||
}
|
||||
}
|
||||
else if (fieldType == typeof(string))
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
toManagedFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToManagedFieldStringValueType), bindingFlags);
|
||||
toNativeFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToNativeFieldStringValueType), bindingFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
toManagedFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToManagedFieldStringReferenceType), bindingFlags);
|
||||
toNativeFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToNativeFieldStringReferenceType), bindingFlags);
|
||||
}
|
||||
}
|
||||
else if (fieldType.IsPointer)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
@@ -666,6 +1029,15 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
}
|
||||
|
||||
/*if (marshallableFieldOffsets != null)
|
||||
{
|
||||
for (int i = 1; i < marshallableFieldOffsets.Length; i++)
|
||||
{
|
||||
if (marshallableFieldOffsets[i - 1] > marshallableFieldOffsets[i])
|
||||
throw new NativeInteropException("marshal field offsets");
|
||||
}
|
||||
}*/
|
||||
|
||||
// Setup marshallers for managed and native directions
|
||||
MethodInfo toManagedMethod;
|
||||
if (type.IsValueType)
|
||||
@@ -682,18 +1054,31 @@ namespace FlaxEngine.Interop
|
||||
//toManagedDelegate = toManagedMethod.CreateDelegate();//.CreateDelegate(typeof(ToManagedDelegate<,>).MakeGenericType(type, toManagedMethod.GetParameters()[0].ParameterType));
|
||||
string methodName = nameof(MarshalInternalHelper<ValueTypePlaceholder, ValueTypePlaceholder>.ToManagedMarshaller);
|
||||
toManagedMethod = typeof(MarshalInternalHelper<,>).MakeGenericType(types).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
marshalledSize = RuntimeHelpers.SizeOf(internalType.TypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
string methodName;
|
||||
if (type == typeof(IntPtr))
|
||||
{
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedPointer);
|
||||
marshalledSize = Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
else if (type == typeof(ManagedHandle))
|
||||
{
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedHandle);
|
||||
marshalledSize = Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
else if (marshallableFields != null)
|
||||
{
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedWithMarshallableFields);
|
||||
marshalledSize = RuntimeHelpers.SizeOf(type.TypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManaged);
|
||||
marshalledSize = RuntimeHelpers.SizeOf(type.TypeHandle);
|
||||
}
|
||||
toManagedMethod = typeof(MarshalHelperValueType<>).MakeGenericType(type).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
}
|
||||
}
|
||||
@@ -707,10 +1092,14 @@ namespace FlaxEngine.Interop
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedArray);
|
||||
else
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedArrayMarshalled);
|
||||
toManagedMethod = typeof(MarshalHelperValueType<>).MakeGenericType(type.GetElementType()).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
toManagedMethod = typeof(MarshalHelperValueType<>).MakeGenericType(elementType).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
marshalledSize = RuntimeHelpers.SizeOf(elementType.TypeHandle);
|
||||
}
|
||||
else
|
||||
toManagedMethod = typeof(MarshalHelperReferenceType<>).MakeGenericType(type.GetElementType()).GetMethod(nameof(MarshalHelperReferenceType<ReferenceTypePlaceholder>.ToManagedArray), BindingFlags.Static | BindingFlags.NonPublic);
|
||||
{
|
||||
toManagedMethod = typeof(MarshalHelperReferenceType<>).MakeGenericType(elementType).GetMethod(nameof(MarshalHelperReferenceType<ReferenceTypePlaceholder>.ToManagedArray), BindingFlags.Static | BindingFlags.NonPublic);
|
||||
marshalledSize = Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -726,7 +1115,10 @@ namespace FlaxEngine.Interop
|
||||
else
|
||||
throw new NativeInteropException($"Unsupported type '{type.FullName}'");
|
||||
toManagedMethod = typeof(MarshalHelperReferenceType<>).MakeGenericType(type).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
marshalledSize = Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
if (marshalledSize <= 0)
|
||||
throw new NativeInteropException($"Missing marshalled size for type '{type.FullName}'");
|
||||
toManagedTypedMarshaller = toManagedMethod.CreateDelegate<MarshalToManagedTypedDelegate>();
|
||||
|
||||
MethodInfo toNativeMethod;
|
||||
@@ -802,6 +1194,18 @@ namespace FlaxEngine.Interop
|
||||
return arr;
|
||||
}
|
||||
|
||||
internal static Array ToManagedArray2(NativeArrayTypeless nativeArray)
|
||||
{
|
||||
T[] arr = new T[nativeArray.Length];
|
||||
IntPtr nativePtr = (IntPtr)nativeArray.Data;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
toManagedTypedMarshaller(ref arr[i], nativePtr, false);
|
||||
nativePtr += marshalledSize;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
internal static void ToNative(ref T managedValue, IntPtr nativePtr)
|
||||
{
|
||||
toNativeTypedMarshaller(ref managedValue, nativePtr);
|
||||
@@ -871,6 +1275,106 @@ namespace FlaxEngine.Interop
|
||||
fieldSize = IntPtr.Size;
|
||||
}
|
||||
|
||||
private static void ToManagedFieldStringValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
NativeString nativeValue = Unsafe.Read<NativeString>(nativeFieldPtr.ToPointer());
|
||||
string value = nativeValue.ToString();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, value);
|
||||
#else
|
||||
ref string fieldValueRef = ref FieldHelper.GetValueTypeFieldReference<T, string>(fieldOffset, ref fieldOwner);
|
||||
fieldValueRef = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void ToManagedFieldStringReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
NativeString nativeValue = Unsafe.Read<NativeString>(nativeFieldPtr.ToPointer());
|
||||
string value = nativeValue.ToString();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, value);
|
||||
#else
|
||||
ref string fieldValueRef = ref FieldHelper.GetReferenceTypeFieldReference<T, string>(fieldOffset, ref fieldOwner);
|
||||
fieldValueRef = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void ToNativeFieldStringValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
string fieldValue = field.GetValue(fieldOwner);
|
||||
#else
|
||||
string fieldValue = FieldHelper.GetValueTypeFieldReference<T, string>(fieldOffset, ref fieldOwner);
|
||||
#endif
|
||||
NativeString value = new NativeString(fieldValue);
|
||||
Unsafe.Write<NativeString>(nativeFieldPtr.ToPointer(), value);
|
||||
}
|
||||
|
||||
private static void ToNativeFieldStringReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
string fieldValue = field.GetValue(fieldOwner);
|
||||
#else
|
||||
string fieldValue = FieldHelper.GetReferenceTypeFieldReference<T, string>(fieldOffset, ref fieldOwner);
|
||||
#endif
|
||||
NativeString value = new NativeString(fieldValue);
|
||||
Unsafe.Write<NativeString>(nativeFieldPtr.ToPointer(), value);
|
||||
}
|
||||
|
||||
private static void ToManagedFieldSoftTypeReferenceValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
NativeString nativeValue = Unsafe.Read<NativeString>(nativeFieldPtr.ToPointer());
|
||||
SoftTypeReference value = new SoftTypeReference(nativeValue.ToString());
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, value);
|
||||
#else
|
||||
ref SoftTypeReference fieldValueRef = ref FieldHelper.GetValueTypeFieldReference<T, SoftTypeReference>(fieldOffset, ref fieldOwner);
|
||||
fieldValueRef = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void ToManagedFieldSoftTypeReferenceReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
NativeString nativeValue = Unsafe.Read<NativeString>(nativeFieldPtr.ToPointer());
|
||||
SoftTypeReference value = new SoftTypeReference(nativeValue.ToString());
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, value);
|
||||
#else
|
||||
ref SoftTypeReference fieldValueRef = ref FieldHelper.GetReferenceTypeFieldReference<T, SoftTypeReference>(fieldOffset, ref fieldOwner);
|
||||
fieldValueRef = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void ToNativeFieldSoftTypeReferenceValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
SoftTypeReference fieldValue = field.GetValue(fieldOwner);
|
||||
#else
|
||||
SoftTypeReference fieldValue = FieldHelper.GetValueTypeFieldReference<T, SoftTypeReference>(fieldOffset, ref fieldOwner);
|
||||
#endif
|
||||
NativeString value = new NativeString(fieldValue);
|
||||
Unsafe.Write<NativeString>(nativeFieldPtr.ToPointer(), value);
|
||||
}
|
||||
|
||||
private static void ToNativeFieldSoftTypeReferenceReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
SoftTypeReference fieldValue = field.GetValue(fieldOwner);
|
||||
#else
|
||||
SoftTypeReference fieldValue = FieldHelper.GetReferenceTypeFieldReference<T, SoftTypeReference>(fieldOffset, ref fieldOwner);
|
||||
#endif
|
||||
NativeString value = new NativeString(fieldValue);
|
||||
Unsafe.Write<NativeString>(nativeFieldPtr.ToPointer(), value);
|
||||
}
|
||||
|
||||
private static IntPtr EnsureAlignment(IntPtr ptr, int alignment)
|
||||
{
|
||||
if (ptr % alignment != 0)
|
||||
@@ -1203,9 +1707,8 @@ namespace FlaxEngine.Interop
|
||||
if (nativePtr != IntPtr.Zero)
|
||||
{
|
||||
int length = Unsafe.Read<int>(IntPtr.Add(nativePtr, Unsafe.SizeOf<IntPtr>()).ToPointer());
|
||||
nativePtr = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
|
||||
var span = new Span<T>(nativePtr.ToPointer(), length);
|
||||
IntPtr data = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
var span = new Span<T>(data.ToPointer(), length);
|
||||
managedValue = span.ToArray();
|
||||
//ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||
//managedValue = Unsafe.As<T[]>(managedArray.ToArray<T>());
|
||||
@@ -1221,8 +1724,12 @@ namespace FlaxEngine.Interop
|
||||
|
||||
if (nativePtr != IntPtr.Zero)
|
||||
{
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray));
|
||||
int length = Unsafe.Read<int>(IntPtr.Add(nativePtr, Unsafe.SizeOf<IntPtr>()).ToPointer());
|
||||
IntPtr data = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
NativeArrayTypeless array = new(data, length);
|
||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray2(array)); // element size for internal structure needed here
|
||||
//ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||
//managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray));
|
||||
}
|
||||
else
|
||||
managedValue = null;
|
||||
@@ -1234,6 +1741,7 @@ namespace FlaxEngine.Interop
|
||||
var fields = MarshalHelper<T>.marshallableFields;
|
||||
var offsets = MarshalHelper<T>.marshallableFieldOffsets;
|
||||
var marshallers = MarshalHelper<T>.toNativeFieldMarshallers;
|
||||
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
marshallers[i](fields[i], offsets[i], ref managedValue, nativePtr, out int fieldSize);
|
||||
@@ -1297,8 +1805,9 @@ namespace FlaxEngine.Interop
|
||||
|
||||
if (nativePtr != IntPtr.Zero)
|
||||
{
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray.ToSpan<IntPtr>()));
|
||||
NativeArray<IntPtr>* array = (NativeArray<IntPtr>*)nativePtr;
|
||||
var span = array->AsSpan();
|
||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(span));
|
||||
}
|
||||
else
|
||||
managedValue = null;
|
||||
@@ -1307,7 +1816,8 @@ namespace FlaxEngine.Interop
|
||||
|
||||
internal static void ToNativeString(ref string managedValue, IntPtr nativePtr)
|
||||
{
|
||||
Unsafe.Write<IntPtr>(nativePtr.ToPointer(), ManagedString.ToNative/*Weak*/(managedValue));
|
||||
//Unsafe.Write<IntPtr>(nativePtr.ToPointer(), ManagedString.ToNative/*Weak*/(managedValue));
|
||||
Unsafe.Write<NativeString>(nativePtr.ToPointer(), new NativeString(managedValue));
|
||||
}
|
||||
|
||||
internal static void ToNativeType(ref Type managedValue, IntPtr nativePtr)
|
||||
@@ -1329,34 +1839,59 @@ namespace FlaxEngine.Interop
|
||||
|
||||
internal static void ToNativeArray(ref T managedValue, IntPtr nativePtr)
|
||||
{
|
||||
IntPtr managedPtr;
|
||||
IntPtr arrayDataPtr;
|
||||
int arrayLength;
|
||||
if (managedValue == null)
|
||||
managedPtr = IntPtr.Zero;
|
||||
{
|
||||
arrayDataPtr = IntPtr.Zero;
|
||||
arrayLength = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type type = typeof(T);
|
||||
var elementType = type.GetElementType();
|
||||
var arr = Unsafe.As<Array>(managedValue);
|
||||
arrayLength = arr.Length;
|
||||
var marshalledType = ArrayFactory.GetMarshalledType(elementType);
|
||||
ManagedArray managedArray;
|
||||
if (marshalledType == elementType)
|
||||
managedArray = ManagedArray.WrapNewArray(arr, type);
|
||||
{
|
||||
var elementLength = RuntimeHelpers.SizeOf(marshalledType.TypeHandle);
|
||||
var bytesLength = elementLength * arrayLength;
|
||||
byte* ptr = (byte*)NativeMemory.AlignedAlloc((UIntPtr)bytesLength, 16);
|
||||
arrayDataPtr = (IntPtr)ptr;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
MarshalToNative(arr.GetValue(i), (IntPtr)ptr, elementType);
|
||||
ptr += elementLength;
|
||||
}
|
||||
}
|
||||
else if (elementType.IsValueType)
|
||||
{
|
||||
// Convert array of custom structures into internal native layout
|
||||
managedArray = ManagedArray.AllocateNewArray(arr.Length, type, marshalledType);
|
||||
IntPtr managedArrayPtr = managedArray.Pointer;
|
||||
var elementLength = RuntimeHelpers.SizeOf(marshalledType.TypeHandle);
|
||||
var bytesLength = elementLength * arrayLength;
|
||||
byte* ptr = (byte*)NativeMemory.AlignedAlloc((UIntPtr)bytesLength, 16);
|
||||
arrayDataPtr = (IntPtr)ptr;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
MarshalToNative(arr.GetValue(i), managedArrayPtr, elementType);
|
||||
managedArrayPtr += managedArray.ElementSize;
|
||||
MarshalToNative(arr.GetValue(i), (IntPtr)ptr, elementType);
|
||||
ptr += elementLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
managedArray = ManagedArrayToGCHandleWrappedArray(arr);
|
||||
managedPtr = ManagedHandle.ToIntPtr(managedArray/*, GCHandleType.Weak*/);
|
||||
{
|
||||
byte* ptr = (byte*)NativeMemory.AlignedAlloc((UIntPtr)(Unsafe.SizeOf<IntPtr>() * arrayLength), 16);
|
||||
arrayDataPtr = (IntPtr)ptr;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
var obj = arr.GetValue(i);
|
||||
Unsafe.Write<IntPtr>(ptr, obj != null ? ManagedHandle.ToIntPtr(obj) : IntPtr.Zero);
|
||||
ptr += Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Unsafe.Write<IntPtr>(nativePtr.ToPointer(), managedPtr);
|
||||
Unsafe.Write<IntPtr>(nativePtr.ToPointer(), arrayDataPtr);
|
||||
Unsafe.Write<long>(IntPtr.Add(nativePtr, Unsafe.SizeOf<IntPtr>()).ToPointer(), arrayLength);
|
||||
}
|
||||
|
||||
internal static void ToNative(ref T managedValue, IntPtr nativePtr)
|
||||
@@ -1819,7 +2354,7 @@ namespace FlaxEngine.Interop
|
||||
|
||||
internal static void InitMethods()
|
||||
{
|
||||
return;
|
||||
#if false
|
||||
MakeNewCustomDelegateFunc =
|
||||
typeof(Expression).Assembly.GetType("System.Linq.Expressions.Compiler.DelegateHelpers")
|
||||
.GetMethod("MakeNewCustomDelegate", BindingFlags.NonPublic | BindingFlags.Static).CreateDelegate<Func<Type[], Type>>();
|
||||
@@ -1851,6 +2386,7 @@ namespace FlaxEngine.Interop
|
||||
var ret = MakeNewCustomDelegateFuncCollectible(new[] { typeof(void) });
|
||||
Assert.IsTrue(ret.IsCollectible);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1871,7 +2407,7 @@ namespace FlaxEngine.Interop
|
||||
return MakeNewCustomDelegateFunc(parameters);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal static class ObjectArrayPool
|
||||
{
|
||||
@@ -1978,8 +2514,8 @@ namespace FlaxEngine.Interop
|
||||
internal MethodInfo method;
|
||||
internal MethodInvoker invoker;
|
||||
internal Type[] parameterTypes;
|
||||
internal Invoker.InvokeThunkDelegate methodDelegate;
|
||||
internal object methodDelegateContext;
|
||||
//internal Invoker.InvokeThunkDelegate methodDelegate;
|
||||
//internal object methodDelegateContext;
|
||||
|
||||
internal static object[] objectPool = new object[128];
|
||||
internal static int objectPoolIndex = 0;
|
||||
@@ -2137,7 +2673,7 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal class NativeInteropException : Exception
|
||||
{
|
||||
|
||||
@@ -35,6 +35,11 @@ DEFINE_INTERNAL_CALL(MObject*) UtilsInternal_ExtractArrayFromList(MObject* obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
//#if USE_NETCORE
|
||||
//APgI_TYPEDEF() typedef MString* ManagedString;
|
||||
API_TYPEDEF() typedef const String& ManagedString;
|
||||
//#endif
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryCopy(void* dst, const void* src, uint64 size)
|
||||
{
|
||||
Platform::MemoryCopy(dst, src, size);
|
||||
@@ -50,24 +55,40 @@ DEFINE_INTERNAL_CALL(int32) PlatformInternal_MemoryCompare(const void* buf1, con
|
||||
return Platform::MemoryCompare(buf1, buf2, size);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, MString* msgObj)
|
||||
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;
|
||||
StringView msg;
|
||||
MUtils::ToString(msgObj, msg);
|
||||
#endif
|
||||
Log::Logger::Write(level, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, MString* msgObj, ScriptingObject* obj, MString* stackTrace)
|
||||
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;
|
||||
|
||||
// Get info
|
||||
StringView msg;
|
||||
MUtils::ToString(msgObj, msg);
|
||||
#endif
|
||||
//const String objName = obj ? obj->ToString() : String::Empty;
|
||||
|
||||
// Send event
|
||||
@@ -79,6 +100,7 @@ DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, MString* m
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogException(MObject* exception, ScriptingObject* obj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
#if USE_CSHARP
|
||||
if (exception == nullptr)
|
||||
return;
|
||||
@@ -117,11 +139,19 @@ namespace
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(MString* nameObj)
|
||||
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;
|
||||
StringView name;
|
||||
MUtils::ToString(nameObj, name);
|
||||
#endif
|
||||
ProfilerCPU::BeginEvent(*name);
|
||||
#if TRACY_ENABLE
|
||||
#if PROFILE_CPU_USE_TRANSIENT_DATA
|
||||
@@ -173,10 +203,18 @@ DEFINE_INTERNAL_CALL(void) ProfilerInternal_EndEvent()
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(MString* nameObj)
|
||||
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 = MCore::String::GetChars(nameObj);
|
||||
#endif
|
||||
const auto index = ProfilerGPU::BeginEvent(nameChars.Get());
|
||||
ManagedEventsGPU.Push(index);
|
||||
#endif
|
||||
@@ -197,6 +235,7 @@ DEFINE_INTERNAL_CALL(bool) ScriptingInternal_HasGameModulesLoaded()
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) ScriptingInternal_IsTypeFromGameScripts(MTypeObject* type)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
return Scripting::IsTypeFromGameScripts(MUtils::GetClass(INTERNAL_TYPE_OBJECT_GET(type)));
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, MOb
|
||||
|
||||
// Write result data
|
||||
stream.RawValue(MCore::String::GetChars(invokeResultStr));
|
||||
MCore::String::Free(invokeResultStr);
|
||||
}
|
||||
|
||||
void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream, MObject* object, MObject* other)
|
||||
@@ -79,6 +80,7 @@ void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream,
|
||||
|
||||
// Write result data
|
||||
stream.RawValue(MCore::String::GetChars(invokeResultStr));
|
||||
MCore::String::Free(invokeResultStr);
|
||||
}
|
||||
|
||||
void ManagedSerialization::Deserialize(ISerializable::DeserializeStream& stream, MObject* object)
|
||||
|
||||
@@ -41,6 +41,118 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_NETCORE
|
||||
StringView MUtils::ToString(MString* str)
|
||||
{
|
||||
if (str == nullptr)
|
||||
return StringView::Empty;
|
||||
return StringView(*(String*)str);
|
||||
}
|
||||
|
||||
StringAnsi MUtils::ToStringAnsi(MString* str)
|
||||
{
|
||||
if (str == nullptr)
|
||||
return StringAnsi::Empty;
|
||||
return StringAnsi(*(String*)str);
|
||||
}
|
||||
|
||||
void MUtils::ToString(MString* str, String& result)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
const StringView chars = StringView(*(String*)str);
|
||||
result.Set(chars.Get(), chars.Length());
|
||||
}
|
||||
else
|
||||
result.Clear();
|
||||
}
|
||||
|
||||
void MUtils::ToString(MString* str, StringView& result)
|
||||
{
|
||||
if (str)
|
||||
result = StringView(*(String*)str);
|
||||
else
|
||||
result = StringView();
|
||||
}
|
||||
|
||||
void MUtils::ToString(MString* str, Variant& result)
|
||||
{
|
||||
result.SetString(str ? StringView(*(String*)str) : StringView::Empty);
|
||||
}
|
||||
|
||||
void MUtils::ToString(MString* str, StringAnsi& result)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
const StringView chars = StringView(*(String*)str);
|
||||
result.Set(chars.Get(), chars.Length());
|
||||
}
|
||||
else
|
||||
result.Clear();
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const char* str)
|
||||
{
|
||||
CRASH;
|
||||
if (str == nullptr || *str == 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str, StringUtils::Length(str)));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const StringAnsi& str)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const String& str)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const String& str, MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const StringAnsiView& str)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const StringView& str)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const StringView& str, MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
#else
|
||||
StringView MUtils::ToString(MString* str)
|
||||
{
|
||||
if (str == nullptr)
|
||||
@@ -144,6 +256,7 @@ MString* MUtils::ToString(const StringView& str, MDomain* domain)
|
||||
return MCore::String::GetEmpty(domain);
|
||||
return MCore::String::New(str.Get(), len, domain);
|
||||
}
|
||||
#endif
|
||||
|
||||
ScriptingTypeHandle MUtils::UnboxScriptingTypeHandle(MTypeObject* value)
|
||||
{
|
||||
|
||||
@@ -85,6 +85,41 @@ struct NativeArray
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// A simple POD type Span used with interop between managed and unmanaged sides.
|
||||
/// </summary>
|
||||
template<typename T>
|
||||
struct NativeSpan
|
||||
{
|
||||
public:
|
||||
T* Data;
|
||||
int32 Length;
|
||||
|
||||
public:
|
||||
static NativeSpan<T> AsSpan(T* data, int32 length)
|
||||
{
|
||||
return { data, length };
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
NativeSpan<T> ToNativeSpan(const T* data, int32 length)
|
||||
{
|
||||
return { data, length };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NativeSpan<T> ToNativeSpan(const Array<T>& array)
|
||||
{
|
||||
return { array.Get(), array.Count() };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NativeSpan<T> ToNativeSpan(const Span<T>& span)
|
||||
{
|
||||
return { span.Get(), span.Length() };
|
||||
}
|
||||
|
||||
#if USE_NETCORE
|
||||
// Special case for boolean values, the handles are fixed and should not be removed
|
||||
template<>
|
||||
@@ -128,7 +163,7 @@ struct MConverter<bool>
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@@ -176,7 +211,7 @@ struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -241,12 +276,13 @@ struct MConverter<String>
|
||||
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
MString** dataPtr = MCore::Array::GetAddress<MString*>(array);
|
||||
auto length = MCore::Array::GetLength(array);
|
||||
for (int32 i = 0; i < length; i++)
|
||||
MCore::String::Free(dataPtr[i]);
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -299,12 +335,13 @@ struct MConverter<StringAnsi>
|
||||
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
MString** dataPtr = MCore::Array::GetAddress<MString*>(array);
|
||||
auto length = MCore::Array::GetLength(array);
|
||||
for (int32 i = 0; i < length; i++)
|
||||
MCore::String::Free(dataPtr[i]);
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -368,7 +405,7 @@ struct MConverter<StringView>
|
||||
for (int32 i = 0; i < length; i++)
|
||||
MCore::String::Free(dataPtr[i]);
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -427,7 +464,7 @@ struct MConverter<Variant>
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -485,7 +522,6 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -540,7 +576,7 @@ struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Val
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -602,7 +638,7 @@ struct MConverter<ScriptingObjectReference<T>>
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -663,7 +699,7 @@ struct MConverter<AssetReference<T>>
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -725,7 +761,7 @@ struct MConverter<SoftAssetReference<T>>
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -778,7 +814,7 @@ struct MConverter<Array<T>>
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1031,6 +1067,27 @@ namespace MUtils
|
||||
}
|
||||
|
||||
#if USE_NETCORE
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
FORCE_INLINE String ToNativeString(const StringAnsi& str)
|
||||
{
|
||||
return String(str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
FORCE_INLINE String ToNativeString(const StringAnsiView& str)
|
||||
{
|
||||
return String(str);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allocates new boolean array and copies data from the given unmanaged data container. The managed runtime is responsible for releasing the returned array data.
|
||||
/// </summary>
|
||||
@@ -1040,7 +1097,7 @@ namespace MUtils
|
||||
FORCE_INLINE T* ToNativeArray(const Array<T>& data)
|
||||
{
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
T* arr = (T*)MCore::GC::AllocateMemory(data.Count() * sizeof(T), true);
|
||||
T* arr = (T*)MCore::GC::AllocateMemory(data.Count() * sizeof(T), false);
|
||||
Platform::MemoryCopy(arr, data.Get(), data.Count() * sizeof(T));
|
||||
return arr;
|
||||
}
|
||||
@@ -1116,7 +1173,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<U> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (U*)MCore::GC::AllocateMemory(arr.length * sizeof(U), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (U*)MCore::GC::AllocateMemory(arr.length * sizeof(U), false) : nullptr;
|
||||
|
||||
// Convert to managed
|
||||
MConverter<T, U> converter;
|
||||
@@ -1136,7 +1193,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
|
||||
// Convert to managed
|
||||
MConverter<T> converter;
|
||||
@@ -1188,7 +1245,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
|
||||
// Convert to managed
|
||||
MConverter<T, U> converter;
|
||||
@@ -1208,7 +1265,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
||||
return arr;
|
||||
}
|
||||
@@ -1239,7 +1296,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
//Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
||||
|
||||
// Convert to managed
|
||||
@@ -1261,7 +1318,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
||||
return arr;
|
||||
}
|
||||
@@ -1302,7 +1359,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<MObject*> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (MObject**)MCore::GC::AllocateMemory(arr.length * sizeof(MObject*), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (MObject**)MCore::GC::AllocateMemory(arr.length * sizeof(MObject*), false) : nullptr;
|
||||
|
||||
// Convert to managed
|
||||
MConverter<T> converter;
|
||||
@@ -1320,7 +1377,7 @@ namespace MUtils
|
||||
FORCE_INLINE bool* ToBoolArray(const Array<bool>& data)
|
||||
{
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), true);
|
||||
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), false);
|
||||
memcpy(arr, data.Get(), data.Count() * sizeof(bool));
|
||||
return arr;
|
||||
}
|
||||
@@ -1334,7 +1391,7 @@ namespace MUtils
|
||||
FORCE_INLINE bool* ToBoolArray(const BitArray<AllocationType>& data)
|
||||
{
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), true);
|
||||
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), false);
|
||||
for (int i = 0; i < data.Count(); i++)
|
||||
arr[i] = data[i];
|
||||
return arr;
|
||||
|
||||
@@ -290,7 +290,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
/// <param name="ptr">The pointer to the unmanaged (native) object.</param>
|
||||
/// <returns>The object.</returns>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr")]
|
||||
public static partial Object FromUnmanagedPtr(IntPtr ptr);
|
||||
|
||||
/// <summary>
|
||||
@@ -315,37 +315,43 @@ namespace FlaxEngine
|
||||
|
||||
#region Internal Calls
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create1", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create1")]
|
||||
internal static partial Object Internal_Create1([MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create2", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial Object Internal_Create2(string typeName);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceCreated", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceCreated")]
|
||||
internal static partial void Internal_ManagedInstanceCreated(Object managedInstance, IntPtr typeClass);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceDeleted", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceDeleted")]
|
||||
internal static partial void Internal_ManagedInstanceDeleted(IntPtr nativeInstance);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Destroy", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Destroy")]
|
||||
internal static partial void Internal_Destroy(IntPtr obj, float timeLeft);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_DestroyNow", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_DestroyNow")]
|
||||
internal static partial void Internal_DestroyNow(IntPtr obj);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial string Internal_GetTypeName(IntPtr obj);
|
||||
internal static string Internal_GetTypeName(IntPtr obj)
|
||||
{
|
||||
Internal_GetTypeName(obj, out string typeName);
|
||||
return typeName;
|
||||
}
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial void Internal_GetTypeName(IntPtr obj, [MarshalUsing(typeof(Interop.StringAnsiViewMarshaller))] out string typeName);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FindObject")]
|
||||
internal static partial Object Internal_FindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type, [MarshalAs(UnmanagedType.U1)] bool skipLog = false);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_TryFindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_TryFindObject")]
|
||||
internal static partial Object Internal_TryFindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ChangeID", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ChangeID")]
|
||||
internal static partial void Internal_ChangeID(IntPtr obj, ref Guid id);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetUnmanagedInterface", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetUnmanagedInterface")]
|
||||
internal static partial IntPtr Internal_GetUnmanagedInterface(IntPtr obj, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -431,6 +431,7 @@ MClass* MCore::Object::GetClass(const MObject* obj)
|
||||
|
||||
MString* MCore::Object::ToString(const MObject* obj)
|
||||
{
|
||||
CRASH;
|
||||
static void* GetObjectStringPtr = GetStaticMethodPointer(TEXT("GetObjectString"));
|
||||
return (MString*)CallStaticMethod<void*, const void*>(GetObjectStringPtr, obj);
|
||||
}
|
||||
@@ -443,28 +444,34 @@ int32 MCore::Object::GetHashCode(const MObject* obj)
|
||||
|
||||
MString* MCore::String::GetEmpty(const MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
static void* GetStringEmptyPtr = GetStaticMethodPointer(TEXT("GetStringEmpty"));
|
||||
return (MString*)CallStaticMethod<void*>(GetStringEmptyPtr);
|
||||
}
|
||||
|
||||
MString* MCore::String::New(const char* str, int32 length, const MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
static void* NewStringUTF8Ptr = GetStaticMethodPointer(TEXT("NewStringUTF8"));
|
||||
return (MString*)CallStaticMethod<void*, const char*, int>(NewStringUTF8Ptr, str, length);
|
||||
}
|
||||
|
||||
MString* MCore::String::New(const Char* str, int32 length, const MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
static void* NewStringUTF16Ptr = GetStaticMethodPointer(TEXT("NewStringUTF16"));
|
||||
return (MString*)CallStaticMethod<void*, const Char*, int>(NewStringUTF16Ptr, str, length);
|
||||
}
|
||||
|
||||
StringView MCore::String::GetChars(const MString* obj)
|
||||
{
|
||||
int32 length = 0;
|
||||
::String& str = *(::String*)obj;
|
||||
return StringView(str);
|
||||
//CRASH;
|
||||
/*int32 length = 0;
|
||||
static void* GetStringPointerPtr = GetStaticMethodPointer(TEXT("GetStringPointer"));
|
||||
const Char* chars = CallStaticMethod<const Char*, const void*, int*>(GetStringPointerPtr, obj, &length);
|
||||
return StringView(chars, length);
|
||||
return StringView(chars, length);*/
|
||||
}
|
||||
|
||||
void MCore::String::Free(const MString* obj)
|
||||
@@ -605,6 +612,8 @@ void MCore::GC::WriteArrayRef(MArray* dst, Span<MObject*> refs)
|
||||
|
||||
void* MCore::GC::AllocateMemory(int32 size, bool coTaskMem)
|
||||
{
|
||||
if (coTaskMem == true)
|
||||
coTaskMem = coTaskMem;
|
||||
static void* AllocMemoryPtr = GetStaticMethodPointer(TEXT("AllocMemory"));
|
||||
return CallStaticMethod<void*, int, bool>(AllocMemoryPtr, size, coTaskMem);
|
||||
}
|
||||
@@ -613,6 +622,8 @@ void MCore::GC::FreeMemory(void* ptr, bool coTaskMem)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
if (coTaskMem == true)
|
||||
coTaskMem = coTaskMem;
|
||||
static void* FreeMemoryPtr = GetStaticMethodPointer(TEXT("FreeMemory"));
|
||||
CallStaticMethod<void, void*, bool>(FreeMemoryPtr, ptr, coTaskMem);
|
||||
}
|
||||
@@ -1323,11 +1334,13 @@ MException::MException(MObject* exception)
|
||||
MMethod* exceptionMsgGetter = exceptionMsgProp->GetGetMethod();
|
||||
MString* exceptionMsg = (MString*)exceptionMsgGetter->Invoke(exception, nullptr, nullptr);
|
||||
Message = MUtils::ToString(exceptionMsg);
|
||||
MCore::String::Free(exceptionMsg);
|
||||
|
||||
MProperty* exceptionStackProp = exceptionClass->GetProperty("StackTrace");
|
||||
MMethod* exceptionStackGetter = exceptionStackProp->GetGetMethod();
|
||||
MString* exceptionStackTrace = (MString*)exceptionStackGetter->Invoke(exception, nullptr, nullptr);
|
||||
StackTrace = MUtils::ToString(exceptionStackTrace);
|
||||
MCore::String::Free(exceptionStackTrace);
|
||||
|
||||
MProperty* innerExceptionProp = exceptionClass->GetProperty("InnerException");
|
||||
MMethod* innerExceptionGetter = innerExceptionProp->GetGetMethod();
|
||||
|
||||
@@ -395,7 +395,7 @@ namespace FlaxEngine
|
||||
/// Returns true if game scripts assembly has been loaded.
|
||||
/// </summary>
|
||||
/// <returns>True if game scripts assembly is loaded, otherwise false.</returns>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_HasGameModulesLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_HasGameModulesLoaded")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static partial bool HasGameModulesLoaded();
|
||||
|
||||
@@ -403,14 +403,14 @@ namespace FlaxEngine
|
||||
/// Returns true if given type is from one of the game scripts assemblies.
|
||||
/// </summary>
|
||||
/// <returns>True if the type is from game assembly, otherwise false.</returns>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_IsTypeFromGameScripts", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_IsTypeFromGameScripts")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static partial bool IsTypeFromGameScripts([MarshalUsing(typeof(SystemTypeMarshaller))] Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Flushes the removed objects (disposed objects using Object.Destroy).
|
||||
/// </summary>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_FlushRemovedObjects", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_FlushRemovedObjects")]
|
||||
public static partial void FlushRemovedObjects();
|
||||
}
|
||||
|
||||
@@ -426,26 +426,26 @@ namespace FlaxEngine
|
||||
/// Begins profiling a piece of code with a custom label.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the event.</param>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
public static partial void BeginEvent(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Ends profiling an event.
|
||||
/// </summary>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
public static partial void EndEvent();
|
||||
|
||||
/// <summary>
|
||||
/// Begins GPU profiling a piece of code with a custom label.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the event.</param>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
public static partial void BeginEventGPU(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Ends GPU profiling an event.
|
||||
/// </summary>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEventGPU")]
|
||||
public static partial void EndEventGPU();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,15 @@
|
||||
#define ScriptingObject_unmanagedPtr "__unmanagedPtr"
|
||||
#define ScriptingObject_id "__internalId"
|
||||
|
||||
//#if USE_NETCORE
|
||||
//APgI_TYPEDEF() typedef MString* ManagedString;
|
||||
//APgI_TYPEDEF() typedef MString* ManagedStringView;
|
||||
//APgI_TYPEDEF() typedef MString* ManagedStringAnsiView;
|
||||
API_TYPEDEF() typedef String ManagedString;
|
||||
API_TYPEDEF() typedef StringView ManagedStringView;
|
||||
API_TYPEDEF() typedef StringAnsiView ManagedStringAnsiView;
|
||||
//#endif
|
||||
|
||||
// TODO: don't leak memory (use some kind of late manual GC for those wrapper objects)
|
||||
typedef Pair<ScriptingObject*, ScriptingTypeHandle> ScriptingObjectsInterfaceKey;
|
||||
Dictionary<ScriptingObjectsInterfaceKey, void*> ScriptingObjectsInterfaceWrappers;
|
||||
@@ -611,12 +620,16 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create1(MTypeObject* type)
|
||||
return managedInstance;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create2(MString* typeNameObj)
|
||||
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create2(ManagedStringView typeNameObj)
|
||||
{
|
||||
// Get typename
|
||||
if (typeNameObj == nullptr)
|
||||
DebugLog::ThrowArgumentNull("typeName");
|
||||
#if USE_NETCORE
|
||||
const StringView typeNameChars = typeNameObj;
|
||||
#else
|
||||
const StringView typeNameChars = MCore::String::GetChars(typeNameObj);
|
||||
#endif
|
||||
const StringAsANSI<100> typeNameData(typeNameChars.Get(), typeNameChars.Length());
|
||||
const StringAnsiView typeName(typeNameData.Get(), typeNameChars.Length());
|
||||
|
||||
@@ -711,10 +724,15 @@ DEFINE_INTERNAL_CALL(void) ObjectInternal_DestroyNow(ScriptingObject* obj)
|
||||
obj->DeleteObjectNow();
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MString*) ObjectInternal_GetTypeName(ScriptingObject* obj)
|
||||
DEFINE_INTERNAL_CALL(void) ObjectInternal_GetTypeName(ScriptingObject* obj, ManagedStringAnsiView* typeName)
|
||||
{
|
||||
#if USE_NETCORE
|
||||
INTERNAL_CALL_CHECK(obj);
|
||||
*typeName = obj->GetType().Fullname;
|
||||
#else
|
||||
INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
|
||||
return MUtils::ToString(obj->GetType().Fullname);
|
||||
*typeName = MUtils::ToString(obj->GetType().Fullname);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject* type, bool skipLog = false)
|
||||
|
||||
@@ -99,6 +99,7 @@ void UICanvas::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
// Write result data
|
||||
stream.RawValue(MCore::String::GetChars(invokeResultStr));
|
||||
}
|
||||
MCore::String::Free(invokeResultStr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ void UIControl::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
const StringView invokeResultStrChars = MCore::String::GetChars(invokeResultStr);
|
||||
stream.JKEY("Data");
|
||||
stream.RawValue(invokeResultStrChars);
|
||||
MCore::String::Free(invokeResultStr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -166,13 +166,20 @@ namespace Flax.Build.Bindings
|
||||
if (typeInfo.IsPtr)
|
||||
return false;
|
||||
|
||||
#if USE_NETCORE
|
||||
//if (typeInfo.IsString)
|
||||
// return true;
|
||||
if (typeInfo.Type == "String" || typeInfo.Type == "StringView")
|
||||
return false;//true;
|
||||
if (typeInfo.Type == "StringAnsi" || typeInfo.Type == "StringAnsiView")
|
||||
return false;
|
||||
//if (typeInfo.IsString)
|
||||
// return false;
|
||||
#else
|
||||
// Skip for strings
|
||||
if ((typeInfo.Type == "String" || typeInfo.Type == "StringView" || typeInfo.Type == "StringAnsi" || typeInfo.Type == "StringAnsiView") && typeInfo.GenericArgs == null)
|
||||
return false;
|
||||
|
||||
// Skip for collections
|
||||
if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer" || typeInfo.Type == "Dictionary" || typeInfo.Type == "HashSet") && typeInfo.GenericArgs != null)
|
||||
if (typeInfo.IsString)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Skip for special types
|
||||
if (typeInfo.GenericArgs == null)
|
||||
@@ -192,6 +199,10 @@ namespace Flax.Build.Bindings
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip for collections
|
||||
if ((typeInfo.IsArrayOrSpan || typeInfo.Type == "Dictionary" || typeInfo.Type == "HashSet") && typeInfo.GenericArgs != null)
|
||||
return false;
|
||||
|
||||
// Find API type info
|
||||
var apiType = FindApiTypeInfo(buildData, typeInfo, caller);
|
||||
if (apiType != null)
|
||||
@@ -213,7 +224,7 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
|
||||
// True for references
|
||||
if (typeInfo.IsRef)
|
||||
if (typeInfo.IsRef && !typeInfo.IsConst)
|
||||
return true;
|
||||
|
||||
// Force for in-build types
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
//#define AUTO_DOC_TOOLTIPS
|
||||
//#define MARSHALLER_FULL_NAME
|
||||
|
||||
#pragma warning disable CS1717
|
||||
#pragma warning disable CS0162
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -592,13 +595,17 @@ namespace Flax.Build.Bindings
|
||||
|
||||
private static void GenerateCSharpWrapperFunction(BuildData buildData, StringBuilder contents, string indent, ApiTypeInfo caller, FunctionInfo functionInfo)
|
||||
{
|
||||
if (functionInfo.Glue.LibraryEntryPoint == "FlaxEngine.Engine::Internal_GetCommandLine")
|
||||
indent = indent;
|
||||
string returnValueType;
|
||||
if (UsePassByReference(buildData, functionInfo.ReturnType, caller))
|
||||
if (!functionInfo.ReturnType.IsString && UsePassByReference(buildData, functionInfo.ReturnType, caller))
|
||||
{
|
||||
returnValueType = "void";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (functionInfo.ReturnType.IsString && functionInfo.ReturnType.IsRef)
|
||||
indent = indent;
|
||||
var apiType = FindApiTypeInfo(buildData, functionInfo.ReturnType, caller);
|
||||
if (apiType != null && apiType.MarshalAs != null)
|
||||
returnValueType = GenerateCSharpNativeToManaged(buildData, apiType.MarshalAs, caller, true);
|
||||
@@ -618,7 +625,7 @@ namespace Flax.Build.Bindings
|
||||
else if (returnValueType == "Version")
|
||||
returnMarshalType = "MarshalUsing(typeof(VersionMarshaller))";
|
||||
else if (functionInfo.ReturnType.Type == "Variant") // object
|
||||
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.ManagedHandleMarshaller))";
|
||||
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.AsManagedHandleMarshaller))";
|
||||
else if (FindApiTypeInfo(buildData, functionInfo.ReturnType, caller)?.IsInterface ?? false)
|
||||
{
|
||||
var apiType = FindApiTypeInfo(buildData, functionInfo.ReturnType, caller);
|
||||
@@ -690,15 +697,33 @@ namespace Flax.Build.Bindings
|
||||
//Log.Warning($"unknown type: '{parameterInfo.Type.GenericArgs[0].Type}'");
|
||||
break;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(unmanagedType))
|
||||
/*if (!string.IsNullOrEmpty(unmanagedType))
|
||||
{
|
||||
string arraySubType = "";
|
||||
if (unmanagedType != "Any")
|
||||
arraySubType = $"ArraySubType = UnmanagedType.{unmanagedType}, ";
|
||||
returnMarshalType = $"MarshalAs(UnmanagedType.LPArray, {arraySubType}SizeParamIndex = {(!functionInfo.IsStatic ? 1 : 0) + functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters.FindIndex(x => x.Name == $"__returnCount"))})";
|
||||
}*/
|
||||
if (!string.IsNullOrEmpty(unmanagedType))
|
||||
{
|
||||
returnMarshalType = "/*marshahh1*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<,>), CountElementName = nameof(__returnCount))";
|
||||
}
|
||||
else if (genericType == "String" || genericType == "StringView")
|
||||
{
|
||||
returnMarshalType = $"/*marsh2c*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, NativeString>), CountElementName = \"__returnCount\")";
|
||||
if (genericType == "StringView")
|
||||
returnMarshalType += $"] [return: MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller), ElementIndirectionDepth = 1)";
|
||||
}
|
||||
else if (genericType == "StringAnsi")
|
||||
{
|
||||
returnMarshalType = $"/*marsh2d*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, NativeStringAnsi>), CountElementName = \"__returnCount\")";
|
||||
returnMarshalType += $"] [return: MarshalUsing(typeof(FlaxEngine.Interop.StringAnsiMarshaller), ElementIndirectionDepth = 1)";
|
||||
}
|
||||
else if (genericType == "StringAnsiView")
|
||||
{
|
||||
returnMarshalType = $"/*marsh2d*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, NativeStringAnsi>), CountElementName = \"__returnCount\")";
|
||||
returnMarshalType += $"] [return: MarshalUsing(typeof(FlaxEngine.Interop.StringAnsiViewMarshaller), ElementIndirectionDepth = 1)";
|
||||
}
|
||||
else if (genericType == "String" || genericType == "StringAnsi" || genericType == "StringView")
|
||||
returnMarshalType = $"/*marsh2c*/MarshalUsing(typeof(FlaxEngine.Interop.BoxedArrayMarshaller<string, IntPtr>), CountElementName = \"__returnCount\")";
|
||||
else if (elementApiType?.IsValueType ?? true)
|
||||
returnMarshalType = $"/*marsh2a*/MarshalUsing(typeof(FlaxEngine.Interop.BoxedArrayMarshaller<,>), CountElementName = \"__returnCount\")";
|
||||
else
|
||||
@@ -718,6 +743,12 @@ namespace Flax.Build.Bindings
|
||||
// Boolean arrays does not support custom marshalling for some unknown reason
|
||||
returnMarshalType = $"MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = {functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters?.Count ?? 0)})";
|
||||
}
|
||||
else if (functionInfo.ReturnType.Type == "StringView")
|
||||
returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller))";
|
||||
else if (functionInfo.ReturnType.Type == "StringAnsi")
|
||||
returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.StringAnsiMarshaller))";
|
||||
else if (functionInfo.ReturnType.Type == "StringAnsiView")
|
||||
returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.StringAnsiViewMarshaller))";
|
||||
#endif
|
||||
#if !USE_NETCORE
|
||||
contents.AppendLine().Append(indent).Append("[MethodImpl(MethodImplOptions.InternalCall)]");
|
||||
@@ -755,7 +786,7 @@ namespace Flax.Build.Bindings
|
||||
else if (parameterInfo.Type.Type == "Version")
|
||||
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.VersionMarshaller))";
|
||||
else if (parameterInfo.Type.Type == "Variant") // object
|
||||
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.ManagedHandleMarshaller))";
|
||||
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.AsManagedHandleMarshaller))";
|
||||
else if (parameterInfo.Type.Type == "MonoArray" || parameterInfo.Type.Type == "MArray")
|
||||
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemArrayMarshaller))";
|
||||
else if (nativeType == "object[]")
|
||||
@@ -824,13 +855,32 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
if (!string.IsNullOrEmpty(unmanagedType))
|
||||
{
|
||||
string arraySubType = "";
|
||||
/*string arraySubType = "";
|
||||
if (unmanagedType != "Any")
|
||||
arraySubType = $"ArraySubType = UnmanagedType.{unmanagedType}, ";
|
||||
parameterMarshalType = $"MarshalAs(UnmanagedType.LPArray, {arraySubType}SizeParamIndex = {(!functionInfo.IsStatic ? 1 : 0) + functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters.FindIndex(x => x.Name == $"__{parameterInfo.Name}Count"))})";
|
||||
*/
|
||||
parameterMarshalType = $"/*marshaaafa1a*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<,>), CountElementName = \"__{parameterInfo.Name}Count\")";
|
||||
if (genericType == "bool")
|
||||
parameterMarshalType += $", MarshalUsing(typeof(FlaxEngine.Interop.BooleanMarshaller), ElementIndirectionDepth = 1)";
|
||||
}
|
||||
else if (genericType == "String" || genericType == "StringView")
|
||||
{
|
||||
parameterMarshalType = $"/*marsh5c*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, NativeString>), CountElementName = \"__{parameterInfo.Name}Count\")";
|
||||
if (genericType == "StringView")
|
||||
parameterMarshalType += $", MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller), ElementIndirectionDepth = 1)";
|
||||
}
|
||||
else if (genericType == "StringAnsi")
|
||||
{
|
||||
parameterMarshalType = $"/*marsh5d*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, NativeStringAnsi>), CountElementName = \"__{parameterInfo.Name}Count\")";
|
||||
//if ((!parameterInfo.IsOut && !parameterInfo.IsRef))
|
||||
parameterMarshalType += $", MarshalUsing(typeof(FlaxEngine.Interop.StringAnsiMarshaller), ElementIndirectionDepth = 1)";
|
||||
}
|
||||
else if (genericType == "StringAnsiView")
|
||||
{
|
||||
parameterMarshalType = $"/*marsh5d*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, NativeStringAnsi>), CountElementName = \"__{parameterInfo.Name}Count\")";
|
||||
parameterMarshalType += $", MarshalUsing(typeof(FlaxEngine.Interop.StringAnsiViewMarshaller), ElementIndirectionDepth = 1)";
|
||||
}
|
||||
else if (genericType == "String" || genericType == "StringAnsi" || genericType == "StringView")
|
||||
parameterMarshalType = $"/*marsh5c*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, IntPtr>), CountElementName = \"__{parameterInfo.Name}Count\")";
|
||||
else if (elementApiType.IsValueType)
|
||||
{
|
||||
var nativeName = parameterInfo.Type.GetFullNameNative(buildData, caller);
|
||||
@@ -862,6 +912,12 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
parameterMarshalType = $"/*marsh6*/MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<,>))";
|
||||
}
|
||||
else if (parameterInfo.Type.Type == "StringView")
|
||||
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller))";
|
||||
else if (parameterInfo.Type.Type == "StringAnsi")
|
||||
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.StringAnsiMarshaller))";
|
||||
else if (parameterInfo.Type.Type == "StringAnsiView")
|
||||
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.StringAnsiViewMarshaller))";
|
||||
|
||||
if (!string.IsNullOrEmpty(parameterMarshalType))
|
||||
contents.Append($"[{parameterMarshalType}] ");
|
||||
@@ -1700,7 +1756,7 @@ namespace Flax.Build.Bindings
|
||||
#endif
|
||||
public static class NativeToManaged
|
||||
{
|
||||
public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(ManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged));
|
||||
public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(AsManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged));
|
||||
public static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => managed != null ? ManagedHandle.ToIntPtr(managed, GCHandleType.Weak) : IntPtr.Zero;
|
||||
public static void Free(IntPtr unmanaged) {}
|
||||
}
|
||||
@@ -1709,28 +1765,28 @@ namespace Flax.Build.Bindings
|
||||
#endif
|
||||
public static class ManagedToNative
|
||||
{
|
||||
public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(ManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged));
|
||||
public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(AsManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged));
|
||||
public static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => managed != null ? ManagedHandle.ToIntPtr(managed/*, GCHandleType.Weak*/) : IntPtr.Zero;
|
||||
public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged);
|
||||
public static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged);
|
||||
}
|
||||
#if FLAX_EDITOR
|
||||
[HideInEditor]
|
||||
#endif
|
||||
public struct Bidirectional
|
||||
{
|
||||
ManagedHandleMarshaller.Bidirectional marsh;
|
||||
AsManagedHandleMarshaller.Bidirectional marsh;
|
||||
public void FromManaged({{classInfo.Name}} managed) => marsh.FromManaged(managed);
|
||||
public IntPtr ToUnmanaged() => marsh.ToUnmanaged();
|
||||
public void FromUnmanaged(IntPtr unmanaged) => marsh.FromUnmanaged(unmanaged);
|
||||
public {{classInfo.Name}} ToManaged() => Unsafe.As<{{classInfo.Name}}>(marsh.ToManaged());
|
||||
public void Free() => marsh.Free();
|
||||
}
|
||||
internal static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(ManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
internal static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed);
|
||||
internal static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged);
|
||||
internal static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(AsManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
internal static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed);
|
||||
internal static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged);
|
||||
|
||||
internal static {{classInfo.Name}} ToManaged(IntPtr managed) => Unsafe.As<{{classInfo.Name}}>(ManagedHandleMarshaller.ToManaged(managed));
|
||||
internal static IntPtr ToNative({{classInfo.Name}} managed) => ManagedHandleMarshaller.ToNative(managed);
|
||||
internal static {{classInfo.Name}} ToManaged(IntPtr managed) => Unsafe.As<{{classInfo.Name}}>(AsManagedHandleMarshaller.ToManaged(managed));
|
||||
internal static IntPtr ToNative({{classInfo.Name}} managed) => AsManagedHandleMarshaller.ToNative(managed);
|
||||
#pragma warning restore 618
|
||||
#pragma warning restore 1591
|
||||
}
|
||||
@@ -1885,7 +1941,7 @@ namespace Flax.Build.Bindings
|
||||
else if (marshalType.Type == "Version")
|
||||
type = "IntPtr";
|
||||
else if (type == "string")
|
||||
type = "IntPtr";
|
||||
type = "NativeString";
|
||||
else if (type == "bool")
|
||||
type = "byte";
|
||||
else if (marshalType.Type == "Variant")
|
||||
@@ -1982,10 +2038,10 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
else if (originalType == "string")
|
||||
{
|
||||
toManagedContent.AppendLine($"ManagedString.ToManaged(unmanaged.{fieldInfo.Name});");
|
||||
toNativeContent.AppendLine($"ManagedString.ToNative(managed.{fieldInfo.Name});");
|
||||
freeContents.AppendLine($"ManagedString.Free(unmanaged.{fieldInfo.Name});");
|
||||
freeContents2.AppendLine($"ManagedString.Free(unmanaged.{fieldInfo.Name});");
|
||||
toManagedContent.AppendLine($"{unmanagedField}.ToString();");
|
||||
toNativeContent.AppendLine($"new NativeString({managedField});");
|
||||
freeContents.AppendLine($"{unmanagedField}.Free();/*hfmm1*/");
|
||||
freeContents2.AppendLine($"{unmanagedField}.Free();/*hfmm2*/");
|
||||
}
|
||||
else if (originalType == "bool")
|
||||
{
|
||||
@@ -1995,8 +2051,8 @@ namespace Flax.Build.Bindings
|
||||
else if (marshalType.Type == "Variant")
|
||||
{
|
||||
// Variant passed as boxed object handle
|
||||
toManagedContent.AppendLine($"ManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged.{fieldInfo.Name});");
|
||||
toNativeContent.AppendLine($"ManagedHandleMarshaller.NativeToManaged.ConvertToUnmanaged(managed.{fieldInfo.Name});");
|
||||
toManagedContent.AppendLine($"AsManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged.{fieldInfo.Name});");
|
||||
toNativeContent.AppendLine($"AsManagedHandleMarshaller.NativeToManaged.ConvertToUnmanaged(managed.{fieldInfo.Name});");
|
||||
}
|
||||
else if (internalType)
|
||||
{
|
||||
@@ -2074,8 +2130,8 @@ namespace Flax.Build.Bindings
|
||||
public {{marshalNativeType}} ToUnmanaged() { unmanaged = {{marshallerFullName}}.ToNative(managed); return unmanaged; }
|
||||
public void FromUnmanaged({{marshalNativeType}} unmanaged)
|
||||
{
|
||||
if (!unmanaged.Equals(this.unmanaged))
|
||||
{{marshallerName}}.Free(this.unmanaged); // Release temporary handles before replacing them with permanent handles
|
||||
//if (!unmanaged.Equals(this.unmanaged))
|
||||
// {{marshallerName}}.Free(this.unmanaged); // Release temporary handles before replacing them with permanent handles
|
||||
this.unmanaged = unmanaged;
|
||||
}
|
||||
public {{marshalManagedType}} ToManaged() { managed = {{marshallerFullName}}.ToManaged(unmanaged); return managed; }
|
||||
@@ -2481,8 +2537,8 @@ namespace Flax.Build.Bindings
|
||||
contents.Append(indent).AppendLine("{");
|
||||
contents.AppendLine("#pragma warning disable 1591");
|
||||
contents.AppendLine("#pragma warning disable 618");
|
||||
contents.Append(indent).Append(" ").AppendLine($"internal static {interfaceInfo.Name} ConvertToManaged(IntPtr unmanaged) => ({interfaceInfo.Name})ManagedHandleMarshaller.ConvertToManaged(unmanaged);");
|
||||
contents.Append(indent).Append(" ").AppendLine($"internal static IntPtr ConvertToUnmanaged({interfaceInfo.Name} managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed);");
|
||||
contents.Append(indent).Append(" ").AppendLine($"internal static {interfaceInfo.Name} ConvertToManaged(IntPtr unmanaged) => ({interfaceInfo.Name})AsManagedHandleMarshaller.ConvertToManaged(unmanaged);");
|
||||
contents.Append(indent).Append(" ").AppendLine($"internal static IntPtr ConvertToUnmanaged({interfaceInfo.Name} managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed);");
|
||||
contents.AppendLine("#pragma warning restore 618");
|
||||
contents.AppendLine("#pragma warning restore 1591");
|
||||
contents.Append(indent).AppendLine("}");
|
||||
|
||||
@@ -7,6 +7,9 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using BuildData = Flax.Build.Builder.BuildData;
|
||||
|
||||
#pragma warning disable CS1717
|
||||
#pragma warning disable CS0162
|
||||
|
||||
namespace Flax.Build.Bindings
|
||||
{
|
||||
[Flags]
|
||||
@@ -48,6 +51,7 @@ namespace Flax.Build.Bindings
|
||||
private static readonly string[] CppParamsThatNeedConversionWrappers = new string[64];
|
||||
private static readonly string[] CppParamsThatNeedConversionTypes = new string[64];
|
||||
private static readonly string[] CppParamsWrappersCache = new string[64];
|
||||
private static readonly string[] CppParamsManagedTypes = new string[64];
|
||||
public static readonly List<KeyValuePair<string, string>> CppInternalCalls = new List<KeyValuePair<string, string>>();
|
||||
public static readonly List<ApiTypeInfo> CppUsedNonPodTypes = new List<ApiTypeInfo>();
|
||||
private static readonly List<ApiTypeInfo> CppUsedNonPodTypesList = new List<ApiTypeInfo>();
|
||||
@@ -154,18 +158,48 @@ namespace Flax.Build.Bindings
|
||||
if (!string.IsNullOrEmpty(nativeToManaged))
|
||||
{
|
||||
result = string.Format(nativeToManaged, paramName);
|
||||
if ((managedTypeAsNative[managedTypeAsNative.Length - 1] == '*' || managedTypeAsNative.StartsWith("NativeArray<")) && !isRef)
|
||||
if ((managedTypeAsNative[managedTypeAsNative.Length - 1] == '*' /*|| managedTypeAsNative.StartsWith("NativeArray<")*/) && !isRef)
|
||||
{
|
||||
// Pass pointer value
|
||||
contents.Append($" //GenerateCppWrapperNativeToManagedParam {paramName} Pass pointer value").AppendLine();
|
||||
}
|
||||
/*else if (!isRef)
|
||||
{
|
||||
// Pass reference as a pointer
|
||||
|
||||
contents.Append($" //GenerateCppWrapperNativeToManagedParam {paramName} Pass reference as a pointer").AppendLine();
|
||||
result = '&' + result;
|
||||
}*/
|
||||
else
|
||||
{
|
||||
// Pass as pointer to local variable converted for managed runtime
|
||||
if (paramType.IsPtr)
|
||||
result = string.Format(nativeToManaged, '*' + paramName);
|
||||
contents.Append($" // localvar1 {managedTypeAsNative}, {paramType.ToString()}").AppendLine();
|
||||
contents.Append($" auto __param_orig_{paramName} = {result};").AppendLine();
|
||||
contents.Append($" auto __param_{paramName} = __param_orig_{paramName};").AppendLine();
|
||||
var origType = paramType.ToString();
|
||||
var origType2 = paramType.Type;
|
||||
contents.Append($" // localvar1 {managedTypeAsNative}, {origType}, {origType2}, isRef: {isRef}, typeIsRef: {paramType.IsRef}").AppendLine();
|
||||
|
||||
if (isRef)
|
||||
{
|
||||
if (origType2 == managedTypeAsNative)
|
||||
{
|
||||
//contents.Append($" auto& __param_orig_{paramName} = {result};").AppendLine();
|
||||
contents.Append($" auto& __param_{paramName} = {result};").AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
contents.Append($" auto __param_orig_{paramName} = {result};").AppendLine();
|
||||
contents.Append($" auto __param_{paramName} = __param_orig_{paramName};").AppendLine();
|
||||
}
|
||||
//contents.Append($" auto __param_{paramName} = __param_orig_{paramName};").AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (origType2 == managedTypeAsNative)
|
||||
contents.Append($" auto& __param_{paramName} = {result};").AppendLine();
|
||||
else
|
||||
contents.Append($" auto __param_{paramName} = {result};").AppendLine();
|
||||
}
|
||||
result = $"&__param_{paramName}";
|
||||
formattingFlags.SetFlag(ParameterFormattingFlags.NeedLocalVariable, true);
|
||||
}
|
||||
@@ -535,12 +569,31 @@ namespace Flax.Build.Bindings
|
||||
|
||||
switch (typeInfo.Type)
|
||||
{
|
||||
#if USE_NETCORE
|
||||
case "String":
|
||||
case "StringView":
|
||||
type = "String";
|
||||
//return "/*hh6hh*/(MString*)&{0}";
|
||||
return "/*hh6hh*/{0}";
|
||||
case "StringAnsi":
|
||||
case "StringAnsiView":
|
||||
if (functionInfo?.UniqueName == "CoverageTest1ByRef")
|
||||
typeInfo = typeInfo;
|
||||
//type = typeInfo.Type + "/*cvcv2*/";//"StringAnsi";
|
||||
type = "String";
|
||||
//return "/*hh6hh*/(MString*)&{0}";
|
||||
//return $"/*hh7hh*/MUtils::ToNativeString({{0}})";
|
||||
if (typeInfo.Type == "StringAnsiView")
|
||||
return "/*hh7hha*/String({0})";
|
||||
return "/*hh7hh*/String({0})";
|
||||
#else
|
||||
case "String":
|
||||
case "StringView":
|
||||
case "StringAnsi":
|
||||
case "StringAnsiView":
|
||||
type = "MString*";
|
||||
return "MUtils::ToString({0})";
|
||||
#endif
|
||||
case "Variant":
|
||||
type = "MObject*";
|
||||
return "MUtils::BoxVariant({0})";
|
||||
@@ -658,7 +711,7 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
if (CppNativeArrayAsParameter)
|
||||
{
|
||||
type = nativeName + $"*/*wahho2 pod:{pod}*/";
|
||||
type = nativeName;
|
||||
//type = $"NativeArray<{arrayApiType.FullNameNative}>/*tahho*/";
|
||||
//if (arrayTypeInfo.Type == "bool")
|
||||
// return "MUtils::ToBoolArray({0})/*bahho*/";
|
||||
@@ -666,12 +719,12 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
else if (arrayTypeInfo.IsObjectRef || (arrayApiType != null && arrayApiType.IsScriptingObject))
|
||||
{
|
||||
type = $"NativeArray<MObject*>/*wahho5 object*/";
|
||||
type = $"NativeArray<MObject*>";
|
||||
return $"MUtils::ToManagedArrayWrapperPointer<{nativeName}>({converter})/*sahho3a*/";
|
||||
}
|
||||
else if (arrayApiType != null && arrayApiType.IsScriptingObject)
|
||||
{
|
||||
type = $"NativeArray<{nativeInternalName}*>/*wahho3 class pod:{pod}*/";
|
||||
type = $"NativeArray<{nativeInternalName}*>";
|
||||
//type = $"NativeArray<{arrayApiType.FullNameNative}>/*tahho*/";
|
||||
//if (arrayTypeInfo.Type == "bool")
|
||||
// return "MUtils::ToBoolArray({0})/*bahho*/";
|
||||
@@ -686,7 +739,7 @@ namespace Flax.Build.Bindings
|
||||
else
|
||||
{
|
||||
// Storage type should be wrapped
|
||||
type = $"NativeArray<{nativeInternalName}>/*wahho1 pod:{pod}*/";
|
||||
type = $"NativeArray<{nativeInternalName}>";
|
||||
//type = nativeName + "*/*wahho1: {caller?.Name}*/";
|
||||
if (nativeName == nativeInternalName)
|
||||
return $"MUtils::ToManagedArrayWrapperCopy<{nativeName}>({converter})/*sahho2a*/";
|
||||
@@ -741,7 +794,14 @@ namespace Flax.Build.Bindings
|
||||
CppReferencesFiles.Add(apiType.File);
|
||||
|
||||
if (apiType.MarshalAs != null)
|
||||
return GenerateCppWrapperNativeToManaged(buildData, apiType.MarshalAs, caller, out type, functionInfo);
|
||||
{
|
||||
var ret = GenerateCppWrapperNativeToManaged(buildData, apiType.MarshalAs, caller, out type, functionInfo);
|
||||
//if (apiType.MarshalAs.Type == "JsonAsset")
|
||||
return ret;
|
||||
//return $"({apiType.MarshalAs}){ret}";
|
||||
}
|
||||
//return $"({apiType.MarshalAs}){GenerateCppWrapperNativeToManaged(buildData, apiType.MarshalAs, caller, out type, functionInfo)}";
|
||||
//return GenerateCppWrapperNativeToManaged(buildData, apiType.MarshalAs, caller, out type, functionInfo);
|
||||
|
||||
// Scripting Object
|
||||
if (apiType.IsScriptingObject)
|
||||
@@ -823,6 +883,25 @@ namespace Flax.Build.Bindings
|
||||
|
||||
switch (typeInfo.Type)
|
||||
{
|
||||
#if USE_NETCORE
|
||||
case "String":
|
||||
if (functionInfo?.UniqueName == "CoverageTest1ByRef")
|
||||
typeInfo = typeInfo;
|
||||
type = "String";
|
||||
return "{0}/*vcvc3a*/";
|
||||
case "StringView":
|
||||
type = "StringView";
|
||||
return "{0}/*vcvc4a*/";
|
||||
case "StringAnsi":
|
||||
type = "StringAnsi";
|
||||
//return $"{typeInfo.Type}({{0}})/*vcvc6a*/";
|
||||
//return $"(StringAnsi{(typeInfo.IsRef ? "*" : "")}){{0}}/*vcvc6a*/";
|
||||
return $"{{0}}/*vcvc6a*/";
|
||||
case "StringAnsiView":
|
||||
type = "StringAnsiView";
|
||||
//return $"{typeInfo.Type}(StringAnsi({{0}}))/*vcvc5a*/";
|
||||
return $"(StringAnsi){{0}}/*vcvc5a*/";
|
||||
#else
|
||||
case "String":
|
||||
type = "MString*";
|
||||
return "String(MUtils::ToString({0}))";
|
||||
@@ -833,6 +912,7 @@ namespace Flax.Build.Bindings
|
||||
case "StringAnsiView":
|
||||
type = "MString*";
|
||||
return "MUtils::ToStringAnsi({0})";
|
||||
#endif
|
||||
case "Variant":
|
||||
type = "MObject*";
|
||||
return "MUtils::UnboxVariant({0})";
|
||||
@@ -920,7 +1000,7 @@ namespace Flax.Build.Bindings
|
||||
type = $"NativeArray<{nativeInternalName}>";
|
||||
result = $"Array<{genericArgs}>(/*({nativeName}*)*/{converter}, {{1}})/*456valuetype {arrayTypeInfo.Type}*/";
|
||||
}
|
||||
else if (nativeName == "String" || nativeName == "StringAnsi" || nativeName == "StringView")
|
||||
else if (nativeName == "String" || nativeName == "StringAnsi" || nativeName == "StringView" || nativeName == "StringAnsiView")
|
||||
{
|
||||
//result += "/*234stringy*/";
|
||||
}
|
||||
@@ -980,7 +1060,7 @@ namespace Flax.Build.Bindings
|
||||
var nativeName = arrayApiType.FullNameNative;
|
||||
if (typeInfo.GenericArgs[0].IsConst)
|
||||
nativeName = "const " + nativeName;
|
||||
return $"Span<{nativeName}>({{0}}, {{1}})/*spantag */";
|
||||
return $"Span<{nativeName}>({{0}}, {{1}})";
|
||||
}
|
||||
|
||||
return "MUtils::ToSpan<" + typeInfo.GenericArgs[0] + ">({0})";
|
||||
@@ -1013,7 +1093,7 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
#if USE_NETCORE
|
||||
//formattingFlags.SetFlag(FormattingFlags.NeedLocalVariable, true);
|
||||
type = "byte*";
|
||||
type = "NativeArray<byte>";
|
||||
return "BytesContainer({0}, {1})";
|
||||
#else
|
||||
formattingFlags.SetFlag(FormattingFlags.NeedLocalVariable, true);
|
||||
@@ -1040,7 +1120,12 @@ namespace Flax.Build.Bindings
|
||||
if (apiType != null)
|
||||
{
|
||||
if (apiType.MarshalAs != null)
|
||||
return GenerateCppWrapperManagedToNative(buildData, apiType.MarshalAs, caller, functionInfo, generatorFlags, out type, out apiType, out formattingFlags);
|
||||
{
|
||||
var ret = GenerateCppWrapperManagedToNative(buildData, apiType.MarshalAs, caller, functionInfo, generatorFlags, out type, out apiType, out formattingFlags);
|
||||
if (string.IsNullOrEmpty(ret))
|
||||
return ret;
|
||||
return $"({type}){ret}";
|
||||
}
|
||||
|
||||
// Scripting Object (for non-pod types converting only, other API converts managed to unmanaged object in C# wrapper code)
|
||||
if (CppNonPodTypesConvertingGeneration && apiType.IsScriptingObject && typeInfo.IsPtr)
|
||||
@@ -1210,14 +1295,16 @@ namespace Flax.Build.Bindings
|
||||
callerName = callerName;
|
||||
if (functionInfo.UniqueName == "CoverageTest4")
|
||||
callerName = callerName;
|
||||
if (functionInfo.UniqueName == "SetFallbackFonts")
|
||||
if (functionInfo.UniqueName == "GetWaitTimeSelector")
|
||||
callerName = callerName;
|
||||
if (functionInfo.ReturnType.IsString)
|
||||
callerName = callerName;
|
||||
|
||||
|
||||
// Setup function binding glue to ensure that wrapper method signature matches for C++ and C#
|
||||
functionInfo.Glue = new FunctionInfo.GlueInfo
|
||||
{
|
||||
UseReferenceForResult = UsePassByReference(buildData, functionInfo.ReturnType, caller),
|
||||
//"why can't we pass string as constref in return (or any other types?)"
|
||||
UseReferenceForResult = !functionInfo.ReturnType.IsString && UsePassByReference(buildData, functionInfo.ReturnType, caller),
|
||||
CustomParameters = new List<FunctionInfo.ParameterInfo>(),
|
||||
};
|
||||
var returnType = functionInfo.ReturnType;
|
||||
@@ -1225,6 +1312,7 @@ namespace Flax.Build.Bindings
|
||||
if (returnApiType != null && returnApiType.MarshalAs != null)
|
||||
returnType = returnApiType.MarshalAs;
|
||||
|
||||
// Setup additional glue parameters and conversion for return type
|
||||
bool returnTypeIsContainer = false;
|
||||
//CppNativeArrayAsParameter = true;
|
||||
var returnValueConvert = GenerateCppWrapperNativeToManaged(buildData, functionInfo.ReturnType, caller, out var returnValueType, functionInfo);
|
||||
@@ -1273,6 +1361,7 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
#endif
|
||||
|
||||
// Start of function definition
|
||||
var prevIndent = " ";
|
||||
var indent = " ";
|
||||
contents.Append(prevIndent);
|
||||
@@ -1309,6 +1398,7 @@ namespace Flax.Build.Bindings
|
||||
#endif
|
||||
CppInternalCalls.Add(new KeyValuePair<string, string>(functionInfo.UniqueName, functionInfo.UniqueName));
|
||||
|
||||
// "This" parameter
|
||||
var separator = false;
|
||||
var signatureStart = contents.Length;
|
||||
if (!functionInfo.IsStatic)
|
||||
@@ -1317,6 +1407,7 @@ namespace Flax.Build.Bindings
|
||||
separator = true;
|
||||
}
|
||||
|
||||
// Setup function parameter list
|
||||
var useInlinedReturn = true;
|
||||
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
||||
{
|
||||
@@ -1338,7 +1429,7 @@ namespace Flax.Build.Bindings
|
||||
|
||||
CppParamsThatNeedConversion[i] = false;
|
||||
//CppNativeArrayAsParameter = true;
|
||||
CppParamsWrappersCache[i] = GenerateCppWrapperManagedToNative(buildData, parameterInfo.Type, caller, functionInfo, genFlags, out var managedType, out var apiType, out CppParamsFormattingFlags[i]);
|
||||
CppParamsWrappersCache[i] = GenerateCppWrapperManagedToNative(buildData, parameterInfo.Type, caller, functionInfo, genFlags, out CppParamsManagedTypes[i], out var apiType, out CppParamsFormattingFlags[i]);
|
||||
//CppNativeArrayAsParameter = false;
|
||||
|
||||
if (functionInfo.UniqueName.StartsWith("Set") && !functionInfo.Name.StartsWith("Set"))
|
||||
@@ -1352,9 +1443,9 @@ namespace Flax.Build.Bindings
|
||||
// Out parameters that need additional converting will be converted at the native side (eg. object reference)
|
||||
var isOutWithManagedConverter = parameterInfo.IsOut && !string.IsNullOrEmpty(GenerateCSharpManagedToNativeConverter(buildData, parameterInfo.Type, caller));
|
||||
if (isOutWithManagedConverter)
|
||||
managedType = "MObject*";
|
||||
CppParamsManagedTypes[i] = "MObject*";
|
||||
|
||||
contents.Append(managedType);
|
||||
contents.Append(CppParamsManagedTypes[i]);
|
||||
if (parameterInfo.IsRef || parameterInfo.IsOut || UsePassByReference(buildData, parameterInfo.Type, caller))
|
||||
contents.Append('*');
|
||||
contents.Append(' ');
|
||||
@@ -1372,15 +1463,26 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
convertOutputParameter = true;
|
||||
}
|
||||
// Arrays, Scripting Objects, Dictionaries and other types that need to be converted into managed format if used as output parameter
|
||||
else if (!apiType.IsPod)
|
||||
{
|
||||
convertOutputParameter = true;
|
||||
}
|
||||
else if (apiType.Name == "Variant")
|
||||
{
|
||||
convertOutputParameter = true;
|
||||
}
|
||||
// Arrays, Scripting Objects, Dictionaries and other types that need to be converted into managed format if used as output parameter
|
||||
else if (!apiType.IsPod)
|
||||
{
|
||||
#if USE_NETCORE
|
||||
if (parameterInfo.Type.IsString)
|
||||
{
|
||||
// StringAnsi requires conversion
|
||||
convertOutputParameter = CppParamsManagedTypes[i] != parameterInfo.Type.Type;
|
||||
}
|
||||
else
|
||||
//if (!parameterInfo.Type.IsString /*&& !parameterInfo.Type.IsArrayOrSpan*/)
|
||||
#endif
|
||||
{
|
||||
convertOutputParameter = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// BytesContainer
|
||||
else if (parameterInfo.Type.Type == "BytesContainer" && parameterInfo.Type.GenericArgs == null)
|
||||
@@ -1414,7 +1516,6 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (var i = 0; i < functionInfo.Glue.CustomParameters.Count; i++)
|
||||
{
|
||||
var parameterInfo = functionInfo.Glue.CustomParameters[i];
|
||||
@@ -1442,6 +1543,8 @@ namespace Flax.Build.Bindings
|
||||
prevIndent = null;
|
||||
indent = " ";
|
||||
}
|
||||
|
||||
// Function body
|
||||
contents.AppendLine();
|
||||
contents.Append(prevIndent).AppendLine("{");
|
||||
#if USE_NETCORE
|
||||
@@ -1451,19 +1554,6 @@ namespace Flax.Build.Bindings
|
||||
if (!functionInfo.IsStatic)
|
||||
contents.Append(indent).AppendLine("if (__obj == nullptr) DebugLog::ThrowNullReference();");
|
||||
|
||||
string callBegin = indent;
|
||||
if (functionInfo.Glue.UseReferenceForResult)
|
||||
{
|
||||
callBegin += "*__resultAsRef = ";
|
||||
}
|
||||
else if (!returnType.IsVoid)
|
||||
{
|
||||
if (useInlinedReturn)
|
||||
callBegin += "return ";
|
||||
else
|
||||
callBegin += "auto __result = ";
|
||||
}
|
||||
|
||||
#if USE_NETCORE
|
||||
string callReturnCount = "";
|
||||
if (returnTypeIsContainer)
|
||||
@@ -1583,9 +1673,16 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
// Non-const lvalue reference parameters needs to be passed via temporary value
|
||||
if (parameterInfo.IsOut || parameterInfo.IsRef)
|
||||
contents.Append(indent).AppendFormat("{2}& {0}Temp = {1}; // non-const lvalue1", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine();
|
||||
{
|
||||
if (parameterInfo.Type.IsString)
|
||||
contents.Append(indent).AppendFormat("{2}& {0}Temp = *{1}; // non-const lvalue1string", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine();
|
||||
else
|
||||
contents.Append(indent).AppendFormat("{2}& {0}Temp = {1}; // non-const lvalue1b", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine();
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(CppParamsWrappersCache[i]))
|
||||
contents.Append(indent).AppendFormat("{2}& {0}Temp = {1}; // non-const lvalue2", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine();
|
||||
else
|
||||
contents.Append(indent).AppendFormat("{2} {0}Temp = {1}; // non-const lvalue1", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine();
|
||||
contents.Append(indent).AppendFormat("{2} {0}Temp = {1}; // non-const lvalue3", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine();
|
||||
callParams += parameterInfo.Name;
|
||||
callParams += "Temp";
|
||||
}
|
||||
@@ -1595,6 +1692,19 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
}
|
||||
|
||||
// Handle return value and conversion here if we have no ref/out parameters
|
||||
string callBegin = indent;
|
||||
if (functionInfo.Glue.UseReferenceForResult)
|
||||
{
|
||||
callBegin += "*__resultAsRef = ";
|
||||
}
|
||||
else if (!returnType.IsVoid)
|
||||
{
|
||||
if (useInlinedReturn)
|
||||
callBegin += "return ";
|
||||
else
|
||||
callBegin += "auto __result = ";
|
||||
}
|
||||
#if USE_NETCORE
|
||||
if (!string.IsNullOrEmpty(callReturnCount))
|
||||
{
|
||||
@@ -1710,7 +1820,8 @@ namespace Flax.Build.Bindings
|
||||
#endif
|
||||
{
|
||||
contents.Append(indent).Append($"// isgigs2").AppendLine();
|
||||
contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine();
|
||||
contents.Append(indent).AppendFormat("*{0} = {1};", parameterInfo.Name, value).AppendLine();
|
||||
//contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1718,7 +1829,11 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
// Structure that has reference to managed objects requries copy relevant for GC barriers (on Mono)
|
||||
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h");
|
||||
#if USE_NETCORE
|
||||
contents.Append(indent).AppendFormat("*{0} = {1}; /*xcic666*/", parameterInfo.Name, value).AppendLine();
|
||||
#else
|
||||
contents.Append(indent).AppendFormat("{{ auto __temp = {1}; MCore::GC::WriteValue({0}, &__temp, 1, {2}::TypeInitializer.GetClass()); }}", parameterInfo.Name, value, apiType.FullNameNative).AppendLine();
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1970,7 +2085,7 @@ namespace Flax.Build.Bindings
|
||||
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
||||
{
|
||||
var parameterInfo = functionInfo.Parameters[i];
|
||||
var paramIsRef = parameterInfo.IsRef || parameterInfo.IsOut;
|
||||
var paramIsRef = (parameterInfo.IsRef || parameterInfo.IsOut) /*&& !parameterInfo.IsConst*/;
|
||||
var paramValue = GenerateCppWrapperNativeToManagedParam(buildData, contents, parameterInfo.Type, parameterInfo.Name, classInfo, paramIsRef, out CppParamsFormattingFlags[i]);
|
||||
contents.Append($" params[{i}] = {paramValue};").AppendLine();
|
||||
}
|
||||
@@ -1989,6 +2104,7 @@ namespace Flax.Build.Bindings
|
||||
// Direct value convert
|
||||
var paramName = CppParamsFormattingFlags[i].HasFlag(ParameterFormattingFlags.NeedLocalVariable) ? $"__param_{parameterInfo.Name}" : $"params[{i}]";
|
||||
var managedToNative = GenerateCppWrapperManagedToNative(buildData, parameterInfo.Type, classInfo, null, ParameterGeneratorFlags.None, out var managedType, out var apiType, out _);
|
||||
var nativeToManaged = GenerateCppWrapperNativeToManaged(buildData, parameterInfo.Type, classInfo, out var managedTypeAsNative, null);
|
||||
var passAsParamPtr = managedType.EndsWith("*") || true;
|
||||
var useLocalVarPointer = !CppParamsFormattingFlags[i].HasFlag(ParameterFormattingFlags.NeedLocalVariable);
|
||||
var paramValue = useLocalVarPointer ? $"*({managedType}{(passAsParamPtr ? "" : "*")}*)&{paramName}" : paramName;
|
||||
@@ -2000,7 +2116,11 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
else if (!passAsParamPtr)
|
||||
paramValue = '*' + paramValue;
|
||||
contents.Append($" {parameterInfo.Name} = {paramValue};").AppendLine();
|
||||
|
||||
if (!string.IsNullOrEmpty(managedTypeAsNative) && managedTypeAsNative != managedType)
|
||||
contents.Append($" {parameterInfo.Name} = ({managedType}){paramValue}; // managedTypeAsNative:{managedTypeAsNative}, managedToNative:{managedToNative} managedType:{managedType}, type:{parameterInfo.Type.ToString()}").AppendLine();
|
||||
else
|
||||
contents.Append($" {parameterInfo.Name} = {paramValue}; // managedTypeAsNative:{managedTypeAsNative}, managedToNative:{managedToNative} managedType:{managedType}, type:{parameterInfo.Type.ToString()}").AppendLine();
|
||||
|
||||
// Release temporary GCHandles
|
||||
/*if (passAsParamPtr)
|
||||
@@ -2050,7 +2170,11 @@ namespace Flax.Build.Bindings
|
||||
|
||||
//var ispod = parameterInfo.Type.IsPod(buildData, apiType);
|
||||
//contents.Append($" // {parameterInfo.Type.Type} is pod: {ispod}||{apiType.IsPod}, valuetype: {apiType.IsValueType}, classtype: {apiType.IsClass} // doerp1").AppendLine();
|
||||
if (useThunk || !paramIsValueType)
|
||||
if (parameterInfo.Type.IsString)
|
||||
{
|
||||
contents.Append($" //durr2string").AppendLine();
|
||||
}
|
||||
else if (useThunk || !paramIsValueType)
|
||||
{
|
||||
contents.Append($" MUtils::FreeManaged<{parameterInfo.Type.Type}>((MObject*)__param_{parameterInfo.Name}); // darr1").AppendLine();
|
||||
// Release the original handle
|
||||
@@ -2059,8 +2183,7 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
else if (paramIsValueType)
|
||||
{
|
||||
contents.Append($" //durr2").AppendLine();
|
||||
|
||||
contents.Append($" //durr2value").AppendLine();
|
||||
}
|
||||
else if (CppParamsThatNeedConversion[i])
|
||||
{
|
||||
@@ -2082,7 +2205,7 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
if (parameterInfo.Type.Type.ToLower().Contains("string"))
|
||||
apiType = apiType;
|
||||
contents.Append($" MUtils::FreeManaged<{parameterInfo.Type.Type}>((MObject*)params[{i}]); //asdf1d").AppendLine();
|
||||
contents.Append($" //MUtils::FreeManaged<{parameterInfo.Type.Type}>((MObject*)params[{i}]); //asdf1d").AppendLine();
|
||||
}
|
||||
else if (useThunk)//if (apiType != null)
|
||||
{
|
||||
@@ -2101,7 +2224,7 @@ namespace Flax.Build.Bindings
|
||||
if (useThunk)
|
||||
contents.Append($" MUtils::FreeManagedArray<byte>((MArray*)params[{i}]); //fgfgh8").AppendLine();
|
||||
else
|
||||
contents.Append($" MCore::GC::FreeMemory(__param_{parameterInfo.Name}.data, true); //fgfghdf8").AppendLine();
|
||||
contents.Append($" MCore::GC::FreeMemory(__param_{parameterInfo.Name}.data, false); //fgfghdf8").AppendLine();
|
||||
//contents.Append($" MUtils::FreeManagedArray<byte>((MArray*)params[{i}]); //fgfgh8").AppendLine();
|
||||
}
|
||||
else if (paramIsRef)
|
||||
@@ -2117,7 +2240,7 @@ namespace Flax.Build.Bindings
|
||||
|
||||
//var isPod = parameterInfo.Type.GenericArgs.Count > 0 ? parameterInfo.Type.GenericArgs[0].IsPod(buildData, apiType) : false;
|
||||
contents.Append($" // {parameterInfo.Type} is pod: {elementApiType?.IsPod}, valuetype: {paramIsValueType}, classtype: {apiType.IsClass} // huah").AppendLine();
|
||||
if (useThunk /*|| CppParamsThatNeedConversion[i]*/ || genericType == "String" || genericType == "StringAnsi" || genericType == "StringView")
|
||||
if (useThunk /*|| CppParamsThatNeedConversion[i]*/ || genericType == "String" || genericType == "StringAnsi" || genericType == "StringView" || genericType == "StringAnsiView")
|
||||
{
|
||||
contents.Append($" MUtils::FreeManagedArray<{genericType}>(__param_{parameterInfo.Name}); //fgfgh3").AppendLine();
|
||||
|
||||
@@ -2131,20 +2254,22 @@ namespace Flax.Build.Bindings
|
||||
}*/
|
||||
else// if (CppParamsThatNeedConversion[i])
|
||||
{
|
||||
contents.Append($" MCore::GC::FreeMemory(__param_{parameterInfo.Name}.data, true); //jfgfgh7").AppendLine();
|
||||
//contents.Append($" MCore::GC::FreeMemory(__param_{parameterInfo.Name}.data, false); //jfgfgh7").AppendLine();
|
||||
contents.Append($" MUtils::FreeManagedArray<{genericType}>((MArray*)params[{i}]); //jfgfgh7").AppendLine();
|
||||
|
||||
// Release the original handle
|
||||
contents.Append($" if (__param_orig_{parameterInfo.Name}.data != __param_{parameterInfo.Name}.data)").AppendLine();
|
||||
contents.Append($" MCore::GC::FreeMemory(__param_orig_{parameterInfo.Name}.data, true); //fgfgh8").AppendLine();
|
||||
contents.Append($" MUtils::FreeManagedArray<{genericType}>((MArray*)&__param_orig_{parameterInfo.Name}); //jfgfgh7b").AppendLine();
|
||||
//contents.Append($" MCore::GC::FreeMemory(__param_orig_{parameterInfo.Name}.data, false); //fgfgh8").AppendLine();
|
||||
}
|
||||
}
|
||||
else if (elementApiType?.IsPod ?? false)
|
||||
{
|
||||
var genericType = parameterInfo.Type.GenericArgs[0].ToString(false);
|
||||
if (CppParamsFormattingFlags[i].HasFlag(ParameterFormattingFlags.NeedLocalVariable))
|
||||
contents.Append($" MCore::GC::FreeMemory(__param_{parameterInfo.Name}.data, true); //kfgfgh7a").AppendLine();
|
||||
contents.Append($" MCore::GC::FreeMemory(__param_{parameterInfo.Name}.data, false); //kfgfgh7a").AppendLine();
|
||||
else
|
||||
contents.Append($" MCore::GC::FreeMemory(params[{i}], true); //kfgfgh7b").AppendLine();
|
||||
contents.Append($" MCore::GC::FreeMemory(params[{i}], false); //kfgfgh7b").AppendLine();
|
||||
}
|
||||
else if (apiType != null && !apiType.IsInBuild)
|
||||
{
|
||||
@@ -3522,6 +3647,9 @@ namespace Flax.Build.Bindings
|
||||
// Get the full typename with nested parent prefix
|
||||
var fullName = apiType.FullNameNative;
|
||||
|
||||
if (wrapperName == "TestStructManaged")
|
||||
wrapperName = wrapperName;
|
||||
|
||||
if (structureInfo != null)
|
||||
{
|
||||
// Generate managed type memory layout
|
||||
@@ -3558,7 +3686,7 @@ namespace Flax.Build.Bindings
|
||||
header.AppendLine("namespace {");
|
||||
header.AppendFormat("{0} ToManaged(const {1}& value);", wrapperName, fullName).AppendLine();
|
||||
header.AppendFormat("{1} ToNative(const {0}& value);", wrapperName, fullName).AppendLine();
|
||||
header.AppendFormat("void FreeManaged(const {0}& value);", wrapperName).AppendLine();
|
||||
header.AppendFormat("void FreeManaged({0}& value);", wrapperName).AppendLine();
|
||||
header.AppendLine("}");
|
||||
|
||||
// Generate MConverter for a structure
|
||||
@@ -3623,7 +3751,7 @@ namespace Flax.Build.Bindings
|
||||
//header.AppendFormat(" auto managed = MCore::Object::Unbox(data);", wrapperName).AppendLine();
|
||||
//header.AppendFormat(" ::FreeManaged(*reinterpret_cast<{0}*>(managed));", wrapperName).AppendLine();
|
||||
header.Append(" MCore::Array::Free(array);").AppendLine();
|
||||
header.Append(" MCore::GCHandle::Free(*(MGCHandle*)&array);").AppendLine();
|
||||
//header.Append(" MCore::GCHandle::Free(*(MGCHandle*)&array);").AppendLine();
|
||||
header.Append(" }").AppendLine();
|
||||
|
||||
header.Append('}').Append(';').AppendLine();
|
||||
@@ -3637,14 +3765,14 @@ namespace Flax.Build.Bindings
|
||||
header.Append(" {").AppendLine();
|
||||
//header.AppendFormat(" result = ToNative(*reinterpret_cast<{0}*>(MCore::Object::Unbox(data)));", wrapperName).AppendLine();
|
||||
//header.Append(" PLATFORM_DEBUG_BREAK;").AppendLine();
|
||||
header.Append(" result = ::ToManaged(data);").AppendLine();
|
||||
header.Append($" new(&result) {wrapperName}(MoveTemp(::ToManaged(data)));").AppendLine();
|
||||
header.Append(" }").AppendLine();
|
||||
|
||||
header.AppendFormat(" DLLEXPORT USED void ToNative({0}& result, const {1}& data) const", fullName, wrapperName).AppendLine();
|
||||
header.Append(" {").AppendLine();
|
||||
//header.AppendFormat(" result = ToNative(*reinterpret_cast<{0}*>(MCore::Object::Unbox(data)));", wrapperName).AppendLine();
|
||||
//header.Append(" PLATFORM_DEBUG_BREAK;").AppendLine();
|
||||
header.Append(" result = ::ToNative(data);").AppendLine();
|
||||
header.Append($" new(&result) {fullName}(MoveTemp(::ToNative(data)));").AppendLine();
|
||||
header.Append(" }").AppendLine();
|
||||
|
||||
header.Append('}').Append(';').AppendLine();
|
||||
@@ -3725,7 +3853,7 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
var arrayElementType = fieldInfo.Type.GenericArgs != null ? FindApiTypeInfo(buildData, fieldInfo.Type.GenericArgs[0], apiType) : null;
|
||||
var ispod = (arrayElementType?.IsPod.ToString() ?? "null");
|
||||
header.Append($" // pluh: {fieldInfo.Type.Type}, {fieldType?.FullNameNative}, {fieldType?.Name}, {fieldTypeName}, {ispod}").AppendLine();
|
||||
header.Append($" // pluh: {fieldInfo.Type.Type}, FullNameNative:{fieldType?.FullNameNative}, Name:{fieldType?.Name}, ManagedToNativeType:{fieldTypeName}, pod:{ispod}").AppendLine();
|
||||
//if (fieldInfo.Type.IsArrayOrSpan && (arrayElementType?.IsValueType ?? false))
|
||||
{
|
||||
header.AppendFormat(" result.{0} = {1}; /*kaek1 */", fieldInfo.Name, string.Format(wrapper, $"value.{fieldInfo.Name}", $"value.{fieldInfo.Name}.length")).AppendLine();
|
||||
@@ -3747,7 +3875,7 @@ namespace Flax.Build.Bindings
|
||||
|
||||
// Generate release function for temporary managed handles
|
||||
header.AppendLine();
|
||||
header.AppendFormat("void FreeManaged(const {0}& value)", wrapperName).AppendLine();
|
||||
header.AppendFormat("void FreeManaged({0}& value)", wrapperName).AppendLine();
|
||||
header.Append('{').AppendLine();
|
||||
for (var i = 0; i < fields.Count; i++)
|
||||
{
|
||||
@@ -3759,7 +3887,15 @@ namespace Flax.Build.Bindings
|
||||
var wrapper = GenerateCppWrapperManagedToNative(buildData, fieldInfo.Type, apiType, null, ParameterGeneratorFlags.None, out var managedType, out var fieldApiType, out _);
|
||||
CppNonPodTypesConvertingGeneration = false;
|
||||
|
||||
if (fieldInfo.Type.IsArray)
|
||||
if (fieldInfo.Type.IsString || (fieldApiType?.MarshalAs?.IsString ?? false))
|
||||
{
|
||||
#if USE_NETCORE
|
||||
header.Append($" value.{fieldInfo.Name}.Clear(); // HUU1").AppendLine();
|
||||
#else
|
||||
header.Append($" MCore::String::Free(value.{fieldInfo.Name});").AppendLine();
|
||||
#endif
|
||||
}
|
||||
else if (fieldInfo.Type.IsArray)
|
||||
{
|
||||
//header.Append($" fixed_array_type = fixed_array_type; // {fieldInfo.Name} ({managedType}) is fixed array").AppendLine();
|
||||
}
|
||||
@@ -3784,7 +3920,11 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
|
||||
}
|
||||
#if USE_NETCORE
|
||||
header.Append($" value.{fieldInfo.Name}.Clear(); // Haa1").AppendLine();
|
||||
#else
|
||||
header.Append($" MCore::String::Free(value.{fieldInfo.Name});").AppendLine();
|
||||
#endif
|
||||
}
|
||||
else if (fieldInfo.Type.Type == "Span")
|
||||
{
|
||||
@@ -3817,18 +3957,20 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
if (fieldApiType.IsClass)
|
||||
{
|
||||
|
||||
header.Append($" // a class").AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
header.Append($" ::FreeManaged(value.{fieldInfo.Name}); // asdfggg588").AppendLine();
|
||||
header.Append($" ::FreeManaged(value.{fieldInfo.Name}); // asdfggg588 not class").AppendLine();
|
||||
//header.Append($" unhandled_type = unhandled_type; // {fieldInfo.Name} ({managedType}) should be cleaned? // asdfggg588").AppendLine();
|
||||
}
|
||||
/*
|
||||
header.Append($" auto __param{fieldInfo.Name}_handle = *(MGCHandle*)&value.{fieldInfo.Name};").AppendLine();
|
||||
//header.Append($" ASSERT((((unsigned long long)__param{fieldInfo.Name}_handle & 0xC000000000000000) >> 62) == 0); // asdf3").AppendLine();
|
||||
header.Append($" if ((((unsigned long long)__param{fieldInfo.Name}_handle & 0xC000000000000000) >> 62) != 0) // asdf3").AppendLine();
|
||||
header.Append($" if ((((unsigned long long)__param{fieldInfo.Name}_handle & 0xC000000000000000) >> 62) != 0) // asdf3 type:{fieldInfo.Type}, api:{fieldApiType?.Name}").AppendLine();
|
||||
header.Append($" __param{fieldInfo.Name}_handle = __param{fieldInfo.Name}_handle;").AppendLine();
|
||||
header.Append($" MCore::GCHandle::Free(__param{fieldInfo.Name}_handle);").AppendLine();
|
||||
*/
|
||||
}
|
||||
else if (fieldApiType.IsPod)
|
||||
{
|
||||
@@ -3864,14 +4006,19 @@ namespace Flax.Build.Bindings
|
||||
var fieldInfo = fields[i];
|
||||
if (fieldInfo.IsStatic || fieldInfo.IsConstexpr)
|
||||
continue;
|
||||
|
||||
if (fullName == "LocalizedString")
|
||||
fieldInfo = fieldInfo;
|
||||
var fieldType = FindApiTypeInfo(buildData, fieldInfo.Type, apiType);
|
||||
if (fieldInfo == null || fieldType.IsValueType) // TODO: support any value type (eg. by boxing)
|
||||
throw new Exception($"Not supported field {fieldInfo.Type} {fieldInfo.Name} in class {classInfo.Name}.");
|
||||
|
||||
var wrapper = GenerateCppWrapperNativeToManaged(buildData, fieldInfo.Type, apiType, out var type, null);
|
||||
var value = string.IsNullOrEmpty(wrapper) ? "data." + fieldInfo.Name : string.Format(wrapper, "data." + fieldInfo.Name);
|
||||
header.AppendFormat(" klass->GetField(\"{0}\")->SetValue(obj, {1});", fieldInfo.Name, value).AppendLine();
|
||||
if (!fieldInfo.Type.IsPtr)
|
||||
header.AppendFormat(" klass->GetField(\"{0}\")->SetValue(obj, (void*)&{1}); //gigigi1no", fieldInfo.Name, value).AppendLine();
|
||||
else
|
||||
header.AppendFormat(" klass->GetField(\"{0}\")->SetValue(obj, {1}); //gigigi1ptr", fieldInfo.Name, value).AppendLine();
|
||||
|
||||
}
|
||||
header.Append(" return obj;").AppendLine();
|
||||
header.Append(" }").AppendLine();
|
||||
@@ -3892,6 +4039,9 @@ namespace Flax.Build.Bindings
|
||||
if (fieldInfo.IsStatic || fieldInfo.IsConstexpr)
|
||||
continue;
|
||||
|
||||
if (fullName == "LocalizedString")
|
||||
fieldInfo = fieldInfo;
|
||||
|
||||
CppNonPodTypesConvertingGeneration = true;
|
||||
var wrapper = GenerateCppWrapperManagedToNative(buildData, fieldInfo.Type, apiType, null, ParameterGeneratorFlags.None, out var type, out _, out _);
|
||||
CppNonPodTypesConvertingGeneration = false;
|
||||
@@ -3899,8 +4049,16 @@ namespace Flax.Build.Bindings
|
||||
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MField.h");
|
||||
|
||||
header.AppendFormat(" klass->GetField(\"{0}\")->GetValue(obj, &v);", fieldInfo.Name).AppendLine();
|
||||
var value = $"({type})v";
|
||||
header.AppendFormat(" result.{0} = {1};", fieldInfo.Name, string.IsNullOrEmpty(wrapper) ? value : string.Format(wrapper, value)).AppendLine();
|
||||
if (type == "String" || type == "String*")
|
||||
{
|
||||
var value = fieldInfo.Type.IsPtr ? $"*({type}*)v" : $"*({type}*)v";
|
||||
header.AppendFormat(" result.{0} = {1};", fieldInfo.Name, string.IsNullOrEmpty(wrapper) ? value : string.Format(wrapper, value)).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
var value = fieldInfo.Type.IsPtr ? $"({type})v" : $"({type}*)&v";
|
||||
header.AppendFormat(" result.{0} = {1};", fieldInfo.Name, string.IsNullOrEmpty(wrapper) ? value : string.Format(wrapper, value)).AppendLine();
|
||||
}
|
||||
}
|
||||
header.Append(" }").AppendLine();
|
||||
|
||||
@@ -3956,7 +4114,7 @@ namespace Flax.Build.Bindings
|
||||
//header.AppendFormat(" auto managed = MCore::Object::Unbox(data);", wrapperName).AppendLine();
|
||||
//header.AppendFormat(" ::FreeManaged(*reinterpret_cast<{0}*>(managed));", wrapperName).AppendLine();
|
||||
header.Append(" MCore::Array::Free(array);").AppendLine();
|
||||
header.Append(" MCore::GCHandle::Free(*(MGCHandle*)&array);").AppendLine();
|
||||
//header.Append(" MCore::GCHandle::Free(*(MGCHandle*)&array);").AppendLine();
|
||||
header.Append(" }").AppendLine();
|
||||
|
||||
header.Append('}').Append(';').AppendLine();
|
||||
|
||||
@@ -55,6 +55,11 @@ namespace Flax.Build.Bindings
|
||||
/// </summary>
|
||||
public bool IsArrayOrSpan => Type is "Array" or "Span" or "DataContainer" or "BytesContainer";
|
||||
|
||||
/// <summary>
|
||||
/// Is this a string type.
|
||||
/// </summary>
|
||||
public bool IsString => Type is "String" or "StringView" or "StringAnsi" or "StringAnsiView" && GenericArgs == null;
|
||||
|
||||
public TypeInfo()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -375,6 +375,7 @@ namespace Flax.Build.NativeCpp
|
||||
|
||||
"System.Reflection",
|
||||
//"System.Reflection.Metadata",
|
||||
"System.Numerics.Vectors",
|
||||
},
|
||||
SystemAnalyzers = new HashSet<string>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user