From f3366178ead4257ef77888938061e2ef622155f2 Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Mon, 23 Jan 2023 18:14:38 +0100 Subject: [PATCH] Refactor manually written managed bindings to use C-style exported P/Invoke --- .../Content/Import/AudioImportSettings.cs | 2 +- .../Editor/Content/Import/ModelImportEntry.cs | 2 +- .../Content/Import/TextureImportEntry.cs | 2 +- .../Editor/CustomEditors/CustomEditorsUtil.cs | 2 +- Source/Editor/Editor.cs | 80 +- .../Editor/Managed/ManagedEditor.Internal.cpp | 1437 ++++++++--------- .../Animations/Graph/AnimGraph.Custom.cpp | 62 +- Source/Engine/Core/Config/GameSettings.cs | 2 +- .../Core/Config/LayersAndTagsSettings.cs | 2 +- Source/Engine/Engine/DebugLogHandler.cs | 6 +- Source/Engine/Platform/Base/PlatformBase.h | 3 - Source/Engine/Scripting/InternalCalls.h | 12 +- Source/Engine/Scripting/Object.cs | 22 +- .../Engine/Scripting/Scripting.Internal.cpp | 155 +- Source/Engine/Scripting/Scripting.cpp | 6 - Source/Engine/Scripting/Scripting.cs | 14 +- Source/Engine/Scripting/ScriptingObject.cpp | 570 ++++--- Source/Engine/Scripting/ScriptingObject.h | 24 +- Source/Engine/Utilities/Utils.cs | 8 +- 19 files changed, 1157 insertions(+), 1254 deletions(-) diff --git a/Source/Editor/Content/Import/AudioImportSettings.cs b/Source/Editor/Content/Import/AudioImportSettings.cs index 70ba0a4f0..98c5324f7 100644 --- a/Source/Editor/Content/Import/AudioImportSettings.cs +++ b/Source/Editor/Content/Import/AudioImportSettings.cs @@ -184,7 +184,7 @@ namespace FlaxEditor.Content.Import #region Internal Calls - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Import.AudioImportEntry::Internal_GetAudioImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "AudioImportEntryInternal_GetAudioImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_GetAudioImportOptions(string path, out AudioImportSettings.InternalOptions result); diff --git a/Source/Editor/Content/Import/ModelImportEntry.cs b/Source/Editor/Content/Import/ModelImportEntry.cs index cf4672154..e9edc0e91 100644 --- a/Source/Editor/Content/Import/ModelImportEntry.cs +++ b/Source/Editor/Content/Import/ModelImportEntry.cs @@ -707,7 +707,7 @@ namespace FlaxEditor.Content.Import #region Internal Calls - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Import.ModelImportEntry::Internal_GetModelImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ModelImportEntryInternal_GetModelImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))] internal static partial void Internal_GetModelImportOptions(string path, out ModelImportSettings.InternalOptions result); #endregion diff --git a/Source/Editor/Content/Import/TextureImportEntry.cs b/Source/Editor/Content/Import/TextureImportEntry.cs index 157d82249..a3ffd8c13 100644 --- a/Source/Editor/Content/Import/TextureImportEntry.cs +++ b/Source/Editor/Content/Import/TextureImportEntry.cs @@ -591,7 +591,7 @@ namespace FlaxEditor.Content.Import #region Internal Calls - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Import.TextureImportEntry::Internal_GetTextureImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "TextureImportEntryInternal_GetTextureImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_GetTextureImportOptions(string path, out TextureImportSettings.InternalOptions result); diff --git a/Source/Editor/CustomEditors/CustomEditorsUtil.cs b/Source/Editor/CustomEditors/CustomEditorsUtil.cs index 4acc5ee0a..2a587d188 100644 --- a/Source/Editor/CustomEditors/CustomEditorsUtil.cs +++ b/Source/Editor/CustomEditors/CustomEditorsUtil.cs @@ -125,7 +125,7 @@ namespace FlaxEditor.CustomEditors return new GenericEditor(); } - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.CustomEditors.CustomEditorsUtil::Internal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "CustomEditorsUtilInternal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalUsing(typeof(SystemTypeMarshaller))] internal static partial Type Internal_GetCustomEditor([MarshalUsing(typeof(SystemTypeMarshaller))] Type targetType); } diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index f6eaef250..66b344d83 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -65,18 +65,18 @@ namespace FlaxEditor /// /// Gets a value indicating whether this Editor is running a dev instance of the engine. /// - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::IsDevInstance", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsDevInstance", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool IsDevInstance(); /// /// Gets a value indicating whether this Editor is running as official build (distributed via Flax services). /// - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::IsOfficialBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsOfficialBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool IsOfficialBuild(); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_IsPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_IsPlayMode(); @@ -1534,132 +1534,132 @@ namespace FlaxEditor Instance.StateMachine.StateChanged += RequestStartPlayOnEditMode; } - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_ReadOutputLogs", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ReadOutputLogs", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial int Internal_ReadOutputLogs([MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref string[] outMessages, [MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref byte[] outLogTypes, [MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref long[] outLogTimes, int outCapacity); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_SetPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_SetPlayMode([MarshalAs(UnmanagedType.U1)] bool value); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial string Internal_GetProjectPath(); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_CloneAssetFile(string dstPath, string srcPath, ref Guid dstId); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_Import", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_Import", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_Import(string inputPath, string outputPath, IntPtr arg); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_ImportTexture", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ImportTexture", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_ImportTexture(string inputPath, string outputPath, ref TextureImportSettings.InternalOptions options); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_ImportModel", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ImportModel", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_ImportModel(string inputPath, string outputPath, ref ModelImportSettings.InternalOptions options); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_ImportAudio", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ImportAudio", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_ImportAudio(string inputPath, string outputPath, ref AudioImportSettings.InternalOptions options); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetAudioClipMetadata", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAudioClipMetadata", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_GetAudioClipMetadata(IntPtr obj, out int originalSize, out int importedSize); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_SaveJsonAsset(string outputPath, string data, string typename); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CopyCache", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CopyCache", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_CopyCache(ref Guid dstId, ref Guid srcId); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_BakeLightmaps", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_BakeLightmaps", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_BakeLightmaps([MarshalAs(UnmanagedType.U1)] bool cancel); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial string Internal_GetShaderAssetSourceCode(IntPtr obj); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.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 = "FlaxEditor.Editor::Internal_GetCollisionWires", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetCollisionWires", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_GetCollisionWires(IntPtr collisionData, [MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "trianglesCount")] out Float3[] triangles, [MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "indicesCount")] out int[] indices, out int trianglesCount, out int indicesCount); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetEditorBoxWithChildren", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetEditorBoxWithChildren", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_GetEditorBoxWithChildren(IntPtr obj, out BoundingBox resultAsRef); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_SetOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_SetOptions(ref InternalOptions options); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_DrawNavMesh", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DrawNavMesh", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_DrawNavMesh(); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CloseSplashScreen", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloseSplashScreen", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_CloseSplashScreen(); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CreateAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CreateAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_CreateAsset(NewAssetType type, string outputPath); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_CreateVisualScript(string outputPath, string baseTypename); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial string Internal_CanImport(string extension); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_CanExport(string path); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_Export(string inputPath, string outputFolder); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetIsEveryAssemblyLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsEveryAssemblyLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_GetIsEveryAssemblyLoaded(); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetLastProjectOpenedEngineBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetLastProjectOpenedEngineBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial int Internal_GetLastProjectOpenedEngineBuild(); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetIsCSGActive", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsCSGActive", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_GetIsCSGActive(); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_RunVisualScriptBreakpointLoopTick", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_RunVisualScriptBreakpointLoopTick", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetVisualScriptLocals", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetVisualScriptLocals", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "localsCount")] internal static partial VisualScriptLocal[] Internal_GetVisualScriptLocals(out int localsCount); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetVisualScriptStackFrames", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetVisualScriptStackFrames", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "stackFrameCount")] internal static partial VisualScriptStackFrame[] Internal_GetVisualScriptStackFrames(out int stackFrameCount); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetVisualScriptPreviousScopeFrame", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetVisualScriptPreviousScopeFrame", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial VisualScriptStackFrame Internal_GetVisualScriptPreviousScopeFrame(); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_EvaluateVisualScriptLocal", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_EvaluateVisualScriptLocal", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_EvaluateVisualScriptLocal(IntPtr script, ref VisualScriptLocal local); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_DeserializeSceneObject(IntPtr sceneObject, string json); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_LoadAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_LoadAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_LoadAsset(ref Guid id); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CanSetToRoot", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanSetToRoot", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] internal static partial bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial float Internal_GetAnimationTime(IntPtr animatedModel); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_SetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_SetAnimationTime(IntPtr animatedModel, float time); #endregion diff --git a/Source/Editor/Managed/ManagedEditor.Internal.cpp b/Source/Editor/Managed/ManagedEditor.Internal.cpp index 353e7117f..dc0dc8299 100644 --- a/Source/Editor/Managed/ManagedEditor.Internal.cpp +++ b/Source/Editor/Managed/ManagedEditor.Internal.cpp @@ -319,35 +319,6 @@ struct InternalAudioOptions #pragma warning( pop ) #endif -namespace CustomEditorsUtilInternal -{ - MonoReflectionType* GetCustomEditor(MonoReflectionType* targetType) - { - SCRIPTING_EXPORT("FlaxEditor.CustomEditors.CustomEditorsUtil::Internal_GetCustomEditor") - return CustomEditorsUtil::GetCustomEditor(targetType); - } -} - -namespace LayersAndTagsSettingsInternal -{ - MonoArray* GetCurrentLayers(int* layersCount) - { - SCRIPTING_EXPORT("FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentLayers") - *layersCount = Math::Max(1, Level::GetNonEmptyLayerNamesCount()); - return MUtils::ToArray(Span(Level::Layers, *layersCount)); - } -} - -namespace GameSettingsInternal1 -{ - void Apply() - { - SCRIPTING_EXPORT("FlaxEditor.Content.Settings.GameSettings::Apply") - LOG(Info, "Apply game settings"); - GameSettings::Load(); - } -} - // Pack log messages into a single scratch buffer to reduce dynamic memory allocations CriticalSection CachedLogDataLocker; Array CachedLogData; @@ -374,829 +345,795 @@ void OnLogMessage(LogType type, const StringView& msg) CachedLogData.Add((byte*)msg.Get(), msg.Length() * 2); } -class ManagedEditorInternal +DEFINE_INTERNAL_CALL(bool) EditorInternal_IsDevInstance() { -public: - static bool IsDevInstance() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::IsDevInstance") #if COMPILE_WITH_DEV_ENV - return true; + return true; #else - return false; + return false; #endif - } +} - static bool IsOfficialBuild() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::IsOfficialBuild") +DEFINE_INTERNAL_CALL(bool) EditorInternal_IsOfficialBuild() +{ #if OFFICIAL_BUILD + return true; +#else + return false; +#endif +} + +DEFINE_INTERNAL_CALL(bool) EditorInternal_IsPlayMode() +{ + return Editor::IsPlayMode; +} + +DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(MonoArray** outMessages, MonoArray** outLogTypes, MonoArray** outLogTimes, int outArraySize) +{ + ScopeLock lock(CachedLogDataLocker); + if (CachedLogData.IsEmpty() || CachedLogData.Get() == nullptr) + return 0; + + int32 count = 0; + const int32 maxCount = outArraySize; + + byte* ptr = CachedLogData.Get(); + byte* end = ptr + CachedLogData.Count(); + while (count < maxCount && ptr != end) + { + auto type = (byte)*(int32*)ptr; + ptr += 4; + + auto time = *(int64*)ptr; + ptr += 8; + + auto length = *(int32*)ptr; + ptr += 4; + + auto msg = (Char*)ptr; + ptr += length * 2; + + auto msgObj = MUtils::ToString(StringView(msg, length)); + + mono_array_setref(*outMessages, count, msgObj); + mono_array_set(*outLogTypes, byte, count, type); + mono_array_set(*outLogTimes, int64, count, time); + + count++; + } + + const int32 dataLeft = (int32)(end - ptr); + Platform::MemoryCopy(CachedLogData.Get(), ptr, dataLeft); + CachedLogData.Resize(dataLeft); + + return count; +} + +DEFINE_INTERNAL_CALL(void) EditorInternal_SetPlayMode(bool value) +{ + Editor::IsPlayMode = value; +} + +DEFINE_INTERNAL_CALL(MonoString*) EditorInternal_GetProjectPath() +{ + return MUtils::ToString(Editor::Project->ProjectPath); +} + +DEFINE_INTERNAL_CALL(void) EditorInternal_CloseSplashScreen() +{ + Editor::CloseSplashScreen(); +} + +DEFINE_INTERNAL_CALL(bool) EditorInternal_CloneAssetFile(MonoString* dstPathObj, MonoString* srcPathObj, Guid* dstId) +{ + // Get normalized paths + String dstPath, srcPath; + MUtils::ToString(dstPathObj, dstPath); + MUtils::ToString(srcPathObj, srcPath); + FileSystem::NormalizePath(dstPath); + FileSystem::NormalizePath(srcPath); + + // Call util function + return Content::CloneAssetFile(dstPath, srcPath, *dstId); +} + +enum class NewAssetType +{ + Material = 0, + MaterialInstance = 1, + CollisionData = 2, + AnimationGraph = 3, + SkeletonMask = 4, + ParticleEmitter = 5, + ParticleSystem = 6, + SceneAnimation = 7, + MaterialFunction = 8, + ParticleEmitterFunction = 9, + AnimationGraphFunction = 10, + Animation = 11, +}; + +DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateAsset(NewAssetType type, MonoString* outputPathObj) +{ + String tag; + switch (type) + { + case NewAssetType::Material: + tag = AssetsImportingManager::CreateMaterialTag; + break; + case NewAssetType::MaterialInstance: + tag = AssetsImportingManager::CreateMaterialInstanceTag; + break; + case NewAssetType::CollisionData: + tag = AssetsImportingManager::CreateCollisionDataTag; + break; + case NewAssetType::AnimationGraph: + tag = AssetsImportingManager::CreateAnimationGraphTag; + break; + case NewAssetType::SkeletonMask: + tag = AssetsImportingManager::CreateSkeletonMaskTag; + break; + case NewAssetType::ParticleEmitter: + tag = AssetsImportingManager::CreateParticleEmitterTag; + break; + case NewAssetType::ParticleSystem: + tag = AssetsImportingManager::CreateParticleSystemTag; + break; + case NewAssetType::SceneAnimation: + tag = AssetsImportingManager::CreateSceneAnimationTag; + break; + case NewAssetType::MaterialFunction: + tag = AssetsImportingManager::CreateMaterialFunctionTag; + break; + case NewAssetType::ParticleEmitterFunction: + tag = AssetsImportingManager::CreateParticleEmitterFunctionTag; + break; + case NewAssetType::AnimationGraphFunction: + tag = AssetsImportingManager::CreateAnimationGraphFunctionTag; + break; + case NewAssetType::Animation: + tag = AssetsImportingManager::CreateAnimationTag; + break; + default: return true; -#else - return false; -#endif } - static bool IsPlayMode() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_IsPlayMode") - return Editor::IsPlayMode; - } + String outputPath; + MUtils::ToString(outputPathObj, outputPath); + FileSystem::NormalizePath(outputPath); - static int32 ReadOutputLogs(MonoArray** outMessages, MonoArray** outLogTypes, MonoArray** outLogTimes, int outArraySize) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_ReadOutputLogs") - ScopeLock lock(CachedLogDataLocker); + return AssetsImportingManager::Create(tag, outputPath); +} - if (CachedLogData.IsEmpty() || CachedLogData.Get() == nullptr) - return 0; +DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MonoString* outputPathObj, MonoString* baseTypenameObj) +{ + String outputPath; + MUtils::ToString(outputPathObj, outputPath); + FileSystem::NormalizePath(outputPath); + String baseTypename; + MUtils::ToString(baseTypenameObj, baseTypename); + return AssetsImportingManager::Create(AssetsImportingManager::CreateVisualScriptTag, outputPath, &baseTypename); +} - int32 count = 0; - const int32 maxCount = outArraySize; +DEFINE_INTERNAL_CALL(MonoString*) EditorInternal_CanImport(MonoString* extensionObj) +{ + String extension; + MUtils::ToString(extensionObj, extension); + if (extension.Length() > 0 && extension[0] == '.') + extension.Remove(0, 1); + const AssetImporter* importer = AssetsImportingManager::GetImporter(extension); + return importer ? MUtils::ToString(importer->ResultExtension) : nullptr; +} - byte* ptr = CachedLogData.Get(); - byte* end = ptr + CachedLogData.Count(); - while (count < maxCount && ptr != end) - { - auto type = (byte)*(int32*)ptr; - ptr += 4; +DEFINE_INTERNAL_CALL(bool) EditorInternal_Import(MonoString* inputPathObj, MonoString* outputPathObj, void* arg) +{ + String inputPath, outputPath; + MUtils::ToString(inputPathObj, inputPath); + MUtils::ToString(outputPathObj, outputPath); + FileSystem::NormalizePath(inputPath); + FileSystem::NormalizePath(outputPath); + return AssetsImportingManager::Import(inputPath, outputPath, arg); +} - auto time = *(int64*)ptr; - ptr += 8; +DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportTexture(MonoString* inputPathObj, MonoString* outputPathObj, InternalTextureOptions* optionsObj) +{ + ImportTexture::Options options; + InternalTextureOptions::Convert(optionsObj, &options); + return EditorInternal_Import(inputPathObj, outputPathObj, &options); +} - auto length = *(int32*)ptr; - ptr += 4; +DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportModel(MonoString* inputPathObj, MonoString* outputPathObj, InternalModelOptions* optionsObj) +{ + ImportModelFile::Options options; + InternalModelOptions::Convert(optionsObj, &options); + return EditorInternal_Import(inputPathObj, outputPathObj, &options); +} - auto msg = (Char*)ptr; - ptr += length * 2; +DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportAudio(MonoString* inputPathObj, MonoString* outputPathObj, InternalAudioOptions* optionsObj) +{ + ImportAudio::Options options; + InternalAudioOptions::Convert(optionsObj, &options); + return EditorInternal_Import(inputPathObj, outputPathObj, &options); +} - auto msgObj = MUtils::ToString(StringView(msg, length)); +DEFINE_INTERNAL_CALL(void) EditorInternal_GetAudioClipMetadata(AudioClip* clip, int32* originalSize, int32* importedSize) +{ + INTERNAL_CALL_CHECK(clip); + *originalSize = clip->AudioHeader.OriginalSize; + *importedSize = clip->AudioHeader.ImportedSize; +} - mono_array_setref(*outMessages, count, msgObj); - mono_array_set(*outLogTypes, byte, count, type); - mono_array_set(*outLogTimes, int64, count, time); +DEFINE_INTERNAL_CALL(bool) EditorInternal_SaveJsonAsset(MonoString* outputPathObj, MonoString* dataObj, MonoString* dataTypeNameObj) +{ + String outputPath; + MUtils::ToString(outputPathObj, outputPath); + FileSystem::NormalizePath(outputPath); - count++; - } + const auto dataObjPtr = mono_string_to_utf8(dataObj); + StringAnsiView data(dataObjPtr); - const int32 dataLeft = (int32)(end - ptr); - Platform::MemoryCopy(CachedLogData.Get(), ptr, dataLeft); - CachedLogData.Resize(dataLeft); + const auto dataTypeNameObjPtr = mono_string_to_utf8(dataTypeNameObj); + StringAnsiView dataTypeName(dataTypeNameObjPtr); - return count; - } + const bool result = CreateJson::Create(outputPath, data, dataTypeName); - static void SetPlayMode(bool value) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_SetPlayMode") - Editor::IsPlayMode = value; - } + mono_free(dataObjPtr); + mono_free(dataTypeNameObjPtr); - static MonoString* GetProjectPath() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetProjectPath") - return MUtils::ToString(Editor::Project->ProjectPath); - } + return result; +} - static void CloseSplashScreen() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CloseSplashScreen") - Editor::CloseSplashScreen(); - } - - static bool CloneAssetFile(MonoString* dstPathObj, MonoString* srcPathObj, Guid* dstId) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CloneAssetFile") - // Get normalized paths - String dstPath, srcPath; - MUtils::ToString(dstPathObj, dstPath); - MUtils::ToString(srcPathObj, srcPath); - FileSystem::NormalizePath(dstPath); - FileSystem::NormalizePath(srcPath); - - // Call util function - return Content::CloneAssetFile(dstPath, srcPath, *dstId); - } - - enum class NewAssetType - { - Material = 0, - MaterialInstance = 1, - CollisionData = 2, - AnimationGraph = 3, - SkeletonMask = 4, - ParticleEmitter = 5, - ParticleSystem = 6, - SceneAnimation = 7, - MaterialFunction = 8, - ParticleEmitterFunction = 9, - AnimationGraphFunction = 10, - Animation = 11, - }; - - static bool CreateAsset(NewAssetType type, MonoString* outputPathObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CreateAsset") - String tag; - switch (type) - { - case NewAssetType::Material: - tag = AssetsImportingManager::CreateMaterialTag; - break; - case NewAssetType::MaterialInstance: - tag = AssetsImportingManager::CreateMaterialInstanceTag; - break; - case NewAssetType::CollisionData: - tag = AssetsImportingManager::CreateCollisionDataTag; - break; - case NewAssetType::AnimationGraph: - tag = AssetsImportingManager::CreateAnimationGraphTag; - break; - case NewAssetType::SkeletonMask: - tag = AssetsImportingManager::CreateSkeletonMaskTag; - break; - case NewAssetType::ParticleEmitter: - tag = AssetsImportingManager::CreateParticleEmitterTag; - break; - case NewAssetType::ParticleSystem: - tag = AssetsImportingManager::CreateParticleSystemTag; - break; - case NewAssetType::SceneAnimation: - tag = AssetsImportingManager::CreateSceneAnimationTag; - break; - case NewAssetType::MaterialFunction: - tag = AssetsImportingManager::CreateMaterialFunctionTag; - break; - case NewAssetType::ParticleEmitterFunction: - tag = AssetsImportingManager::CreateParticleEmitterFunctionTag; - break; - case NewAssetType::AnimationGraphFunction: - tag = AssetsImportingManager::CreateAnimationGraphFunctionTag; - break; - case NewAssetType::Animation: - tag = AssetsImportingManager::CreateAnimationTag; - break; - default: - return true; - } - - String outputPath; - MUtils::ToString(outputPathObj, outputPath); - FileSystem::NormalizePath(outputPath); - - return AssetsImportingManager::Create(tag, outputPath); - } - - static bool CreateVisualScript(MonoString* outputPathObj, MonoString* baseTypenameObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CreateVisualScript") - String outputPath; - MUtils::ToString(outputPathObj, outputPath); - FileSystem::NormalizePath(outputPath); - String baseTypename; - MUtils::ToString(baseTypenameObj, baseTypename); - return AssetsImportingManager::Create(AssetsImportingManager::CreateVisualScriptTag, outputPath, &baseTypename); - } - - static MonoString* CanImport(MonoString* extensionObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CanImport") - String extension; - MUtils::ToString(extensionObj, extension); - if (extension.Length() > 0 && extension[0] == '.') - extension.Remove(0, 1); - const AssetImporter* importer = AssetsImportingManager::GetImporter(extension); - return importer ? MUtils::ToString(importer->ResultExtension) : nullptr; - } - - static bool Import(MonoString* inputPathObj, MonoString* outputPathObj, void* arg) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_Import") - String inputPath, outputPath; - MUtils::ToString(inputPathObj, inputPath); - MUtils::ToString(outputPathObj, outputPath); - FileSystem::NormalizePath(inputPath); - FileSystem::NormalizePath(outputPath); - - return AssetsImportingManager::Import(inputPath, outputPath, arg); - } - - static bool ImportTexture(MonoString* inputPathObj, MonoString* outputPathObj, InternalTextureOptions* optionsObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_ImportTexture") - ImportTexture::Options options; - InternalTextureOptions::Convert(optionsObj, &options); - - return Import(inputPathObj, outputPathObj, &options); - } - - static bool ImportModel(MonoString* inputPathObj, MonoString* outputPathObj, InternalModelOptions* optionsObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_ImportModel") - ImportModelFile::Options options; - InternalModelOptions::Convert(optionsObj, &options); - - return Import(inputPathObj, outputPathObj, &options); - } - - static bool ImportAudio(MonoString* inputPathObj, MonoString* outputPathObj, InternalAudioOptions* optionsObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_ImportAudio") - ImportAudio::Options options; - InternalAudioOptions::Convert(optionsObj, &options); - - return Import(inputPathObj, outputPathObj, &options); - } - - static void GetAudioClipMetadata(AudioClip* clip, int32* originalSize, int32* importedSize) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetAudioClipMetadata") - INTERNAL_CALL_CHECK(clip); - *originalSize = clip->AudioHeader.OriginalSize; - *importedSize = clip->AudioHeader.ImportedSize; - } - - static bool SaveJsonAsset(MonoString* outputPathObj, MonoString* dataObj, MonoString* dataTypeNameObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_SaveJsonAsset") - String outputPath; - MUtils::ToString(outputPathObj, outputPath); - FileSystem::NormalizePath(outputPath); - - const auto dataObjPtr = mono_string_to_utf8(dataObj); - StringAnsiView data(dataObjPtr); - - const auto dataTypeNameObjPtr = mono_string_to_utf8(dataTypeNameObj); - StringAnsiView dataTypeName(dataTypeNameObjPtr); - - const bool result = CreateJson::Create(outputPath, data, dataTypeName); - - mono_free(dataObjPtr); - mono_free(dataTypeNameObjPtr); - - return result; - } - - static bool GetTextureImportOptions(MonoString* pathObj, InternalTextureOptions* result) - { - SCRIPTING_EXPORT("FlaxEditor.Content.Import.TextureImportEntry::Internal_GetTextureImportOptions") - - String path; - MUtils::ToString(pathObj, path); - FileSystem::NormalizePath(path); - - ImportTexture::Options options; - if (ImportTexture::TryGetImportOptions(path, options)) - { - // Convert into managed storage - InternalTextureOptions::Convert(&options, result); - - return true; - } - - return false; - } - - static void GetModelImportOptions(MonoString* pathObj, InternalModelOptions* result) - { - SCRIPTING_EXPORT("FlaxEditor.Content.Import.ModelImportEntry::Internal_GetModelImportOptions") - // Initialize defaults - ImportModelFile::Options options; - if (const auto* graphicsSettings = GraphicsSettings::Get()) - { - options.GenerateSDF = graphicsSettings->GenerateSDFOnModelImport; - } - - // Get options from model - String path; - MUtils::ToString(pathObj, path); - FileSystem::NormalizePath(path); - ImportModelFile::TryGetImportOptions(path, options); - - // Convert into managed storage - InternalModelOptions::Convert(&options, result); - } - - static bool GetAudioImportOptions(MonoString* pathObj, InternalAudioOptions* result) - { - SCRIPTING_EXPORT("FlaxEditor.Content.Import.AudioImportEntry::Internal_GetAudioImportOptions") - String path; - MUtils::ToString(pathObj, path); - FileSystem::NormalizePath(path); - - ImportAudio::Options options; - if (ImportAudio::TryGetImportOptions(path, options)) - { - // Convert into managed storage - InternalAudioOptions::Convert(&options, result); - - return true; - } - - return false; - } - - static bool CanExport(MonoString* pathObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CanExport") +DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MonoString* pathObj) +{ #if COMPILE_WITH_ASSETS_EXPORTER - String path; - MUtils::ToString(pathObj, path); - FileSystem::NormalizePath(path); + String path; + MUtils::ToString(pathObj, path); + FileSystem::NormalizePath(path); - return AssetsExportingManager::CanExport(path); + return AssetsExportingManager::CanExport(path); #else - return false; + return false; #endif - } +} - static bool Export(MonoString* inputPathObj, MonoString* outputFolderObj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_Export") +DEFINE_INTERNAL_CALL(bool) EditorInternal_Export(MonoString* inputPathObj, MonoString* outputFolderObj) +{ #if COMPILE_WITH_ASSETS_EXPORTER - String inputPath; - MUtils::ToString(inputPathObj, inputPath); - FileSystem::NormalizePath(inputPath); + String inputPath; + MUtils::ToString(inputPathObj, inputPath); + FileSystem::NormalizePath(inputPath); - String outputFolder; - MUtils::ToString(outputFolderObj, outputFolder); - FileSystem::NormalizePath(outputFolder); + String outputFolder; + MUtils::ToString(outputFolderObj, outputFolder); + FileSystem::NormalizePath(outputFolder); - return AssetsExportingManager::Export(inputPath, outputFolder); + return AssetsExportingManager::Export(inputPath, outputFolder); #else - return false; + return false; #endif - } +} - static void CopyCache(Guid* dstId, Guid* srcId) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CopyCache") - ShaderCacheManager::CopyCache(*dstId, *srcId); - } +DEFINE_INTERNAL_CALL(void) EditorInternal_CopyCache(Guid* dstId, Guid* srcId) +{ + ShaderCacheManager::CopyCache(*dstId, *srcId); +} - static void BakeLightmaps(bool cancel) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_BakeLightmaps") - auto builder = ShadowsOfMordor::Builder::Instance(); - if (cancel) - builder->CancelBuild(); - else - builder->Build(); - } +DEFINE_INTERNAL_CALL(void) EditorInternal_BakeLightmaps(bool cancel) +{ + auto builder = ShadowsOfMordor::Builder::Instance(); + if (cancel) + builder->CancelBuild(); + else + builder->Build(); +} - static MonoString* GetShaderAssetSourceCode(BinaryAsset* obj) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetShaderAssetSourceCode") - INTERNAL_CALL_CHECK_RETURN(obj, nullptr); - if (obj->WaitForLoaded()) - DebugLog::ThrowNullReference(); +DEFINE_INTERNAL_CALL(MonoString*) EditorInternal_GetShaderAssetSourceCode(BinaryAsset* obj) +{ + INTERNAL_CALL_CHECK_RETURN(obj, nullptr); + if (obj->WaitForLoaded()) + DebugLog::ThrowNullReference(); - auto lock = obj->Storage->Lock(); + auto lock = obj->Storage->Lock(); - if (obj->LoadChunk(SHADER_FILE_CHUNK_SOURCE)) - return nullptr; + if (obj->LoadChunk(SHADER_FILE_CHUNK_SOURCE)) + return nullptr; - BytesContainer data; - obj->GetChunkData(SHADER_FILE_CHUNK_SOURCE, data); + BytesContainer data; + obj->GetChunkData(SHADER_FILE_CHUNK_SOURCE, data); - Encryption::DecryptBytes((byte*)data.Get(), data.Length()); + Encryption::DecryptBytes((byte*)data.Get(), data.Length()); - const StringAnsiView srcData((const char*)data.Get(), data.Length()); - const String source(srcData); - const auto str = MUtils::ToString(source); + const StringAnsiView srcData((const char*)data.Get(), data.Length()); + const String source(srcData); + const auto str = MUtils::ToString(source); - Encryption::EncryptBytes((byte*)data.Get(), data.Length()); + Encryption::EncryptBytes((byte*)data.Get(), data.Length()); - return str; - } + return str; +} - static bool CookMeshCollision(MonoString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CookMeshCollision") +DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MonoString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit) +{ #if COMPILE_WITH_PHYSICS_COOKING - CollisionCooking::Argument arg; - String path; - MUtils::ToString(pathObj, path); - FileSystem::NormalizePath(path); - arg.Type = type; - arg.Model = modelObj; - arg.ModelLodIndex = modelLodIndex; - arg.MaterialSlotsMask = materialSlotsMask; - arg.ConvexFlags = convexFlags; - arg.ConvexVertexLimit = convexVertexLimit; - return CreateCollisionData::CookMeshCollision(path, arg); + CollisionCooking::Argument arg; + String path; + MUtils::ToString(pathObj, path); + FileSystem::NormalizePath(path); + arg.Type = type; + arg.Model = modelObj; + arg.ModelLodIndex = modelLodIndex; + arg.MaterialSlotsMask = materialSlotsMask; + arg.ConvexFlags = convexFlags; + arg.ConvexVertexLimit = convexVertexLimit; + return CreateCollisionData::CookMeshCollision(path, arg); #else - LOG(Warning, "Collision cooking is disabled."); - return true; + LOG(Warning, "Collision cooking is disabled."); + return true; #endif - } +} - static void GetCollisionWires(CollisionData* collisionData, MonoArray** triangles, MonoArray** indices, int* trianglesCount, int* indicesCount) +DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* collisionData, MonoArray** triangles, MonoArray** indices, int* trianglesCount, int* indicesCount) +{ + if (!collisionData || collisionData->WaitForLoaded() || collisionData->GetOptions().Type == CollisionDataType::None) + return; + + const auto& debugLines = collisionData->GetDebugLines(); + + const int32 linesCount = debugLines.Count() / 2; + mono_gc_wbarrier_generic_store(triangles, (MonoObject*)mono_array_new(mono_domain_get(), Float3::TypeInitializer.GetMonoClass(), debugLines.Count())); + mono_gc_wbarrier_generic_store(indices, (MonoObject*)mono_array_new(mono_domain_get(), mono_get_int32_class(), linesCount * 3)); + + // Use one triangle per debug line + for (int32 i = 0; i < debugLines.Count(); i++) { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetCollisionWires") - if (!collisionData || collisionData->WaitForLoaded() || collisionData->GetOptions().Type == CollisionDataType::None) - return; - - const auto& debugLines = collisionData->GetDebugLines(); - - const int32 linesCount = debugLines.Count() / 2; - mono_gc_wbarrier_generic_store(triangles, (MonoObject*)mono_array_new(mono_domain_get(), Float3::TypeInitializer.GetMonoClass(), debugLines.Count())); - mono_gc_wbarrier_generic_store(indices, (MonoObject*)mono_array_new(mono_domain_get(), mono_get_int32_class(), linesCount * 3)); - - // Use one triangle per debug line - for (int32 i = 0; i < debugLines.Count(); i++) - { - mono_array_set(*triangles, Float3, i, debugLines[i]); - } - int32 iI = 0; - for (int32 i = 0; i < debugLines.Count(); i += 2) - { - mono_array_set(*indices, int32, iI++, i); - mono_array_set(*indices, int32, iI++, i + 1); - mono_array_set(*indices, int32, iI++, i); - } - *trianglesCount = debugLines.Count(); - *indicesCount = linesCount * 3; + mono_array_set(*triangles, Float3, i, debugLines[i]); } - - static void GetEditorBoxWithChildren(Actor* obj, BoundingBox* result) + int32 iI = 0; + for (int32 i = 0; i < debugLines.Count(); i += 2) { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetEditorBoxWithChildren") - INTERNAL_CALL_CHECK(obj); - *result = obj->GetEditorBoxChildren(); + mono_array_set(*indices, int32, iI++, i); + mono_array_set(*indices, int32, iI++, i + 1); + mono_array_set(*indices, int32, iI++, i); } + *trianglesCount = debugLines.Count(); + *indicesCount = linesCount * 3; +} - static void SetOptions(ManagedEditor::InternalOptions* options) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_SetOptions") - ManagedEditor::ManagedEditorOptions = *options; +DEFINE_INTERNAL_CALL(void) EditorInternal_GetEditorBoxWithChildren(Actor* obj, BoundingBox* result) +{ + INTERNAL_CALL_CHECK(obj); + *result = obj->GetEditorBoxChildren(); +} - // Apply options - AssetsImportingManager::UseImportPathRelative = ManagedEditor::ManagedEditorOptions.UseAssetImportPathRelative != 0; - } +DEFINE_INTERNAL_CALL(void) EditorInternal_SetOptions(ManagedEditor::InternalOptions* options) +{ + ManagedEditor::ManagedEditorOptions = *options; - static void DrawNavMesh() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_DrawNavMesh") - Navigation::DrawNavMesh(); - } + // Apply options + AssetsImportingManager::UseImportPathRelative = ManagedEditor::ManagedEditorOptions.UseAssetImportPathRelative != 0; +} - static bool GetIsEveryAssemblyLoaded() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetIsEveryAssemblyLoaded") - return Scripting::IsEveryAssemblyLoaded(); - } +DEFINE_INTERNAL_CALL(void) EditorInternal_DrawNavMesh() +{ + Navigation::DrawNavMesh(); +} - static int32 GetLastProjectOpenedEngineBuild() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetLastProjectOpenedEngineBuild") - return Editor::LastProjectOpenedEngineBuild; - } +DEFINE_INTERNAL_CALL(bool) EditorInternal_GetIsEveryAssemblyLoaded() +{ + return Scripting::IsEveryAssemblyLoaded(); +} - static bool GetIsCSGActive() - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetIsCSGActive") +DEFINE_INTERNAL_CALL(int32) EditorInternal_GetLastProjectOpenedEngineBuild() +{ + return Editor::LastProjectOpenedEngineBuild; +} + +DEFINE_INTERNAL_CALL(bool) EditorInternal_GetIsCSGActive() +{ #if COMPILE_WITH_CSG_BUILDER - return CSG::Builder::IsActive(); + return CSG::Builder::IsActive(); #else - return false; + return false; #endif - } +} - static void RunVisualScriptBreakpointLoopTick(float deltaTime) +DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(float deltaTime) +{ + // Update + Platform::Tick(); + Engine::HasFocus = (Engine::MainWindow && Engine::MainWindow->IsFocused()) || Platform::GetHasFocus(); + if (Engine::HasFocus) { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_RunVisualScriptBreakpointLoopTick") - // Update - Platform::Tick(); - Engine::HasFocus = (Engine::MainWindow && Engine::MainWindow->IsFocused()) || Platform::GetHasFocus(); - if (Engine::HasFocus) + InputDevice::EventQueue inputEvents; + if (Input::Mouse) { - InputDevice::EventQueue inputEvents; - if (Input::Mouse) + if (Input::Mouse->Update(inputEvents)) { - if (Input::Mouse->Update(inputEvents)) - { - Input::Mouse->DeleteObject(); - Input::Mouse = nullptr; - } + Input::Mouse->DeleteObject(); + Input::Mouse = nullptr; } - if (Input::Keyboard) + } + if (Input::Keyboard) + { + if (Input::Keyboard->Update(inputEvents)) { - if (Input::Keyboard->Update(inputEvents)) - { - Input::Keyboard->DeleteObject(); - Input::Keyboard = nullptr; - } + Input::Keyboard->DeleteObject(); + Input::Keyboard = nullptr; } - WindowsManager::WindowsLocker.Lock(); - Window* defaultWindow = nullptr; - for (auto window : WindowsManager::Windows) - { - if (window->IsFocused() && window->GetSettings().AllowInput) - { - defaultWindow = window; - break; - } - } - for (const auto& e : inputEvents) - { - auto window = e.Target ? e.Target : defaultWindow; - if (!window) - continue; - switch (e.Type) - { - // Keyboard events - case InputDevice::EventType::Char: - window->OnCharInput(e.CharData.Char); - break; - case InputDevice::EventType::KeyDown: - window->OnKeyDown(e.KeyData.Key); - break; - case InputDevice::EventType::KeyUp: - window->OnKeyUp(e.KeyData.Key); - break; - // Mouse events - case InputDevice::EventType::MouseDown: - window->OnMouseDown(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button); - break; - case InputDevice::EventType::MouseUp: - window->OnMouseUp(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button); - break; - case InputDevice::EventType::MouseDoubleClick: - window->OnMouseDoubleClick(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button); - break; - case InputDevice::EventType::MouseWheel: - window->OnMouseWheel(window->ScreenToClient(e.MouseWheelData.Position), e.MouseWheelData.WheelDelta); - break; - case InputDevice::EventType::MouseMove: - window->OnMouseMove(window->ScreenToClient(e.MouseData.Position)); - break; - case InputDevice::EventType::MouseLeave: - window->OnMouseLeave(); - break; - } - } - WindowsManager::WindowsLocker.Unlock(); } WindowsManager::WindowsLocker.Lock(); - for (auto& win : WindowsManager::Windows) + Window* defaultWindow = nullptr; + for (auto window : WindowsManager::Windows) { - if (win->IsVisible()) - win->OnUpdate(deltaTime); + if (window->IsFocused() && window->GetSettings().AllowInput) + { + defaultWindow = window; + break; + } + } + for (const auto& e : inputEvents) + { + auto window = e.Target ? e.Target : defaultWindow; + if (!window) + continue; + switch (e.Type) + { + // Keyboard events + case InputDevice::EventType::Char: + window->OnCharInput(e.CharData.Char); + break; + case InputDevice::EventType::KeyDown: + window->OnKeyDown(e.KeyData.Key); + break; + case InputDevice::EventType::KeyUp: + window->OnKeyUp(e.KeyData.Key); + break; + // Mouse events + case InputDevice::EventType::MouseDown: + window->OnMouseDown(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button); + break; + case InputDevice::EventType::MouseUp: + window->OnMouseUp(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button); + break; + case InputDevice::EventType::MouseDoubleClick: + window->OnMouseDoubleClick(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button); + break; + case InputDevice::EventType::MouseWheel: + window->OnMouseWheel(window->ScreenToClient(e.MouseWheelData.Position), e.MouseWheelData.WheelDelta); + break; + case InputDevice::EventType::MouseMove: + window->OnMouseMove(window->ScreenToClient(e.MouseData.Position)); + break; + case InputDevice::EventType::MouseLeave: + window->OnMouseLeave(); + break; + } } WindowsManager::WindowsLocker.Unlock(); - - // Draw - Engine::OnDraw(); } - - struct VisualScriptLocalManaged + WindowsManager::WindowsLocker.Lock(); + for (auto& win : WindowsManager::Windows) { - MonoString* Value; - MonoString* ValueTypeName; - uint32 NodeId; - int32 BoxId; - }; - - static MonoArray* GetVisualScriptLocals(int* localsCount) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetVisualScriptLocals") - MonoArray* result = nullptr; - *localsCount = 0; - const auto stack = VisualScripting::GetThreadStackTop(); - if (stack && stack->Scope) - { - const int32 count = stack->Scope->Parameters.Length() + stack->Scope->ReturnedValues.Count(); - const auto mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptLocal"); - ASSERT(mclass); - result = mono_array_new(mono_domain_get(), mclass->GetNative(), count); - VisualScriptLocalManaged local; - local.NodeId = MAX_uint32; - if (stack->Scope->Parameters.Length() != 0) - { - auto s = stack; - while (s->PreviousFrame && s->PreviousFrame->Scope == stack->Scope) - s = s->PreviousFrame; - if (s) - local.NodeId = s->Node->ID; - } - for (int32 i = 0; i < stack->Scope->Parameters.Length(); i++) - { - auto& v = stack->Scope->Parameters[i]; - local.BoxId = i + 1; - local.Value = MUtils::ToString(v.ToString()); - local.ValueTypeName = MUtils::ToString(v.Type.GetTypeName()); - mono_array_set(result, VisualScriptLocalManaged, i, local); - } - for (int32 i = 0; i < stack->Scope->ReturnedValues.Count(); i++) - { - auto& v = stack->Scope->ReturnedValues[i]; - local.NodeId = v.NodeId; - local.BoxId = v.BoxId; - local.Value = MUtils::ToString(v.Value.ToString()); - local.ValueTypeName = MUtils::ToString(v.Value.Type.GetTypeName()); - mono_array_set(result, VisualScriptLocalManaged, stack->Scope->Parameters.Length() + i, local); - } - *localsCount = count; - } - return result; + if (win->IsVisible()) + win->OnUpdate(deltaTime); } + WindowsManager::WindowsLocker.Unlock(); - struct VisualScriptStackFrameManaged - { - MonoObject* Script; - uint32 NodeId; - int32 BoxId; - }; + // Draw + Engine::OnDraw(); +} - static MonoArray* GetVisualScriptStackFrames(int* stackFramesCount) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetVisualScriptStackFrames") - MonoArray* result = nullptr; - *stackFramesCount = 0; - const auto stack = VisualScripting::GetThreadStackTop(); - if (stack) - { - int32 count = 0; - auto s = stack; - while (s) - { - s = s->PreviousFrame; - count++; - } - const auto mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptStackFrame"); - ASSERT(mclass); - result = mono_array_new(mono_domain_get(), mclass->GetNative(), count); - s = stack; - count = 0; - while (s) - { - VisualScriptStackFrameManaged frame; - frame.Script = s->Script->GetOrCreateManagedInstance(); - frame.NodeId = s->Node->ID; - frame.BoxId = s->Box ? s->Box->ID : MAX_uint32; - mono_array_set(result, VisualScriptStackFrameManaged, count, frame); - s = s->PreviousFrame; - count++; - } - *stackFramesCount = count; - } - return result; - } +struct VisualScriptLocalManaged +{ + MonoString* Value; + MonoString* ValueTypeName; + uint32 NodeId; + int32 BoxId; +}; - static VisualScriptStackFrameManaged GetVisualScriptPreviousScopeFrame() +DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptLocals(int* localsCount) +{ + MonoArray* result = nullptr; + *localsCount = 0; + const auto stack = VisualScripting::GetThreadStackTop(); + if (stack && stack->Scope) { - VisualScriptStackFrameManaged frame; - Platform::MemoryClear(&frame, sizeof(frame)); - const auto stack = VisualScripting::GetThreadStackTop(); - if (stack) + const int32 count = stack->Scope->Parameters.Length() + stack->Scope->ReturnedValues.Count(); + const auto mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptLocal"); + ASSERT(mclass); + result = mono_array_new(mono_domain_get(), mclass->GetNative(), count); + VisualScriptLocalManaged local; + local.NodeId = MAX_uint32; + if (stack->Scope->Parameters.Length() != 0) { auto s = stack; while (s->PreviousFrame && s->PreviousFrame->Scope == stack->Scope) s = s->PreviousFrame; - if (s && s->PreviousFrame) - { - s = s->PreviousFrame; - frame.Script = s->Script->GetOrCreateManagedInstance(); - frame.NodeId = s->Node->ID; - frame.BoxId = s->Box ? s->Box->ID : MAX_uint32; - } + if (s) + local.NodeId = s->Node->ID; } - return frame; + for (int32 i = 0; i < stack->Scope->Parameters.Length(); i++) + { + auto& v = stack->Scope->Parameters[i]; + local.BoxId = i + 1; + local.Value = MUtils::ToString(v.ToString()); + local.ValueTypeName = MUtils::ToString(v.Type.GetTypeName()); + mono_array_set(result, VisualScriptLocalManaged, i, local); + } + for (int32 i = 0; i < stack->Scope->ReturnedValues.Count(); i++) + { + auto& v = stack->Scope->ReturnedValues[i]; + local.NodeId = v.NodeId; + local.BoxId = v.BoxId; + local.Value = MUtils::ToString(v.Value.ToString()); + local.ValueTypeName = MUtils::ToString(v.Value.Type.GetTypeName()); + mono_array_set(result, VisualScriptLocalManaged, stack->Scope->Parameters.Length() + i, local); + } + *localsCount = count; + } + return result; +} + +struct VisualScriptStackFrameManaged +{ + MonoObject* Script; + uint32 NodeId; + int32 BoxId; +}; + +DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptStackFrames(int* stackFramesCount) +{ + MonoArray* result = nullptr; + *stackFramesCount = 0; + const auto stack = VisualScripting::GetThreadStackTop(); + if (stack) + { + int32 count = 0; + auto s = stack; + while (s) + { + s = s->PreviousFrame; + count++; + } + const auto mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptStackFrame"); + ASSERT(mclass); + result = mono_array_new(mono_domain_get(), mclass->GetNative(), count); + s = stack; + count = 0; + while (s) + { + VisualScriptStackFrameManaged frame; + frame.Script = s->Script->GetOrCreateManagedInstance(); + frame.NodeId = s->Node->ID; + frame.BoxId = s->Box ? s->Box->ID : MAX_uint32; + mono_array_set(result, VisualScriptStackFrameManaged, count, frame); + s = s->PreviousFrame; + count++; + } + *stackFramesCount = count; + } + return result; +} + +DEFINE_INTERNAL_CALL(VisualScriptStackFrameManaged) EditorInternal_GetVisualScriptPreviousScopeFrame() +{ + VisualScriptStackFrameManaged frame; + Platform::MemoryClear(&frame, sizeof(frame)); + const auto stack = VisualScripting::GetThreadStackTop(); + if (stack) + { + auto s = stack; + while (s->PreviousFrame && s->PreviousFrame->Scope == stack->Scope) + s = s->PreviousFrame; + if (s && s->PreviousFrame) + { + s = s->PreviousFrame; + frame.Script = s->Script->GetOrCreateManagedInstance(); + frame.NodeId = s->Node->ID; + frame.BoxId = s->Box ? s->Box->ID : MAX_uint32; + } + } + return frame; +} + +DEFINE_INTERNAL_CALL(bool) EditorInternal_EvaluateVisualScriptLocal(VisualScript* script, VisualScriptLocalManaged* local) +{ + Variant v; + if (VisualScripting::Evaluate(script, VisualScripting::GetThreadStackTop()->Instance, local->NodeId, local->BoxId, v)) + { + local->Value = MUtils::ToString(v.ToString()); + local->ValueTypeName = MUtils::ToString(v.Type.GetTypeName()); + return true; + } + return false; +} + +DEFINE_INTERNAL_CALL(void) EditorInternal_DeserializeSceneObject(SceneObject* sceneObject, MonoString* jsonObj) +{ + PROFILE_CPU_NAMED("DeserializeSceneObject"); + + StringAnsi json; + MUtils::ToString(jsonObj, json); + + rapidjson_flax::Document document; + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse(json.Get(), json.Length()); + } + if (document.HasParseError()) + { + Log::JsonParseException(document.GetParseError(), document.GetErrorOffset()); + DebugLog::ThrowException("Failed to parse Json."); } - static bool EvaluateVisualScriptLocal(VisualScript* script, VisualScriptLocalManaged* local) + auto modifier = Cache::ISerializeModifier.Get(); + modifier->EngineBuild = FLAXENGINE_VERSION_BUILD; + Scripting::ObjectsLookupIdMapping.Set(&modifier.Value->IdsMapping); + { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_EvaluateVisualScriptLocal") - Variant v; - if (VisualScripting::Evaluate(script, VisualScripting::GetThreadStackTop()->Instance, local->NodeId, local->BoxId, v)) - { - local->Value = MUtils::ToString(v.ToString()); - local->ValueTypeName = MUtils::ToString(v.Type.GetTypeName()); - return true; - } + PROFILE_CPU_NAMED("Deserialize"); + sceneObject->Deserialize(document, modifier.Value); + } +} + +DEFINE_INTERNAL_CALL(void) EditorInternal_LoadAsset(Guid* id) +{ + Content::LoadAsync(*id); +} + +DEFINE_INTERNAL_CALL(bool) EditorInternal_CanSetToRoot(Prefab* prefab, Actor* targetActor) +{ + // Reference: Prefab::ApplyAll(Actor* targetActor) + if (targetActor->GetPrefabID() != prefab->GetID()) return false; - } - - static void DeserializeSceneObject(SceneObject* sceneObject, MonoString* jsonObj) + if (targetActor->GetPrefabObjectID() != prefab->GetRootObjectId()) { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_DeserializeSceneObject") - PROFILE_CPU_NAMED("DeserializeSceneObject"); - - StringAnsi json; - MUtils::ToString(jsonObj, json); - - rapidjson_flax::Document document; - { - PROFILE_CPU_NAMED("Json.Parse"); - document.Parse(json.Get(), json.Length()); - } - if (document.HasParseError()) - { - Log::JsonParseException(document.GetParseError(), document.GetErrorOffset()); - DebugLog::ThrowException("Failed to parse Json."); - } - - auto modifier = Cache::ISerializeModifier.Get(); - modifier->EngineBuild = FLAXENGINE_VERSION_BUILD; - Scripting::ObjectsLookupIdMapping.Set(&modifier.Value->IdsMapping); - - { - PROFILE_CPU_NAMED("Deserialize"); - sceneObject->Deserialize(document, modifier.Value); - } - } - - static void LoadAsset(Guid* id) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_LoadAsset") - Content::LoadAsync(*id); - } - - static bool CanSetToRoot(Prefab* prefab, Actor* targetActor) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CanSetToRoot") - // Reference: Prefab::ApplyAll(Actor* targetActor) - if (targetActor->GetPrefabID() != prefab->GetID()) + const ISerializable::DeserializeStream** newRootDataPtr = prefab->ObjectsDataCache.TryGet(targetActor->GetPrefabObjectID()); + if (!newRootDataPtr || !*newRootDataPtr) return false; - if (targetActor->GetPrefabObjectID() != prefab->GetRootObjectId()) + const ISerializable::DeserializeStream& newRootData = **newRootDataPtr; + Guid prefabId, prefabObjectID; + if (JsonTools::GetGuidIfValid(prefabId, newRootData, "PrefabID") && JsonTools::GetGuidIfValid(prefabObjectID, newRootData, "PrefabObjectID")) { - const ISerializable::DeserializeStream** newRootDataPtr = prefab->ObjectsDataCache.TryGet(targetActor->GetPrefabObjectID()); - if (!newRootDataPtr || !*newRootDataPtr) + const auto nestedPrefab = Content::Load(prefabId); + if (nestedPrefab && nestedPrefab->GetRootObjectId() != prefabObjectID) return false; - const ISerializable::DeserializeStream& newRootData = **newRootDataPtr; - Guid prefabId, prefabObjectID; - if (JsonTools::GetGuidIfValid(prefabId, newRootData, "PrefabID") && JsonTools::GetGuidIfValid(prefabObjectID, newRootData, "PrefabObjectID")) - { - const auto nestedPrefab = Content::Load(prefabId); - if (nestedPrefab && nestedPrefab->GetRootObjectId() != prefabObjectID) - return false; - } } + } + return true; +} + +DEFINE_INTERNAL_CALL(float) EditorInternal_GetAnimationTime(AnimatedModel* animatedModel) +{ + return animatedModel && animatedModel->GraphInstance.State.Count() == 1 ? animatedModel->GraphInstance.State[0].Animation.TimePosition : 0.0f; +} + +DEFINE_INTERNAL_CALL(void) EditorInternal_SetAnimationTime(AnimatedModel* animatedModel, float time) +{ + if (animatedModel && animatedModel->GraphInstance.State.Count() == 1) + animatedModel->GraphInstance.State[0].Animation.TimePosition = time; +} + +DEFINE_INTERNAL_CALL(MonoReflectionType*) CustomEditorsUtilInternal_GetCustomEditor(MonoReflectionType* targetType) +{ + return CustomEditorsUtil::GetCustomEditor(targetType); +} + +DEFINE_INTERNAL_CALL(bool) TextureImportEntryInternal_GetTextureImportOptions(MonoString* pathObj, InternalTextureOptions* result) +{ + String path; + MUtils::ToString(pathObj, path); + FileSystem::NormalizePath(path); + ImportTexture::Options options; + if (ImportTexture::TryGetImportOptions(path, options)) + { + // Convert into managed storage + InternalTextureOptions::Convert(&options, result); + return true; + } + return false; +} + +DEFINE_INTERNAL_CALL(void) ModelImportEntryInternal_GetModelImportOptions(MonoString* pathObj, InternalModelOptions* result) +{ + // Initialize defaults + ImportModelFile::Options options; + if (const auto* graphicsSettings = GraphicsSettings::Get()) + { + options.GenerateSDF = graphicsSettings->GenerateSDFOnModelImport; + } + + // Get options from model + String path; + MUtils::ToString(pathObj, path); + FileSystem::NormalizePath(path); + ImportModelFile::TryGetImportOptions(path, options); + + // Convert into managed storage + InternalModelOptions::Convert(&options, result); +} + +DEFINE_INTERNAL_CALL(bool) AudioImportEntryInternal_GetAudioImportOptions(MonoString* pathObj, InternalAudioOptions* result) +{ + String path; + MUtils::ToString(pathObj, path); + FileSystem::NormalizePath(path); + + ImportAudio::Options options; + if (ImportAudio::TryGetImportOptions(path, options)) + { + // Convert into managed storage + InternalAudioOptions::Convert(&options, result); + return true; } - static float GetAnimationTime(AnimatedModel* animatedModel) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetAnimationTime") - return animatedModel && animatedModel->GraphInstance.State.Count() == 1 ? animatedModel->GraphInstance.State[0].Animation.TimePosition : 0.0f; - } + return false; +} - static void SetAnimationTime(AnimatedModel* animatedModel, float time) - { - SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_SetAnimationTime") - if (animatedModel && animatedModel->GraphInstance.State.Count() == 1) - animatedModel->GraphInstance.State[0].Animation.TimePosition = time; - } +DEFINE_INTERNAL_CALL(MonoArray*) LayersAndTagsSettingsInternal_GetCurrentLayers(int* layersCount) +{ + *layersCount = Math::Max(1, Level::GetNonEmptyLayerNamesCount()); + return MUtils::ToArray(Span(Level::Layers, *layersCount)); +} +DEFINE_INTERNAL_CALL(void) GameSettingsInternal_Apply() +{ + LOG(Info, "Apply game settings"); + GameSettings::Load(); +} + +class ManagedEditorInternal +{ +public: static void InitRuntime() { - ADD_INTERNAL_CALL("FlaxEditor.Editor::IsDevInstance", &IsDevInstance); - ADD_INTERNAL_CALL("FlaxEditor.Editor::IsOfficialBuild", &IsOfficialBuild); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_IsPlayMode", &IsPlayMode); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_ReadOutputLogs", &ReadOutputLogs); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SetPlayMode", &SetPlayMode); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetProjectPath", &GetProjectPath); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_Import", &Import); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_ImportTexture", &ImportTexture); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_ImportModel", &ImportModel); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_ImportAudio", &ImportAudio); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetAudioClipMetadata", &GetAudioClipMetadata); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SaveJsonAsset", &SaveJsonAsset); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CopyCache", &CopyCache); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CloneAssetFile", &CloneAssetFile); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_BakeLightmaps", &BakeLightmaps); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetShaderAssetSourceCode", &GetShaderAssetSourceCode); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CookMeshCollision", &CookMeshCollision); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetCollisionWires", &GetCollisionWires); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetEditorBoxWithChildren", &GetEditorBoxWithChildren); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SetOptions", &SetOptions); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_DrawNavMesh", &DrawNavMesh); - ADD_INTERNAL_CALL("FlaxEditor.CustomEditors.CustomEditorsUtil::Internal_GetCustomEditor", &CustomEditorsUtilInternal::GetCustomEditor); - ADD_INTERNAL_CALL("FlaxEditor.Content.Import.TextureImportEntry::Internal_GetTextureImportOptions", &GetTextureImportOptions); - ADD_INTERNAL_CALL("FlaxEditor.Content.Import.ModelImportEntry::Internal_GetModelImportOptions", &GetModelImportOptions); - ADD_INTERNAL_CALL("FlaxEditor.Content.Import.AudioImportEntry::Internal_GetAudioImportOptions", &GetAudioImportOptions); - ADD_INTERNAL_CALL("FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentLayers", &LayersAndTagsSettingsInternal::GetCurrentLayers); - ADD_INTERNAL_CALL("FlaxEditor.Content.Settings.GameSettings::Apply", &GameSettingsInternal1::Apply); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CloseSplashScreen", &CloseSplashScreen); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CreateAsset", &CreateAsset); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CreateVisualScript", &CreateVisualScript); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CanImport", &CanImport); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CanExport", &CanExport); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_Export", &Export); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetIsEveryAssemblyLoaded", &GetIsEveryAssemblyLoaded); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetLastProjectOpenedEngineBuild", &GetLastProjectOpenedEngineBuild); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetIsCSGActive", &GetIsCSGActive); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_RunVisualScriptBreakpointLoopTick", &RunVisualScriptBreakpointLoopTick); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetVisualScriptLocals", &GetVisualScriptLocals); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetVisualScriptStackFrames", &GetVisualScriptStackFrames); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetVisualScriptPreviousScopeFrame", &GetVisualScriptPreviousScopeFrame); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_EvaluateVisualScriptLocal", &EvaluateVisualScriptLocal); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_DeserializeSceneObject", &DeserializeSceneObject); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_LoadAsset", &LoadAsset); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CanSetToRoot", &CanSetToRoot); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetAnimationTime", &GetAnimationTime); - ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SetAnimationTime", &SetAnimationTime); + ADD_INTERNAL_CALL("FlaxEditor.Editor::IsDevInstance", &EditorInternal_IsDevInstance); + ADD_INTERNAL_CALL("FlaxEditor.Editor::IsOfficialBuild", &EditorInternal_IsOfficialBuild); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_IsPlayMode", &EditorInternal_IsPlayMode); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_ReadOutputLogs", &EditorInternal_ReadOutputLogs); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SetPlayMode", &EditorInternal_SetPlayMode); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetProjectPath", &EditorInternal_GetProjectPath); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_Import", &EditorInternal_Import); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_ImportTexture", &EditorInternal_ImportTexture); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_ImportModel", &EditorInternal_ImportModel); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_ImportAudio", &EditorInternal_ImportAudio); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetAudioClipMetadata", &EditorInternal_GetAudioClipMetadata); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SaveJsonAsset", &EditorInternal_SaveJsonAsset); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CopyCache", &EditorInternal_CopyCache); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CloneAssetFile", &EditorInternal_CloneAssetFile); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_BakeLightmaps", &EditorInternal_BakeLightmaps); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetShaderAssetSourceCode", &EditorInternal_GetShaderAssetSourceCode); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CookMeshCollision", &EditorInternal_CookMeshCollision); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetCollisionWires", &EditorInternal_GetCollisionWires); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetEditorBoxWithChildren", &EditorInternal_GetEditorBoxWithChildren); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SetOptions", &EditorInternal_SetOptions); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_DrawNavMesh", &EditorInternal_DrawNavMesh); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CloseSplashScreen", &EditorInternal_CloseSplashScreen); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CreateAsset", &EditorInternal_CreateAsset); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CreateVisualScript", &EditorInternal_CreateVisualScript); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CanImport", &EditorInternal_CanImport); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CanExport", &EditorInternal_CanExport); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_Export", &EditorInternal_Export); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetIsEveryAssemblyLoaded", &EditorInternal_GetIsEveryAssemblyLoaded); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetLastProjectOpenedEngineBuild", &EditorInternal_GetLastProjectOpenedEngineBuild); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetIsCSGActive", &EditorInternal_GetIsCSGActive); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_RunVisualScriptBreakpointLoopTick", &EditorInternal_RunVisualScriptBreakpointLoopTick); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetVisualScriptLocals", &EditorInternal_GetVisualScriptLocals); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetVisualScriptStackFrames", &EditorInternal_GetVisualScriptStackFrames); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetVisualScriptPreviousScopeFrame", &EditorInternal_GetVisualScriptPreviousScopeFrame); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_EvaluateVisualScriptLocal", &EditorInternal_EvaluateVisualScriptLocal); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_DeserializeSceneObject", &EditorInternal_DeserializeSceneObject); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_LoadAsset", &EditorInternal_LoadAsset); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CanSetToRoot", &EditorInternal_CanSetToRoot); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetAnimationTime", &EditorInternal_GetAnimationTime); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SetAnimationTime", &EditorInternal_SetAnimationTime); + ADD_INTERNAL_CALL("FlaxEditor.CustomEditors.CustomEditorsUtil::Internal_GetCustomEditor", &CustomEditorsUtilInternal_GetCustomEditor); + ADD_INTERNAL_CALL("FlaxEditor.Content.Import.TextureImportEntry::Internal_GetTextureImportOptions", &TextureImportEntryInternal_GetTextureImportOptions); + ADD_INTERNAL_CALL("FlaxEditor.Content.Import.ModelImportEntry::Internal_GetModelImportOptions", &ModelImportEntryInternal_GetModelImportOptions); + ADD_INTERNAL_CALL("FlaxEditor.Content.Import.AudioImportEntry::Internal_GetAudioImportOptions", &AudioImportEntryInternal_GetAudioImportOptions); + ADD_INTERNAL_CALL("FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentLayers", &LayersAndTagsSettingsInternal_GetCurrentLayers); + ADD_INTERNAL_CALL("FlaxEditor.Content.Settings.GameSettings::Apply", &GameSettingsInternal_Apply); } }; diff --git a/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp b/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp index 3f1e771e0..fc3e0d225 100644 --- a/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp +++ b/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp @@ -49,42 +49,36 @@ struct InternalImpulse static_assert(sizeof(InternalImpulse) == sizeof(AnimGraphImpulse), "Please update managed impulse type for Anim Graph to match the C++ backend data layout."); -namespace AnimGraphInternal +DEFINE_INTERNAL_CALL(bool) AnimGraphInternal_HasConnection(InternalContext* context, int32 boxId) { - bool HasConnection(InternalContext* context, int32 boxId) - { - SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_HasConnection") - const auto box = context->Node->TryGetBox(boxId); - if (box == nullptr) - DebugLog::ThrowArgumentOutOfRange("boxId"); - return box->HasConnection(); - } + const auto box = context->Node->TryGetBox(boxId); + if (box == nullptr) + DebugLog::ThrowArgumentOutOfRange("boxId"); + return box->HasConnection(); +} - MonoObject* GetInputValue(InternalContext* context, int32 boxId) - { - SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_GetInputValue") - const auto box = context->Node->TryGetBox(boxId); - if (box == nullptr) - DebugLog::ThrowArgumentOutOfRange("boxId"); - if (!box->HasConnection()) - DebugLog::ThrowArgument("boxId", "This box has no connection. Use HasConnection to check if can get input value."); +DEFINE_INTERNAL_CALL(MonoObject*) AnimGraphInternal_GetInputValue(InternalContext* context, int32 boxId) +{ + const auto box = context->Node->TryGetBox(boxId); + if (box == nullptr) + DebugLog::ThrowArgumentOutOfRange("boxId"); + if (!box->HasConnection()) + DebugLog::ThrowArgument("boxId", "This box has no connection. Use HasConnection to check if can get input value."); - Variant value = Variant::Null; - context->GraphExecutor->GetInputValue(box, value); + Variant value = Variant::Null; + context->GraphExecutor->GetInputValue(box, value); - // Cast value to prevent implicit value conversion issues and handling this on C# side - if (!(box->Type.Type == VariantType::Void && value.Type.Type == VariantType::Pointer)) - value = Variant::Cast(value, box->Type); - return MUtils::BoxVariant(value); - } + // Cast value to prevent implicit value conversion issues and handling this on C# side + if (!(box->Type.Type == VariantType::Void && value.Type.Type == VariantType::Pointer)) + value = Variant::Cast(value, box->Type); + return MUtils::BoxVariant(value); +} - AnimGraphImpulse* GetOutputImpulseData(InternalContext* context) - { - SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData") - const auto nodes = context->Node->GetNodes(context->GraphExecutor); - context->GraphExecutor->InitNodes(nodes); - return nodes; - } +DEFINE_INTERNAL_CALL(AnimGraphImpulse*) AnimGraphInternal_GetOutputImpulseData(InternalContext* context) +{ + const auto nodes = context->Node->GetNodes(context->GraphExecutor); + context->GraphExecutor->InitNodes(nodes); + return nodes; } #endif @@ -92,9 +86,9 @@ namespace AnimGraphInternal void AnimGraphExecutor::initRuntime() { #if USE_MONO - ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_HasConnection", &AnimGraphInternal::HasConnection); - ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetInputValue", &AnimGraphInternal::GetInputValue); - ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData", &AnimGraphInternal::GetOutputImpulseData); + ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_HasConnection", &AnimGraphInternal_HasConnection); + ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetInputValue", &AnimGraphInternal_GetInputValue); + ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData", &AnimGraphInternal_GetOutputImpulseData); #endif } diff --git a/Source/Engine/Core/Config/GameSettings.cs b/Source/Engine/Core/Config/GameSettings.cs index 15a6e902e..81520c019 100644 --- a/Source/Engine/Core/Config/GameSettings.cs +++ b/Source/Engine/Core/Config/GameSettings.cs @@ -563,7 +563,7 @@ namespace FlaxEditor.Content.Settings /// /// Loads the current game settings asset and applies it to the engine runtime configuration. /// - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Settings.GameSettings::Apply")] + [LibraryImport("FlaxEngine", EntryPoint = "GameSettingsInternal_Apply")] public static partial void Apply(); #endif } diff --git a/Source/Engine/Core/Config/LayersAndTagsSettings.cs b/Source/Engine/Core/Config/LayersAndTagsSettings.cs index 151cf767f..c0f333548 100644 --- a/Source/Engine/Core/Config/LayersAndTagsSettings.cs +++ b/Source/Engine/Core/Config/LayersAndTagsSettings.cs @@ -31,7 +31,7 @@ namespace FlaxEditor.Content.Settings return GetCurrentLayers(out int _); } - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentLayers", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "LayersAndTagsSettingsInternal_GetCurrentLayers", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "layerCount")] internal static partial string[] GetCurrentLayers(out int layerCount); } diff --git a/Source/Engine/Engine/DebugLogHandler.cs b/Source/Engine/Engine/DebugLogHandler.cs index 657a7fdf6..b9e69bd7f 100644 --- a/Source/Engine/Engine/DebugLogHandler.cs +++ b/Source/Engine/Engine/DebugLogHandler.cs @@ -66,13 +66,13 @@ namespace FlaxEngine Debug.Logger.LogException(exception); } - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.DebugLogHandler::Internal_LogWrite", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "DebugLogHandlerInternal_LogWrite", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_LogWrite(LogType level, string msg); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.DebugLogHandler::Internal_Log", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "DebugLogHandlerInternal_Log", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_Log(LogType level, string msg, IntPtr obj, string stackTrace); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.DebugLogHandler::Internal_LogException", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "DebugLogHandlerInternal_LogException", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_LogException([MarshalUsing(typeof(FlaxEngine.ExceptionMarshaller))] Exception exception, IntPtr obj); [SecuritySafeCritical] diff --git a/Source/Engine/Platform/Base/PlatformBase.h b/Source/Engine/Platform/Base/PlatformBase.h index 25d4b1d65..e7800c94d 100644 --- a/Source/Engine/Platform/Base/PlatformBase.h +++ b/Source/Engine/Platform/Base/PlatformBase.h @@ -175,7 +175,6 @@ public: /// Size of the memory to copy in bytes FORCE_INLINE static void MemoryCopy(void* dst, const void* src, uint64 size) { - SCRIPTING_EXPORT("FlaxEngine.Utils::MemoryCopy") memcpy(dst, src, static_cast(size)); } @@ -197,7 +196,6 @@ public: /// Size of the memory to clear in bytes FORCE_INLINE static void MemoryClear(void* dst, uint64 size) { - SCRIPTING_EXPORT("FlaxEngine.Utils::MemoryClear") memset(dst, 0, static_cast(size)); } @@ -209,7 +207,6 @@ public: /// Size of the memory to compare in bytes. FORCE_INLINE static int32 MemoryCompare(const void* buf1, const void* buf2, uint64 size) { - SCRIPTING_EXPORT("FlaxEngine.Utils::MemoryCompare") return memcmp(buf1, buf2, static_cast(size)); } diff --git a/Source/Engine/Scripting/InternalCalls.h b/Source/Engine/Scripting/InternalCalls.h index 7d771e1df..cb6df4c9d 100644 --- a/Source/Engine/Scripting/InternalCalls.h +++ b/Source/Engine/Scripting/InternalCalls.h @@ -29,12 +29,20 @@ struct FLAXENGINE_API VTableFunctionInjector *VTableAddr = OriginalValue; } }; +#elif defined(_MSC_VER) +#define MSVC_FUNC_EXPORT(name) __pragma(comment(linker, "/EXPORT:" #name "=" __FUNCDNAME__)) #endif #if USE_MONO +#if USE_NETCORE +#define ADD_INTERNAL_CALL(fullName, method) +#define DEFINE_INTERNAL_CALL(returnType) extern "C" DLLEXPORT returnType +#else extern "C" FLAXENGINE_API void mono_add_internal_call(const char* name, const void* method); #define ADD_INTERNAL_CALL(fullName, method) mono_add_internal_call(fullName, (const void*)method) +#define DEFINE_INTERNAL_CALL(returnType) static returnType +#endif #if BUILD_RELEASE && 0 @@ -76,9 +84,7 @@ extern "C" FLAXENGINE_API void mono_add_internal_call(const char* name, const vo #else -extern void DotNetAddInternalCall(const wchar_t* fullName, void* function); - -#define ADD_INTERNAL_CALL(fullName, method) DotNetAddInternalCall(TEXT(fullName), (void*)(method)) +#define ADD_INTERNAL_CALL(fullName, method) #define INTERNAL_CALL_CHECK(obj) #define INTERNAL_CALL_CHECK_EXP(expression) #define INTERNAL_CALL_CHECK_RETURN(obj, defaultValue) diff --git a/Source/Engine/Scripting/Object.cs b/Source/Engine/Scripting/Object.cs index 2d5516d24..21c68fcd2 100644 --- a/Source/Engine/Scripting/Object.cs +++ b/Source/Engine/Scripting/Object.cs @@ -240,7 +240,7 @@ namespace FlaxEngine /// /// The pointer to the unmanaged (native) object. /// The object. - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::FromUnmanagedPtr", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] public static partial Object FromUnmanagedPtr(IntPtr ptr); /// @@ -251,34 +251,34 @@ namespace FlaxEngine #region Internal Calls - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_Create1", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create1", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial Object Internal_Create1([MarshalUsing(typeof(SystemTypeMarshaller))] Type type); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_Create2", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create2", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial Object Internal_Create2(string typeName); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_ManagedInstanceCreated", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceCreated", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_ManagedInstanceCreated(Object managedInstance); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_ManagedInstanceDeleted", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceDeleted", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_ManagedInstanceDeleted(IntPtr nativeInstance); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_Destroy", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Destroy", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_Destroy(IntPtr obj, float timeLeft); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial string Internal_GetTypeName(IntPtr obj); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_FindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial Object Internal_FindObject(ref Guid id, [MarshalUsing(typeof(SystemTypeMarshaller))] Type type); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_TryFindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_TryFindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial Object Internal_TryFindObject(ref Guid id, [MarshalUsing(typeof(SystemTypeMarshaller))] Type type); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_ChangeID", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ChangeID", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial void Internal_ChangeID(IntPtr obj, ref Guid id); - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_GetUnmanagedInterface", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetUnmanagedInterface", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] internal static partial IntPtr Internal_GetUnmanagedInterface(IntPtr obj, [MarshalUsing(typeof(SystemTypeMarshaller))] Type type); #endregion diff --git a/Source/Engine/Scripting/Scripting.Internal.cpp b/Source/Engine/Scripting/Scripting.Internal.cpp index 70f6112d9..e940271ca 100644 --- a/Source/Engine/Scripting/Scripting.Internal.cpp +++ b/Source/Engine/Scripting/Scripting.Internal.cpp @@ -20,7 +20,7 @@ #if USE_MONO -namespace ProfilerInternal +namespace { #if COMPILE_WITH_PROFILER Array> ManagedEventsGPU; @@ -37,74 +37,86 @@ namespace ProfilerInternal ChunkedArray ManagedSourceLocations; #endif #endif +} - void BeginEvent(MonoString* nameObj) - { - SCRIPTING_EXPORT("FlaxEngine.Profiler::BeginEvent") +DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(MonoString* nameObj) +{ #if COMPILE_WITH_PROFILER - const StringView name((const Char*)mono_string_chars(nameObj), mono_string_length(nameObj)); - ProfilerCPU::BeginEvent(*name); + const StringView name((const Char*)mono_string_chars(nameObj), mono_string_length(nameObj)); + ProfilerCPU::BeginEvent(*name); #if TRACY_ENABLE #if PROFILE_CPU_USE_TRANSIENT_DATA - tracy::ScopedZone::Begin(__LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name.Get(), name.Length() ); + tracy::ScopedZone::Begin(__LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name.Get(), name.Length() ); #else - ScopeLock lock(ManagedSourceLocationsLocker); - tracy::SourceLocationData* srcLoc = nullptr; - for (auto e = ManagedSourceLocations.Begin(); e.IsNotEnd(); ++e) - { - if (name == e->Name) - { - srcLoc = &e->SrcLocation; - break; - } - } - if (!srcLoc) - { - auto& e = ManagedSourceLocations.AddOne(); - e.Name = name; - e.NameAnsi = name.Get(); - srcLoc = &e.SrcLocation; - srcLoc->name = e.NameAnsi.Get(); - srcLoc->function = nullptr; - srcLoc->file = nullptr; - srcLoc->line = 0; - srcLoc->color = 0; - } - //static constexpr tracy::SourceLocationData tracySrcLoc{ nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; - tracy::ScopedZone::Begin(srcLoc); -#endif -#endif -#endif - } - - void EndEvent() + ScopeLock lock(ManagedSourceLocationsLocker); + tracy::SourceLocationData* srcLoc = nullptr; + for (auto e = ManagedSourceLocations.Begin(); e.IsNotEnd(); ++e) { - SCRIPTING_EXPORT("FlaxEngine.Profiler::EndEvent") + if (name == e->Name) + { + srcLoc = &e->SrcLocation; + break; + } + } + if (!srcLoc) + { + auto& e = ManagedSourceLocations.AddOne(); + e.Name = name; + e.NameAnsi = name.Get(); + srcLoc = &e.SrcLocation; + srcLoc->name = e.NameAnsi.Get(); + srcLoc->function = nullptr; + srcLoc->file = nullptr; + srcLoc->line = 0; + srcLoc->color = 0; + } + //static constexpr tracy::SourceLocationData tracySrcLoc{ nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; + tracy::ScopedZone::Begin(srcLoc); +#endif +#endif +#endif +} + +DEFINE_INTERNAL_CALL(void) ProfilerInternal_EndEvent() +{ #if COMPILE_WITH_PROFILER #if TRACY_ENABLE - tracy::ScopedZone::End(); + tracy::ScopedZone::End(); #endif - ProfilerCPU::EndEvent(); + ProfilerCPU::EndEvent(); #endif - } +} - void BeginEventGPU(MonoString* nameObj) - { - SCRIPTING_EXPORT("FlaxEngine.Profiler::BeginEventGPU") +DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(MonoString* nameObj) +{ #if COMPILE_WITH_PROFILER - const auto index = ProfilerGPU::BeginEvent((const Char*)mono_string_chars(nameObj)); - ManagedEventsGPU.Push(index); + const auto index = ProfilerGPU::BeginEvent((const Char*)mono_string_chars(nameObj)); + ManagedEventsGPU.Push(index); #endif - } +} - void EndEventGPU() - { - SCRIPTING_EXPORT("FlaxEngine.Profiler::EndEventGPU") +DEFINE_INTERNAL_CALL(void) ProfilerInternal_EndEventGPU() +{ #if COMPILE_WITH_PROFILER - const auto index = ManagedEventsGPU.Pop(); - ProfilerGPU::EndEvent(index); + const auto index = ManagedEventsGPU.Pop(); + ProfilerGPU::EndEvent(index); #endif - } +} + +DEFINE_INTERNAL_CALL(bool) ScriptingInternal_HasGameModulesLoaded() +{ + return Scripting::HasGameModulesLoaded(); +} + +DEFINE_INTERNAL_CALL(bool) ScriptingInternal_IsTypeFromGameScripts(MonoReflectionType* type) +{ + return Scripting::IsTypeFromGameScripts(Scripting::FindClass(MUtils::GetClass(type))); +} + +DEFINE_INTERNAL_CALL(void) ScriptingInternal_FlushRemovedObjects() +{ + ASSERT(IsInMainThread()); + ObjectsRemovalService::Flush(); } #endif @@ -112,41 +124,18 @@ namespace ProfilerInternal class ScriptingInternal { public: -#if USE_MONO - static bool HasGameModulesLoaded() - { - SCRIPTING_EXPORT("FlaxEngine.Scripting::HasGameModulesLoaded") - return Scripting::HasGameModulesLoaded(); - } - - static bool IsTypeFromGameScripts(MonoReflectionType* type) - { - SCRIPTING_EXPORT("FlaxEngine.Scripting::IsTypeFromGameScripts") - return Scripting::IsTypeFromGameScripts(Scripting::FindClass(MUtils::GetClass(type))); - } - - static void FlushRemovedObjects() - { - SCRIPTING_EXPORT("FlaxEngine.Scripting::FlushRemovedObjects") - ASSERT(IsInMainThread()); - ObjectsRemovalService::Flush(); - } -#endif - static void InitRuntime() { -#if USE_MONO // Scripting API - ADD_INTERNAL_CALL("FlaxEngine.Scripting::HasGameModulesLoaded", &HasGameModulesLoaded); - ADD_INTERNAL_CALL("FlaxEngine.Scripting::IsTypeFromGameScripts", &IsTypeFromGameScripts); - ADD_INTERNAL_CALL("FlaxEngine.Scripting::FlushRemovedObjects", &FlushRemovedObjects); + ADD_INTERNAL_CALL("FlaxEngine.Scripting::HasGameModulesLoaded", &ScriptingInternal_HasGameModulesLoaded); + ADD_INTERNAL_CALL("FlaxEngine.Scripting::IsTypeFromGameScripts", &ScriptingInternal_IsTypeFromGameScripts); + ADD_INTERNAL_CALL("FlaxEngine.Scripting::FlushRemovedObjects", &ScriptingInternal_FlushRemovedObjects); // Profiler API - ADD_INTERNAL_CALL("FlaxEngine.Profiler::BeginEvent", &ProfilerInternal::BeginEvent); - ADD_INTERNAL_CALL("FlaxEngine.Profiler::EndEvent", &ProfilerInternal::EndEvent); - ADD_INTERNAL_CALL("FlaxEngine.Profiler::BeginEventGPU", &ProfilerInternal::BeginEventGPU); - ADD_INTERNAL_CALL("FlaxEngine.Profiler::EndEventGPU", &ProfilerInternal::EndEventGPU); -#endif + ADD_INTERNAL_CALL("FlaxEngine.Profiler::BeginEvent", &ProfilerInternal_BeginEvent); + ADD_INTERNAL_CALL("FlaxEngine.Profiler::EndEvent", &ProfilerInternal_EndEvent); + ADD_INTERNAL_CALL("FlaxEngine.Profiler::BeginEventGPU", &ProfilerInternal_BeginEventGPU); + ADD_INTERNAL_CALL("FlaxEngine.Profiler::EndEventGPU", &ProfilerInternal_EndEventGPU); } }; diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index 99446c220..5c0e6a400 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -201,35 +201,30 @@ bool ScriptingService::Init() void ScriptingService::Update() { PROFILE_CPU_NAMED("Scripting::Update"); - INVOKE_EVENT(Update); } void ScriptingService::LateUpdate() { PROFILE_CPU_NAMED("Scripting::LateUpdate"); - INVOKE_EVENT(LateUpdate); } void ScriptingService::FixedUpdate() { PROFILE_CPU_NAMED("Scripting::FixedUpdate"); - INVOKE_EVENT(FixedUpdate); } void ScriptingService::Draw() { PROFILE_CPU_NAMED("Scripting::Draw"); - INVOKE_EVENT(Draw); } void ScriptingService::BeforeExit() { PROFILE_CPU_NAMED("Scripting::BeforeExit"); - INVOKE_EVENT(Exit); } @@ -927,7 +922,6 @@ ScriptingObject* Scripting::FindObject(const MObject* managedInstance) void Scripting::OnManagedInstanceDeleted(ScriptingObject* obj) { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_ManagedInstanceDeleted") PROFILE_CPU(); ASSERT(obj); diff --git a/Source/Engine/Scripting/Scripting.cs b/Source/Engine/Scripting/Scripting.cs index 393a20af7..410f372f5 100644 --- a/Source/Engine/Scripting/Scripting.cs +++ b/Source/Engine/Scripting/Scripting.cs @@ -310,7 +310,7 @@ namespace FlaxEngine /// Returns true if game scripts assembly has been loaded. /// /// True if game scripts assembly is loaded, otherwise false. - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Scripting::HasGameModulesLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_HasGameModulesLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] public static partial bool HasGameModulesLoaded(); @@ -318,14 +318,14 @@ namespace FlaxEngine /// Returns true if given type is from one of the game scripts assemblies. /// /// True if the type is from game assembly, otherwise false. - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Scripting::IsTypeFromGameScripts", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_IsTypeFromGameScripts", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] [return: MarshalAs(UnmanagedType.U1)] public static partial bool IsTypeFromGameScripts([MarshalUsing(typeof(SystemTypeMarshaller))] Type type); /// /// Flushes the removed objects (disposed objects using Object.Destroy). /// - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Scripting::FlushRemovedObjects", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_FlushRemovedObjects", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] public static partial void FlushRemovedObjects(); } @@ -341,26 +341,26 @@ namespace FlaxEngine /// Begins profiling a piece of code with a custom label. /// /// The name of the event. - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Profiler::BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] public static partial void BeginEvent(string name); /// /// Ends profiling an event. /// - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Profiler::EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] public static partial void EndEvent(); /// /// Begins GPU profiling a piece of code with a custom label. /// /// The name of the event. - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Profiler::BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] public static partial void BeginEventGPU(string name); /// /// Ends GPU profiling an event. /// - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Profiler::EndEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] + [LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))] public static partial void EndEventGPU(); } } diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index 3cef7e420..e4ffbffae 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -221,6 +221,16 @@ void ScriptingObject::ChangeID(const Guid& newId) _type.GetType().Module->OnObjectIdChanged(this, prevId); } +void ScriptingObject::SetManagedInstance(MonoObject* instance) +{ + ASSERT(_gcHandle == 0); +#if USE_NETCORE + _gcHandle = (MGCHandle)instance; +#else + _gcHandle = MUtils::NewGCHandle(instance, false); +#endif +} + void ScriptingObject::OnManagedInstanceDeleted() { // Release the handle @@ -444,6 +454,16 @@ ManagedScriptingObject::ManagedScriptingObject(const SpawnParams& params) { } +void ManagedScriptingObject::SetManagedInstance(MonoObject* instance) +{ + ASSERT(_gcHandle == 0); +#if USE_NETCORE + _gcHandle = (MGCHandle)instance; +#else + _gcHandle = MUtils::NewGCHandleWeakref(instance, false); +#endif +} + void ManagedScriptingObject::OnManagedInstanceDeleted() { // Base @@ -508,302 +528,274 @@ PersistentScriptingObject::PersistentScriptingObject(const SpawnParams& params) { } +#if !COMPILE_WITHOUT_CSHARP + +DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create1(MonoReflectionType* type) +{ + // Peek class for that type (handle generic class cases) + if (!type) + DebugLog::ThrowArgumentNull("type"); + MonoType* monoType = mono_reflection_type_get_type(type); + const int32 monoTypeType = mono_type_get_type(monoType); + if (monoTypeType == MONO_TYPE_GENERICINST) + { + LOG(Error, "Generic scripts are not supported."); + return nullptr; + } + MonoClass* typeClass = mono_type_get_class(monoType); + if (typeClass == nullptr) + { + LOG(Error, "Invalid type."); + return nullptr; + } + + // Get the assembly with that class + auto module = ManagedBinaryModule::FindModule(typeClass); + if (module == nullptr) + { + LOG(Error, "Cannot find scripting assembly for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + return nullptr; + } + + // Try to find the scripting type for this class + int32 typeIndex; + if (!module->ClassToTypeIndex.TryGet(typeClass, typeIndex)) + { + LOG(Error, "Cannot spawn objects of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + return nullptr; + } + const ScriptingType& scriptingType = module->Types[typeIndex]; + + // Create unmanaged object + const ScriptingObjectSpawnParams params(Guid::New(), ScriptingTypeHandle(module, typeIndex)); + ScriptingObject* obj = scriptingType.Script.Spawn(params); + if (obj == nullptr) + { + LOG(Error, "Failed to spawn object of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + return nullptr; + } + + // Set default name for actors + if (auto* actor = dynamic_cast(obj)) + { + actor->SetName(String(mono_class_get_name(typeClass))); + } + + // Create managed object + obj->CreateManaged(); + MonoObject* managedInstance = obj->GetManagedInstance(); + if (managedInstance == nullptr) + { + LOG(Error, "Cannot create managed instance for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + Delete(obj); + } + + return managedInstance; +} + +DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create2(MonoString* typeNameObj) +{ + // Get typename + if (typeNameObj == nullptr) + DebugLog::ThrowArgumentNull("typeName"); + const StringAsANSI<> typeNameData((const Char*)mono_string_chars(typeNameObj), (int32)mono_string_length(typeNameObj)); + const StringAnsiView typeName(typeNameData.Get(), (int32)mono_string_length(typeNameObj)); + + // Try to find the scripting type for this typename + const ScriptingTypeHandle type = Scripting::FindScriptingType(typeName); + if (!type) + { + LOG(Error, "Cannot find scripting type for \'{0}\'.", String(typeName)); + return nullptr; + } + + // Create unmanaged object + const ScriptingObjectSpawnParams params(Guid::New(), type); + ScriptingObject* obj = type.GetType().Script.Spawn(params); + if (obj == nullptr) + { + LOG(Error, "Failed to spawn object of type \'{0}\'.", String(typeName)); + return nullptr; + } + + // Create managed object + obj->CreateManaged(); + MonoObject* managedInstance = obj->GetManagedInstance(); + if (managedInstance == nullptr) + { + LOG(Error, "Cannot create managed instance for type \'{0}\'.", String(typeName)); + Delete(obj); + } + + return managedInstance; +} + +DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceCreated(MonoObject* managedInstance) +{ + MonoClass* typeClass = mono_object_get_class(managedInstance); + + // Get the assembly with that class + auto module = ManagedBinaryModule::FindModule(typeClass); + if (module == nullptr) + { + LOG(Error, "Cannot find scripting assembly for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + return; + } + + // Try to find the scripting type for this class + int32 typeIndex; + if (!module->ClassToTypeIndex.TryGet(typeClass, typeIndex)) + { + LOG(Error, "Cannot spawn objects of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + return; + } + const ScriptingType& scriptingType = module->Types[typeIndex]; + + // Create unmanaged object + const ScriptingObjectSpawnParams params(Guid::New(), ScriptingTypeHandle(module, typeIndex)); + ScriptingObject* obj = scriptingType.Script.Spawn(params); + if (obj == nullptr) + { + LOG(Error, "Failed to spawn object of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + return; + } + + // Set default name for actors + if (auto* actor = dynamic_cast(obj)) + { + actor->SetName(String(mono_class_get_name(typeClass))); + } + + // Link created managed instance to the unmanaged object + obj->SetManagedInstance(managedInstance); + + MClass* monoClass = obj->GetClass(); + + // Set handle to unmanaged object + const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr); + if (monoUnmanagedPtrField) + { + const void* value = obj; + monoUnmanagedPtrField->SetValue(managedInstance, &value); + } + + // Set object id + const MField* monoIdField = monoClass->GetField(ScriptingObject_id); + if (monoIdField) + { + const Guid id = obj->GetID(); + monoIdField->SetValue(managedInstance, (void*)&id); + } + + // Register object + if (!obj->IsRegistered()) + obj->RegisterObject(); +} + +DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceDeleted(ScriptingObject* obj) +{ + Scripting::OnManagedInstanceDeleted(obj); +} + +DEFINE_INTERNAL_CALL(void) ObjectInternal_Destroy(ScriptingObject* obj, float timeLeft) +{ + // Use scaled game time for removing actors/scripts by the user (maybe expose it to the api?) + const bool useGameTime = timeLeft > ZeroTolerance; + + if (obj) + obj->DeleteObject(timeLeft, useGameTime); +} + +DEFINE_INTERNAL_CALL(MonoString*) ObjectInternal_GetTypeName(ScriptingObject* obj) +{ + INTERNAL_CALL_CHECK_RETURN(obj, nullptr); + return MUtils::ToString(obj->GetType().Fullname); +} + +DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_FindObject(Guid* id, MonoReflectionType* type) +{ + if (!id->IsValid()) + return nullptr; + auto klass = MUtils::GetClass(type); + ScriptingObject* obj = Scripting::TryFindObject(*id); + if (!obj) + { + if (!klass || klass == ScriptingObject::GetStaticClass()->GetNative() || mono_class_is_subclass_of(klass, Asset::GetStaticClass()->GetNative(), false) != 0) + { + obj = Content::LoadAsync(*id); + } + } + if (obj) + { + if (klass && !obj->Is(klass)) + { + LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}.", *id, String(obj->GetType().Fullname), String(MUtils::GetClassFullname(klass))); + return nullptr; + } + return obj->GetOrCreateManagedInstance(); + } + if (klass) + LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}.", *id, String(MUtils::GetClassFullname(klass))); + else + LOG(Warning, "Unable to find scripting object with ID={0}", *id); + return nullptr; +} + +DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_TryFindObject(Guid* id, MonoReflectionType* type) +{ + ScriptingObject* obj = Scripting::TryFindObject(*id); + if (obj && !obj->Is(MUtils::GetClass(type))) + obj = nullptr; + return obj ? obj->GetOrCreateManagedInstance() : nullptr; +} + +DEFINE_INTERNAL_CALL(void) ObjectInternal_ChangeID(ScriptingObject* obj, Guid* id) +{ + INTERNAL_CALL_CHECK(obj); + obj->ChangeID(*id); +} + +DEFINE_INTERNAL_CALL(void*) ObjectInternal_GetUnmanagedInterface(ScriptingObject* obj, MonoReflectionType* type) +{ + if (obj && type) + { + auto typeClass = MUtils::GetClass(type); + const ScriptingTypeHandle interfaceType = ManagedBinaryModule::FindType(typeClass); + if (interfaceType) + { + return ScriptingObject::ToInterface(obj, interfaceType); + } + } + return nullptr; +} + +DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_FromUnmanagedPtr(ScriptingObject* obj) +{ + MonoObject* result = nullptr; + if (obj) + result = obj->GetOrCreateManagedInstance(); + return result; +} +#endif + class ScriptingObjectInternal { public: -#if !COMPILE_WITHOUT_CSHARP - - static MonoObject* Create1(MonoReflectionType* type) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_Create1") - // Peek class for that type (handle generic class cases) - if (!type) - DebugLog::ThrowArgumentNull("type"); - MonoType* monoType = mono_reflection_type_get_type(type); - const int32 monoTypeType = mono_type_get_type(monoType); - if (monoTypeType == MONO_TYPE_GENERICINST) - { - LOG(Error, "Generic scripts are not supported."); - return nullptr; - } - MonoClass* typeClass = mono_type_get_class(monoType); - if (typeClass == nullptr) - { - LOG(Error, "Invalid type."); - return nullptr; - } - - // Get the assembly with that class - auto module = ManagedBinaryModule::FindModule(typeClass); - if (module == nullptr) - { - LOG(Error, "Cannot find scripting assembly for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); - return nullptr; - } - - // Try to find the scripting type for this class - int32 typeIndex; - if (!module->ClassToTypeIndex.TryGet(typeClass, typeIndex)) - { - LOG(Error, "Cannot spawn objects of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); - return nullptr; - } - const ScriptingType& scriptingType = module->Types[typeIndex]; - - // Create unmanaged object - const ScriptingObjectSpawnParams params(Guid::New(), ScriptingTypeHandle(module, typeIndex)); - ScriptingObject* obj = scriptingType.Script.Spawn(params); - if (obj == nullptr) - { - LOG(Error, "Failed to spawn object of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); - return nullptr; - } - - // Set default name for actors - if (auto* actor = dynamic_cast(obj)) - { - actor->SetName(String(mono_class_get_name(typeClass))); - } - - // Create managed object - obj->CreateManaged(); - MonoObject* managedInstance = obj->GetManagedInstance(); - if (managedInstance == nullptr) - { - LOG(Error, "Cannot create managed instance for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); - Delete(obj); - } - - return managedInstance; - } - - static MonoObject* Create2(MonoString* typeNameObj) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_Create2") - // Get typename - if (typeNameObj == nullptr) - DebugLog::ThrowArgumentNull("typeName"); - const StringAsANSI<> typeNameData((const Char*)mono_string_chars(typeNameObj), (int32)mono_string_length(typeNameObj)); - const StringAnsiView typeName(typeNameData.Get(), (int32)mono_string_length(typeNameObj)); - - // Try to find the scripting type for this typename - const ScriptingTypeHandle type = Scripting::FindScriptingType(typeName); - if (!type) - { - LOG(Error, "Cannot find scripting type for \'{0}\'.", String(typeName)); - return nullptr; - } - - // Create unmanaged object - const ScriptingObjectSpawnParams params(Guid::New(), type); - ScriptingObject* obj = type.GetType().Script.Spawn(params); - if (obj == nullptr) - { - LOG(Error, "Failed to spawn object of type \'{0}\'.", String(typeName)); - return nullptr; - } - - // Create managed object - obj->CreateManaged(); - MonoObject* managedInstance = obj->GetManagedInstance(); - if (managedInstance == nullptr) - { - LOG(Error, "Cannot create managed instance for type \'{0}\'.", String(typeName)); - Delete(obj); - } - - return managedInstance; - } - - static void ManagedInstanceCreated(MonoObject* managedInstance) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_ManagedInstanceCreated") - MonoClass* typeClass = mono_object_get_class(managedInstance); - - // Get the assembly with that class - auto module = ManagedBinaryModule::FindModule(typeClass); - if (module == nullptr) - { - LOG(Error, "Cannot find scripting assembly for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); - return; - } - - // Try to find the scripting type for this class - int32 typeIndex; - if (!module->ClassToTypeIndex.TryGet(typeClass, typeIndex)) - { - LOG(Error, "Cannot spawn objects of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); - return; - } - const ScriptingType& scriptingType = module->Types[typeIndex]; - - // Create unmanaged object - const ScriptingObjectSpawnParams params(Guid::New(), ScriptingTypeHandle(module, typeIndex)); - ScriptingObject* obj = scriptingType.Script.Spawn(params); - if (obj == nullptr) - { - LOG(Error, "Failed to spawn object of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); - return; - } - - // Set default name for actors - if (auto* actor = dynamic_cast(obj)) - { - actor->SetName(String(mono_class_get_name(typeClass))); - } - - // Link created managed instance to the unmanaged object - if (auto* managedScriptingObject = dynamic_cast(obj)) - { - // Managed -#if USE_NETCORE - managedScriptingObject->_gcHandle = (MGCHandle)managedInstance; -#else - managedScriptingObject->_gcHandle = MUtils::NewGCHandleWeakref(managedInstance, false); -#endif - } - else - { - // Persistent -#if USE_NETCORE - obj->_gcHandle = (MGCHandle)managedInstance; -#else - obj->_gcHandle = MUtils::NewGCHandle(managedInstance, false); -#endif - } - - MClass* monoClass = obj->GetClass(); - - // Set handle to unmanaged object - const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr); - if (monoUnmanagedPtrField) - { - const void* value = obj; - monoUnmanagedPtrField->SetValue(managedInstance, &value); - } - - // Set object id - const MField* monoIdField = monoClass->GetField(ScriptingObject_id); - if (monoIdField) - { - monoIdField->SetValue(managedInstance, (void*)&obj->_id); - } - - // Register object - if (!obj->IsRegistered()) - obj->RegisterObject(); - } - - static void Destroy(ScriptingObject* obj, float timeLeft) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_Destroy") - // Use scaled game time for removing actors/scripts by the user (maybe expose it to the api?) - const bool useGameTime = timeLeft > ZeroTolerance; - - if (obj) - obj->DeleteObject(timeLeft, useGameTime); - } - - static MonoString* GetTypeName(ScriptingObject* obj) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_GetTypeName") - INTERNAL_CALL_CHECK_RETURN(obj, nullptr); - return MUtils::ToString(obj->GetType().Fullname); - } - - static MonoObject* FindObject(Guid* id, MonoReflectionType* type) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_FindObject") - if (!id->IsValid()) - return nullptr; - auto klass = MUtils::GetClass(type); - ScriptingObject* obj = Scripting::TryFindObject(*id); - if (!obj) - { - if (!klass || klass == ScriptingObject::GetStaticClass()->GetNative() || mono_class_is_subclass_of(klass, Asset::GetStaticClass()->GetNative(), false) != 0) - { - obj = Content::LoadAsync(*id); - } - } - if (obj) - { - if (klass && !obj->Is(klass)) - { - LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}.", *id, String(obj->GetType().Fullname), String(MUtils::GetClassFullname(klass))); - return nullptr; - } - return obj->GetOrCreateManagedInstance(); - } - if (klass) - LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}.", *id, String(MUtils::GetClassFullname(klass))); - else - LOG(Warning, "Unable to find scripting object with ID={0}", *id); - return nullptr; - } - - static MonoObject* TryFindObject(Guid* id, MonoReflectionType* type) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_TryFindObject") - ScriptingObject* obj = Scripting::TryFindObject(*id); - if (obj && !obj->Is(MUtils::GetClass(type))) - obj = nullptr; - return obj ? obj->GetOrCreateManagedInstance() : nullptr; - } - - static void ChangeID(ScriptingObject* obj, Guid* id) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_ChangeID") - INTERNAL_CALL_CHECK(obj); - obj->ChangeID(*id); - } - - static void* GetUnmanagedInterface(ScriptingObject* obj, MonoReflectionType* type) - { - SCRIPTING_EXPORT("FlaxEngine.Object::Internal_GetUnmanagedInterface") - if (obj && type) - { - auto typeClass = MUtils::GetClass(type); - const ScriptingTypeHandle interfaceType = ManagedBinaryModule::FindType(typeClass); - if (interfaceType) - { - return ScriptingObject::ToInterface(obj, interfaceType); - } - } - return nullptr; - } - - static MonoObject* FromUnmanagedPtr(ScriptingObject* obj) - { - SCRIPTING_EXPORT("FlaxEngine.Object::FromUnmanagedPtr") - MonoObject* result = nullptr; - if (obj) - result = obj->GetOrCreateManagedInstance(); - return result; - } - static void InitRuntime() { - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Create1", &Create1); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Create2", &Create2); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ManagedInstanceCreated", &ManagedInstanceCreated); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ManagedInstanceDeleted", &Scripting::OnManagedInstanceDeleted); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Destroy", &Destroy); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetTypeName", &GetTypeName); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_FindObject", &FindObject); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_TryFindObject", &TryFindObject); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ChangeID", &ChangeID); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetUnmanagedInterface", &GetUnmanagedInterface); - ADD_INTERNAL_CALL("FlaxEngine.Object::FromUnmanagedPtr", &FromUnmanagedPtr); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Create1", &ObjectInternal_Create1); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Create2", &ObjectInternal_Create2); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ManagedInstanceCreated", &ObjectInternal_ManagedInstanceCreated); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ManagedInstanceDeleted", &ObjectInternal_ManagedInstanceDeleted); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Destroy", &ObjectInternal_Destroy); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetTypeName", &ObjectInternal_GetTypeName); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_FindObject", &ObjectInternal_FindObject); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_TryFindObject", &ObjectInternal_TryFindObject); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ChangeID", &ObjectInternal_ChangeID); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetUnmanagedInterface", &ObjectInternal_GetUnmanagedInterface); + ADD_INTERNAL_CALL("FlaxEngine.Object::FromUnmanagedPtr", &ObjectInternal_FromUnmanagedPtr); } -#else - - static void InitRuntime() - { - } - -#endif - static ScriptingObject* Spawn(const ScriptingObjectSpawnParams& params) { return New(params); diff --git a/Source/Engine/Scripting/ScriptingObject.h b/Source/Engine/Scripting/ScriptingObject.h index efaa5eb90..160203e0a 100644 --- a/Source/Engine/Scripting/ScriptingObject.h +++ b/Source/Engine/Scripting/ScriptingObject.h @@ -14,19 +14,17 @@ API_CLASS(InBuild) class FLAXENGINE_API ScriptingObject : public Object { friend class Scripting; friend class BinaryModule; -DECLARE_SCRIPTING_TYPE_NO_SPAWN(ScriptingObject); -public: + DECLARE_SCRIPTING_TYPE_NO_SPAWN(ScriptingObject); +public: typedef ScriptingObjectSpawnParams SpawnParams; protected: - MGCHandle _gcHandle; ScriptingTypeHandle _type; Guid _id; public: - /// /// Initializes a new instance of the class. /// @@ -39,14 +37,15 @@ public: virtual ~ScriptingObject(); public: - // Spawns a new objects of the given type. static ScriptingObject* NewObject(const ScriptingTypeHandle& typeHandle); + template static T* NewObject() { return (T*)NewObject(T::TypeInitializer); } + template static T* NewObject(const ScriptingTypeHandle& typeHandle) { @@ -60,14 +59,12 @@ public: } public: - /// /// Event fired when object gets deleted. /// Delegate Deleted; public: - /// /// Gets the managed instance object. /// @@ -116,15 +113,17 @@ public: MClass* GetClass() const; public: - // Tries to cast native interface object to scripting object instance. Returns null if fails. static ScriptingObject* FromInterface(void* interfaceObj, const ScriptingTypeHandle& interfaceType); + template static ScriptingObject* FromInterface(T* interfaceObj) { return FromInterface(interfaceObj, T::TypeInitializer); } + static void* ToInterface(ScriptingObject* obj, const ScriptingTypeHandle& interfaceType); + template static T* ToInterface(ScriptingObject* obj) { @@ -184,7 +183,6 @@ public: } public: - /// /// Changes the object id (both managed and unmanaged). Warning! Use with caution as object ID is what it identifies it and change might cause issues. /// @@ -192,7 +190,7 @@ public: virtual void ChangeID(const Guid& newId); public: - + virtual void SetManagedInstance(MonoObject* instance); virtual void OnManagedInstanceDeleted(); virtual void OnScriptingDispose(); @@ -200,7 +198,6 @@ public: virtual void DestroyManaged(); public: - /// /// Determines whether this object is registered or not (can be found by the queries and used in a game). /// @@ -220,7 +217,6 @@ public: void UnregisterObject(); protected: - #if USE_MONO /// /// Create a new managed object. @@ -229,7 +225,6 @@ protected: #endif public: - // [Object] void OnDeleteObject() override; String ToString() const override; @@ -243,7 +238,6 @@ public: API_CLASS(InBuild) class FLAXENGINE_API ManagedScriptingObject : public ScriptingObject { public: - /// /// Initializes a new instance of the class. /// @@ -251,8 +245,8 @@ public: explicit ManagedScriptingObject(const SpawnParams& params); public: - // [ScriptingObject] + void SetManagedInstance(MonoObject* instance) override; void OnManagedInstanceDeleted() override; void OnScriptingDispose() override; bool CreateManaged() override; diff --git a/Source/Engine/Utilities/Utils.cs b/Source/Engine/Utilities/Utils.cs index e4dae22be..540f3291a 100644 --- a/Source/Engine/Utilities/Utils.cs +++ b/Source/Engine/Utilities/Utils.cs @@ -36,7 +36,7 @@ namespace FlaxEngine /// The source location. /// The destination location. /// The length (amount of bytes to copy). - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Utils::MemoryCopy")] + [LibraryImport("FlaxEngine", EntryPoint = "PlatformInternal_MemoryCopy")] public static partial void MemoryCopy(IntPtr destination, IntPtr source, ulong length); /// @@ -45,7 +45,7 @@ namespace FlaxEngine /// Uses low-level platform impl. /// Destination memory address /// Size of the memory to clear in bytes - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Utils::MemoryClear")] + [LibraryImport("FlaxEngine", EntryPoint = "PlatformInternal_MemoryClear")] public static partial void MemoryClear(IntPtr dst, ulong size); /// @@ -55,7 +55,7 @@ namespace FlaxEngine /// The first buffer address. /// The second buffer address. /// Size of the memory to compare in bytes. - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Utils::MemoryCompare")] + [LibraryImport("FlaxEngine", EntryPoint = "PlatformInternal_MemoryCompare")] public static partial int MemoryCompare(IntPtr buf1, IntPtr buf2, ulong size); /// @@ -355,7 +355,7 @@ namespace FlaxEngine #if USE_NETCORE #else - [LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Utils::Internal_ExtractArrayFromList")] + [LibraryImport("FlaxEngine", EntryPoint = "UtilsInternal_ExtractArrayFromList")] [return: MarshalUsing(typeof(FlaxEngine.SystemArrayMarshaller))] internal static partial Array Internal_ExtractArrayFromList([MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))] object list); #endif