Merge branch 'GoaLitiuM-dotnet7' into dotnet7
This commit is contained in:
1
.github/workflows/build_android.yml
vendored
1
.github/workflows/build_android.yml
vendored
@@ -5,6 +5,7 @@ jobs:
|
|||||||
|
|
||||||
# Game
|
# Game
|
||||||
game-windows:
|
game-windows:
|
||||||
|
if: ${{ false }}
|
||||||
name: Game (Android, Release ARM64)
|
name: Game (Android, Release ARM64)
|
||||||
runs-on: "windows-2019"
|
runs-on: "windows-2019"
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
2
.github/workflows/build_linux.yml
vendored
2
.github/workflows/build_linux.yml
vendored
@@ -5,6 +5,7 @@ jobs:
|
|||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
editor-linux:
|
editor-linux:
|
||||||
|
if: ${{ false }}
|
||||||
name: Editor (Linux, Development x64)
|
name: Editor (Linux, Development x64)
|
||||||
runs-on: "ubuntu-20.04"
|
runs-on: "ubuntu-20.04"
|
||||||
steps:
|
steps:
|
||||||
@@ -28,6 +29,7 @@ jobs:
|
|||||||
|
|
||||||
# Game
|
# Game
|
||||||
game-linux:
|
game-linux:
|
||||||
|
if: ${{ false }}
|
||||||
name: Game (Linux, Release x64)
|
name: Game (Linux, Release x64)
|
||||||
runs-on: "ubuntu-20.04"
|
runs-on: "ubuntu-20.04"
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
2
.github/workflows/build_mac.yml
vendored
2
.github/workflows/build_mac.yml
vendored
@@ -5,6 +5,7 @@ jobs:
|
|||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
editor-mac:
|
editor-mac:
|
||||||
|
if: ${{ false }}
|
||||||
name: Editor (Mac, Development x64)
|
name: Editor (Mac, Development x64)
|
||||||
runs-on: "macos-latest"
|
runs-on: "macos-latest"
|
||||||
steps:
|
steps:
|
||||||
@@ -22,6 +23,7 @@ jobs:
|
|||||||
|
|
||||||
# Game
|
# Game
|
||||||
game-mac:
|
game-mac:
|
||||||
|
if: ${{ false }}
|
||||||
name: Game (Mac, Release x64)
|
name: Game (Mac, Release x64)
|
||||||
runs-on: "macos-latest"
|
runs-on: "macos-latest"
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
15
.github/workflows/build_windows.yml
vendored
15
.github/workflows/build_windows.yml
vendored
@@ -6,12 +6,19 @@ jobs:
|
|||||||
# Editor
|
# Editor
|
||||||
editor-windows:
|
editor-windows:
|
||||||
name: Editor (Windows, Development x64)
|
name: Editor (Windows, Development x64)
|
||||||
runs-on: "windows-2019"
|
runs-on: "windows-2022"
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: 7.0.x
|
||||||
|
- name: Check .NET versions
|
||||||
|
run: |
|
||||||
|
dotnet --list-sdks
|
||||||
- name: Checkout LFS
|
- name: Checkout LFS
|
||||||
run: |
|
run: |
|
||||||
git lfs version
|
git lfs version
|
||||||
@@ -23,12 +30,16 @@ jobs:
|
|||||||
# Game
|
# Game
|
||||||
game-windows:
|
game-windows:
|
||||||
name: Game (Windows, Release x64)
|
name: Game (Windows, Release x64)
|
||||||
runs-on: "windows-2019"
|
runs-on: "windows-2022"
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: 7.0.x
|
||||||
- name: Checkout LFS
|
- name: Checkout LFS
|
||||||
run: |
|
run: |
|
||||||
git lfs version
|
git lfs version
|
||||||
|
|||||||
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@@ -5,6 +5,7 @@ jobs:
|
|||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
tests-linux:
|
tests-linux:
|
||||||
|
if: ${{ false }}
|
||||||
name: Tests (Linux)
|
name: Tests (Linux)
|
||||||
runs-on: "ubuntu-20.04"
|
runs-on: "ubuntu-20.04"
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ if [ $testfilesize -le 1000 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Compile the build tool.
|
# Compile the build tool.
|
||||||
xbuild /nologo /verbosity:quiet "Source/Tools/Flax.Build/Flax.Build.csproj" /property:Configuration=Release /property:Platform=AnyCPU /target:Build
|
dotnet msbuild /nologo /verbosity:quiet "Source/Tools/Flax.Build/Flax.Build.csproj" /property:Configuration=Release /target:Restore,Clean /property:RestorePackagesConfig=True /p:RuntimeIdentifiers=linux-x64
|
||||||
|
dotnet msbuild /nologo /verbosity:quiet "Source/Tools/Flax.Build/Flax.Build.csproj" /property:Configuration=Release /target:Build /property:SelfContained=False /property:RuntimeIdentifiers=linux-x64
|
||||||
|
|
||||||
# Run the build tool using the provided arguments.
|
# Run the build tool using the provided arguments.
|
||||||
#mono --debug --debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:55555 Binaries/Tools/Flax.Build.exe "$@"
|
#mono --debug --debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:55555 Binaries/Tools/Flax.Build.exe "$@"
|
||||||
mono Binaries/Tools/Flax.Build.exe "$@"
|
Binaries/Tools/Flax.Build "$@"
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ fc /b Cache\Intermediate\Build\Flax.Build.Files.txt Cache\Intermediate\Build\Fla
|
|||||||
if not errorlevel 1 goto SkipClean
|
if not errorlevel 1 goto SkipClean
|
||||||
|
|
||||||
copy /y Cache\Intermediate\Build\Flax.Build.Files.txt Cache\Intermediate\Build\Flax.Build.PrevFiles.txt >nul
|
copy /y Cache\Intermediate\Build\Flax.Build.Files.txt Cache\Intermediate\Build\Flax.Build.PrevFiles.txt >nul
|
||||||
%MSBUILD_PATH% /nologo /verbosity:quiet Source\Tools\Flax.Build\Flax.Build.csproj /property:Configuration=Release /property:Platform=AnyCPU /target:Clean
|
%MSBUILD_PATH% /nologo /verbosity:quiet Source\Tools\Flax.Build\Flax.Build.csproj /property:Configuration=Release /target:Restore,Clean /property:RestorePackagesConfig=True /p:RuntimeIdentifiers=win-x64
|
||||||
:SkipClean
|
:SkipClean
|
||||||
%MSBUILD_PATH% /nologo /verbosity:quiet Source\Tools\Flax.Build\Flax.Build.csproj /property:Configuration=Release /property:Platform=AnyCPU /target:Build
|
%MSBUILD_PATH% /nologo /verbosity:quiet Source\Tools\Flax.Build\Flax.Build.csproj /property:Configuration=Release /target:Build /property:SelfContained=False /property:RuntimeIdentifiers=win-x64
|
||||||
if errorlevel 1 goto Error_CompilationFailed
|
if errorlevel 1 goto Error_CompilationFailed
|
||||||
|
|
||||||
Binaries\Tools\Flax.Build.exe %*
|
Binaries\Tools\Flax.Build.exe %*
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"EditorTarget": "FlaxEditor",
|
"EditorTarget": "FlaxEditor",
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"UseCSharp": true,
|
"UseCSharp": true,
|
||||||
"UseLargeWorlds": false
|
"UseLargeWorlds": false,
|
||||||
|
"UseDotNet": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.Content.Import
|
namespace FlaxEditor.Content.Import
|
||||||
@@ -93,6 +94,7 @@ namespace FlaxEditor.Content.Import
|
|||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
internal struct InternalOptions
|
internal struct InternalOptions
|
||||||
{
|
{
|
||||||
|
[MarshalAs(UnmanagedType.I1)]
|
||||||
public AudioFormat Format;
|
public AudioFormat Format;
|
||||||
public byte DisableStreaming;
|
public byte DisableStreaming;
|
||||||
public byte Is3D;
|
public byte Is3D;
|
||||||
@@ -144,7 +146,7 @@ namespace FlaxEditor.Content.Import
|
|||||||
/// Audio asset import entry.
|
/// Audio asset import entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="AssetImportEntry" />
|
/// <seealso cref="AssetImportEntry" />
|
||||||
public class AudioImportEntry : AssetImportEntry
|
public partial class AudioImportEntry : AssetImportEntry
|
||||||
{
|
{
|
||||||
private AudioImportSettings _settings = new AudioImportSettings();
|
private AudioImportSettings _settings = new AudioImportSettings();
|
||||||
|
|
||||||
@@ -182,8 +184,9 @@ namespace FlaxEditor.Content.Import
|
|||||||
|
|
||||||
#region Internal Calls
|
#region Internal Calls
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Import.AudioImportEntry::Internal_GetAudioImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||||
internal static extern bool Internal_GetAudioImportOptions(string path, out AudioImportSettings.InternalOptions result);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_GetAudioImportOptions(string path, out AudioImportSettings.InternalOptions result);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.Content.Import
|
namespace FlaxEditor.Content.Import
|
||||||
@@ -355,6 +357,7 @@ namespace FlaxEditor.Content.Import
|
|||||||
private bool ShowAnimation => Type == ModelType.Animation;
|
private bool ShowAnimation => Type == ModelType.Animation;
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[NativeMarshalling(typeof(InternalOptionsMarshaler))]
|
||||||
internal struct InternalOptions
|
internal struct InternalOptions
|
||||||
{
|
{
|
||||||
public ModelType Type;
|
public ModelType Type;
|
||||||
@@ -410,6 +413,162 @@ namespace FlaxEditor.Content.Import
|
|||||||
public int ObjectIndex;
|
public int ObjectIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CustomMarshaller(typeof(InternalOptions), MarshalMode.Default, typeof(InternalOptionsMarshaler))]
|
||||||
|
internal static class InternalOptionsMarshaler
|
||||||
|
{
|
||||||
|
[Unmanaged]
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct InternalOptionsNative
|
||||||
|
{
|
||||||
|
public int Type;
|
||||||
|
|
||||||
|
// Geometry
|
||||||
|
public byte CalculateNormals;
|
||||||
|
public float SmoothingNormalsAngle;
|
||||||
|
public byte FlipNormals;
|
||||||
|
public float SmoothingTangentsAngle;
|
||||||
|
public byte CalculateTangents;
|
||||||
|
public byte OptimizeMeshes;
|
||||||
|
public byte MergeMeshes;
|
||||||
|
public byte ImportLODs;
|
||||||
|
public byte ImportVertexColors;
|
||||||
|
public byte ImportBlendShapes;
|
||||||
|
public int LightmapUVsSource;
|
||||||
|
//[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
public IntPtr CollisionMeshesPrefix;
|
||||||
|
|
||||||
|
// Transform
|
||||||
|
public float Scale;
|
||||||
|
public Quaternion Rotation;
|
||||||
|
public Float3 Translation;
|
||||||
|
public byte CenterGeometry;
|
||||||
|
|
||||||
|
// Animation
|
||||||
|
public int Duration;
|
||||||
|
public float FramesRangeStart;
|
||||||
|
public float FramesRangeEnd;
|
||||||
|
public float DefaultFrameRate;
|
||||||
|
public float SamplingRate;
|
||||||
|
public byte SkipEmptyCurves;
|
||||||
|
public byte OptimizeKeyframes;
|
||||||
|
public byte EnableRootMotion;
|
||||||
|
//[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
public IntPtr RootNodeName;
|
||||||
|
|
||||||
|
// Level Of Detail
|
||||||
|
public byte GenerateLODs;
|
||||||
|
public int BaseLOD;
|
||||||
|
public int LODCount;
|
||||||
|
public float TriangleReduction;
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
public byte ImportMaterials;
|
||||||
|
public byte ImportTextures;
|
||||||
|
public byte RestoreMaterialsOnReimport;
|
||||||
|
|
||||||
|
// SDF
|
||||||
|
public byte GenerateSDF;
|
||||||
|
public float SDFResolution;
|
||||||
|
|
||||||
|
// Splitting
|
||||||
|
public byte SplitObjects;
|
||||||
|
public int ObjectIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static InternalOptions ConvertToManaged(InternalOptionsNative unmanaged) => ToManaged(unmanaged);
|
||||||
|
internal static InternalOptionsNative ConvertToUnmanaged(InternalOptions managed) => ToNative(managed);
|
||||||
|
|
||||||
|
internal static InternalOptions ToManaged(InternalOptionsNative managed)
|
||||||
|
{
|
||||||
|
return new InternalOptions()
|
||||||
|
{
|
||||||
|
Type = (ModelType)managed.Type,
|
||||||
|
CalculateNormals = managed.CalculateNormals,
|
||||||
|
SmoothingNormalsAngle = managed.SmoothingNormalsAngle,
|
||||||
|
FlipNormals = managed.FlipNormals,
|
||||||
|
SmoothingTangentsAngle = managed.SmoothingTangentsAngle,
|
||||||
|
CalculateTangents = managed.CalculateTangents,
|
||||||
|
OptimizeMeshes = managed.OptimizeMeshes,
|
||||||
|
MergeMeshes = managed.MergeMeshes,
|
||||||
|
ImportLODs = managed.ImportLODs,
|
||||||
|
ImportVertexColors = managed.ImportVertexColors,
|
||||||
|
ImportBlendShapes = managed.ImportBlendShapes,
|
||||||
|
LightmapUVsSource = (ModelLightmapUVsSource)managed.LightmapUVsSource,
|
||||||
|
CollisionMeshesPrefix = ManagedString.ToManaged(managed.CollisionMeshesPrefix),
|
||||||
|
Scale = managed.Scale,
|
||||||
|
Rotation = managed.Rotation,
|
||||||
|
Translation = managed.Translation,
|
||||||
|
CenterGeometry = managed.CenterGeometry,
|
||||||
|
Duration = (AnimationDuration)managed.Duration,
|
||||||
|
FramesRangeStart = managed.FramesRangeStart,
|
||||||
|
FramesRangeEnd = managed.FramesRangeEnd,
|
||||||
|
DefaultFrameRate = managed.DefaultFrameRate,
|
||||||
|
SamplingRate = managed.SamplingRate,
|
||||||
|
SkipEmptyCurves = managed.SkipEmptyCurves,
|
||||||
|
OptimizeKeyframes = managed.OptimizeKeyframes,
|
||||||
|
EnableRootMotion = managed.EnableRootMotion,
|
||||||
|
RootNodeName = ManagedString.ToManaged(managed.RootNodeName),
|
||||||
|
GenerateLODs = managed.GenerateLODs,
|
||||||
|
BaseLOD = managed.BaseLOD,
|
||||||
|
LODCount = managed.LODCount,
|
||||||
|
TriangleReduction = managed.TriangleReduction,
|
||||||
|
ImportMaterials = managed.ImportMaterials,
|
||||||
|
ImportTextures = managed.ImportTextures,
|
||||||
|
RestoreMaterialsOnReimport = managed.RestoreMaterialsOnReimport,
|
||||||
|
GenerateSDF = managed.GenerateSDF,
|
||||||
|
SDFResolution = managed.SDFResolution,
|
||||||
|
SplitObjects = managed.SplitObjects,
|
||||||
|
ObjectIndex = managed.ObjectIndex,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static InternalOptionsNative ToNative(InternalOptions managed)
|
||||||
|
{
|
||||||
|
return new InternalOptionsNative()
|
||||||
|
{
|
||||||
|
Type = (int)managed.Type,
|
||||||
|
CalculateNormals = managed.CalculateNormals,
|
||||||
|
SmoothingNormalsAngle = managed.SmoothingNormalsAngle,
|
||||||
|
FlipNormals = managed.FlipNormals,
|
||||||
|
SmoothingTangentsAngle = managed.SmoothingTangentsAngle,
|
||||||
|
CalculateTangents = managed.CalculateTangents,
|
||||||
|
OptimizeMeshes = managed.OptimizeMeshes,
|
||||||
|
MergeMeshes = managed.MergeMeshes,
|
||||||
|
ImportLODs = managed.ImportLODs,
|
||||||
|
ImportVertexColors = managed.ImportVertexColors,
|
||||||
|
ImportBlendShapes = managed.ImportBlendShapes,
|
||||||
|
LightmapUVsSource = (int)managed.LightmapUVsSource,
|
||||||
|
CollisionMeshesPrefix = ManagedString.ToNative(managed.CollisionMeshesPrefix),
|
||||||
|
Scale = managed.Scale,
|
||||||
|
Rotation = managed.Rotation,
|
||||||
|
Translation = managed.Translation,
|
||||||
|
CenterGeometry = managed.CenterGeometry,
|
||||||
|
Duration = (int)managed.Duration,
|
||||||
|
FramesRangeStart = managed.FramesRangeStart,
|
||||||
|
FramesRangeEnd = managed.FramesRangeEnd,
|
||||||
|
DefaultFrameRate = managed.DefaultFrameRate,
|
||||||
|
SamplingRate = managed.SamplingRate,
|
||||||
|
SkipEmptyCurves = managed.SkipEmptyCurves,
|
||||||
|
OptimizeKeyframes = managed.OptimizeKeyframes,
|
||||||
|
EnableRootMotion = managed.EnableRootMotion,
|
||||||
|
RootNodeName = ManagedString.ToNative(managed.RootNodeName),
|
||||||
|
GenerateLODs = managed.GenerateLODs,
|
||||||
|
BaseLOD = managed.BaseLOD,
|
||||||
|
LODCount = managed.LODCount,
|
||||||
|
TriangleReduction = managed.TriangleReduction,
|
||||||
|
ImportMaterials = managed.ImportMaterials,
|
||||||
|
ImportTextures = managed.ImportTextures,
|
||||||
|
RestoreMaterialsOnReimport = managed.RestoreMaterialsOnReimport,
|
||||||
|
GenerateSDF = managed.GenerateSDF,
|
||||||
|
SDFResolution = managed.SDFResolution,
|
||||||
|
SplitObjects = managed.SplitObjects,
|
||||||
|
ObjectIndex = managed.ObjectIndex,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static void Free(InternalOptionsNative unmanaged)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void ToInternal(out InternalOptions options)
|
internal void ToInternal(out InternalOptions options)
|
||||||
{
|
{
|
||||||
options = new InternalOptions
|
options = new InternalOptions
|
||||||
@@ -511,7 +670,7 @@ namespace FlaxEditor.Content.Import
|
|||||||
/// Model asset import entry.
|
/// Model asset import entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="AssetImportEntry" />
|
/// <seealso cref="AssetImportEntry" />
|
||||||
public class ModelImportEntry : AssetImportEntry
|
public partial class ModelImportEntry : AssetImportEntry
|
||||||
{
|
{
|
||||||
private ModelImportSettings _settings = new ModelImportSettings();
|
private ModelImportSettings _settings = new ModelImportSettings();
|
||||||
|
|
||||||
@@ -548,8 +707,8 @@ namespace FlaxEditor.Content.Import
|
|||||||
|
|
||||||
#region Internal Calls
|
#region Internal Calls
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Import.ModelImportEntry::Internal_GetModelImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||||
internal static extern void Internal_GetModelImportOptions(string path, out ModelImportSettings.InternalOptions result);
|
internal static partial void Internal_GetModelImportOptions(string path, out ModelImportSettings.InternalOptions result);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
@@ -297,6 +299,7 @@ namespace FlaxEditor.Content.Import
|
|||||||
public List<SpriteInfo> Sprites = new List<SpriteInfo>();
|
public List<SpriteInfo> Sprites = new List<SpriteInfo>();
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[NativeMarshalling(typeof(InternalOptionsMarshaler))]
|
||||||
internal struct InternalOptions
|
internal struct InternalOptions
|
||||||
{
|
{
|
||||||
public TextureFormatType Type;
|
public TextureFormatType Type;
|
||||||
@@ -318,6 +321,85 @@ namespace FlaxEditor.Content.Import
|
|||||||
public string[] SpriteNames;
|
public string[] SpriteNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CustomMarshaller(typeof(InternalOptions), MarshalMode.Default, typeof(InternalOptionsMarshaler))]
|
||||||
|
internal static class InternalOptionsMarshaler
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct InternalOptionsNative
|
||||||
|
{
|
||||||
|
public byte Type;
|
||||||
|
public byte IsAtlas;
|
||||||
|
public byte NeverStream;
|
||||||
|
public byte Compress;
|
||||||
|
public byte IndependentChannels;
|
||||||
|
public byte sRGB;
|
||||||
|
public byte GenerateMipMaps;
|
||||||
|
public byte FlipY;
|
||||||
|
public byte Resize;
|
||||||
|
public byte PreserveAlphaCoverage;
|
||||||
|
public float PreserveAlphaCoverageReference;
|
||||||
|
public float Scale;
|
||||||
|
public int MaxSize;
|
||||||
|
public int TextureGroup;
|
||||||
|
public Int2 Size;
|
||||||
|
public IntPtr SpriteAreas;
|
||||||
|
public IntPtr SpriteNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static InternalOptions ConvertToManaged(InternalOptionsNative unmanaged) => ToManaged(unmanaged);
|
||||||
|
internal static InternalOptionsNative ConvertToUnmanaged(InternalOptions managed) => ToNative(managed);
|
||||||
|
|
||||||
|
internal static InternalOptions ToManaged(InternalOptionsNative managed)
|
||||||
|
{
|
||||||
|
return new InternalOptions()
|
||||||
|
{
|
||||||
|
Type = (TextureFormatType)managed.Type,
|
||||||
|
IsAtlas = managed.IsAtlas,
|
||||||
|
NeverStream = managed.NeverStream,
|
||||||
|
Compress = managed.Compress,
|
||||||
|
IndependentChannels = managed.IndependentChannels,
|
||||||
|
sRGB = managed.sRGB,
|
||||||
|
GenerateMipMaps = managed.GenerateMipMaps,
|
||||||
|
FlipY = managed.FlipY,
|
||||||
|
Resize = managed.Resize,
|
||||||
|
PreserveAlphaCoverage = managed.PreserveAlphaCoverage,
|
||||||
|
PreserveAlphaCoverageReference = managed.PreserveAlphaCoverageReference,
|
||||||
|
Scale = managed.Scale,
|
||||||
|
MaxSize = managed.MaxSize,
|
||||||
|
TextureGroup = managed.TextureGroup,
|
||||||
|
Size = managed.Size,
|
||||||
|
SpriteAreas = managed.SpriteAreas != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<Rectangle>((ManagedArray)GCHandle.FromIntPtr(managed.SpriteAreas).Target) : null,
|
||||||
|
SpriteNames = managed.SpriteNames != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<string>((ManagedArray)GCHandle.FromIntPtr(managed.SpriteNames).Target) : null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static InternalOptionsNative ToNative(InternalOptions managed)
|
||||||
|
{
|
||||||
|
return new InternalOptionsNative()
|
||||||
|
{
|
||||||
|
Type = (byte)managed.Type,
|
||||||
|
IsAtlas = managed.IsAtlas,
|
||||||
|
NeverStream = managed.NeverStream,
|
||||||
|
Compress = managed.Compress,
|
||||||
|
IndependentChannels = managed.IndependentChannels,
|
||||||
|
sRGB = managed.sRGB,
|
||||||
|
GenerateMipMaps = managed.GenerateMipMaps,
|
||||||
|
FlipY = managed.FlipY,
|
||||||
|
Resize = managed.Resize,
|
||||||
|
PreserveAlphaCoverage = managed.PreserveAlphaCoverage,
|
||||||
|
PreserveAlphaCoverageReference = managed.PreserveAlphaCoverageReference,
|
||||||
|
Scale = managed.Scale,
|
||||||
|
MaxSize = managed.MaxSize,
|
||||||
|
TextureGroup = managed.TextureGroup,
|
||||||
|
Size = managed.Size,
|
||||||
|
SpriteAreas = managed.SpriteAreas?.Length > 0 ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteAreas)))) : IntPtr.Zero,
|
||||||
|
SpriteNames = managed.SpriteNames?.Length > 0 ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteNames)))) : IntPtr.Zero,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static void Free(InternalOptionsNative unmanaged)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void ToInternal(out InternalOptions options)
|
internal void ToInternal(out InternalOptions options)
|
||||||
{
|
{
|
||||||
options = new InternalOptions
|
options = new InternalOptions
|
||||||
@@ -406,7 +488,7 @@ namespace FlaxEditor.Content.Import
|
|||||||
/// Texture asset import entry.
|
/// Texture asset import entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="AssetImportEntry" />
|
/// <seealso cref="AssetImportEntry" />
|
||||||
public class TextureImportEntry : AssetImportEntry
|
public partial class TextureImportEntry : AssetImportEntry
|
||||||
{
|
{
|
||||||
private TextureImportSettings _settings = new TextureImportSettings();
|
private TextureImportSettings _settings = new TextureImportSettings();
|
||||||
|
|
||||||
@@ -509,8 +591,9 @@ namespace FlaxEditor.Content.Import
|
|||||||
|
|
||||||
#region Internal Calls
|
#region Internal Calls
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Import.TextureImportEntry::Internal_GetTextureImportOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_GetTextureImportOptions(string path, out TextureImportSettings.InternalOptions result);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_GetTextureImportOptions(string path, out TextureImportSettings.InternalOptions result);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
using FlaxEditor.CustomEditors.Editors;
|
using FlaxEditor.CustomEditors.Editors;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.CustomEditors
|
namespace FlaxEditor.CustomEditors
|
||||||
{
|
{
|
||||||
internal static class CustomEditorsUtil
|
internal static partial class CustomEditorsUtil
|
||||||
{
|
{
|
||||||
internal static readonly Dictionary<Type, string> InBuildTypeNames = new Dictionary<Type, string>()
|
internal static readonly Dictionary<Type, string> InBuildTypeNames = new Dictionary<Type, string>()
|
||||||
{
|
{
|
||||||
@@ -129,7 +131,8 @@ namespace FlaxEditor.CustomEditors
|
|||||||
return new GenericEditor();
|
return new GenericEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.CustomEditors.CustomEditorsUtil::Internal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern Type Internal_GetCustomEditor(Type targetType);
|
[return: MarshalUsing(typeof(SystemTypeMarshaller))]
|
||||||
|
internal static partial Type Internal_GetCustomEditor([MarshalUsing(typeof(SystemTypeMarshaller))] Type targetType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
using FlaxEditor.Content;
|
using FlaxEditor.Content;
|
||||||
using FlaxEditor.Content.Import;
|
using FlaxEditor.Content.Import;
|
||||||
using FlaxEditor.Content.Settings;
|
using FlaxEditor.Content.Settings;
|
||||||
@@ -20,6 +21,8 @@ using FlaxEngine.Assertions;
|
|||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Json;
|
using FlaxEngine.Json;
|
||||||
|
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
namespace FlaxEditor
|
namespace FlaxEditor
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -59,17 +62,20 @@ namespace FlaxEditor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this Editor is running a dev instance of the engine.
|
/// Gets a value indicating whether this Editor is running a dev instance of the engine.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::IsDevInstance", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool IsDevInstance();
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool IsDevInstance();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this Editor is running as official build (distributed via Flax services).
|
/// Gets a value indicating whether this Editor is running as official build (distributed via Flax services).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::IsOfficialBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool IsOfficialBuild();
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool IsOfficialBuild();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_IsPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_IsPlayMode();
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_IsPlayMode();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// True if the editor is running now in a play mode. Assigned by the managed editor instance.
|
/// True if the editor is running now in a play mode. Assigned by the managed editor instance.
|
||||||
@@ -1206,6 +1212,7 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[NativeMarshalling(typeof(VisualScriptLocalMarshaller))]
|
||||||
internal struct VisualScriptLocal
|
internal struct VisualScriptLocal
|
||||||
{
|
{
|
||||||
public string Value;
|
public string Value;
|
||||||
@@ -1214,7 +1221,48 @@ namespace FlaxEditor
|
|||||||
public int BoxId;
|
public int BoxId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CustomMarshaller(typeof(VisualScriptLocal), MarshalMode.Default, typeof(VisualScriptLocalMarshaller))]
|
||||||
|
internal static class VisualScriptLocalMarshaller
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct VisualScriptLocalNative
|
||||||
|
{
|
||||||
|
public IntPtr Value;
|
||||||
|
public IntPtr ValueTypeName;
|
||||||
|
public uint NodeId;
|
||||||
|
public int BoxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static VisualScriptLocal ConvertToManaged(VisualScriptLocalNative unmanaged) => ToManaged(unmanaged);
|
||||||
|
internal static VisualScriptLocalNative ConvertToUnmanaged(VisualScriptLocal managed) => ToNative(managed);
|
||||||
|
|
||||||
|
internal static VisualScriptLocal ToManaged(VisualScriptLocalNative managed)
|
||||||
|
{
|
||||||
|
return new VisualScriptLocal()
|
||||||
|
{
|
||||||
|
Value = ManagedString.ToManaged(managed.Value),
|
||||||
|
ValueTypeName = ManagedString.ToManaged(managed.ValueTypeName),
|
||||||
|
NodeId = managed.NodeId,
|
||||||
|
BoxId = managed.BoxId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static VisualScriptLocalNative ToNative(VisualScriptLocal managed)
|
||||||
|
{
|
||||||
|
return new VisualScriptLocalNative()
|
||||||
|
{
|
||||||
|
Value = ManagedString.ToNative(managed.Value),
|
||||||
|
ValueTypeName = ManagedString.ToNative(managed.ValueTypeName),
|
||||||
|
NodeId = managed.NodeId,
|
||||||
|
BoxId = managed.BoxId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static void Free(VisualScriptLocalNative unmanaged)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[NativeMarshalling(typeof(VisualScriptStackFrameMarshaller))]
|
||||||
internal struct VisualScriptStackFrame
|
internal struct VisualScriptStackFrame
|
||||||
{
|
{
|
||||||
public VisualScript Script;
|
public VisualScript Script;
|
||||||
@@ -1222,6 +1270,43 @@ namespace FlaxEditor
|
|||||||
public int BoxId;
|
public int BoxId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CustomMarshaller(typeof(VisualScriptStackFrame), MarshalMode.Default, typeof(VisualScriptStackFrameMarshaller))]
|
||||||
|
internal static class VisualScriptStackFrameMarshaller
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct VisualScriptStackFrameNative
|
||||||
|
{
|
||||||
|
public IntPtr Script;
|
||||||
|
public uint NodeId;
|
||||||
|
public int BoxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static VisualScriptStackFrame ConvertToManaged(VisualScriptStackFrameNative unmanaged) => ToManaged(unmanaged);
|
||||||
|
internal static VisualScriptStackFrameNative ConvertToUnmanaged(VisualScriptStackFrame managed) => ToNative(managed);
|
||||||
|
|
||||||
|
internal static VisualScriptStackFrame ToManaged(VisualScriptStackFrameNative managed)
|
||||||
|
{
|
||||||
|
return new VisualScriptStackFrame()
|
||||||
|
{
|
||||||
|
Script = VisualScriptMarshaller.ConvertToManaged(managed.Script),
|
||||||
|
NodeId = managed.NodeId,
|
||||||
|
BoxId = managed.BoxId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static VisualScriptStackFrameNative ToNative(VisualScriptStackFrame managed)
|
||||||
|
{
|
||||||
|
return new VisualScriptStackFrameNative()
|
||||||
|
{
|
||||||
|
Script = VisualScriptMarshaller.ConvertToUnmanaged(managed.Script),
|
||||||
|
NodeId = managed.NodeId,
|
||||||
|
BoxId = managed.BoxId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static void Free(VisualScriptStackFrameNative unmanaged)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void BuildCommand(string arg)
|
internal void BuildCommand(string arg)
|
||||||
{
|
{
|
||||||
if (TryBuildCommand(arg))
|
if (TryBuildCommand(arg))
|
||||||
@@ -1419,116 +1504,133 @@ namespace FlaxEditor
|
|||||||
Instance.StateMachine.StateChanged += RequestStartPlayOnEditMode;
|
Instance.StateMachine.StateChanged += RequestStartPlayOnEditMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_ReadOutputLogs", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern int Internal_ReadOutputLogs(string[] outMessages, byte[] outLogTypes, long[] outLogTimes);
|
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);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_SetPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_SetPlayMode(bool value);
|
internal static partial void Internal_SetPlayMode([MarshalAs(UnmanagedType.U1)] bool value);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern string Internal_GetProjectPath();
|
internal static partial string Internal_GetProjectPath();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_CloneAssetFile(string dstPath, string srcPath, ref Guid dstId);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_CloneAssetFile(string dstPath, string srcPath, ref Guid dstId);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_Import", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_Import(string inputPath, string outputPath, IntPtr arg);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_Import(string inputPath, string outputPath, IntPtr arg);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_ImportTexture", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_ImportTexture(string inputPath, string outputPath, ref TextureImportSettings.InternalOptions options);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_ImportTexture(string inputPath, string outputPath, ref TextureImportSettings.InternalOptions options);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_ImportModel", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_ImportModel(string inputPath, string outputPath, ref ModelImportSettings.InternalOptions options);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_ImportModel(string inputPath, string outputPath, ref ModelImportSettings.InternalOptions options);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_ImportAudio", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_ImportAudio(string inputPath, string outputPath, ref AudioImportSettings.InternalOptions options);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_ImportAudio(string inputPath, string outputPath, ref AudioImportSettings.InternalOptions options);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetAudioClipMetadata", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_GetAudioClipMetadata(IntPtr obj, out int originalSize, out int importedSize);
|
internal static partial void Internal_GetAudioClipMetadata(IntPtr obj, out int originalSize, out int importedSize);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_SaveJsonAsset(string outputPath, string data, string typename);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_SaveJsonAsset(string outputPath, string data, string typename);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CopyCache", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_CopyCache(ref Guid dstId, ref Guid srcId);
|
internal static partial void Internal_CopyCache(ref Guid dstId, ref Guid srcId);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_BakeLightmaps", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_BakeLightmaps(bool cancel);
|
internal static partial void Internal_BakeLightmaps([MarshalAs(UnmanagedType.U1)] bool cancel);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern string Internal_GetShaderAssetSourceCode(IntPtr obj);
|
internal static partial string Internal_GetShaderAssetSourceCode(IntPtr obj);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_CookMeshCollision(string path, CollisionDataType type, IntPtr model, int modelLodIndex, uint materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int convexVertexLimit);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_CookMeshCollision(string path, CollisionDataType type, IntPtr model, int modelLodIndex, uint materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int convexVertexLimit);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetCollisionWires", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_GetCollisionWires(IntPtr collisionData, out Float3[] triangles, out int[] indices);
|
internal static partial void Internal_GetCollisionWires(IntPtr collisionData, [MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), ConstantElementCount = 1)] out Float3[] triangles, [MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), ConstantElementCount = 1)] out int[] indices);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetEditorBoxWithChildren", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_GetEditorBoxWithChildren(IntPtr obj, out BoundingBox resultAsRef);
|
internal static partial void Internal_GetEditorBoxWithChildren(IntPtr obj, out BoundingBox resultAsRef);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_SetOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_SetOptions(ref InternalOptions options);
|
internal static partial void Internal_SetOptions(ref InternalOptions options);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_DrawNavMesh", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_DrawNavMesh();
|
internal static partial void Internal_DrawNavMesh();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CloseSplashScreen", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_CloseSplashScreen();
|
internal static partial void Internal_CloseSplashScreen();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CreateAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_CreateAsset(NewAssetType type, string outputPath);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_CreateAsset(NewAssetType type, string outputPath);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_CreateVisualScript(string outputPath, string baseTypename);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_CreateVisualScript(string outputPath, string baseTypename);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern string Internal_CanImport(string extension);
|
internal static partial string Internal_CanImport(string extension);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_CanExport(string path);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_CanExport(string path);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_Export(string inputPath, string outputFolder);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_Export(string inputPath, string outputFolder);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetIsEveryAssemblyLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_GetIsEveryAssemblyLoaded();
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_GetIsEveryAssemblyLoaded();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetLastProjectOpenedEngineBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern int Internal_GetLastProjectOpenedEngineBuild();
|
internal static partial int Internal_GetLastProjectOpenedEngineBuild();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetIsCSGActive", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_GetIsCSGActive();
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_GetIsCSGActive();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_RunVisualScriptBreakpointLoopTick", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime);
|
internal static partial void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetVisualScriptLocals", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern VisualScriptLocal[] Internal_GetVisualScriptLocals();
|
[return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), ConstantElementCount = 1)]
|
||||||
|
internal static partial VisualScriptLocal[] Internal_GetVisualScriptLocals();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetVisualScriptStackFrames", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern VisualScriptStackFrame[] Internal_GetVisualScriptStackFrames();
|
[return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), ConstantElementCount = 1)]
|
||||||
|
internal static partial VisualScriptStackFrame[] Internal_GetVisualScriptStackFrames();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetVisualScriptPreviousScopeFrame", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern VisualScriptStackFrame Internal_GetVisualScriptPreviousScopeFrame();
|
internal static partial VisualScriptStackFrame Internal_GetVisualScriptPreviousScopeFrame();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_EvaluateVisualScriptLocal", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_EvaluateVisualScriptLocal(IntPtr script, ref VisualScriptLocal local);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_EvaluateVisualScriptLocal(IntPtr script, ref VisualScriptLocal local);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_DeserializeSceneObject(IntPtr sceneObject, string json);
|
internal static partial void Internal_DeserializeSceneObject(IntPtr sceneObject, string json);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_LoadAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_LoadAsset(ref Guid id);
|
internal static partial void Internal_LoadAsset(ref Guid id);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_CanSetToRoot", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_GetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern float Internal_GetAnimationTime(IntPtr animatedModel);
|
internal static partial float Internal_GetAnimationTime(IntPtr animatedModel);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Editor::Internal_SetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_SetAnimationTime(IntPtr animatedModel, float time);
|
internal static partial void Internal_SetAnimationTime(IntPtr animatedModel, float time);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using FlaxEditor.GUI.Timeline.Tracks;
|
|||||||
using FlaxEditor.Utilities;
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEditor.Viewport.Previews;
|
using FlaxEditor.Viewport.Previews;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.GUI.Timeline
|
namespace FlaxEditor.GUI.Timeline
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -323,20 +323,25 @@ namespace CustomEditorsUtilInternal
|
|||||||
{
|
{
|
||||||
MonoReflectionType* GetCustomEditor(MonoReflectionType* targetType)
|
MonoReflectionType* GetCustomEditor(MonoReflectionType* targetType)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.CustomEditors.CustomEditorsUtil::Internal_GetCustomEditor")
|
||||||
return CustomEditorsUtil::GetCustomEditor(targetType);
|
return CustomEditorsUtil::GetCustomEditor(targetType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace LayersAndTagsSettingsInternal1
|
namespace LayersAndTagsSettingsInternal1
|
||||||
{
|
{
|
||||||
MonoArray* GetCurrentTags()
|
MonoArray* GetCurrentTags(int* tagsCount)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentTags")
|
||||||
|
*tagsCount = Level::Tags.Count();
|
||||||
return MUtils::ToArray(Level::Tags);
|
return MUtils::ToArray(Level::Tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoArray* GetCurrentLayers()
|
MonoArray* GetCurrentLayers(int* layersCount)
|
||||||
{
|
{
|
||||||
return MUtils::ToArray(Span<String>(Level::Layers, Math::Max(1, Level::GetNonEmptyLayerNamesCount())));
|
SCRIPTING_EXPORT("FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentLayers")
|
||||||
|
*layersCount = Math::Max(1, Level::GetNonEmptyLayerNamesCount());
|
||||||
|
return MUtils::ToArray(Span<String>(Level::Layers, *layersCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,6 +349,7 @@ namespace GameSettingsInternal1
|
|||||||
{
|
{
|
||||||
void Apply()
|
void Apply()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Content.Settings.GameSettings::Apply")
|
||||||
LOG(Info, "Apply game settings");
|
LOG(Info, "Apply game settings");
|
||||||
GameSettings::Load();
|
GameSettings::Load();
|
||||||
}
|
}
|
||||||
@@ -380,6 +386,7 @@ class ManagedEditorInternal
|
|||||||
public:
|
public:
|
||||||
static bool IsDevInstance()
|
static bool IsDevInstance()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::IsDevInstance")
|
||||||
#if COMPILE_WITH_DEV_ENV
|
#if COMPILE_WITH_DEV_ENV
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
@@ -389,6 +396,7 @@ public:
|
|||||||
|
|
||||||
static bool IsOfficialBuild()
|
static bool IsOfficialBuild()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::IsOfficialBuild")
|
||||||
#if OFFICIAL_BUILD
|
#if OFFICIAL_BUILD
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
@@ -398,18 +406,20 @@ public:
|
|||||||
|
|
||||||
static bool IsPlayMode()
|
static bool IsPlayMode()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_IsPlayMode")
|
||||||
return Editor::IsPlayMode;
|
return Editor::IsPlayMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32 ReadOutputLogs(MonoArray* outMessages, MonoArray* outLogTypes, MonoArray* outLogTimes)
|
static int32 ReadOutputLogs(MonoArray** outMessages, MonoArray** outLogTypes, MonoArray** outLogTimes, int outArraySize)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_ReadOutputLogs")
|
||||||
ScopeLock lock(CachedLogDataLocker);
|
ScopeLock lock(CachedLogDataLocker);
|
||||||
|
|
||||||
if (CachedLogData.IsEmpty() || CachedLogData.Get() == nullptr)
|
if (CachedLogData.IsEmpty() || CachedLogData.Get() == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
const int32 maxCount = (int32)mono_array_length(outMessages);
|
const int32 maxCount = outArraySize;//(int32)mono_array_length(*outMessages);
|
||||||
|
|
||||||
byte* ptr = CachedLogData.Get();
|
byte* ptr = CachedLogData.Get();
|
||||||
byte* end = ptr + CachedLogData.Count();
|
byte* end = ptr + CachedLogData.Count();
|
||||||
@@ -429,9 +439,9 @@ public:
|
|||||||
|
|
||||||
auto msgObj = MUtils::ToString(StringView(msg, length));
|
auto msgObj = MUtils::ToString(StringView(msg, length));
|
||||||
|
|
||||||
mono_array_setref(outMessages, count, msgObj);
|
mono_array_setref(*outMessages, count, msgObj);
|
||||||
mono_array_set(outLogTypes, byte, count, type);
|
mono_array_set(*outLogTypes, byte, count, type);
|
||||||
mono_array_set(outLogTimes, int64, count, time);
|
mono_array_set(*outLogTimes, int64, count, time);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -445,21 +455,25 @@ public:
|
|||||||
|
|
||||||
static void SetPlayMode(bool value)
|
static void SetPlayMode(bool value)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_SetPlayMode")
|
||||||
Editor::IsPlayMode = value;
|
Editor::IsPlayMode = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MonoString* GetProjectPath()
|
static MonoString* GetProjectPath()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetProjectPath")
|
||||||
return MUtils::ToString(Editor::Project->ProjectPath);
|
return MUtils::ToString(Editor::Project->ProjectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CloseSplashScreen()
|
static void CloseSplashScreen()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CloseSplashScreen")
|
||||||
Editor::CloseSplashScreen();
|
Editor::CloseSplashScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CloneAssetFile(MonoString* dstPathObj, MonoString* srcPathObj, Guid* dstId)
|
static bool CloneAssetFile(MonoString* dstPathObj, MonoString* srcPathObj, Guid* dstId)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CloneAssetFile")
|
||||||
// Get normalized paths
|
// Get normalized paths
|
||||||
String dstPath, srcPath;
|
String dstPath, srcPath;
|
||||||
MUtils::ToString(dstPathObj, dstPath);
|
MUtils::ToString(dstPathObj, dstPath);
|
||||||
@@ -489,6 +503,7 @@ public:
|
|||||||
|
|
||||||
static bool CreateAsset(NewAssetType type, MonoString* outputPathObj)
|
static bool CreateAsset(NewAssetType type, MonoString* outputPathObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CreateAsset")
|
||||||
String tag;
|
String tag;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@@ -541,6 +556,7 @@ public:
|
|||||||
|
|
||||||
static bool CreateVisualScript(MonoString* outputPathObj, MonoString* baseTypenameObj)
|
static bool CreateVisualScript(MonoString* outputPathObj, MonoString* baseTypenameObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CreateVisualScript")
|
||||||
String outputPath;
|
String outputPath;
|
||||||
MUtils::ToString(outputPathObj, outputPath);
|
MUtils::ToString(outputPathObj, outputPath);
|
||||||
FileSystem::NormalizePath(outputPath);
|
FileSystem::NormalizePath(outputPath);
|
||||||
@@ -551,6 +567,7 @@ public:
|
|||||||
|
|
||||||
static MonoString* CanImport(MonoString* extensionObj)
|
static MonoString* CanImport(MonoString* extensionObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CanImport")
|
||||||
String extension;
|
String extension;
|
||||||
MUtils::ToString(extensionObj, extension);
|
MUtils::ToString(extensionObj, extension);
|
||||||
if (extension.Length() > 0 && extension[0] == '.')
|
if (extension.Length() > 0 && extension[0] == '.')
|
||||||
@@ -561,6 +578,7 @@ public:
|
|||||||
|
|
||||||
static bool Import(MonoString* inputPathObj, MonoString* outputPathObj, void* arg)
|
static bool Import(MonoString* inputPathObj, MonoString* outputPathObj, void* arg)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_Import")
|
||||||
String inputPath, outputPath;
|
String inputPath, outputPath;
|
||||||
MUtils::ToString(inputPathObj, inputPath);
|
MUtils::ToString(inputPathObj, inputPath);
|
||||||
MUtils::ToString(outputPathObj, outputPath);
|
MUtils::ToString(outputPathObj, outputPath);
|
||||||
@@ -572,6 +590,7 @@ public:
|
|||||||
|
|
||||||
static bool ImportTexture(MonoString* inputPathObj, MonoString* outputPathObj, InternalTextureOptions* optionsObj)
|
static bool ImportTexture(MonoString* inputPathObj, MonoString* outputPathObj, InternalTextureOptions* optionsObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_ImportTexture")
|
||||||
ImportTexture::Options options;
|
ImportTexture::Options options;
|
||||||
InternalTextureOptions::Convert(optionsObj, &options);
|
InternalTextureOptions::Convert(optionsObj, &options);
|
||||||
|
|
||||||
@@ -580,6 +599,7 @@ public:
|
|||||||
|
|
||||||
static bool ImportModel(MonoString* inputPathObj, MonoString* outputPathObj, InternalModelOptions* optionsObj)
|
static bool ImportModel(MonoString* inputPathObj, MonoString* outputPathObj, InternalModelOptions* optionsObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_ImportModel")
|
||||||
ImportModelFile::Options options;
|
ImportModelFile::Options options;
|
||||||
InternalModelOptions::Convert(optionsObj, &options);
|
InternalModelOptions::Convert(optionsObj, &options);
|
||||||
|
|
||||||
@@ -588,6 +608,7 @@ public:
|
|||||||
|
|
||||||
static bool ImportAudio(MonoString* inputPathObj, MonoString* outputPathObj, InternalAudioOptions* optionsObj)
|
static bool ImportAudio(MonoString* inputPathObj, MonoString* outputPathObj, InternalAudioOptions* optionsObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_ImportAudio")
|
||||||
ImportAudio::Options options;
|
ImportAudio::Options options;
|
||||||
InternalAudioOptions::Convert(optionsObj, &options);
|
InternalAudioOptions::Convert(optionsObj, &options);
|
||||||
|
|
||||||
@@ -596,6 +617,7 @@ public:
|
|||||||
|
|
||||||
static void GetAudioClipMetadata(AudioClip* clip, int32* originalSize, int32* importedSize)
|
static void GetAudioClipMetadata(AudioClip* clip, int32* originalSize, int32* importedSize)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetAudioClipMetadata")
|
||||||
INTERNAL_CALL_CHECK(clip);
|
INTERNAL_CALL_CHECK(clip);
|
||||||
*originalSize = clip->AudioHeader.OriginalSize;
|
*originalSize = clip->AudioHeader.OriginalSize;
|
||||||
*importedSize = clip->AudioHeader.ImportedSize;
|
*importedSize = clip->AudioHeader.ImportedSize;
|
||||||
@@ -603,6 +625,7 @@ public:
|
|||||||
|
|
||||||
static bool SaveJsonAsset(MonoString* outputPathObj, MonoString* dataObj, MonoString* dataTypeNameObj)
|
static bool SaveJsonAsset(MonoString* outputPathObj, MonoString* dataObj, MonoString* dataTypeNameObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_SaveJsonAsset")
|
||||||
String outputPath;
|
String outputPath;
|
||||||
MUtils::ToString(outputPathObj, outputPath);
|
MUtils::ToString(outputPathObj, outputPath);
|
||||||
FileSystem::NormalizePath(outputPath);
|
FileSystem::NormalizePath(outputPath);
|
||||||
@@ -623,6 +646,8 @@ public:
|
|||||||
|
|
||||||
static bool GetTextureImportOptions(MonoString* pathObj, InternalTextureOptions* result)
|
static bool GetTextureImportOptions(MonoString* pathObj, InternalTextureOptions* result)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Content.Import.TextureImportEntry::Internal_GetTextureImportOptions")
|
||||||
|
|
||||||
String path;
|
String path;
|
||||||
MUtils::ToString(pathObj, path);
|
MUtils::ToString(pathObj, path);
|
||||||
FileSystem::NormalizePath(path);
|
FileSystem::NormalizePath(path);
|
||||||
@@ -641,6 +666,7 @@ public:
|
|||||||
|
|
||||||
static void GetModelImportOptions(MonoString* pathObj, InternalModelOptions* result)
|
static void GetModelImportOptions(MonoString* pathObj, InternalModelOptions* result)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Content.Import.ModelImportEntry::Internal_GetModelImportOptions")
|
||||||
// Initialize defaults
|
// Initialize defaults
|
||||||
ImportModelFile::Options options;
|
ImportModelFile::Options options;
|
||||||
if (const auto* graphicsSettings = GraphicsSettings::Get())
|
if (const auto* graphicsSettings = GraphicsSettings::Get())
|
||||||
@@ -660,6 +686,7 @@ public:
|
|||||||
|
|
||||||
static bool GetAudioImportOptions(MonoString* pathObj, InternalAudioOptions* result)
|
static bool GetAudioImportOptions(MonoString* pathObj, InternalAudioOptions* result)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Content.Import.AudioImportEntry::Internal_GetAudioImportOptions")
|
||||||
String path;
|
String path;
|
||||||
MUtils::ToString(pathObj, path);
|
MUtils::ToString(pathObj, path);
|
||||||
FileSystem::NormalizePath(path);
|
FileSystem::NormalizePath(path);
|
||||||
@@ -678,6 +705,7 @@ public:
|
|||||||
|
|
||||||
static bool CanExport(MonoString* pathObj)
|
static bool CanExport(MonoString* pathObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CanExport")
|
||||||
#if COMPILE_WITH_ASSETS_EXPORTER
|
#if COMPILE_WITH_ASSETS_EXPORTER
|
||||||
String path;
|
String path;
|
||||||
MUtils::ToString(pathObj, path);
|
MUtils::ToString(pathObj, path);
|
||||||
@@ -691,6 +719,7 @@ public:
|
|||||||
|
|
||||||
static bool Export(MonoString* inputPathObj, MonoString* outputFolderObj)
|
static bool Export(MonoString* inputPathObj, MonoString* outputFolderObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_Export")
|
||||||
#if COMPILE_WITH_ASSETS_EXPORTER
|
#if COMPILE_WITH_ASSETS_EXPORTER
|
||||||
String inputPath;
|
String inputPath;
|
||||||
MUtils::ToString(inputPathObj, inputPath);
|
MUtils::ToString(inputPathObj, inputPath);
|
||||||
@@ -708,11 +737,13 @@ public:
|
|||||||
|
|
||||||
static void CopyCache(Guid* dstId, Guid* srcId)
|
static void CopyCache(Guid* dstId, Guid* srcId)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CopyCache")
|
||||||
ShaderCacheManager::CopyCache(*dstId, *srcId);
|
ShaderCacheManager::CopyCache(*dstId, *srcId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BakeLightmaps(bool cancel)
|
static void BakeLightmaps(bool cancel)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_BakeLightmaps")
|
||||||
auto builder = ShadowsOfMordor::Builder::Instance();
|
auto builder = ShadowsOfMordor::Builder::Instance();
|
||||||
if (cancel)
|
if (cancel)
|
||||||
builder->CancelBuild();
|
builder->CancelBuild();
|
||||||
@@ -722,6 +753,7 @@ public:
|
|||||||
|
|
||||||
static MonoString* GetShaderAssetSourceCode(BinaryAsset* obj)
|
static MonoString* GetShaderAssetSourceCode(BinaryAsset* obj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetShaderAssetSourceCode")
|
||||||
INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
|
INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
|
||||||
if (obj->WaitForLoaded())
|
if (obj->WaitForLoaded())
|
||||||
DebugLog::ThrowNullReference();
|
DebugLog::ThrowNullReference();
|
||||||
@@ -747,6 +779,7 @@ public:
|
|||||||
|
|
||||||
static bool CookMeshCollision(MonoString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit)
|
static bool CookMeshCollision(MonoString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CookMeshCollision")
|
||||||
#if COMPILE_WITH_PHYSICS_COOKING
|
#if COMPILE_WITH_PHYSICS_COOKING
|
||||||
CollisionCooking::Argument arg;
|
CollisionCooking::Argument arg;
|
||||||
String path;
|
String path;
|
||||||
@@ -767,6 +800,7 @@ public:
|
|||||||
|
|
||||||
static void GetCollisionWires(CollisionData* collisionData, MonoArray** triangles, MonoArray** indices)
|
static void GetCollisionWires(CollisionData* collisionData, MonoArray** triangles, MonoArray** indices)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetCollisionWires")
|
||||||
if (!collisionData || collisionData->WaitForLoaded() || collisionData->GetOptions().Type == CollisionDataType::None)
|
if (!collisionData || collisionData->WaitForLoaded() || collisionData->GetOptions().Type == CollisionDataType::None)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -792,32 +826,38 @@ public:
|
|||||||
|
|
||||||
static void GetEditorBoxWithChildren(Actor* obj, BoundingBox* result)
|
static void GetEditorBoxWithChildren(Actor* obj, BoundingBox* result)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetEditorBoxWithChildren")
|
||||||
INTERNAL_CALL_CHECK(obj);
|
INTERNAL_CALL_CHECK(obj);
|
||||||
*result = obj->GetEditorBoxChildren();
|
*result = obj->GetEditorBoxChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetOptions(ManagedEditor::InternalOptions* options)
|
static void SetOptions(ManagedEditor::InternalOptions* options)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_SetOptions")
|
||||||
ManagedEditor::ManagedEditorOptions = *options;
|
ManagedEditor::ManagedEditorOptions = *options;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawNavMesh()
|
static void DrawNavMesh()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_DrawNavMesh")
|
||||||
Navigation::DrawNavMesh();
|
Navigation::DrawNavMesh();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetIsEveryAssemblyLoaded()
|
static bool GetIsEveryAssemblyLoaded()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetIsEveryAssemblyLoaded")
|
||||||
return Scripting::IsEveryAssemblyLoaded();
|
return Scripting::IsEveryAssemblyLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32 GetLastProjectOpenedEngineBuild()
|
static int32 GetLastProjectOpenedEngineBuild()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetLastProjectOpenedEngineBuild")
|
||||||
return Editor::LastProjectOpenedEngineBuild;
|
return Editor::LastProjectOpenedEngineBuild;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetIsCSGActive()
|
static bool GetIsCSGActive()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetIsCSGActive")
|
||||||
#if COMPILE_WITH_CSG_BUILDER
|
#if COMPILE_WITH_CSG_BUILDER
|
||||||
return CSG::Builder::IsActive();
|
return CSG::Builder::IsActive();
|
||||||
#else
|
#else
|
||||||
@@ -827,6 +867,7 @@ public:
|
|||||||
|
|
||||||
static void RunVisualScriptBreakpointLoopTick(float deltaTime)
|
static void RunVisualScriptBreakpointLoopTick(float deltaTime)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_RunVisualScriptBreakpointLoopTick")
|
||||||
// Update
|
// Update
|
||||||
Platform::Tick();
|
Platform::Tick();
|
||||||
Engine::HasFocus = (Engine::MainWindow && Engine::MainWindow->IsFocused()) || Platform::GetHasFocus();
|
Engine::HasFocus = (Engine::MainWindow && Engine::MainWindow->IsFocused()) || Platform::GetHasFocus();
|
||||||
@@ -921,6 +962,7 @@ public:
|
|||||||
|
|
||||||
static MonoArray* GetVisualScriptLocals()
|
static MonoArray* GetVisualScriptLocals()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetVisualScriptLocals")
|
||||||
MonoArray* result = nullptr;
|
MonoArray* result = nullptr;
|
||||||
const auto stack = VisualScripting::GetThreadStackTop();
|
const auto stack = VisualScripting::GetThreadStackTop();
|
||||||
if (stack && stack->Scope)
|
if (stack && stack->Scope)
|
||||||
@@ -969,6 +1011,7 @@ public:
|
|||||||
|
|
||||||
static MonoArray* GetVisualScriptStackFrames()
|
static MonoArray* GetVisualScriptStackFrames()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_GetVisualScriptStackFrames")
|
||||||
MonoArray* result = nullptr;
|
MonoArray* result = nullptr;
|
||||||
const auto stack = VisualScripting::GetThreadStackTop();
|
const auto stack = VisualScripting::GetThreadStackTop();
|
||||||
if (stack)
|
if (stack)
|
||||||
@@ -1022,6 +1065,7 @@ public:
|
|||||||
|
|
||||||
static bool EvaluateVisualScriptLocal(VisualScript* script, VisualScriptLocalManaged* local)
|
static bool EvaluateVisualScriptLocal(VisualScript* script, VisualScriptLocalManaged* local)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_EvaluateVisualScriptLocal")
|
||||||
Variant v;
|
Variant v;
|
||||||
if (VisualScripting::Evaluate(script, VisualScripting::GetThreadStackTop()->Instance, local->NodeId, local->BoxId, v))
|
if (VisualScripting::Evaluate(script, VisualScripting::GetThreadStackTop()->Instance, local->NodeId, local->BoxId, v))
|
||||||
{
|
{
|
||||||
@@ -1034,6 +1078,7 @@ public:
|
|||||||
|
|
||||||
static void DeserializeSceneObject(SceneObject* sceneObject, MonoString* jsonObj)
|
static void DeserializeSceneObject(SceneObject* sceneObject, MonoString* jsonObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_DeserializeSceneObject")
|
||||||
PROFILE_CPU_NAMED("DeserializeSceneObject");
|
PROFILE_CPU_NAMED("DeserializeSceneObject");
|
||||||
|
|
||||||
StringAnsi json;
|
StringAnsi json;
|
||||||
@@ -1062,11 +1107,13 @@ public:
|
|||||||
|
|
||||||
static void LoadAsset(Guid* id)
|
static void LoadAsset(Guid* id)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_LoadAsset")
|
||||||
Content::LoadAsync<Asset>(*id);
|
Content::LoadAsync<Asset>(*id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CanSetToRoot(Prefab* prefab, Actor* targetActor)
|
static bool CanSetToRoot(Prefab* prefab, Actor* targetActor)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_CanSetToRoot")
|
||||||
// Reference: Prefab::ApplyAll(Actor* targetActor)
|
// Reference: Prefab::ApplyAll(Actor* targetActor)
|
||||||
if (targetActor->GetPrefabID() != prefab->GetID())
|
if (targetActor->GetPrefabID() != prefab->GetID())
|
||||||
return false;
|
return false;
|
||||||
@@ -1089,11 +1136,13 @@ public:
|
|||||||
|
|
||||||
static float GetAnimationTime(AnimatedModel* animatedModel)
|
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 animatedModel && animatedModel->GraphInstance.State.Count() == 1 ? animatedModel->GraphInstance.State[0].Animation.TimePosition : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetAnimationTime(AnimatedModel* animatedModel, float time)
|
static void SetAnimationTime(AnimatedModel* animatedModel, float time)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.Editor::Internal_SetAnimationTime")
|
||||||
if (animatedModel && animatedModel->GraphInstance.State.Count() == 1)
|
if (animatedModel && animatedModel->GraphInstance.State.Count() == 1)
|
||||||
animatedModel->GraphInstance.State[0].Animation.TimePosition = time;
|
animatedModel->GraphInstance.State[0].Animation.TimePosition = time;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -375,7 +375,9 @@ namespace FlaxEditor.Modules
|
|||||||
Thread.Sleep(0);
|
Thread.Sleep(0);
|
||||||
|
|
||||||
_workerThread.Join(1000);
|
_workerThread.Join(1000);
|
||||||
_workerThread.Abort();
|
#if !USE_NETCORE
|
||||||
|
_workerThread.Abort(); // Deprecated in .NET 7
|
||||||
|
#endif
|
||||||
_workerThread = null;
|
_workerThread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ namespace FlaxEditor.Modules.SourceCodeEditing
|
|||||||
{
|
{
|
||||||
Profiler.BeginEvent("GetXmlDocs");
|
Profiler.BeginEvent("GetXmlDocs");
|
||||||
|
|
||||||
var uri = new UriBuilder(assembly.CodeBase);
|
var uri = new UriBuilder(Utils.GetAssemblyLocation(assembly));
|
||||||
var path = Uri.UnescapeDataString(uri.Path);
|
var path = Uri.UnescapeDataString(uri.Path);
|
||||||
var name = assembly.GetName().Name;
|
var name = assembly.GetName().Name;
|
||||||
var xmlFilePath = Path.Combine(Path.GetDirectoryName(path), name + ".xml");
|
var xmlFilePath = Path.Combine(Path.GetDirectoryName(path), name + ".xml");
|
||||||
|
|||||||
@@ -391,9 +391,27 @@ namespace FlaxEditor.Modules.SourceCodeEditing
|
|||||||
|
|
||||||
private static bool HasAssemblyValidAnyTypes(Assembly assembly)
|
private static bool HasAssemblyValidAnyTypes(Assembly assembly)
|
||||||
{
|
{
|
||||||
|
var codeBase = Utils.GetAssemblyLocation(assembly);
|
||||||
|
#if USE_NETCORE
|
||||||
|
if (assembly.ManifestModule.FullyQualifiedName == "<In Memory Module>")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(codeBase))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Skip runtime related assemblies
|
||||||
|
string repositoryUrl = assembly.GetCustomAttributes<AssemblyMetadataAttribute>().FirstOrDefault(x => x.Key == "RepositoryUrl")?.Value ?? "";
|
||||||
|
if (repositoryUrl != "https://github.com/dotnet/runtime")
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
if (string.IsNullOrEmpty(codeBase))
|
||||||
|
return true;
|
||||||
|
|
||||||
// Skip assemblies from in-build Mono directory
|
// Skip assemblies from in-build Mono directory
|
||||||
var codeBase = assembly.CodeBase;
|
if (!codeBase.Contains("/Mono/lib/mono/"))
|
||||||
return string.IsNullOrEmpty(codeBase) || !codeBase.Contains("/Mono/lib/mono/");
|
return true;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool HasAssemblyValidScriptingTypes(Assembly a)
|
private static bool HasAssemblyValidScriptingTypes(Assembly a)
|
||||||
|
|||||||
@@ -218,6 +218,16 @@ namespace FlaxEditor.Options
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace FlaxEditor
|
|||||||
|
|
||||||
var type = plugin.GetType();
|
var type = plugin.GetType();
|
||||||
var assembly = type.Assembly;
|
var assembly = type.Assembly;
|
||||||
var assemblyPath = assembly.Location;
|
var assemblyPath = Utils.GetAssemblyLocation(assembly);
|
||||||
var assemblyName = assembly.GetName().Name;
|
var assemblyName = assembly.GetName().Name;
|
||||||
var dotEditorPos = assemblyName.LastIndexOf(".Editor", StringComparison.OrdinalIgnoreCase);
|
var dotEditorPos = assemblyName.LastIndexOf(".Editor", StringComparison.OrdinalIgnoreCase);
|
||||||
if (dotEditorPos != -1)
|
if (dotEditorPos != -1)
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ namespace FlaxEditor.Progress.Handlers
|
|||||||
|
|
||||||
private void OnScriptsReload()
|
private void OnScriptsReload()
|
||||||
{
|
{
|
||||||
|
#if !USE_NETCORE
|
||||||
// Clear types cache
|
// Clear types cache
|
||||||
Newtonsoft.Json.JsonSerializer.ClearCache();
|
Newtonsoft.Json.JsonSerializer.ClearCache();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnScriptsReloadEnd()
|
private void OnScriptsReloadEnd()
|
||||||
|
|||||||
@@ -8,6 +8,110 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace FlaxEditor
|
namespace FlaxEditor
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class FlaxVersionConverter : JsonConverter
|
||||||
|
{
|
||||||
|
// Original implementation is based on Newtonsoft.Json VersionConverter
|
||||||
|
/// <summary>
|
||||||
|
/// Writes the JSON representation of the object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
|
||||||
|
/// <param name="value">The value.</param>
|
||||||
|
/// <param name="serializer">The calling serializer.</param>
|
||||||
|
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNull();
|
||||||
|
}
|
||||||
|
else if (value is Version)
|
||||||
|
{
|
||||||
|
writer.WriteValue(value.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new JsonSerializationException("Expected Version object value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads the JSON representation of the object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
|
||||||
|
/// <param name="objectType">Type of the object.</param>
|
||||||
|
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
|
||||||
|
/// <param name="serializer">The calling serializer.</param>
|
||||||
|
/// <returns>The object value.</returns>
|
||||||
|
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonToken.Null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonToken.StartObject)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
Dictionary<string, int> values = new Dictionary<string, int>();
|
||||||
|
while (reader.TokenType == JsonToken.PropertyName)
|
||||||
|
{
|
||||||
|
var key = reader.Value as string;
|
||||||
|
reader.Read();
|
||||||
|
var val = (long)reader.Value;
|
||||||
|
reader.Read();
|
||||||
|
values.Add(key, (int)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int major = 0, minor = 0, build = 0;
|
||||||
|
values.TryGetValue("Major", out major);
|
||||||
|
values.TryGetValue("Minor", out minor);
|
||||||
|
values.TryGetValue("Build", out build);
|
||||||
|
|
||||||
|
Version v = new Version(major, minor, build);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reader.TokenType == JsonToken.String)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Version v = new Version((string)reader.Value!);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether this instance can convert the specified object type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectType">Type of the object.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
|
||||||
|
/// </returns>
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return objectType == typeof(Version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains information about Flax project.
|
/// Contains information about Flax project.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -154,7 +258,7 @@ namespace FlaxEditor
|
|||||||
{
|
{
|
||||||
// Load
|
// Load
|
||||||
var contents = File.ReadAllText(path);
|
var contents = File.ReadAllText(path);
|
||||||
var project = JsonConvert.DeserializeObject<ProjectInfo>(contents);
|
var project = JsonConvert.DeserializeObject<ProjectInfo>(contents, new JsonSerializerSettings() { Converters = new[] { new FlaxVersionConverter() } });
|
||||||
project.ProjectPath = path;
|
project.ProjectPath = path;
|
||||||
project.ProjectFolderPath = StringUtils.NormalizePath(Path.GetDirectoryName(path));
|
project.ProjectFolderPath = StringUtils.NormalizePath(Path.GetDirectoryName(path));
|
||||||
|
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ bool ScriptsBuilder::IsReady()
|
|||||||
|
|
||||||
void ScriptsBuilder::MarkWorkspaceDirty()
|
void ScriptsBuilder::MarkWorkspaceDirty()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.ScriptsBuilder::Internal_MarkWorkspaceDirty")
|
||||||
ScopeLock scopeLock(_locker);
|
ScopeLock scopeLock(_locker);
|
||||||
_lastSourceCodeEdited = DateTime::Now();
|
_lastSourceCodeEdited = DateTime::Now();
|
||||||
_wasProjectStructureChanged = true;
|
_wasProjectStructureChanged = true;
|
||||||
@@ -183,6 +184,7 @@ void ScriptsBuilder::MarkWorkspaceDirty()
|
|||||||
|
|
||||||
void ScriptsBuilder::CheckForCompile()
|
void ScriptsBuilder::CheckForCompile()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.ScriptsBuilder::Internal_CheckForCompile")
|
||||||
ScopeLock scopeLock(_locker);
|
ScopeLock scopeLock(_locker);
|
||||||
if (IsSourceDirty())
|
if (IsSourceDirty())
|
||||||
Compile();
|
Compile();
|
||||||
@@ -205,6 +207,7 @@ void ScriptsBuilderImpl::onScriptsReloadEnd()
|
|||||||
|
|
||||||
void ScriptsBuilder::Compile()
|
void ScriptsBuilder::Compile()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEditor.ScriptsBuilder::Internal_Compile")
|
||||||
ScopeLock scopeLock(_locker);
|
ScopeLock scopeLock(_locker);
|
||||||
|
|
||||||
// Request compile job
|
// Request compile job
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ using System.Linq;
|
|||||||
using FlaxEditor.Options;
|
using FlaxEditor.Options;
|
||||||
using FlaxEditor.SceneGraph.Actors;
|
using FlaxEditor.SceneGraph.Actors;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
using Utils = FlaxEngine.Utils;
|
||||||
|
|
||||||
namespace FlaxEditor.States
|
namespace FlaxEditor.States
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.States
|
namespace FlaxEditor.States
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.States
|
namespace FlaxEditor.States
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using FlaxEditor.GUI.ContextMenu;
|
|||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Surface.Elements;
|
using FlaxEditor.Surface.Elements;
|
||||||
using FlaxEditor.Windows.Assets;
|
using FlaxEditor.Windows.Assets;
|
||||||
|
using FlaxEngine.Utilities;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
@@ -587,7 +588,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
for (int i = 0; i < _parameters.Length; i++)
|
for (int i = 0; i < _parameters.Length; i++)
|
||||||
{
|
{
|
||||||
writer.Write(_parameters[i].Name); // Parameter name
|
writer.Write(_parameters[i].Name); // Parameter name
|
||||||
Utilities.VariantUtils.WriteVariantType(writer, TypeUtils.GetType(_parameters[i].Type)); // Box type
|
VariantUtils.WriteVariantType(writer, TypeUtils.GetType(_parameters[i].Type)); // Box type
|
||||||
}
|
}
|
||||||
SetValue(2, stream.ToArray());
|
SetValue(2, stream.ToArray());
|
||||||
}
|
}
|
||||||
@@ -605,7 +606,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
for (int i = 0; i < parametersCount; i++)
|
for (int i = 0; i < parametersCount; i++)
|
||||||
{
|
{
|
||||||
var parameterName = reader.ReadString(); // Parameter name
|
var parameterName = reader.ReadString(); // Parameter name
|
||||||
var boxType = Utilities.VariantUtils.ReadVariantType(reader); // Box type
|
var boxType = VariantUtils.ReadVariantType(reader); // Box type
|
||||||
MakeBox(i + 1, parameterName, boxType);
|
MakeBox(i + 1, parameterName, boxType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -788,14 +789,14 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
reader.ReadByte(); // Version
|
reader.ReadByte(); // Version
|
||||||
signature.IsStatic = reader.ReadBoolean(); // Is Static
|
signature.IsStatic = reader.ReadBoolean(); // Is Static
|
||||||
signature.ReturnType = Utilities.VariantUtils.ReadVariantScriptType(reader); // Return type
|
signature.ReturnType = VariantUtils.ReadVariantScriptType(reader); // Return type
|
||||||
var parametersCount = reader.ReadInt32(); // Parameters count
|
var parametersCount = reader.ReadInt32(); // Parameters count
|
||||||
signature.Params = parametersCount != 0 ? new SignatureParamInfo[parametersCount] : Utils.GetEmptyArray<SignatureParamInfo>();
|
signature.Params = parametersCount != 0 ? new SignatureParamInfo[parametersCount] : Utils.GetEmptyArray<SignatureParamInfo>();
|
||||||
for (int i = 0; i < parametersCount; i++)
|
for (int i = 0; i < parametersCount; i++)
|
||||||
{
|
{
|
||||||
ref var param = ref signature.Params[i];
|
ref var param = ref signature.Params[i];
|
||||||
param.Name = Utilities.Utils.ReadStr(reader, 11); // Parameter name
|
param.Name = Utilities.Utils.ReadStr(reader, 11); // Parameter name
|
||||||
param.Type = Utilities.VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
param.Type = VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
||||||
param.IsOut = reader.ReadByte() != 0; // Is parameter out
|
param.IsOut = reader.ReadByte() != 0; // Is parameter out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -809,14 +810,14 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
reader.ReadByte(); // Version
|
reader.ReadByte(); // Version
|
||||||
signature.IsStatic = reader.ReadBoolean(); // Is Static
|
signature.IsStatic = reader.ReadBoolean(); // Is Static
|
||||||
signature.ReturnType = Utilities.VariantUtils.ReadVariantScriptType(reader); // Return type
|
signature.ReturnType = VariantUtils.ReadVariantScriptType(reader); // Return type
|
||||||
var parametersCount = reader.ReadInt32(); // Parameters count
|
var parametersCount = reader.ReadInt32(); // Parameters count
|
||||||
signature.Params = parametersCount != 0 ? new SignatureParamInfo[parametersCount] : Utils.GetEmptyArray<SignatureParamInfo>();
|
signature.Params = parametersCount != 0 ? new SignatureParamInfo[parametersCount] : Utils.GetEmptyArray<SignatureParamInfo>();
|
||||||
for (int i = 0; i < parametersCount; i++)
|
for (int i = 0; i < parametersCount; i++)
|
||||||
{
|
{
|
||||||
ref var param = ref signature.Params[i];
|
ref var param = ref signature.Params[i];
|
||||||
param.Name = reader.ReadString(); // Parameter name
|
param.Name = reader.ReadString(); // Parameter name
|
||||||
param.Type = Utilities.VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
param.Type = VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
||||||
param.IsOut = reader.ReadByte() != 0; // Is parameter out
|
param.IsOut = reader.ReadByte() != 0; // Is parameter out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -833,13 +834,13 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
writer.Write((byte)4); // Version
|
writer.Write((byte)4); // Version
|
||||||
writer.Write(methodInfo.IsStatic); // Is Static
|
writer.Write(methodInfo.IsStatic); // Is Static
|
||||||
Utilities.VariantUtils.WriteVariantType(writer, methodInfo.ValueType); // Return type
|
VariantUtils.WriteVariantType(writer, methodInfo.ValueType); // Return type
|
||||||
writer.Write(parameters.Length); // Parameters count
|
writer.Write(parameters.Length); // Parameters count
|
||||||
for (int i = 0; i < parameters.Length; i++)
|
for (int i = 0; i < parameters.Length; i++)
|
||||||
{
|
{
|
||||||
ref var param = ref parameters[i];
|
ref var param = ref parameters[i];
|
||||||
Utilities.Utils.WriteStr(writer, param.Name, 11); // Parameter name
|
Utilities.Utils.WriteStr(writer, param.Name, 11); // Parameter name
|
||||||
Utilities.VariantUtils.WriteVariantType(writer, param.Type); // Parameter type
|
VariantUtils.WriteVariantType(writer, param.Type); // Parameter type
|
||||||
writer.Write((byte)(param.IsOut ? 1 : 0)); // Is parameter out
|
writer.Write((byte)(param.IsOut ? 1 : 0)); // Is parameter out
|
||||||
}
|
}
|
||||||
return stream.ToArray();
|
return stream.ToArray();
|
||||||
@@ -1461,14 +1462,14 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
if (_signature.IsVirtual)
|
if (_signature.IsVirtual)
|
||||||
flags |= Flags.Virtual;
|
flags |= Flags.Virtual;
|
||||||
writer.Write((byte)flags); // Flags
|
writer.Write((byte)flags); // Flags
|
||||||
Utilities.VariantUtils.WriteVariantType(writer, _signature.ReturnType); // Return Type
|
VariantUtils.WriteVariantType(writer, _signature.ReturnType); // Return Type
|
||||||
var parametersCount = _signature.Parameters?.Length ?? 0;
|
var parametersCount = _signature.Parameters?.Length ?? 0;
|
||||||
writer.Write(parametersCount); // Parameters count
|
writer.Write(parametersCount); // Parameters count
|
||||||
for (int i = 0; i < parametersCount; i++)
|
for (int i = 0; i < parametersCount; i++)
|
||||||
{
|
{
|
||||||
ref var param = ref _signature.Parameters[i];
|
ref var param = ref _signature.Parameters[i];
|
||||||
Utilities.Utils.WriteStrAnsi(writer, param.Name, 13); // Parameter name
|
Utilities.Utils.WriteStrAnsi(writer, param.Name, 13); // Parameter name
|
||||||
Utilities.VariantUtils.WriteVariantType(writer, param.Type); // Parameter type
|
VariantUtils.WriteVariantType(writer, param.Type); // Parameter type
|
||||||
writer.Write((byte)0); // Is parameter out
|
writer.Write((byte)0); // Is parameter out
|
||||||
writer.Write((byte)0); // Has default value
|
writer.Write((byte)0); // Has default value
|
||||||
}
|
}
|
||||||
@@ -1497,13 +1498,13 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
var flags = (Flags)reader.ReadByte(); // Flags
|
var flags = (Flags)reader.ReadByte(); // Flags
|
||||||
_signature.IsStatic = (flags & Flags.Static) == Flags.Static;
|
_signature.IsStatic = (flags & Flags.Static) == Flags.Static;
|
||||||
_signature.IsVirtual = (flags & Flags.Virtual) == Flags.Virtual;
|
_signature.IsVirtual = (flags & Flags.Virtual) == Flags.Virtual;
|
||||||
_signature.ReturnType = Utilities.VariantUtils.ReadVariantScriptType(reader); // Return Type
|
_signature.ReturnType = VariantUtils.ReadVariantScriptType(reader); // Return Type
|
||||||
var parametersCount = reader.ReadInt32(); // Parameters count
|
var parametersCount = reader.ReadInt32(); // Parameters count
|
||||||
_signature.Parameters = new Parameter[parametersCount];
|
_signature.Parameters = new Parameter[parametersCount];
|
||||||
for (int i = 0; i < parametersCount; i++)
|
for (int i = 0; i < parametersCount; i++)
|
||||||
{
|
{
|
||||||
var paramName = Utilities.Utils.ReadStrAnsi(reader, 13); // Parameter name
|
var paramName = Utilities.Utils.ReadStrAnsi(reader, 13); // Parameter name
|
||||||
var paramType = Utilities.VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
var paramType = VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
||||||
var isOut = reader.ReadByte() != 0; // Is parameter out
|
var isOut = reader.ReadByte() != 0; // Is parameter out
|
||||||
var hasDefaultValue = reader.ReadByte() != 0; // Has default value
|
var hasDefaultValue = reader.ReadByte() != 0; // Has default value
|
||||||
_signature.Parameters[i] = new Parameter
|
_signature.Parameters[i] = new Parameter
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Surface.Elements;
|
using FlaxEditor.Surface.Elements;
|
||||||
|
using FlaxEngine.Utilities;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.Surface.Archetypes
|
namespace FlaxEditor.Surface.Archetypes
|
||||||
@@ -167,7 +168,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
for (int i = 0; i < fieldsLength; i++)
|
for (int i = 0; i < fieldsLength; i++)
|
||||||
{
|
{
|
||||||
Utilities.Utils.WriteStr(writer, fields[i].Name, 11); // Field type
|
Utilities.Utils.WriteStr(writer, fields[i].Name, 11); // Field type
|
||||||
Utilities.VariantUtils.WriteVariantType(writer, fields[i].ValueType); // Field type
|
VariantUtils.WriteVariantType(writer, fields[i].ValueType); // Field type
|
||||||
}
|
}
|
||||||
Values[1] = stream.ToArray();
|
Values[1] = stream.ToArray();
|
||||||
}
|
}
|
||||||
@@ -184,7 +185,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
for (int i = 0; i < fieldsLength; i++)
|
for (int i = 0; i < fieldsLength; i++)
|
||||||
{
|
{
|
||||||
var fieldName = Utilities.Utils.ReadStr(reader, 11); // Field name
|
var fieldName = Utilities.Utils.ReadStr(reader, 11); // Field name
|
||||||
var fieldType = Utilities.VariantUtils.ReadVariantType(reader); // Field type
|
var fieldType = VariantUtils.ReadVariantType(reader); // Field type
|
||||||
MakeBox(i + 1, fieldName, new ScriptType(fieldType));
|
MakeBox(i + 1, fieldName, new ScriptType(fieldType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.Loader;
|
||||||
using System.Runtime.Serialization.Formatters.Binary;
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
using FlaxEditor.CustomEditors;
|
using FlaxEditor.CustomEditors;
|
||||||
using FlaxEditor.CustomEditors.Editors;
|
using FlaxEditor.CustomEditors.Editors;
|
||||||
@@ -118,8 +119,13 @@ namespace FlaxEditor.Surface
|
|||||||
|
|
||||||
using (var stream = new MemoryStream())
|
using (var stream = new MemoryStream())
|
||||||
{
|
{
|
||||||
|
// Ensure we are in the correct load context (https://github.com/dotnet/runtime/issues/42041)
|
||||||
|
using var ctx = AssemblyLoadContext.EnterContextualReflection(typeof(Editor).Assembly);
|
||||||
|
|
||||||
var formatter = new BinaryFormatter();
|
var formatter = new BinaryFormatter();
|
||||||
|
#pragma warning disable SYSLIB0011
|
||||||
formatter.Serialize(stream, attributes);
|
formatter.Serialize(stream, attributes);
|
||||||
|
#pragma warning restore SYSLIB0011
|
||||||
_oldData = stream.ToArray();
|
_oldData = stream.ToArray();
|
||||||
}
|
}
|
||||||
editor.Select(new Proxy
|
editor.Select(new Proxy
|
||||||
@@ -141,8 +147,13 @@ namespace FlaxEditor.Surface
|
|||||||
}
|
}
|
||||||
using (var stream = new MemoryStream())
|
using (var stream = new MemoryStream())
|
||||||
{
|
{
|
||||||
|
// Ensure we are in the correct load context (https://github.com/dotnet/runtime/issues/42041)
|
||||||
|
using var ctx = AssemblyLoadContext.EnterContextualReflection(typeof(Editor).Assembly);
|
||||||
|
|
||||||
var formatter = new BinaryFormatter();
|
var formatter = new BinaryFormatter();
|
||||||
|
#pragma warning disable SYSLIB0011
|
||||||
formatter.Serialize(stream, newValue);
|
formatter.Serialize(stream, newValue);
|
||||||
|
#pragma warning restore SYSLIB0011
|
||||||
var newData = stream.ToArray();
|
var newData = stream.ToArray();
|
||||||
if (!_oldData.SequenceEqual(newData))
|
if (!_oldData.SequenceEqual(newData))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Loader;
|
||||||
using System.Runtime.Serialization.Formatters.Binary;
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
@@ -54,8 +56,13 @@ namespace FlaxEditor.Surface
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Ensure we are in the correct load context (https://github.com/dotnet/runtime/issues/42041)
|
||||||
|
using var ctx = AssemblyLoadContext.EnterContextualReflection(typeof(Editor).Assembly);
|
||||||
|
|
||||||
var formatter = new BinaryFormatter();
|
var formatter = new BinaryFormatter();
|
||||||
|
#pragma warning disable SYSLIB0011
|
||||||
return (Attribute[])formatter.Deserialize(stream);
|
return (Attribute[])formatter.Deserialize(stream);
|
||||||
|
#pragma warning restore SYSLIB0011
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -122,8 +129,13 @@ namespace FlaxEditor.Surface
|
|||||||
}
|
}
|
||||||
using (var stream = new MemoryStream())
|
using (var stream = new MemoryStream())
|
||||||
{
|
{
|
||||||
|
// Ensure we are in the correct load context (https://github.com/dotnet/runtime/issues/42041)
|
||||||
|
using var ctx = AssemblyLoadContext.EnterContextualReflection(typeof(Editor).Assembly);
|
||||||
|
|
||||||
var formatter = new BinaryFormatter();
|
var formatter = new BinaryFormatter();
|
||||||
|
#pragma warning disable SYSLIB0011
|
||||||
formatter.Serialize(stream, attributes);
|
formatter.Serialize(stream, attributes);
|
||||||
|
#pragma warning restore SYSLIB0011
|
||||||
AddEntry(AttributeMetaTypeID, stream.ToArray());
|
AddEntry(AttributeMetaTypeID, stream.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using FlaxEditor.CustomEditors;
|
|||||||
using FlaxEditor.CustomEditors.Elements;
|
using FlaxEditor.CustomEditors.Elements;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Utilities;
|
using FlaxEditor.Utilities;
|
||||||
|
using FlaxEngine.Utilities;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.Surface
|
namespace FlaxEditor.Surface
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using FlaxEditor.Scripting;
|
|||||||
using FlaxEditor.Surface.Elements;
|
using FlaxEditor.Surface.Elements;
|
||||||
using FlaxEditor.Utilities;
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.Utilities;
|
||||||
using Utils = FlaxEditor.Utilities.Utils;
|
using Utils = FlaxEditor.Utilities.Utils;
|
||||||
|
|
||||||
namespace FlaxEditor.Surface
|
namespace FlaxEditor.Surface
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.Tools.Terrain.Sculpt
|
namespace FlaxEditor.Tools.Terrain.Sculpt
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ namespace FlaxEditor.Windows
|
|||||||
int logCount;
|
int logCount;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
logCount = Editor.Internal_ReadOutputLogs(_outMessages, _outLogTypes, _outLogTimes);
|
logCount = Editor.Internal_ReadOutputLogs(ref _outMessages, ref _outLogTypes, ref _outLogTimes, OutCapacity);
|
||||||
|
|
||||||
for (int i = 0; i < logCount; i++)
|
for (int i = 0; i < logCount; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,16 +19,16 @@ namespace FlaxEngine
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
fixed (char* name = &Name0)
|
fixed (short* name = Name0)
|
||||||
{
|
{
|
||||||
return new string(name);
|
return new string((char*)name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe bool NameStartsWith(string prefix)
|
internal unsafe bool NameStartsWith(string prefix)
|
||||||
{
|
{
|
||||||
fixed (char* name = &Name0)
|
fixed (short* name = Name0)
|
||||||
{
|
{
|
||||||
fixed (char* p = prefix)
|
fixed (char* p = prefix)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
|
|
||||||
namespace FlaxEngine
|
namespace FlaxEngine
|
||||||
{
|
{
|
||||||
@@ -44,6 +45,7 @@ namespace FlaxEngine
|
|||||||
/// The node evaluation context structure.
|
/// The node evaluation context structure.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[NativeMarshalling(typeof(ContextMarshaler))]
|
||||||
public struct Context
|
public struct Context
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -92,6 +94,61 @@ namespace FlaxEngine
|
|||||||
public AnimatedModel Instance;
|
public AnimatedModel Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CustomMarshaller(typeof(Context), MarshalMode.Default, typeof(ContextMarshaler))]
|
||||||
|
internal static class ContextMarshaler
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct ContextNative
|
||||||
|
{
|
||||||
|
public IntPtr Graph;
|
||||||
|
public IntPtr GraphExecutor;
|
||||||
|
public IntPtr Node;
|
||||||
|
public uint NodeId;
|
||||||
|
public int BoxId;
|
||||||
|
public float DeltaTime;
|
||||||
|
public ulong CurrentFrameIndex;
|
||||||
|
public IntPtr BaseModel;
|
||||||
|
public IntPtr Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Context ConvertToManaged(ContextNative unmanaged) => ToManaged(unmanaged);
|
||||||
|
internal static ContextNative ConvertToUnmanaged(Context managed) => ToNative(managed);
|
||||||
|
|
||||||
|
internal static Context ToManaged(ContextNative managed)
|
||||||
|
{
|
||||||
|
return new Context()
|
||||||
|
{
|
||||||
|
Graph = managed.Graph,
|
||||||
|
GraphExecutor = managed.GraphExecutor,
|
||||||
|
Node = managed.Node,
|
||||||
|
NodeId = managed.NodeId,
|
||||||
|
BoxId = managed.BoxId,
|
||||||
|
DeltaTime = managed.DeltaTime,
|
||||||
|
CurrentFrameIndex = managed.CurrentFrameIndex,
|
||||||
|
BaseModel = SkinnedModelMarshaller.ConvertToManaged(managed.BaseModel),
|
||||||
|
Instance = AnimatedModelMarshaller.ConvertToManaged(managed.Instance),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static ContextNative ToNative(Context managed)
|
||||||
|
{
|
||||||
|
return new ContextNative()
|
||||||
|
{
|
||||||
|
Graph = managed.Graph,
|
||||||
|
GraphExecutor = managed.GraphExecutor,
|
||||||
|
Node = managed.Node,
|
||||||
|
NodeId = managed.NodeId,
|
||||||
|
BoxId = managed.BoxId,
|
||||||
|
DeltaTime = managed.DeltaTime,
|
||||||
|
CurrentFrameIndex = managed.CurrentFrameIndex,
|
||||||
|
BaseModel = SkinnedModelMarshaller.ConvertToUnmanaged(managed.BaseModel),
|
||||||
|
Instance = AnimatedModelMarshaller.ConvertToUnmanaged(managed.Instance),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
internal static void Free(ContextNative unmanaged)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The animation graph 'impulse' connections data container (the actual transfer is done via pointer as it gives better performance).
|
/// The animation graph 'impulse' connections data container (the actual transfer is done via pointer as it gives better performance).
|
||||||
/// Container for skeleton nodes transformation hierarchy and any other required data.
|
/// Container for skeleton nodes transformation hierarchy and any other required data.
|
||||||
@@ -203,14 +260,16 @@ namespace FlaxEngine
|
|||||||
|
|
||||||
#region Internal Calls
|
#region Internal Calls
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.AnimationGraph::Internal_HasConnection")]
|
||||||
internal static extern bool Internal_HasConnection(ref CustomNode.Context context, int boxId);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
internal static partial bool Internal_HasConnection(ref AnimationGraph.CustomNode.Context context, int boxId);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.AnimationGraph::Internal_GetInputValue")]
|
||||||
internal static extern object Internal_GetInputValue(ref CustomNode.Context context, int boxId);
|
[return: MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))]
|
||||||
|
internal static partial object Internal_GetInputValue(ref AnimationGraph.CustomNode.Context context, int boxId);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData")]
|
||||||
internal static extern IntPtr Internal_GetOutputImpulseData(ref CustomNode.Context context);
|
internal static partial IntPtr Internal_GetOutputImpulseData(ref AnimationGraph.CustomNode.Context context);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
#include "Engine/Content/Assets/SkinnedModel.h"
|
#include "Engine/Content/Assets/SkinnedModel.h"
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct InternalInitData
|
struct InternalInitData
|
||||||
{
|
{
|
||||||
@@ -52,6 +52,7 @@ namespace AnimGraphInternal
|
|||||||
{
|
{
|
||||||
bool HasConnection(InternalContext* context, int32 boxId)
|
bool HasConnection(InternalContext* context, int32 boxId)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_HasConnection")
|
||||||
const auto box = context->Node->TryGetBox(boxId);
|
const auto box = context->Node->TryGetBox(boxId);
|
||||||
if (box == nullptr)
|
if (box == nullptr)
|
||||||
DebugLog::ThrowArgumentOutOfRange("boxId");
|
DebugLog::ThrowArgumentOutOfRange("boxId");
|
||||||
@@ -60,6 +61,7 @@ namespace AnimGraphInternal
|
|||||||
|
|
||||||
MonoObject* GetInputValue(InternalContext* context, int32 boxId)
|
MonoObject* GetInputValue(InternalContext* context, int32 boxId)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_GetInputValue")
|
||||||
const auto box = context->Node->TryGetBox(boxId);
|
const auto box = context->Node->TryGetBox(boxId);
|
||||||
if (box == nullptr)
|
if (box == nullptr)
|
||||||
DebugLog::ThrowArgumentOutOfRange("boxId");
|
DebugLog::ThrowArgumentOutOfRange("boxId");
|
||||||
@@ -77,14 +79,13 @@ namespace AnimGraphInternal
|
|||||||
|
|
||||||
AnimGraphImpulse* GetOutputImpulseData(InternalContext* context)
|
AnimGraphImpulse* GetOutputImpulseData(InternalContext* context)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData")
|
||||||
const auto nodes = context->Node->GetNodes(context->GraphExecutor);
|
const auto nodes = context->Node->GetNodes(context->GraphExecutor);
|
||||||
context->GraphExecutor->InitNodes(nodes);
|
context->GraphExecutor->InitNodes(nodes);
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void AnimGraphExecutor::initRuntime()
|
void AnimGraphExecutor::initRuntime()
|
||||||
{
|
{
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
@@ -122,7 +123,7 @@ void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value&
|
|||||||
internalContext.Instance = context.Data->Object ? context.Data->Object->GetOrCreateManagedInstance() : nullptr;
|
internalContext.Instance = context.Data->Object ? context.Data->Object->GetOrCreateManagedInstance() : nullptr;
|
||||||
|
|
||||||
// Peek managed object
|
// Peek managed object
|
||||||
const auto obj = mono_gchandle_get_target(data.Handle);
|
const auto obj = MUtils::GetGCHandleTarget(data.Handle);
|
||||||
if (obj == nullptr)
|
if (obj == nullptr)
|
||||||
{
|
{
|
||||||
LOG(Warning, "Custom node instance is null.");
|
LOG(Warning, "Custom node instance is null.");
|
||||||
@@ -166,7 +167,7 @@ void AnimGraph::ClearCustomNode(Node* node)
|
|||||||
if (data.Handle)
|
if (data.Handle)
|
||||||
{
|
{
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
mono_gchandle_free(data.Handle);
|
MUtils::FreeGCHandle(data.Handle);
|
||||||
#endif
|
#endif
|
||||||
data.Handle = 0;
|
data.Handle = 0;
|
||||||
}
|
}
|
||||||
@@ -216,7 +217,7 @@ bool AnimGraph::InitCustomNode(Node* node)
|
|||||||
|
|
||||||
// Allocate managed node object (create GC handle to prevent destruction)
|
// Allocate managed node object (create GC handle to prevent destruction)
|
||||||
const auto obj = type->CreateInstance();
|
const auto obj = type->CreateInstance();
|
||||||
const auto handleGC = mono_gchandle_new(obj, false);
|
const auto handleGC = MUtils::NewGCHandle(obj, false);
|
||||||
|
|
||||||
// Initialize node
|
// Initialize node
|
||||||
InternalInitData initData;
|
InternalInitData initData;
|
||||||
@@ -228,7 +229,7 @@ bool AnimGraph::InitCustomNode(Node* node)
|
|||||||
load->Invoke(obj, params, &exception);
|
load->Invoke(obj, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
mono_gchandle_free(handleGC);
|
MUtils::FreeGCHandle(handleGC);
|
||||||
|
|
||||||
MException ex(exception);
|
MException ex(exception);
|
||||||
ex.Log(LogType::Warning, TEXT("AnimGraph"));
|
ex.Log(LogType::Warning, TEXT("AnimGraph"));
|
||||||
|
|||||||
@@ -516,7 +516,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The GC handle to the managed instance of the node object.
|
/// The GC handle to the managed instance of the node object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
uint32 Handle;
|
gchandle Handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CurveData
|
struct CurveData
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "Engine/Threading/MainThreadTask.h"
|
#include "Engine/Threading/MainThreadTask.h"
|
||||||
#include "Engine/Threading/ConcurrentTaskQueue.h"
|
#include "Engine/Threading/ConcurrentTaskQueue.h"
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-gc.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-gc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -270,7 +271,7 @@ void Asset::OnManagedInstanceDeleted()
|
|||||||
if (_gcHandle)
|
if (_gcHandle)
|
||||||
{
|
{
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
mono_gchandle_free(_gcHandle);
|
MUtils::FreeGCHandle(_gcHandle);
|
||||||
#endif
|
#endif
|
||||||
_gcHandle = 0;
|
_gcHandle = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ namespace FlaxEngine
|
|||||||
|
|
||||||
var dataTypeName = DataTypeName;
|
var dataTypeName = DataTypeName;
|
||||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
for (int i = 0; i < assemblies.Length; i++)
|
|
||||||
|
// Going through the assemblies in order will return collected assemblies first,
|
||||||
|
// use reverse order instead to find the type currently loaded assemblies instead.
|
||||||
|
for (int i = assemblies.Length-1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var assembly = assemblies[i];
|
var assembly = assemblies[i];
|
||||||
if (assembly != null)
|
if (assembly != null)
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
#pragma clang diagnostic ignored "-Wnull-dereference"
|
#pragma clang diagnostic ignored "-Wnull-dereference"
|
||||||
#pragma clang diagnostic ignored "-Winvalid-noreturn"
|
#pragma clang diagnostic ignored "-Winvalid-noreturn"
|
||||||
|
|
||||||
|
#define SCRIPTING_EXPORT(name)
|
||||||
|
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
|
|
||||||
#define DLLEXPORT __attribute__ ((__visibility__ ("default")))
|
#define DLLEXPORT __attribute__ ((__visibility__ ("default")))
|
||||||
@@ -86,6 +88,8 @@
|
|||||||
|
|
||||||
#pragma warning(disable: 4251)
|
#pragma warning(disable: 4251)
|
||||||
|
|
||||||
|
#define SCRIPTING_EXPORT(name) __pragma(comment(linker, "/EXPORT:" #name "=" __FUNCDNAME__))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#pragma error "Unknown compiler."
|
#pragma error "Unknown compiler."
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.Content.Settings
|
namespace FlaxEditor.Content.Settings
|
||||||
@@ -562,8 +563,8 @@ namespace FlaxEditor.Content.Settings
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the current game settings asset and applies it to the engine runtime configuration.
|
/// Loads the current game settings asset and applies it to the engine runtime configuration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Settings.GameSettings::Apply")]
|
||||||
public static extern void Apply();
|
public static partial void Apply();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.Content.Settings
|
namespace FlaxEditor.Content.Settings
|
||||||
@@ -24,14 +26,26 @@ namespace FlaxEditor.Content.Settings
|
|||||||
/// Gets the current tags collection.
|
/// Gets the current tags collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The tags collection.</returns>
|
/// <returns>The tags collection.</returns>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
internal static string[] GetCurrentTags()
|
||||||
internal static extern string[] GetCurrentTags();
|
{
|
||||||
|
return GetCurrentTags(out int _);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current layer names (max 32 items but trims last empty items).
|
/// Gets the current layer names (max 32 items but trims last empty items).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The layers.</returns>
|
/// <returns>The layers.</returns>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
public static string[] GetCurrentLayers()
|
||||||
public static extern string[] GetCurrentLayers();
|
{
|
||||||
|
return GetCurrentLayers(out int _);
|
||||||
|
}
|
||||||
|
|
||||||
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentTags", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
|
[return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "tagCount")]
|
||||||
|
internal static partial string[] GetCurrentTags(out int tagCount);
|
||||||
|
|
||||||
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentLayers", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
|
[return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "layerCount")]
|
||||||
|
internal static partial string[] GetCurrentLayers(out int layerCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,16 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
@@ -25,9 +35,9 @@ namespace FlaxEngine.TypeConverters
|
|||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
if (v.Length == 4)
|
if (v.Length == 4)
|
||||||
return new Color(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), float.Parse(v[3]));
|
return new Color(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture));
|
||||||
if (v.Length == 3)
|
if (v.Length == 3)
|
||||||
return new Color(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), 1.0f);
|
return new Color(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), 1.0f);
|
||||||
throw new FormatException("Invalid Color value format.");
|
throw new FormatException("Invalid Color value format.");
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
@@ -39,7 +49,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Color)value;
|
var v = (Color)value;
|
||||||
return v.R + "," + v.G + "," + v.B + "," + v.A;
|
return v.R.ToString(culture) + "," + v.G.ToString(culture) + "," + v.B.ToString(culture) + "," + v.A.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Double2(double.Parse(v[0]), double.Parse(v[1]));
|
return new Double2(double.Parse(v[0], culture), double.Parse(v[1], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Double2)value;
|
var v = (Double2)value;
|
||||||
return v.X + "," + v.Y;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Double3(double.Parse(v[0]), double.Parse(v[1]), double.Parse(v[2]));
|
return new Double3(double.Parse(v[0], culture), double.Parse(v[1], culture), double.Parse(v[2], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Double3)value;
|
var v = (Double3)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Double4(double.Parse(v[0]), double.Parse(v[1]), double.Parse(v[2]), double.Parse(v[3]));
|
return new Double4(double.Parse(v[0], culture), double.Parse(v[1], culture), double.Parse(v[2], culture), double.Parse(v[3], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Double4)value;
|
var v = (Double4)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Float2(float.Parse(v[0]), float.Parse(v[1]));
|
return new Float2(float.Parse(v[0], culture), float.Parse(v[1], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Float2)value;
|
var v = (Float2)value;
|
||||||
return v.X + "," + v.Y;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Float3(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]));
|
return new Float3(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Float3)value;
|
var v = (Float3)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Float4(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), float.Parse(v[3]));
|
return new Float4(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Float4)value;
|
var v = (Float4)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Int2(int.Parse(v[0]), int.Parse(v[1]));
|
return new Int2(int.Parse(v[0], culture), int.Parse(v[1], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Int2)value;
|
var v = (Int2)value;
|
||||||
return v.X + "," + v.Y;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Int3(int.Parse(v[0]), int.Parse(v[1]), int.Parse(v[2]));
|
return new Int3(int.Parse(v[0], culture), int.Parse(v[1], culture), int.Parse(v[2], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Int3)value;
|
var v = (Int3)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Int4(int.Parse(v[0]), int.Parse(v[1]), int.Parse(v[2]), int.Parse(v[3]));
|
return new Int4(int.Parse(v[0], culture), int.Parse(v[1], culture), int.Parse(v[2], culture), int.Parse(v[3], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Int4)value;
|
var v = (Int4)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Quaternion(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), float.Parse(v[3]));
|
return new Quaternion(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Quaternion)value;
|
var v = (Quaternion)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Vector2(float.Parse(v[0]), float.Parse(v[1]));
|
return new Vector2(float.Parse(v[0], culture), float.Parse(v[1], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Vector2)value;
|
var v = (Vector2)value;
|
||||||
return v.X + "," + v.Y;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Vector3(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]));
|
return new Vector3(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Vector3)value;
|
var v = (Vector3)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
|
|||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
{
|
{
|
||||||
if (value is string str)
|
if (value is string str)
|
||||||
{
|
{
|
||||||
string[] v = str.Split(',');
|
string[] v = str.Split(',');
|
||||||
return new Vector4(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), float.Parse(v[3]));
|
return new Vector4(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture));
|
||||||
}
|
}
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
|
|||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
{
|
||||||
var v = (Vector4)value;
|
var v = (Vector4)value;
|
||||||
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
|
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
|
||||||
}
|
}
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -619,7 +619,11 @@ Variant::Variant(Asset* v)
|
|||||||
Variant::Variant(_MonoObject* v)
|
Variant::Variant(_MonoObject* v)
|
||||||
: Type(VariantType::ManagedObject, v ? mono_object_get_class(v) : nullptr)
|
: Type(VariantType::ManagedObject, v ? mono_object_get_class(v) : nullptr)
|
||||||
{
|
{
|
||||||
AsUint = v ? mono_gchandle_new(v, true) : 0;
|
#if USE_NETCORE
|
||||||
|
AsUint64 = v ? MUtils::NewGCHandle(v, true) : 0;
|
||||||
|
#else
|
||||||
|
AsUint = v ? MUtils::NewGCHandle(v, true) : 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -957,9 +961,13 @@ Variant::~Variant()
|
|||||||
Delete(AsDictionary);
|
Delete(AsDictionary);
|
||||||
break;
|
break;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
|
if (AsUint64)
|
||||||
|
MUtils::FreeGCHandle(AsUint64);
|
||||||
|
break;
|
||||||
|
#elif USE_MONO
|
||||||
if (AsUint)
|
if (AsUint)
|
||||||
mono_gchandle_free(AsUint);
|
MUtils::FreeGCHandle(AsUint);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default: ;
|
default: ;
|
||||||
@@ -1088,8 +1096,10 @@ Variant& Variant::operator=(const Variant& other)
|
|||||||
AsDictionary = New<Dictionary<Variant, Variant>>(*other.AsDictionary);
|
AsDictionary = New<Dictionary<Variant, Variant>>(*other.AsDictionary);
|
||||||
break;
|
break;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
AsUint = other.AsUint ? mono_gchandle_new(mono_gchandle_get_target(other.AsUint), true) : 0;
|
AsUint64 = other.AsUint64 ? MUtils::NewGCHandle(MUtils::GetGCHandleTarget(other.AsUint64), true) : 0;
|
||||||
|
#elif USE_MONO
|
||||||
|
AsUint = other.AsUint ? MUtils::NewGCHandle(MUtils::GetGCHandleTarget(other.AsUint), true) : 0;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case VariantType::Null:
|
case VariantType::Null:
|
||||||
@@ -1217,7 +1227,7 @@ bool Variant::operator==(const Variant& other) const
|
|||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
// TODO: invoke C# Equality logic?
|
// TODO: invoke C# Equality logic?
|
||||||
return AsUint == other.AsUint || mono_gchandle_get_target(AsUint) == mono_gchandle_get_target(other.AsUint);
|
return AsUint == other.AsUint || MUtils::GetGCHandleTarget(AsUint) == MUtils::GetGCHandleTarget(other.AsUint);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -1308,8 +1318,10 @@ Variant::operator bool() const
|
|||||||
case VariantType::Asset:
|
case VariantType::Asset:
|
||||||
return AsAsset != nullptr;
|
return AsAsset != nullptr;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
return AsUint != 0 && mono_gchandle_get_target(AsUint) != nullptr;
|
return AsUint64 != 0 && MUtils::GetGCHandleTarget(AsUint64) != nullptr;
|
||||||
|
#elif USE_MONO
|
||||||
|
return AsUint != 0 && MUtils::GetGCHandleTarget(AsUint) != nullptr;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -1578,8 +1590,10 @@ Variant::operator void*() const
|
|||||||
case VariantType::Blob:
|
case VariantType::Blob:
|
||||||
return AsBlob.Data;
|
return AsBlob.Data;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
return AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
|
return AsUint64 ? MUtils::GetGCHandleTarget(AsUint64) : nullptr;
|
||||||
|
#elif USE_MONO
|
||||||
|
return AsUint ? MUtils::GetGCHandleTarget(AsUint) : nullptr;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -1623,8 +1637,10 @@ Variant::operator ScriptingObject*() const
|
|||||||
|
|
||||||
Variant::operator _MonoObject*() const
|
Variant::operator _MonoObject*() const
|
||||||
{
|
{
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
return Type.Type == VariantType::ManagedObject && AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
|
return Type.Type == VariantType::ManagedObject && AsUint64 ? MUtils::GetGCHandleTarget(AsUint64) : nullptr;
|
||||||
|
#elif USE_MONO
|
||||||
|
return Type.Type == VariantType::ManagedObject && AsUint ? MUtils::GetGCHandleTarget(AsUint) : nullptr;
|
||||||
#else
|
#else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
@@ -2337,9 +2353,14 @@ void Variant::SetType(const VariantType& type)
|
|||||||
Delete(AsDictionary);
|
Delete(AsDictionary);
|
||||||
break;
|
break;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
|
if (AsUint64)
|
||||||
|
MUtils::FreeGCHandle(AsUint64);
|
||||||
|
break;
|
||||||
|
#elif USE_MONO
|
||||||
if (AsUint)
|
if (AsUint)
|
||||||
mono_gchandle_free(AsUint);
|
MUtils::FreeGCHandle(AsUint);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
@@ -2447,9 +2468,14 @@ void Variant::SetType(VariantType&& type)
|
|||||||
Delete(AsDictionary);
|
Delete(AsDictionary);
|
||||||
break;
|
break;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
|
if (AsUint64)
|
||||||
|
MUtils::FreeGCHandle(AsUint64);
|
||||||
|
break;
|
||||||
|
#elif USE_MONO
|
||||||
if (AsUint)
|
if (AsUint)
|
||||||
mono_gchandle_free(AsUint);
|
MUtils::FreeGCHandle(AsUint);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
@@ -2632,7 +2658,11 @@ void Variant::SetManagedObject(_MonoObject* object)
|
|||||||
{
|
{
|
||||||
if (Type.Type != VariantType::ManagedObject)
|
if (Type.Type != VariantType::ManagedObject)
|
||||||
SetType(VariantType(VariantType::ManagedObject, mono_object_get_class(object)));
|
SetType(VariantType(VariantType::ManagedObject, mono_object_get_class(object)));
|
||||||
AsUint = mono_gchandle_new(object, true);
|
#if USE_NETCORE
|
||||||
|
AsUint64 = MUtils::NewGCHandle(object, true);
|
||||||
|
#else
|
||||||
|
AsUint = MUtils::NewGCHandle(object, true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2751,8 +2781,10 @@ String Variant::ToString() const
|
|||||||
case VariantType::Typename:
|
case VariantType::Typename:
|
||||||
return String((const char*)AsBlob.Data, AsBlob.Length ? AsBlob.Length - 1 : 0);
|
return String((const char*)AsBlob.Data, AsBlob.Length ? AsBlob.Length - 1 : 0);
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
return AsUint ? String(MUtils::ToString(mono_object_to_string(mono_gchandle_get_target(AsUint), nullptr))) : TEXT("null");
|
return AsUint64 ? String(MUtils::ToString(mono_object_to_string(MUtils::GetGCHandleTarget(AsUint64), nullptr))) : TEXT("null");
|
||||||
|
#elif USE_MONO
|
||||||
|
return AsUint ? String(MUtils::ToString(mono_object_to_string(MUtils::GetGCHandleTarget(AsUint), nullptr))) : TEXT("null");
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return String::Empty;
|
return String::Empty;
|
||||||
@@ -3671,7 +3703,12 @@ void Variant::AllocStructure()
|
|||||||
Platform::MemoryCopy(AsBlob.Data, data, AsBlob.Length);
|
Platform::MemoryCopy(AsBlob.Data, data, AsBlob.Length);
|
||||||
#else
|
#else
|
||||||
Type.Type = VariantType::ManagedObject;
|
Type.Type = VariantType::ManagedObject;
|
||||||
AsUint = mono_gchandle_new(instance, true);
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
AsUint64 = MUtils::NewGCHandle(instance, true);
|
||||||
|
#else
|
||||||
|
AsUint = MUtils::NewGCHandle(instance, true);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3763,8 +3800,10 @@ uint32 GetHash(const Variant& key)
|
|||||||
case VariantType::Typename:
|
case VariantType::Typename:
|
||||||
return GetHash((const char*)key.AsBlob.Data);
|
return GetHash((const char*)key.AsBlob.Data);
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
return key.AsUint ? (uint32)mono_object_hash(mono_gchandle_get_target(key.AsUint)) : 0;
|
return key.AsUint64 ? (uint32)mono_object_hash(MUtils::GetGCHandleTarget(key.AsUint64)) : 0;
|
||||||
|
#elif USE_MONO
|
||||||
|
return key.AsUint ? (uint32)mono_object_hash(MUtils::GetGCHandleTarget(key.AsUint)) : 0;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
|
|
||||||
namespace FlaxEngine
|
namespace FlaxEngine
|
||||||
{
|
{
|
||||||
internal sealed class DebugLogHandler : ILogHandler
|
internal partial class DebugLogHandler : ILogHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs on sending a log message.
|
/// Occurs on sending a log message.
|
||||||
@@ -64,14 +66,14 @@ namespace FlaxEngine
|
|||||||
Debug.Logger.LogException(exception);
|
Debug.Logger.LogException(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.DebugLogHandler::Internal_LogWrite", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_LogWrite(LogType level, string msg);
|
internal static partial void Internal_LogWrite(LogType level, string msg);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.DebugLogHandler::Internal_Log", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_Log(LogType level, string msg, IntPtr obj, string stackTrace);
|
internal static partial void Internal_Log(LogType level, string msg, IntPtr obj, string stackTrace);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.DebugLogHandler::Internal_LogException", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_LogException(Exception exception, IntPtr obj);
|
internal static partial void Internal_LogException([MarshalUsing(typeof(FlaxEngine.ExceptionMarshaller))] Exception exception, IntPtr obj);
|
||||||
|
|
||||||
[SecuritySafeCritical]
|
[SecuritySafeCritical]
|
||||||
public static string Internal_GetStackTrace()
|
public static string Internal_GetStackTrace()
|
||||||
|
|||||||
2256
Source/Engine/Engine/NativeInterop.cs
Normal file
2256
Source/Engine/Engine/NativeInterop.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1277,6 +1277,7 @@ bool Level::SaveAllScenes()
|
|||||||
|
|
||||||
void Level::SaveAllScenesAsync()
|
void Level::SaveAllScenesAsync()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Level::Internal_SaveAllScenesAsync")
|
||||||
ScopeLock lock(_sceneActionsLocker);
|
ScopeLock lock(_sceneActionsLocker);
|
||||||
for (int32 i = 0; i < Scenes.Count(); i++)
|
for (int32 i = 0; i < Scenes.Count(); i++)
|
||||||
_sceneActions.Enqueue(New<SaveSceneAction>(Scenes[i]));
|
_sceneActions.Enqueue(New<SaveSceneAction>(Scenes[i]));
|
||||||
@@ -1381,6 +1382,7 @@ bool Level::UnloadAllScenes()
|
|||||||
|
|
||||||
void Level::UnloadAllScenesAsync()
|
void Level::UnloadAllScenesAsync()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Level::Internal_UnloadAllScenesAsync")
|
||||||
ScopeLock lock(_sceneActionsLocker);
|
ScopeLock lock(_sceneActionsLocker);
|
||||||
_sceneActions.Enqueue(New<UnloadScenesAction>());
|
_sceneActions.Enqueue(New<UnloadScenesAction>());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,6 +303,7 @@ bool NetworkManager::StartHost()
|
|||||||
|
|
||||||
void NetworkManager::Stop()
|
void NetworkManager::Stop()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Networking.NetworkManager::Internal_Stop");
|
||||||
if (Mode == NetworkManagerMode::Offline && State == NetworkConnectionState::Offline)
|
if (Mode == NetworkManagerMode::Offline && State == NetworkConnectionState::Offline)
|
||||||
return;
|
return;
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ public:
|
|||||||
/// <param name="size">Size of the memory to copy in bytes</param>
|
/// <param name="size">Size of the memory to copy in bytes</param>
|
||||||
FORCE_INLINE static void MemoryCopy(void* dst, const void* src, uint64 size)
|
FORCE_INLINE static void MemoryCopy(void* dst, const void* src, uint64 size)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Utils::MemoryCopy")
|
||||||
memcpy(dst, src, static_cast<size_t>(size));
|
memcpy(dst, src, static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +197,7 @@ public:
|
|||||||
/// <param name="size">Size of the memory to clear in bytes</param>
|
/// <param name="size">Size of the memory to clear in bytes</param>
|
||||||
FORCE_INLINE static void MemoryClear(void* dst, uint64 size)
|
FORCE_INLINE static void MemoryClear(void* dst, uint64 size)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Utils::MemoryClear")
|
||||||
memset(dst, 0, static_cast<size_t>(size));
|
memset(dst, 0, static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,6 +209,7 @@ public:
|
|||||||
/// <param name="size">Size of the memory to compare in bytes.</param>
|
/// <param name="size">Size of the memory to compare in bytes.</param>
|
||||||
FORCE_INLINE static int32 MemoryCompare(const void* buf1, const void* buf2, uint64 size)
|
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_t>(size));
|
return memcmp(buf1, buf2, static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1658,6 +1658,7 @@ DragDropEffect LinuxWindow::DoDragDrop(const StringView& data)
|
|||||||
|
|
||||||
void LinuxClipboard::Clear()
|
void LinuxClipboard::Clear()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Clipboard::Internal_Clear");
|
||||||
SetText(StringView::Empty);
|
SetText(StringView::Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ Float2 MacUtils::GetScreensOrigin()
|
|||||||
|
|
||||||
void MacClipboard::Clear()
|
void MacClipboard::Clear()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Clipboard::Internal_Clear");
|
||||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||||
[pasteboard clearContents];
|
[pasteboard clearContents];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ typedef struct _DROPFILES
|
|||||||
|
|
||||||
void WindowsClipboard::Clear()
|
void WindowsClipboard::Clear()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Clipboard::Internal_Clear");
|
||||||
OpenClipboard(nullptr);
|
OpenClipboard(nullptr);
|
||||||
EmptyClipboard();
|
EmptyClipboard();
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
|
|||||||
@@ -699,6 +699,7 @@ void Render2D::Begin(GPUContext* context, GPUTextureView* output, GPUTextureView
|
|||||||
|
|
||||||
void Render2D::End()
|
void Render2D::End()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Render2D::Internal_End")
|
||||||
RENDER2D_CHECK_RENDERING_STATE;
|
RENDER2D_CHECK_RENDERING_STATE;
|
||||||
ASSERT(Context != nullptr && Output != nullptr);
|
ASSERT(Context != nullptr && Output != nullptr);
|
||||||
ASSERT(GUIShader != nullptr);
|
ASSERT(GUIShader != nullptr);
|
||||||
@@ -814,6 +815,7 @@ void Render2D::PeekTransform(Matrix3x3& transform)
|
|||||||
|
|
||||||
void Render2D::PopTransform()
|
void Render2D::PopTransform()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Render2D::Internal_PopTransform")
|
||||||
RENDER2D_CHECK_RENDERING_STATE;
|
RENDER2D_CHECK_RENDERING_STATE;
|
||||||
|
|
||||||
ASSERT(TransformLayersStack.HasItems());
|
ASSERT(TransformLayersStack.HasItems());
|
||||||
@@ -855,6 +857,7 @@ void Render2D::PeekClip(Rectangle& clipRect)
|
|||||||
|
|
||||||
void Render2D::PopClip()
|
void Render2D::PopClip()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Render2D::Internal_PopClip")
|
||||||
RENDER2D_CHECK_RENDERING_STATE;
|
RENDER2D_CHECK_RENDERING_STATE;
|
||||||
|
|
||||||
ClipLayersStack.Pop();
|
ClipLayersStack.Pop();
|
||||||
@@ -876,6 +879,7 @@ void Render2D::PeekTint(Color& tint)
|
|||||||
|
|
||||||
void Render2D::PopTint()
|
void Render2D::PopTint()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Render2D::Internal_PopTint")
|
||||||
RENDER2D_CHECK_RENDERING_STATE;
|
RENDER2D_CHECK_RENDERING_STATE;
|
||||||
|
|
||||||
TintLayersStack.Pop();
|
TintLayersStack.Pop();
|
||||||
|
|||||||
@@ -64,8 +64,7 @@ namespace FlaxEngine
|
|||||||
/// <param name="rect">The rectangle to draw.</param>
|
/// <param name="rect">The rectangle to draw.</param>
|
||||||
public static void DrawSprite(SpriteHandle spriteHandle, Rectangle rect)
|
public static void DrawSprite(SpriteHandle spriteHandle, Rectangle rect)
|
||||||
{
|
{
|
||||||
var color = Color.White;
|
DrawSprite(spriteHandle, rect, Color.White);
|
||||||
Internal_DrawSprite(ref spriteHandle, ref rect, ref color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -86,8 +85,7 @@ namespace FlaxEngine
|
|||||||
/// <param name="rect">The rectangle to draw.</param>
|
/// <param name="rect">The rectangle to draw.</param>
|
||||||
public static void DrawSpritePoint(SpriteHandle spriteHandle, Rectangle rect)
|
public static void DrawSpritePoint(SpriteHandle spriteHandle, Rectangle rect)
|
||||||
{
|
{
|
||||||
var color = Color.White;
|
DrawSpritePoint(spriteHandle, rect, Color.White);
|
||||||
Internal_DrawSpritePoint(ref spriteHandle, ref rect, ref color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ namespace FlaxEngine
|
|||||||
/// <param name="customActors">The custom set of actors to render. If empty, the loaded scenes will be rendered.</param>
|
/// <param name="customActors">The custom set of actors to render. If empty, the loaded scenes will be rendered.</param>
|
||||||
public static void DrawSceneDepth(GPUContext context, SceneRenderTask task, GPUTexture output, List<Actor> customActors)
|
public static void DrawSceneDepth(GPUContext context, SceneRenderTask task, GPUTexture output, List<Actor> customActors)
|
||||||
{
|
{
|
||||||
Internal_DrawSceneDepth(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(output), Utils.ExtractArrayFromList(customActors));
|
var temp = Utils.ExtractArrayFromList(customActors);
|
||||||
|
var tempCount = temp.Length;
|
||||||
|
Internal_DrawSceneDepth(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(output), ref temp, ref tempCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -820,22 +820,33 @@ MMethod* ManagedBinaryModule::FindMethod(MClass* mclass, const ScriptingTypeMeth
|
|||||||
{
|
{
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
MonoMethodSignature* sig = mono_method_signature(method->GetNative());
|
MonoMethodSignature* sig = mono_method_signature(method->GetNative());
|
||||||
if (method->IsStatic() != signature.IsStatic ||
|
/*if (method->IsStatic() != signature.IsStatic ||
|
||||||
method->GetName() != signature.Name ||
|
method->GetName() != signature.Name ||
|
||||||
(int32)mono_signature_get_param_count(sig) != signature.Params.Count())
|
(int32)mono_signature_get_param_count(sig) != signature.Params.Count())
|
||||||
|
continue;*/
|
||||||
|
if (method->IsStatic() != signature.IsStatic)
|
||||||
|
continue;
|
||||||
|
if (method->GetName() != signature.Name)
|
||||||
|
continue;
|
||||||
|
if ((int32)mono_signature_get_param_count(sig) != signature.Params.Count())
|
||||||
continue;
|
continue;
|
||||||
void* sigParams = nullptr;
|
void* sigParams = nullptr;
|
||||||
mono_signature_get_params(sig, &sigParams);
|
MonoType* type = mono_signature_get_params(sig, &sigParams);
|
||||||
bool isValid = true;
|
bool isValid = true;
|
||||||
for (int32 paramIdx = 0; paramIdx < signature.Params.Count(); paramIdx++)
|
int paramIdx = 0;
|
||||||
|
while (type != nullptr)
|
||||||
{
|
{
|
||||||
auto& param = signature.Params[paramIdx];
|
auto& param = signature.Params[paramIdx];
|
||||||
if (param.IsOut != (mono_signature_param_is_out(sig, paramIdx) != 0) ||
|
if (param.IsOut != (mono_signature_param_is_out(sig, paramIdx) != 0) ||
|
||||||
!VariantTypeEquals(param.Type, ((MonoType**)sigParams)[paramIdx]))
|
!VariantTypeEquals(param.Type, type))
|
||||||
{
|
{
|
||||||
|
auto asdf = VariantTypeEquals(param.Type, type);
|
||||||
isValid = false;
|
isValid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type = mono_signature_get_params(sig, &sigParams);
|
||||||
|
paramIdx++;
|
||||||
}
|
}
|
||||||
if (isValid && VariantTypeEquals(signature.ReturnType, mono_signature_get_return_type(sig)))
|
if (isValid && VariantTypeEquals(signature.ReturnType, mono_signature_get_return_type(sig)))
|
||||||
return method;
|
return method;
|
||||||
@@ -1187,8 +1198,6 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
|||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
const auto mMethod = (MMethod*)method;
|
const auto mMethod = (MMethod*)method;
|
||||||
MonoMethodSignature* signature = mono_method_signature(mMethod->GetNative());
|
MonoMethodSignature* signature = mono_method_signature(mMethod->GetNative());
|
||||||
void* signatureParams = nullptr;
|
|
||||||
mono_signature_get_params(signature, &signatureParams);
|
|
||||||
const int32 parametersCount = mono_signature_get_param_count(signature);
|
const int32 parametersCount = mono_signature_get_param_count(signature);
|
||||||
if (paramValues.Length() != parametersCount)
|
if (paramValues.Length() != parametersCount)
|
||||||
{
|
{
|
||||||
@@ -1222,20 +1231,25 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
|||||||
void** params = (void**)alloca(parametersCount * sizeof(void*));
|
void** params = (void**)alloca(parametersCount * sizeof(void*));
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
bool hasOutParams = false;
|
bool hasOutParams = false;
|
||||||
for (int32 paramIdx = 0; paramIdx < parametersCount; paramIdx++)
|
void* sigParams = nullptr;
|
||||||
|
MonoType* type = mono_signature_get_params(signature, &sigParams);
|
||||||
|
for (int paramIdx = 0; type != nullptr;)
|
||||||
{
|
{
|
||||||
auto& paramValue = paramValues[paramIdx];
|
auto& paramValue = paramValues[paramIdx];
|
||||||
const bool isOut = mono_signature_param_is_out(signature, paramIdx) != 0;
|
const bool isOut = mono_signature_param_is_out(signature, paramIdx) != 0;
|
||||||
hasOutParams |= isOut;
|
hasOutParams |= isOut;
|
||||||
|
|
||||||
// Marshal parameter for managed method
|
// Marshal parameter for managed method
|
||||||
MType paramType(((MonoType**)signatureParams)[paramIdx]);
|
MType paramType(type);
|
||||||
params[paramIdx] = MUtils::VariantToManagedArgPtr(paramValue, paramType, failed);
|
params[paramIdx] = MUtils::VariantToManagedArgPtr(paramValue, paramType, failed);
|
||||||
if (failed)
|
if (failed)
|
||||||
{
|
{
|
||||||
LOG(Error, "Failed to marshal parameter {5}:{4} of method '{0}.{1}' (args count: {2}), value type: {6}, value: {3}", String(mMethod->GetParentClass()->GetFullName()), String(mMethod->GetName()), parametersCount, paramValue, paramType.ToString(), paramIdx, paramValue.Type);
|
LOG(Error, "Failed to marshal parameter {5}:{4} of method '{0}.{1}' (args count: {2}), value type: {6}, value: {3}", String(mMethod->GetParentClass()->GetFullName()), String(mMethod->GetName()), parametersCount, paramValue, paramType.ToString(), paramIdx, paramValue.Type);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type = mono_signature_get_params(signature, &sigParams);
|
||||||
|
paramIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the method
|
// Invoke the method
|
||||||
|
|||||||
151
Source/Engine/Scripting/DotNet/CoreCLR.cpp
Normal file
151
Source/Engine/Scripting/DotNet/CoreCLR.cpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#include "CoreCLR.h"
|
||||||
|
|
||||||
|
#include "Engine/Core/Log.h"
|
||||||
|
#include "Engine/Platform/Platform.h"
|
||||||
|
#include "Engine/Platform/FileSystem.h"
|
||||||
|
#include "Engine/Core/Types/DateTime.h"
|
||||||
|
#include "Engine/Debug/DebugLog.h"
|
||||||
|
#include "Engine/Core/Collections/Dictionary.h"
|
||||||
|
|
||||||
|
#include <nethost.h>
|
||||||
|
#include <coreclr_delegates.h>
|
||||||
|
#include <hostfxr.h>
|
||||||
|
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
#include <combaseapi.h> // CoTask*
|
||||||
|
#undef SetEnvironmentVariable
|
||||||
|
#undef LoadLibrary
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if COMPILE_WITH_PROFILER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static Dictionary<String, void*> cachedFunctions;
|
||||||
|
static String assemblyName = TEXT("FlaxEngine.CSharp");
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
static const char_t* typeName = TEXT("FlaxEngine.NativeInterop, FlaxEngine.CSharp");
|
||||||
|
#else
|
||||||
|
static const char_t* typeName = "FlaxEngine.NativeInterop, FlaxEngine.CSharp";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hostfxr_initialize_for_runtime_config_fn hostfxr_initialize_for_runtime_config;
|
||||||
|
hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line;
|
||||||
|
hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate;
|
||||||
|
hostfxr_close_fn hostfxr_close;
|
||||||
|
load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer;
|
||||||
|
get_function_pointer_fn get_function_pointer;
|
||||||
|
hostfxr_set_error_writer_fn hostfxr_set_error_writer;
|
||||||
|
hostfxr_get_dotnet_environment_info_result_fn hostfxr_get_dotnet_environment_info_result;
|
||||||
|
hostfxr_run_app_fn hostfxr_run_app;
|
||||||
|
|
||||||
|
bool CoreCLR::LoadHostfxr(const String& library_path_)
|
||||||
|
{
|
||||||
|
const FLAX_CORECLR_STRING& library_path = FLAX_CORECLR_STRING(library_path_);
|
||||||
|
|
||||||
|
Platform::SetEnvironmentVariable(TEXT("DOTNET_TieredPGO"), TEXT("1"));
|
||||||
|
Platform::SetEnvironmentVariable(TEXT("DOTNET_TC_QuickJitForLoops"), TEXT("1"));
|
||||||
|
Platform::SetEnvironmentVariable(TEXT("DOTNET_ReadyToRun"), TEXT("0"));
|
||||||
|
|
||||||
|
char_t hostfxrPath[1024];
|
||||||
|
size_t hostfxrPathSize = sizeof(hostfxrPath) / sizeof(char_t);
|
||||||
|
|
||||||
|
get_hostfxr_parameters params;
|
||||||
|
params.size = sizeof(hostfxr_initialize_parameters);
|
||||||
|
params.assembly_path = library_path.Get();
|
||||||
|
params.dotnet_root = nullptr;//dotnetRoot.Get();
|
||||||
|
|
||||||
|
int rc = get_hostfxr_path(hostfxrPath, &hostfxrPathSize, ¶ms);
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
LOG(Error, "Failed to find hostfxr: {0:x}", (unsigned int)rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String path(hostfxrPath);
|
||||||
|
LOG(Info, "Found hostfxr in {0}", path);
|
||||||
|
|
||||||
|
void *hostfxr = Platform::LoadLibrary(path.Get());
|
||||||
|
hostfxr_initialize_for_runtime_config = (hostfxr_initialize_for_runtime_config_fn)Platform::GetProcAddress(hostfxr, "hostfxr_initialize_for_runtime_config");
|
||||||
|
hostfxr_initialize_for_dotnet_command_line = (hostfxr_initialize_for_dotnet_command_line_fn)Platform::GetProcAddress(hostfxr, "hostfxr_initialize_for_dotnet_command_line");
|
||||||
|
hostfxr_get_runtime_delegate = (hostfxr_get_runtime_delegate_fn)Platform::GetProcAddress(hostfxr, "hostfxr_get_runtime_delegate");
|
||||||
|
hostfxr_close = (hostfxr_close_fn)Platform::GetProcAddress(hostfxr, "hostfxr_close");
|
||||||
|
hostfxr_set_error_writer = (hostfxr_set_error_writer_fn)Platform::GetProcAddress(hostfxr, "hostfxr_set_error_writer");
|
||||||
|
hostfxr_get_dotnet_environment_info_result = (hostfxr_get_dotnet_environment_info_result_fn)Platform::GetProcAddress(hostfxr, "hostfxr_get_dotnet_environment_info_result");
|
||||||
|
hostfxr_run_app = (hostfxr_run_app_fn)Platform::GetProcAddress(hostfxr, "hostfxr_run_app");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CoreCLR::InitHostfxr(const String& config_path, const String& library_path_)
|
||||||
|
{
|
||||||
|
const FLAX_CORECLR_STRING& library_path = FLAX_CORECLR_STRING(library_path_);
|
||||||
|
const char_t* argv[1] = { library_path.Get() };
|
||||||
|
|
||||||
|
hostfxr_initialize_parameters params;
|
||||||
|
params.size = sizeof(hostfxr_initialize_parameters);
|
||||||
|
params.host_path = library_path.Get();
|
||||||
|
params.dotnet_root = nullptr;//dotnetRoot.Get(); // This probably must be set
|
||||||
|
|
||||||
|
hostfxr_handle handle = nullptr;
|
||||||
|
|
||||||
|
// Initialize hosting component, hostfxr_initialize_for_dotnet_command_line is used here
|
||||||
|
// to allow self-contained engine installation to be used when needed.
|
||||||
|
|
||||||
|
int rc = hostfxr_initialize_for_dotnet_command_line(1, argv, ¶ms, &handle);
|
||||||
|
if (rc != 0 || handle == nullptr)
|
||||||
|
{
|
||||||
|
LOG(Error, "Failed to initialize hostfxr: {0:x}", (unsigned int)rc);
|
||||||
|
hostfxr_close(handle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* pget_function_pointer = nullptr;
|
||||||
|
rc = hostfxr_get_runtime_delegate(handle, hdt_get_function_pointer, &pget_function_pointer);
|
||||||
|
if (rc != 0 || pget_function_pointer == nullptr)
|
||||||
|
LOG(Error, "Failed to get runtime delegate hdt_get_function_pointer: {0:x}", (unsigned int)rc);
|
||||||
|
|
||||||
|
hostfxr_close(handle);
|
||||||
|
get_function_pointer = (get_function_pointer_fn)pget_function_pointer;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CoreCLR::GetStaticMethodPointer(const String& methodName)
|
||||||
|
{
|
||||||
|
void* fun;
|
||||||
|
if (cachedFunctions.TryGet(methodName, fun))
|
||||||
|
return fun;
|
||||||
|
|
||||||
|
int rc = get_function_pointer(typeName, FLAX_CORECLR_STRING(methodName).Get(), UNMANAGEDCALLERSONLY_METHOD, nullptr, nullptr, &fun);
|
||||||
|
if (rc != 0)
|
||||||
|
LOG(Fatal, "Failed to get unmanaged function pointer for method {0}: 0x{1:x}", methodName.Get(), (unsigned int)rc);
|
||||||
|
|
||||||
|
cachedFunctions.Add(String(methodName), fun);
|
||||||
|
|
||||||
|
return fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CoreCLR::Allocate(int size)
|
||||||
|
{
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
void* ptr = CoTaskMemAlloc(size);
|
||||||
|
#else
|
||||||
|
void* ptr = malloc(size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if COMPILE_WITH_PROFILER
|
||||||
|
Platform::OnMemoryAlloc(ptr, size);
|
||||||
|
#endif
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreCLR::Free(void* ptr)
|
||||||
|
{
|
||||||
|
#if COMPILE_WITH_PROFILER
|
||||||
|
Platform::OnMemoryFree(ptr);
|
||||||
|
#endif
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
CoTaskMemFree(ptr);
|
||||||
|
#else
|
||||||
|
free(ptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
49
Source/Engine/Scripting/DotNet/CoreCLR.h
Normal file
49
Source/Engine/Scripting/DotNet/CoreCLR.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
#include <ThirdParty/mono-2.0/mono/metadata/blob.h>
|
||||||
|
|
||||||
|
#include "Engine/Core/Types/String.h"
|
||||||
|
#include "Engine/Scripting/Types.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define CORECLR_DELEGATE_CALLTYPE __stdcall
|
||||||
|
#define FLAX_CORECLR_STRING String
|
||||||
|
#else
|
||||||
|
#define CORECLR_DELEGATE_CALLTYPE
|
||||||
|
#define FLAX_CORECLR_STRING StringAnsi
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CoreCLR
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
static bool LoadHostfxr(const String& library_path);
|
||||||
|
static bool InitHostfxr(const String& config_path, const String& library_path);
|
||||||
|
|
||||||
|
static void* GetStaticMethodPointer(const String& methodName);
|
||||||
|
|
||||||
|
template<typename RetType, typename ...Args>
|
||||||
|
static RetType CallStaticMethodInternal(const String& methodName, Args... args)
|
||||||
|
{
|
||||||
|
typedef RetType(CORECLR_DELEGATE_CALLTYPE* fun)(Args...);
|
||||||
|
fun function = (fun)GetStaticMethodPointer(methodName);
|
||||||
|
return function(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RetType, typename ...Args>
|
||||||
|
static RetType CallStaticMethodInternalPointer(void* funPtr, Args... args)
|
||||||
|
{
|
||||||
|
typedef RetType(CORECLR_DELEGATE_CALLTYPE* fun)(Args...);
|
||||||
|
fun function = (fun)funPtr;
|
||||||
|
return function(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* GetClassFullname(void* klass);
|
||||||
|
static void* Allocate(int size);
|
||||||
|
static void Free(void* ptr);
|
||||||
|
static gchandle NewGCHandle(void* obj, bool pinned);
|
||||||
|
static gchandle NewGCHandleWeakref(void* obj, bool track_resurrection);
|
||||||
|
static void* GetGCHandleTarget(const gchandle& gchandle);
|
||||||
|
static void FreeGCHandle(const gchandle& gchandle);
|
||||||
|
};
|
||||||
1564
Source/Engine/Scripting/DotNet/MonoApi.cpp
Normal file
1564
Source/Engine/Scripting/DotNet/MonoApi.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,9 @@ extern "C" FLAXENGINE_API void mono_add_internal_call(const char* name, const vo
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define ADD_INTERNAL_CALL(fullName, method)
|
extern void DotNetAddInternalCall(const wchar_t* fullName, void* function);
|
||||||
|
|
||||||
|
#define ADD_INTERNAL_CALL(fullName, method) DotNetAddInternalCall(TEXT(fullName), (void*)(method))
|
||||||
#define INTERNAL_CALL_CHECK(obj)
|
#define INTERNAL_CALL_CHECK(obj)
|
||||||
#define INTERNAL_CALL_CHECK_EXP(expression)
|
#define INTERNAL_CALL_CHECK_EXP(expression)
|
||||||
#define INTERNAL_CALL_CHECK_RETURN(obj, defaultValue)
|
#define INTERNAL_CALL_CHECK_RETURN(obj, defaultValue)
|
||||||
|
|||||||
@@ -6,17 +6,20 @@
|
|||||||
#include "Engine/Scripting/MException.h"
|
#include "Engine/Scripting/MException.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
namespace UtilsInternal
|
namespace UtilsInternal
|
||||||
{
|
{
|
||||||
MonoObject* ExtractArrayFromList(MonoObject* obj)
|
MonoObject* ExtractArrayFromList(MonoObject* obj)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
auto klass = mono_object_get_class(obj);
|
auto klass = mono_object_get_class(obj);
|
||||||
auto field = mono_class_get_field_from_name(klass, "_items");
|
auto field = mono_class_get_field_from_name(klass, "_items");
|
||||||
MonoObject* o;
|
MonoObject* o;
|
||||||
mono_field_get_value(obj, field, &o);
|
mono_field_get_value(obj, field, &o);
|
||||||
return o;
|
return o;
|
||||||
|
#else
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Utils::Internal_ExtractArrayFromList")
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,6 +27,7 @@ namespace DebugLogHandlerInternal
|
|||||||
{
|
{
|
||||||
void LogWrite(LogType level, MonoString* msgObj)
|
void LogWrite(LogType level, MonoString* msgObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.DebugLogHandler::Internal_LogWrite")
|
||||||
StringView msg;
|
StringView msg;
|
||||||
MUtils::ToString(msgObj, msg);
|
MUtils::ToString(msgObj, msg);
|
||||||
Log::Logger::Write(level, msg);
|
Log::Logger::Write(level, msg);
|
||||||
@@ -31,6 +35,8 @@ namespace DebugLogHandlerInternal
|
|||||||
|
|
||||||
void Log(LogType level, MonoString* msgObj, ScriptingObject* obj, MonoString* stackTrace)
|
void Log(LogType level, MonoString* msgObj, ScriptingObject* obj, MonoString* stackTrace)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.DebugLogHandler::Internal_Log")
|
||||||
|
|
||||||
if (msgObj == nullptr)
|
if (msgObj == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -45,8 +51,11 @@ namespace DebugLogHandlerInternal
|
|||||||
Log::Logger::Write(level, msg);
|
Log::Logger::Write(level, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LogException(MonoException* exception, ScriptingObject* obj)
|
void LogException(MonoException* exception, ScriptingObject* obj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.DebugLogHandler::Internal_LogException")
|
||||||
|
#if USE_MONO
|
||||||
if (exception == nullptr)
|
if (exception == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -57,13 +66,16 @@ namespace DebugLogHandlerInternal
|
|||||||
// Print exception including inner exceptions
|
// Print exception including inner exceptions
|
||||||
// TODO: maybe option for build to threat warnings and errors as fatal errors?
|
// TODO: maybe option for build to threat warnings and errors as fatal errors?
|
||||||
ex.Log(LogType::Warning, objName.GetText());
|
ex.Log(LogType::Warning, objName.GetText());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FlaxLogWriterInternal
|
namespace FlaxLogWriterInternal
|
||||||
{
|
{
|
||||||
void WriteStringToLog(MonoString* msgObj)
|
void WriteStringToLog(MonoString* msgObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.FlaxLogWriter::Internal_WriteStringToLog")
|
||||||
if (msgObj == nullptr)
|
if (msgObj == nullptr)
|
||||||
return;
|
return;
|
||||||
StringView msg;
|
StringView msg;
|
||||||
@@ -72,8 +84,6 @@ namespace FlaxLogWriterInternal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void registerFlaxEngineInternalCalls()
|
void registerFlaxEngineInternalCalls()
|
||||||
{
|
{
|
||||||
AnimGraphExecutor::initRuntime();
|
AnimGraphExecutor::initRuntime();
|
||||||
|
|||||||
@@ -86,7 +86,11 @@ struct FLAXENGINE_API ManagedDictionary
|
|||||||
CHECK_RETURN(makeGenericMethod, nullptr);
|
CHECK_RETURN(makeGenericMethod, nullptr);
|
||||||
|
|
||||||
auto genericType = MUtils::GetType(StdTypesContainer::Instance()->DictionaryClass->GetNative());
|
auto genericType = MUtils::GetType(StdTypesContainer::Instance()->DictionaryClass->GetNative());
|
||||||
|
#if USE_NETCORE
|
||||||
|
auto genericArgs = mono_array_new(domain, mono_get_intptr_class(), 2);
|
||||||
|
#else
|
||||||
auto genericArgs = mono_array_new(domain, mono_get_object_class(), 2);
|
auto genericArgs = mono_array_new(domain, mono_get_object_class(), 2);
|
||||||
|
#endif
|
||||||
mono_array_set(genericArgs, MonoReflectionType*, 0, mono_type_get_object(domain, keyType));
|
mono_array_set(genericArgs, MonoReflectionType*, 0, mono_type_get_object(domain, keyType));
|
||||||
mono_array_set(genericArgs, MonoReflectionType*, 1, mono_type_get_object(domain, valueType));
|
mono_array_set(genericArgs, MonoReflectionType*, 1, mono_type_get_object(domain, valueType));
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
#include "Engine/Platform/Thread.h"
|
#include "Engine/Platform/Thread.h"
|
||||||
#include "Engine/Scripting/MException.h"
|
#include "Engine/Scripting/MException.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
|
#include "Engine/Platform/FileSystem.h"
|
||||||
|
#if USE_NETCORE
|
||||||
|
#include "Engine/Scripting/DotNet/CoreCLR.h"
|
||||||
|
#endif
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
#ifdef USE_MONO_AOT_MODULE
|
#ifdef USE_MONO_AOT_MODULE
|
||||||
#include "Engine/Core/Types/TimeSpan.h"
|
#include "Engine/Core/Types/TimeSpan.h"
|
||||||
@@ -52,6 +56,9 @@ MDomain* MCore::GetActiveDomain()
|
|||||||
|
|
||||||
MDomain* MCore::CreateDomain(const MString& domainName)
|
MDomain* MCore::CreateDomain(const MString& domainName)
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
return nullptr;
|
||||||
|
#else
|
||||||
#if USE_MONO_AOT
|
#if USE_MONO_AOT
|
||||||
LOG(Fatal, "Scripts can run only in single domain mode with AOT mode enabled.");
|
LOG(Fatal, "Scripts can run only in single domain mode with AOT mode enabled.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -74,10 +81,13 @@ MDomain* MCore::CreateDomain(const MString& domainName)
|
|||||||
#endif
|
#endif
|
||||||
MDomains.Add(domain);
|
MDomains.Add(domain);
|
||||||
return domain;
|
return domain;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCore::UnloadDomain(const MString& domainName)
|
void MCore::UnloadDomain(const MString& domainName)
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
#else
|
||||||
int32 i = 0;
|
int32 i = 0;
|
||||||
for (; i < MDomains.Count(); i++)
|
for (; i < MDomains.Count(); i++)
|
||||||
{
|
{
|
||||||
@@ -103,9 +113,48 @@ void MCore::UnloadDomain(const MString& domainName)
|
|||||||
#endif
|
#endif
|
||||||
Delete(domain);
|
Delete(domain);
|
||||||
MDomains.RemoveAtKeepOrder(i);
|
MDomains.RemoveAtKeepOrder(i);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_NETCORE
|
||||||
|
bool MCore::LoadEngine()
|
||||||
|
{
|
||||||
|
const String csharpLibraryPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll");
|
||||||
|
const String csharpRuntimeConfigPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.runtimeconfig.json");
|
||||||
|
if (!FileSystem::FileExists(csharpLibraryPath))
|
||||||
|
LOG(Fatal, "Failed to initialize managed runtime, FlaxEngine.CSharp.dll is missing.");
|
||||||
|
if (!FileSystem::FileExists(csharpRuntimeConfigPath))
|
||||||
|
LOG(Fatal, "Failed to initialize managed runtime, FlaxEngine.CSharp.runtimeconfig.json is missing.");
|
||||||
|
|
||||||
|
// Locate hostfxr and load it
|
||||||
|
if (!CoreCLR::LoadHostfxr(csharpLibraryPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Initialize hosting component
|
||||||
|
if (!CoreCLR::InitHostfxr(csharpRuntimeConfigPath, csharpLibraryPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Prepare managed side
|
||||||
|
const String hostExecutable = Platform::GetExecutableFilePath();
|
||||||
|
CoreCLR::CallStaticMethodInternal<void, const Char*>(TEXT("Init"), hostExecutable.Get());
|
||||||
|
|
||||||
|
MRootDomain = New<MDomain>("Root");
|
||||||
|
MDomains.Add(MRootDomain);
|
||||||
|
|
||||||
|
char* buildInfo = mono_get_runtime_build_info();
|
||||||
|
LOG(Info, ".NET runtime version: {0}", String(buildInfo));
|
||||||
|
mono_free(buildInfo);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCore::UnloadEngine()
|
||||||
|
{
|
||||||
|
CoreCLR::CallStaticMethodInternal<void>(TEXT("Exit"));
|
||||||
|
MDomains.ClearDelete();
|
||||||
|
MRootDomain = nullptr;
|
||||||
|
}
|
||||||
|
#elif USE_MONO
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
@@ -518,7 +567,7 @@ bool MCore::LoadEngine()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init Mono
|
// Init managed runtime
|
||||||
#if PLATFORM_ANDROID
|
#if PLATFORM_ANDROID
|
||||||
const char* monoVersion = "mobile";
|
const char* monoVersion = "mobile";
|
||||||
#else
|
#else
|
||||||
@@ -530,6 +579,7 @@ bool MCore::LoadEngine()
|
|||||||
MRootDomain->_monoDomain = monoRootDomain;
|
MRootDomain->_monoDomain = monoRootDomain;
|
||||||
MDomains.Add(MRootDomain);
|
MDomains.Add(MRootDomain);
|
||||||
|
|
||||||
|
#if !USE_NETCORE
|
||||||
auto exePath = Platform::GetExecutableFilePath();
|
auto exePath = Platform::GetExecutableFilePath();
|
||||||
auto configDir = StringUtils::GetDirectoryName(exePath).ToStringAnsi();
|
auto configDir = StringUtils::GetDirectoryName(exePath).ToStringAnsi();
|
||||||
auto configFilename = StringUtils::GetFileName(exePath).ToStringAnsi() + ".config";
|
auto configFilename = StringUtils::GetFileName(exePath).ToStringAnsi() + ".config";
|
||||||
@@ -542,10 +592,11 @@ bool MCore::LoadEngine()
|
|||||||
#endif
|
#endif
|
||||||
mono_domain_set_config(monoRootDomain, configDir.Get(), configFilename.Get());
|
mono_domain_set_config(monoRootDomain, configDir.Get(), configFilename.Get());
|
||||||
mono_thread_set_main(mono_thread_current());
|
mono_thread_set_main(mono_thread_current());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Info
|
// Info
|
||||||
char* buildInfo = mono_get_runtime_build_info();
|
char* buildInfo = mono_get_runtime_build_info();
|
||||||
LOG(Info, "Mono version: {0}", String(buildInfo));
|
LOG(Info, "Mono runtime version: {0}", String(buildInfo));
|
||||||
mono_free(buildInfo);
|
mono_free(buildInfo);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -672,7 +723,7 @@ void MCore::GC::WaitForPendingFinalizers()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_MONO && PLATFORM_WIN32 && !USE_MONO_DYNAMIC_LIB
|
#if USE_MONO && PLATFORM_WIN32 && !USE_MONO_DYNAMIC_LIB && !USE_NETCORE
|
||||||
|
|
||||||
// Export Mono functions
|
// Export Mono functions
|
||||||
#pragma comment(linker, "/export:mono_add_internal_call")
|
#pragma comment(linker, "/export:mono_add_internal_call")
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This is the fastest way of calling managed code.
|
/// This is the fastest way of calling managed code.
|
||||||
/// Get thunk from class if you want to call static method. You to call it from method of a instance wrapper to call a specific instance.
|
/// Get thunk from class if you want to call static method. You need to call it from method of a instance wrapper to call a specific instance.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>The method thunk pointer.</returns>
|
/// <returns>The method thunk pointer.</returns>
|
||||||
void* GetThunk();
|
void* GetThunk();
|
||||||
|
|||||||
@@ -24,6 +24,10 @@
|
|||||||
#include "Engine/Utilities/StringConverter.h"
|
#include "Engine/Utilities/StringConverter.h"
|
||||||
#include "Engine/Content/Asset.h"
|
#include "Engine/Content/Asset.h"
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
#include "Engine/Scripting/DotNet/CoreCLR.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
// Inlined mono private types to access MonoType internals
|
// Inlined mono private types to access MonoType internals
|
||||||
@@ -356,11 +360,17 @@ Variant MUtils::UnboxVariant(MonoObject* value)
|
|||||||
return Variant::Null;
|
return Variant::Null;
|
||||||
const auto& stdTypes = *StdTypesContainer::Instance();
|
const auto& stdTypes = *StdTypesContainer::Instance();
|
||||||
const auto klass = mono_object_get_class(value);
|
const auto klass = mono_object_get_class(value);
|
||||||
|
|
||||||
|
MonoType* monoType = mono_class_get_type(klass);
|
||||||
|
const MonoTypeEnum monoTypeId = (MonoTypeEnum)mono_type_get_type(monoType);
|
||||||
|
#if USE_NETCORE
|
||||||
|
void* unboxed = mono_object_unbox(value);
|
||||||
|
#else
|
||||||
void* unboxed = (byte*)value + sizeof(MonoObject);
|
void* unboxed = (byte*)value + sizeof(MonoObject);
|
||||||
const MonoType* monoType = mono_class_get_type(klass);
|
#endif
|
||||||
|
|
||||||
// Fast type detection for in-built types
|
// Fast type detection for in-built types
|
||||||
switch (monoType->type)
|
switch (monoTypeId)
|
||||||
{
|
{
|
||||||
case MONO_TYPE_VOID:
|
case MONO_TYPE_VOID:
|
||||||
return Variant(VariantType(VariantType::Void));
|
return Variant(VariantType(VariantType::Void));
|
||||||
@@ -660,7 +670,11 @@ MonoObject* MUtils::BoxVariant(const Variant& value)
|
|||||||
case VariantType::Guid:
|
case VariantType::Guid:
|
||||||
return mono_value_box(mono_domain_get(), stdTypes.GuidClass->GetNative(), (void*)&value.AsData);
|
return mono_value_box(mono_domain_get(), stdTypes.GuidClass->GetNative(), (void*)&value.AsData);
|
||||||
case VariantType::String:
|
case VariantType::String:
|
||||||
|
#if USE_NETCORE
|
||||||
return (MonoObject*)MUtils::ToString((StringView)value);
|
return (MonoObject*)MUtils::ToString((StringView)value);
|
||||||
|
#else
|
||||||
|
return (MonoObject*)MUtils::ToString((StringView)value);
|
||||||
|
#endif
|
||||||
case VariantType::Quaternion:
|
case VariantType::Quaternion:
|
||||||
return mono_value_box(mono_domain_get(), stdTypes.QuaternionClass->GetNative(), (void*)&value.AsData);
|
return mono_value_box(mono_domain_get(), stdTypes.QuaternionClass->GetNative(), (void*)&value.AsData);
|
||||||
case VariantType::BoundingSphere:
|
case VariantType::BoundingSphere:
|
||||||
@@ -844,7 +858,11 @@ MonoObject* MUtils::BoxVariant(const Variant& value)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
return value.AsUint ? mono_gchandle_get_target(value.AsUint) : nullptr;
|
#if USE_NETCORE
|
||||||
|
return value.AsUint64 ? MUtils::GetGCHandleTarget(value.AsUint64) : nullptr;
|
||||||
|
#else
|
||||||
|
return value.AsUint ? MUtils::GetGCHandleTarget(value.AsUint) : nullptr;
|
||||||
|
#endif
|
||||||
case VariantType::Typename:
|
case VariantType::Typename:
|
||||||
{
|
{
|
||||||
const auto klass = Scripting::FindClassNative((StringAnsiView)value);
|
const auto klass = Scripting::FindClassNative((StringAnsiView)value);
|
||||||
@@ -869,6 +887,9 @@ void MUtils::GetClassFullname(MonoObject* obj, MString& fullname)
|
|||||||
|
|
||||||
void MUtils::GetClassFullname(MonoClass* monoClass, MString& fullname)
|
void MUtils::GetClassFullname(MonoClass* monoClass, MString& fullname)
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
fullname = CoreCLR::GetClassFullname(monoClass);
|
||||||
|
#else
|
||||||
static MString plusStr("+");
|
static MString plusStr("+");
|
||||||
static MString dotStr(".");
|
static MString dotStr(".");
|
||||||
|
|
||||||
@@ -906,6 +927,7 @@ void MUtils::GetClassFullname(MonoClass* monoClass, MString& fullname)
|
|||||||
}
|
}
|
||||||
fullname += ']';
|
fullname += ']';
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MUtils::GetClassFullname(MonoReflectionType* type, MString& fullname)
|
void MUtils::GetClassFullname(MonoReflectionType* type, MString& fullname)
|
||||||
@@ -1138,7 +1160,8 @@ BytesContainer MUtils::LinkArray(MonoArray* arrayObj)
|
|||||||
void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& failed)
|
void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& failed)
|
||||||
{
|
{
|
||||||
// Convert Variant into matching managed type and return pointer to data for the method invocation
|
// Convert Variant into matching managed type and return pointer to data for the method invocation
|
||||||
switch (type.GetNative()->type)
|
MonoTypeEnum monoType = (MonoTypeEnum)mono_type_get_type(type.GetNative());
|
||||||
|
switch (monoType)
|
||||||
{
|
{
|
||||||
case MONO_TYPE_BOOLEAN:
|
case MONO_TYPE_BOOLEAN:
|
||||||
if (value.Type.Type != VariantType::Bool)
|
if (value.Type.Type != VariantType::Bool)
|
||||||
@@ -1183,7 +1206,11 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa
|
|||||||
return MUtils::ToString((StringView)value);
|
return MUtils::ToString((StringView)value);
|
||||||
case MONO_TYPE_VALUETYPE:
|
case MONO_TYPE_VALUETYPE:
|
||||||
{
|
{
|
||||||
|
#if !USE_NETCORE
|
||||||
MonoClass* klass = type.GetNative()->data.klass;
|
MonoClass* klass = type.GetNative()->data.klass;
|
||||||
|
#else
|
||||||
|
MonoClass* klass = mono_type_get_class(type.GetNative());
|
||||||
|
#endif
|
||||||
if (mono_class_is_enum(klass))
|
if (mono_class_is_enum(klass))
|
||||||
{
|
{
|
||||||
if (value.Type.Type != VariantType::Enum)
|
if (value.Type.Type != VariantType::Enum)
|
||||||
@@ -1305,15 +1332,52 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa
|
|||||||
|
|
||||||
MonoObject* MUtils::ToManaged(const Version& value)
|
MonoObject* MUtils::ToManaged(const Version& value)
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
auto scriptingClass = Scripting::GetStaticClass();
|
||||||
|
CHECK_RETURN(scriptingClass, nullptr);
|
||||||
|
auto versionToManaged = scriptingClass->GetMethod("VersionToManaged", 4);
|
||||||
|
CHECK_RETURN(versionToManaged, nullptr);
|
||||||
|
|
||||||
|
int major = value.Major();
|
||||||
|
int minor = value.Minor();
|
||||||
|
int build = value.Build();
|
||||||
|
int revision = value.Revision();
|
||||||
|
|
||||||
|
void* params[4];
|
||||||
|
params[0] = &major;
|
||||||
|
params[1] = &minor;
|
||||||
|
params[2] = &build;
|
||||||
|
params[3] = &revision;
|
||||||
|
auto obj = versionToManaged->Invoke(nullptr, params, nullptr);
|
||||||
|
#else
|
||||||
auto obj = mono_object_new(mono_domain_get(), Scripting::FindClassNative("System.Version"));
|
auto obj = mono_object_new(mono_domain_get(), Scripting::FindClassNative("System.Version"));
|
||||||
Platform::MemoryCopy((byte*)obj + sizeof(MonoObject), &value, sizeof(Version));
|
Platform::MemoryCopy((byte*)obj + sizeof(MonoObject), &value, sizeof(Version));
|
||||||
|
#endif
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
Version MUtils::ToNative(MonoObject* value)
|
Version MUtils::ToNative(MonoObject* value)
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
|
#if USE_NETCORE
|
||||||
|
{
|
||||||
|
auto ver = Version();
|
||||||
|
|
||||||
|
auto scriptingClass = Scripting::GetStaticClass();
|
||||||
|
CHECK_RETURN(scriptingClass, ver);
|
||||||
|
auto versionToNative = scriptingClass->GetMethod("VersionToNative", 2);
|
||||||
|
CHECK_RETURN(versionToNative, ver);
|
||||||
|
|
||||||
|
void* params[2];
|
||||||
|
params[0] = value;
|
||||||
|
params[1] = &ver;
|
||||||
|
versionToNative->Invoke(nullptr, params, nullptr);
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
return *(Version*)((byte*)value + sizeof(MonoObject));
|
return *(Version*)((byte*)value + sizeof(MonoObject));
|
||||||
|
#endif
|
||||||
return Version();
|
return Version();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,11 @@
|
|||||||
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
#include "Engine/Scripting/DotNet/CoreCLR.h"
|
||||||
|
#include "Engine/Core/Collections/BitArray.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Version;
|
struct Version;
|
||||||
|
|
||||||
namespace MUtils
|
namespace MUtils
|
||||||
@@ -53,6 +58,19 @@ struct MConverter
|
|||||||
void ToNativeArray(Array<T, AllocationType>& result, MonoArray* data, int32 length);
|
void ToNativeArray(Array<T, AllocationType>& result, MonoArray* data, int32 length);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
// Pass-through converter for ScriptingObjects (passed as GCHandles)
|
||||||
|
template<>
|
||||||
|
struct MConverter<void*>
|
||||||
|
{
|
||||||
|
void Unbox(void*& result, MonoObject* data)
|
||||||
|
{
|
||||||
|
CHECK(data);
|
||||||
|
result = data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
// Converter for POD types (that can use raw memory copy).
|
// Converter for POD types (that can use raw memory copy).
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class ScriptingObject, typename TRemovePointer<T>::Type>>>::Value>::Type>
|
struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class ScriptingObject, typename TRemovePointer<T>::Type>>>::Value>::Type>
|
||||||
@@ -86,12 +104,22 @@ struct MConverter<String>
|
|||||||
{
|
{
|
||||||
MonoObject* Box(const String& data, MonoClass* klass)
|
MonoObject* Box(const String& data, MonoClass* klass)
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
MonoString* str = MUtils::ToString(data);
|
||||||
|
return mono_value_box(nullptr, klass, str);
|
||||||
|
#else
|
||||||
return (MonoObject*)MUtils::ToString(data);
|
return (MonoObject*)MUtils::ToString(data);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unbox(String& result, MonoObject* data)
|
void Unbox(String& result, MonoObject* data)
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
MonoString* str = (MonoString*)mono_object_unbox(data);
|
||||||
|
result = MUtils::ToString(str);
|
||||||
|
#else
|
||||||
result = MUtils::ToString((MonoString*)data);
|
result = MUtils::ToString((MonoString*)data);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToManagedArray(MonoArray* result, const Span<String>& data)
|
void ToManagedArray(MonoArray* result, const Span<String>& data)
|
||||||
@@ -564,6 +592,72 @@ namespace MUtils
|
|||||||
return ToArray(Span<String>(data.Get(), data.Count()), mono_get_string_class());
|
return ToArray(Span<String>(data.Get(), data.Count()), mono_get_string_class());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
/// <summary>
|
||||||
|
/// Allocates new boolean array and copies data from the given unmanaged data container.
|
||||||
|
/// The managed runtime is responsible for releasing the returned array data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">The input data.</param>
|
||||||
|
/// <returns>The output array.</returns>
|
||||||
|
FORCE_INLINE bool* ToBoolArray(const Array<bool>& data)
|
||||||
|
{
|
||||||
|
bool* arr = (bool*)CoreCLR::Allocate(data.Count() * sizeof(bool));
|
||||||
|
memcpy(arr, data.Get(), data.Count() * sizeof(bool));
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allocates new boolean array and copies data from the given unmanaged data container.
|
||||||
|
/// The managed runtime is responsible for releasing the returned array data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">The input data.</param>
|
||||||
|
/// <returns>The output array.</returns>
|
||||||
|
FORCE_INLINE bool* ToBoolArray(const BitArray<>& data)
|
||||||
|
{
|
||||||
|
bool* arr = (bool*)CoreCLR::Allocate(data.Count() * sizeof(bool));
|
||||||
|
//memcpy(arr, data.Get(), data.Count() * sizeof(bool));
|
||||||
|
for (int i = 0; i < data.Count(); i++)
|
||||||
|
arr[i] = data[i];
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FORCE_INLINE gchandle NewGCHandle(MonoObject* obj, bool pinned)
|
||||||
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
return CoreCLR::NewGCHandle(obj, pinned);
|
||||||
|
#else
|
||||||
|
return mono_gchandle_new(obj, pinned);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE gchandle NewGCHandleWeakref(MonoObject* obj, bool track_resurrection)
|
||||||
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
return CoreCLR::NewGCHandleWeakref(obj, track_resurrection);
|
||||||
|
#else
|
||||||
|
return mono_gchandle_new_weak_ref(obj, track_resurrection);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE MonoObject* GetGCHandleTarget(const gchandle& handle)
|
||||||
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
return (MonoObject*)CoreCLR::GetGCHandleTarget(handle);
|
||||||
|
#else
|
||||||
|
return mono_gchandle_get_target(handle);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE void FreeGCHandle(const gchandle& handle)
|
||||||
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
CoreCLR::FreeGCHandle(handle);
|
||||||
|
#else
|
||||||
|
mono_gchandle_free(handle);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
extern void* VariantToManagedArgPtr(Variant& value, const MType& type, bool& failed);
|
extern void* VariantToManagedArgPtr(Variant& value, const MType& type, bool& failed);
|
||||||
extern MonoObject* ToManaged(const Version& value);
|
extern MonoObject* ToManaged(const Version& value);
|
||||||
extern Version ToNative(MonoObject* value);
|
extern Version ToNative(MonoObject* value);
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
|
|
||||||
// ReSharper disable UnassignedReadonlyField
|
// ReSharper disable UnassignedReadonlyField
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
@@ -13,13 +15,14 @@ namespace FlaxEngine
|
|||||||
/// Base class for all objects Flax can reference. Every object has unique identifier.
|
/// Base class for all objects Flax can reference. Every object has unique identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public abstract class Object
|
[NativeMarshalling(typeof(ObjectMarshaller))]
|
||||||
|
public abstract partial class Object
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The pointer to the unmanaged object (native C++ instance).
|
/// The pointer to the unmanaged object (native C++ instance).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
protected readonly IntPtr __unmanagedPtr;
|
internal readonly IntPtr __unmanagedPtr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The object unique identifier.
|
/// The object unique identifier.
|
||||||
@@ -248,35 +251,35 @@ namespace FlaxEngine
|
|||||||
|
|
||||||
#region Internal Calls
|
#region Internal Calls
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_Create1", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern Object Internal_Create1(Type type);
|
internal static partial Object Internal_Create1([MarshalUsing(typeof(SystemTypeMarshaller))] Type type);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_Create2", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern Object Internal_Create2(string typeName);
|
internal static partial Object Internal_Create2(string typeName);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_ManagedInstanceCreated", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_ManagedInstanceCreated(Object managedInstance);
|
internal static partial void Internal_ManagedInstanceCreated(Object managedInstance);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_ManagedInstanceDeleted", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_ManagedInstanceDeleted(IntPtr nativeInstance);
|
internal static partial void Internal_ManagedInstanceDeleted(IntPtr nativeInstance);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_Destroy", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_Destroy(IntPtr obj, float timeLeft);
|
internal static partial void Internal_Destroy(IntPtr obj, float timeLeft);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern string Internal_GetTypeName(IntPtr obj);
|
internal static partial string Internal_GetTypeName(IntPtr obj);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_FindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern Object Internal_FindObject(ref Guid id, Type type);
|
internal static partial Object Internal_FindObject(ref Guid id, [MarshalUsing(typeof(SystemTypeMarshaller))] Type type);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_TryFindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern Object Internal_TryFindObject(ref Guid id, Type type);
|
internal static partial Object Internal_TryFindObject(ref Guid id, [MarshalUsing(typeof(SystemTypeMarshaller))] Type type);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_ChangeID", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern void Internal_ChangeID(IntPtr obj, ref Guid id);
|
internal static partial void Internal_ChangeID(IntPtr obj, ref Guid id);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Object::Internal_GetUnmanagedInterface", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
internal static extern IntPtr Internal_GetUnmanagedInterface(IntPtr obj, Type type);
|
internal static partial IntPtr Internal_GetUnmanagedInterface(IntPtr obj, [MarshalUsing(typeof(SystemTypeMarshaller))] Type type);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ public class Scripting : EngineModule
|
|||||||
|
|
||||||
if (EngineConfiguration.WithCSharp(options))
|
if (EngineConfiguration.WithCSharp(options))
|
||||||
{
|
{
|
||||||
options.PublicDependencies.Add("mono");
|
if (EngineConfiguration.UseDotNet)
|
||||||
|
options.PublicDependencies.Add("nethost");
|
||||||
|
else
|
||||||
|
options.PublicDependencies.Add("mono");
|
||||||
}
|
}
|
||||||
|
|
||||||
options.PrivateDependencies.Add("Utilities");
|
options.PrivateDependencies.Add("Utilities");
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ namespace ProfilerInternal
|
|||||||
|
|
||||||
void BeginEvent(MonoString* nameObj)
|
void BeginEvent(MonoString* nameObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Profiler::BeginEvent")
|
||||||
#if COMPILE_WITH_PROFILER
|
#if COMPILE_WITH_PROFILER
|
||||||
const StringView name((const Char*)mono_string_chars(nameObj), mono_string_length(nameObj));
|
const StringView name((const Char*)mono_string_chars(nameObj), mono_string_length(nameObj));
|
||||||
ProfilerCPU::BeginEvent(*name);
|
ProfilerCPU::BeginEvent(*name);
|
||||||
@@ -78,6 +79,7 @@ namespace ProfilerInternal
|
|||||||
|
|
||||||
void EndEvent()
|
void EndEvent()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Profiler::EndEvent")
|
||||||
#if COMPILE_WITH_PROFILER
|
#if COMPILE_WITH_PROFILER
|
||||||
#if TRACY_ENABLE
|
#if TRACY_ENABLE
|
||||||
tracy::ScopedZone::End();
|
tracy::ScopedZone::End();
|
||||||
@@ -88,6 +90,7 @@ namespace ProfilerInternal
|
|||||||
|
|
||||||
void BeginEventGPU(MonoString* nameObj)
|
void BeginEventGPU(MonoString* nameObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Profiler::BeginEventGPU")
|
||||||
#if COMPILE_WITH_PROFILER
|
#if COMPILE_WITH_PROFILER
|
||||||
const auto index = ProfilerGPU::BeginEvent((const Char*)mono_string_chars(nameObj));
|
const auto index = ProfilerGPU::BeginEvent((const Char*)mono_string_chars(nameObj));
|
||||||
ManagedEventsGPU.Push(index);
|
ManagedEventsGPU.Push(index);
|
||||||
@@ -96,6 +99,7 @@ namespace ProfilerInternal
|
|||||||
|
|
||||||
void EndEventGPU()
|
void EndEventGPU()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Profiler::EndEventGPU")
|
||||||
#if COMPILE_WITH_PROFILER
|
#if COMPILE_WITH_PROFILER
|
||||||
const auto index = ManagedEventsGPU.Pop();
|
const auto index = ManagedEventsGPU.Pop();
|
||||||
ProfilerGPU::EndEvent(index);
|
ProfilerGPU::EndEvent(index);
|
||||||
@@ -111,16 +115,19 @@ public:
|
|||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
static bool HasGameModulesLoaded()
|
static bool HasGameModulesLoaded()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Scripting::HasGameModulesLoaded")
|
||||||
return Scripting::HasGameModulesLoaded();
|
return Scripting::HasGameModulesLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsTypeFromGameScripts(MonoReflectionType* type)
|
static bool IsTypeFromGameScripts(MonoReflectionType* type)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Scripting::IsTypeFromGameScripts")
|
||||||
return Scripting::IsTypeFromGameScripts(Scripting::FindClass(MUtils::GetClass(type)));
|
return Scripting::IsTypeFromGameScripts(Scripting::FindClass(MUtils::GetClass(type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FlushRemovedObjects()
|
static void FlushRemovedObjects()
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Scripting::FlushRemovedObjects")
|
||||||
ASSERT(IsInMainThread());
|
ASSERT(IsInMainThread());
|
||||||
ObjectsRemovalService::Flush();
|
ObjectsRemovalService::Flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -903,6 +903,7 @@ ScriptingObject* Scripting::FindObject(const MObject* managedInstance)
|
|||||||
|
|
||||||
void Scripting::OnManagedInstanceDeleted(ScriptingObject* obj)
|
void Scripting::OnManagedInstanceDeleted(ScriptingObject* obj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_ManagedInstanceDeleted")
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
ASSERT(obj);
|
ASSERT(obj);
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using System.Collections;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
@@ -65,7 +67,7 @@ namespace FlaxEngine
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// C# scripting service.
|
/// C# scripting service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Scripting
|
public static partial class Scripting
|
||||||
{
|
{
|
||||||
private static readonly List<Action> UpdateActions = new List<Action>();
|
private static readonly List<Action> UpdateActions = new List<Action>();
|
||||||
private static readonly MainThreadTaskScheduler MainThreadTaskScheduler = new MainThreadTaskScheduler();
|
private static readonly MainThreadTaskScheduler MainThreadTaskScheduler = new MainThreadTaskScheduler();
|
||||||
@@ -207,6 +209,21 @@ namespace FlaxEngine
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static IntPtr VersionToManaged(int major, int minor, int build, int revision)
|
||||||
|
{
|
||||||
|
Version version = new Version(major, minor, Math.Max(build, 0), Math.Max(revision, 0));
|
||||||
|
return GCHandle.ToIntPtr(GCHandle.Alloc(version));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void VersionToNative(IntPtr versionHandle, IntPtr nativePtr)
|
||||||
|
{
|
||||||
|
Version version = (Version)GCHandle.FromIntPtr(versionHandle).Target;
|
||||||
|
Marshal.WriteInt32(nativePtr, 0, version.Major);
|
||||||
|
Marshal.WriteInt32(nativePtr, 4, version.Minor);
|
||||||
|
Marshal.WriteInt32(nativePtr, 8, version.Build);
|
||||||
|
Marshal.WriteInt32(nativePtr, 12, version.Revision);
|
||||||
|
}
|
||||||
|
|
||||||
private static void CreateGuiStyle()
|
private static void CreateGuiStyle()
|
||||||
{
|
{
|
||||||
var style = new Style
|
var style = new Style
|
||||||
@@ -283,21 +300,23 @@ namespace FlaxEngine
|
|||||||
/// Returns true if game scripts assembly has been loaded.
|
/// Returns true if game scripts assembly has been loaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if game scripts assembly is loaded, otherwise false.</returns>
|
/// <returns>True if game scripts assembly is loaded, otherwise false.</returns>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Scripting::HasGameModulesLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
public static extern bool HasGameModulesLoaded();
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
public static partial bool HasGameModulesLoaded();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if given type is from one of the game scripts assemblies.
|
/// Returns true if given type is from one of the game scripts assemblies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if the type is from game assembly, otherwise false.</returns>
|
/// <returns>True if the type is from game assembly, otherwise false.</returns>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Scripting::IsTypeFromGameScripts", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
public static extern bool IsTypeFromGameScripts(Type type);
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
|
public static partial bool IsTypeFromGameScripts([MarshalUsing(typeof(SystemTypeMarshaller))] Type type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Flushes the removed objects (disposed objects using Object.Destroy).
|
/// Flushes the removed objects (disposed objects using Object.Destroy).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Scripting::FlushRemovedObjects", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
public static extern void FlushRemovedObjects();
|
public static partial void FlushRemovedObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -306,32 +325,32 @@ namespace FlaxEngine
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Profiler is available in the editor and Debug/Development builds. Release builds don't have profiling tools.
|
/// Profiler is available in the editor and Debug/Development builds. Release builds don't have profiling tools.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static class Profiler
|
public static partial class Profiler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Begins profiling a piece of code with a custom label.
|
/// Begins profiling a piece of code with a custom label.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the event.</param>
|
/// <param name="name">The name of the event.</param>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Profiler::BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
public static extern void BeginEvent(string name);
|
public static partial void BeginEvent(string name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ends profiling an event.
|
/// Ends profiling an event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Profiler::EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
public static extern void EndEvent();
|
public static partial void EndEvent();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Begins GPU profiling a piece of code with a custom label.
|
/// Begins GPU profiling a piece of code with a custom label.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the event.</param>
|
/// <param name="name">The name of the event.</param>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Profiler::BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
public static extern void BeginEventGPU(string name);
|
public static partial void BeginEventGPU(string name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ends GPU profiling an event.
|
/// Ends GPU profiling an event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Profiler::EndEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
|
||||||
public static extern void EndEventGPU();
|
public static partial void EndEventGPU();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,9 +68,13 @@ ScriptingObject* ScriptingObject::NewObject(const ScriptingTypeHandle& typeHandl
|
|||||||
|
|
||||||
MObject* ScriptingObject::GetManagedInstance() const
|
MObject* ScriptingObject::GetManagedInstance() const
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
const gchandle handle = Platform::AtomicRead((int64*)&_gcHandle);
|
||||||
|
#elif USE_MONO
|
||||||
|
const gchandle handle = Platform::AtomicRead((int32*)&_gcHandle);
|
||||||
|
#endif
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
const int32 handle = Platform::AtomicRead((int32*)&_gcHandle);
|
return handle ? MUtils::GetGCHandleTarget(handle) : nullptr;
|
||||||
return handle ? mono_gchandle_get_target(handle) : nullptr;
|
|
||||||
#else
|
#else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
@@ -211,7 +215,7 @@ void ScriptingObject::OnManagedInstanceDeleted()
|
|||||||
if (_gcHandle)
|
if (_gcHandle)
|
||||||
{
|
{
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
mono_gchandle_free(_gcHandle);
|
MUtils::FreeGCHandle(_gcHandle);
|
||||||
#endif
|
#endif
|
||||||
_gcHandle = 0;
|
_gcHandle = 0;
|
||||||
}
|
}
|
||||||
@@ -236,10 +240,16 @@ bool ScriptingObject::CreateManaged()
|
|||||||
if (!managedInstance)
|
if (!managedInstance)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Prevent form object GC destruction
|
// Prevent from object GC destruction
|
||||||
auto handle = mono_gchandle_new(managedInstance, false);
|
#if USE_NETCORE
|
||||||
|
auto handle = (gchandle)managedInstance;
|
||||||
|
auto oldHandle = Platform::InterlockedCompareExchange((int64*)&_gcHandle, *(int64*)&handle, 0);
|
||||||
|
if (*(uint64*)&oldHandle != 0)
|
||||||
|
#else
|
||||||
|
auto handle = MUtils::NewGCHandle(managedInstance, false);
|
||||||
auto oldHandle = Platform::InterlockedCompareExchange((int32*)&_gcHandle, *(int32*)&handle, 0);
|
auto oldHandle = Platform::InterlockedCompareExchange((int32*)&_gcHandle, *(int32*)&handle, 0);
|
||||||
if (*(uint32*)&oldHandle != 0)
|
if (*(uint32*)&oldHandle != 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// Other thread already created the object before
|
// Other thread already created the object before
|
||||||
if (const auto monoClass = GetClass())
|
if (const auto monoClass = GetClass())
|
||||||
@@ -252,7 +262,7 @@ bool ScriptingObject::CreateManaged()
|
|||||||
monoUnmanagedPtrField->SetValue(managedInstance, ¶m);
|
monoUnmanagedPtrField->SetValue(managedInstance, ¶m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mono_gchandle_free(handle);
|
MUtils::FreeGCHandle(handle);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -337,7 +347,7 @@ void ScriptingObject::DestroyManaged()
|
|||||||
// Clear the handle
|
// Clear the handle
|
||||||
if (_gcHandle)
|
if (_gcHandle)
|
||||||
{
|
{
|
||||||
mono_gchandle_free(_gcHandle);
|
MUtils::FreeGCHandle(_gcHandle);
|
||||||
_gcHandle = 0;
|
_gcHandle = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -448,9 +458,15 @@ bool ManagedScriptingObject::CreateManaged()
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Cache the GC handle to the object (used to track the target object because it can be moved in a memory)
|
// Cache the GC handle to the object (used to track the target object because it can be moved in a memory)
|
||||||
auto handle = mono_gchandle_new_weakref(managedInstance, false);
|
#if USE_NETCORE
|
||||||
|
auto handle = (gchandle)managedInstance;
|
||||||
|
auto oldHandle = Platform::InterlockedCompareExchange((int64*)&_gcHandle, *(int64*)&handle, 0);
|
||||||
|
if (*(uint64*)&oldHandle != 0)
|
||||||
|
#else
|
||||||
|
auto handle = MUtils::NewGCHandleWeakref(managedInstance, false);
|
||||||
auto oldHandle = Platform::InterlockedCompareExchange((int32*)&_gcHandle, *(int32*)&handle, 0);
|
auto oldHandle = Platform::InterlockedCompareExchange((int32*)&_gcHandle, *(int32*)&handle, 0);
|
||||||
if (*(uint32*)&oldHandle != 0)
|
if (*(uint32*)&oldHandle != 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// Other thread already created the object before
|
// Other thread already created the object before
|
||||||
if (const auto monoClass = GetClass())
|
if (const auto monoClass = GetClass())
|
||||||
@@ -463,7 +479,7 @@ bool ManagedScriptingObject::CreateManaged()
|
|||||||
monoUnmanagedPtrField->SetValue(managedInstance, ¶m);
|
monoUnmanagedPtrField->SetValue(managedInstance, ¶m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mono_gchandle_free(handle);
|
MUtils::FreeGCHandle(handle);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -487,6 +503,7 @@ public:
|
|||||||
|
|
||||||
static MonoObject* Create1(MonoReflectionType* type)
|
static MonoObject* Create1(MonoReflectionType* type)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_Create1")
|
||||||
// Peek class for that type (handle generic class cases)
|
// Peek class for that type (handle generic class cases)
|
||||||
if (!type)
|
if (!type)
|
||||||
DebugLog::ThrowArgumentNull("type");
|
DebugLog::ThrowArgumentNull("type");
|
||||||
@@ -550,6 +567,7 @@ public:
|
|||||||
|
|
||||||
static MonoObject* Create2(MonoString* typeNameObj)
|
static MonoObject* Create2(MonoString* typeNameObj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_Create2")
|
||||||
// Get typename
|
// Get typename
|
||||||
if (typeNameObj == nullptr)
|
if (typeNameObj == nullptr)
|
||||||
DebugLog::ThrowArgumentNull("typeName");
|
DebugLog::ThrowArgumentNull("typeName");
|
||||||
@@ -587,6 +605,7 @@ public:
|
|||||||
|
|
||||||
static void ManagedInstanceCreated(MonoObject* managedInstance)
|
static void ManagedInstanceCreated(MonoObject* managedInstance)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_ManagedInstanceCreated")
|
||||||
MonoClass* typeClass = mono_object_get_class(managedInstance);
|
MonoClass* typeClass = mono_object_get_class(managedInstance);
|
||||||
|
|
||||||
// Get the assembly with that class
|
// Get the assembly with that class
|
||||||
@@ -625,12 +644,20 @@ public:
|
|||||||
if (auto* managedScriptingObject = dynamic_cast<ManagedScriptingObject*>(obj))
|
if (auto* managedScriptingObject = dynamic_cast<ManagedScriptingObject*>(obj))
|
||||||
{
|
{
|
||||||
// Managed
|
// Managed
|
||||||
managedScriptingObject->_gcHandle = mono_gchandle_new_weakref(managedInstance, false);
|
#if USE_NETCORE
|
||||||
|
managedScriptingObject->_gcHandle = (gchandle)managedInstance;
|
||||||
|
#else
|
||||||
|
managedScriptingObject->_gcHandle = MUtils::NewGCHandleWeakref(managedInstance, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Persistent
|
// Persistent
|
||||||
obj->_gcHandle = mono_gchandle_new(managedInstance, false);
|
#if USE_NETCORE
|
||||||
|
obj->_gcHandle = (gchandle)managedInstance;
|
||||||
|
#else
|
||||||
|
obj->_gcHandle = MUtils::NewGCHandle(managedInstance, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MClass* monoClass = obj->GetClass();
|
MClass* monoClass = obj->GetClass();
|
||||||
@@ -657,6 +684,7 @@ public:
|
|||||||
|
|
||||||
static void Destroy(ScriptingObject* obj, float timeLeft)
|
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?)
|
// Use scaled game time for removing actors/scripts by the user (maybe expose it to the api?)
|
||||||
const bool useGameTime = timeLeft > ZeroTolerance;
|
const bool useGameTime = timeLeft > ZeroTolerance;
|
||||||
|
|
||||||
@@ -666,12 +694,14 @@ public:
|
|||||||
|
|
||||||
static MonoString* GetTypeName(ScriptingObject* obj)
|
static MonoString* GetTypeName(ScriptingObject* obj)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_GetTypeName")
|
||||||
INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
|
INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
|
||||||
return MUtils::ToString(obj->GetType().Fullname);
|
return MUtils::ToString(obj->GetType().Fullname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MonoObject* FindObject(Guid* id, MonoReflectionType* type)
|
static MonoObject* FindObject(Guid* id, MonoReflectionType* type)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_FindObject")
|
||||||
if (!id->IsValid())
|
if (!id->IsValid())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto klass = MUtils::GetClass(type);
|
auto klass = MUtils::GetClass(type);
|
||||||
@@ -701,6 +731,7 @@ public:
|
|||||||
|
|
||||||
static MonoObject* TryFindObject(Guid* id, MonoReflectionType* type)
|
static MonoObject* TryFindObject(Guid* id, MonoReflectionType* type)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_TryFindObject")
|
||||||
ScriptingObject* obj = Scripting::TryFindObject(*id);
|
ScriptingObject* obj = Scripting::TryFindObject(*id);
|
||||||
if (obj && !obj->Is(MUtils::GetClass(type)))
|
if (obj && !obj->Is(MUtils::GetClass(type)))
|
||||||
obj = nullptr;
|
obj = nullptr;
|
||||||
@@ -709,12 +740,14 @@ public:
|
|||||||
|
|
||||||
static void ChangeID(ScriptingObject* obj, Guid* id)
|
static void ChangeID(ScriptingObject* obj, Guid* id)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_ChangeID")
|
||||||
INTERNAL_CALL_CHECK(obj);
|
INTERNAL_CALL_CHECK(obj);
|
||||||
obj->ChangeID(*id);
|
obj->ChangeID(*id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* GetUnmanagedInterface(ScriptingObject* obj, MonoReflectionType* type)
|
static void* GetUnmanagedInterface(ScriptingObject* obj, MonoReflectionType* type)
|
||||||
{
|
{
|
||||||
|
SCRIPTING_EXPORT("FlaxEngine.Object::Internal_GetUnmanagedInterface")
|
||||||
if (obj && type)
|
if (obj && type)
|
||||||
{
|
{
|
||||||
auto typeClass = MUtils::GetClass(type);
|
auto typeClass = MUtils::GetClass(type);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
uint32 _gcHandle;
|
gchandle _gcHandle;
|
||||||
ScriptingTypeHandle _type;
|
ScriptingTypeHandle _type;
|
||||||
Guid _id;
|
Guid _id;
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ typedef void MObject;
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#define USE_MONO 1
|
#define USE_MONO 1
|
||||||
#define USE_NETCORE 0
|
#define USE_NETCORE 1
|
||||||
|
|
||||||
// Enables using single (root) app domain for the user scripts
|
// Enables using single (root) app domain for the user scripts
|
||||||
#define USE_SCRIPTING_SINGLE_DOMAIN 1
|
#define USE_SCRIPTING_SINGLE_DOMAIN 1
|
||||||
@@ -49,6 +49,17 @@ typedef void MObject;
|
|||||||
#define USE_MONO_AOT_MODE MONO_AOT_MODE_NONE
|
#define USE_MONO_AOT_MODE MONO_AOT_MODE_NONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
struct _MonoDomain {};
|
||||||
|
struct _MonoThread {};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
typedef unsigned long long gchandle;
|
||||||
|
#else
|
||||||
|
typedef uint32 gchandle;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Mono types declarations
|
// Mono types declarations
|
||||||
typedef struct _MonoClass MonoClass;
|
typedef struct _MonoClass MonoClass;
|
||||||
typedef struct _MonoDomain MonoDomain;
|
typedef struct _MonoDomain MonoDomain;
|
||||||
|
|||||||
@@ -37,7 +37,11 @@ namespace FlaxEngine.Json
|
|||||||
{
|
{
|
||||||
// Skip serialization as reference id for the root object serialization (eg. Script)
|
// Skip serialization as reference id for the root object serialization (eg. Script)
|
||||||
var cache = JsonSerializer.Current.Value;
|
var cache = JsonSerializer.Current.Value;
|
||||||
|
#if !USE_NETCORE
|
||||||
if (cache != null && cache.IsDuringSerialization && cache.SerializerWriter.SerializeStackSize == 0)
|
if (cache != null && cache.IsDuringSerialization && cache.SerializerWriter.SerializeStackSize == 0)
|
||||||
|
#else
|
||||||
|
if (cache != null && cache.IsDuringSerialization)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -142,6 +146,7 @@ namespace FlaxEngine.Json
|
|||||||
writer.WriteEndObject();
|
writer.WriteEndObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !USE_NETCORE
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void WriteJsonDiff(JsonWriter writer, object value, object other, Newtonsoft.Json.JsonSerializer serializer)
|
public override void WriteJsonDiff(JsonWriter writer, object value, object other, Newtonsoft.Json.JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
@@ -170,6 +175,7 @@ namespace FlaxEngine.Json
|
|||||||
}
|
}
|
||||||
writer.WriteEndObject();
|
writer.WriteEndObject();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
|
||||||
@@ -232,8 +238,10 @@ namespace FlaxEngine.Json
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool CanWrite => true;
|
public override bool CanWrite => true;
|
||||||
|
|
||||||
|
#if !USE_NETCORE
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool CanWriteDiff => true;
|
public override bool CanWriteDiff => true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@@ -11,7 +12,7 @@ using FlaxEngine.Json.JsonCustomSerializers;
|
|||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace FlaxEngine.Json
|
namespace FlaxEngine.Json
|
||||||
{
|
{
|
||||||
@@ -23,7 +24,11 @@ namespace FlaxEngine.Json
|
|||||||
public StringBuilder StringBuilder;
|
public StringBuilder StringBuilder;
|
||||||
public StringWriter StringWriter;
|
public StringWriter StringWriter;
|
||||||
public JsonTextWriter JsonWriter;
|
public JsonTextWriter JsonWriter;
|
||||||
|
#if !USE_NETCORE
|
||||||
public JsonSerializerInternalWriter SerializerWriter;
|
public JsonSerializerInternalWriter SerializerWriter;
|
||||||
|
#else
|
||||||
|
public /*JsonSerializerInternalWriter*/ object SerializerWriter;
|
||||||
|
#endif
|
||||||
public UnmanagedMemoryStream MemoryStream;
|
public UnmanagedMemoryStream MemoryStream;
|
||||||
public StreamReader Reader;
|
public StreamReader Reader;
|
||||||
public bool IsDuringSerialization;
|
public bool IsDuringSerialization;
|
||||||
@@ -32,9 +37,18 @@ namespace FlaxEngine.Json
|
|||||||
{
|
{
|
||||||
JsonSerializer = Newtonsoft.Json.JsonSerializer.CreateDefault(settings);
|
JsonSerializer = Newtonsoft.Json.JsonSerializer.CreateDefault(settings);
|
||||||
JsonSerializer.Formatting = Formatting.Indented;
|
JsonSerializer.Formatting = Formatting.Indented;
|
||||||
|
#if USE_NETCORE
|
||||||
|
Type jsonSerializerInternalWriterType =
|
||||||
|
typeof(Newtonsoft.Json.Serialization.IValueProvider).Assembly.GetType(
|
||||||
|
"Newtonsoft.Json.Serialization.JsonSerializerInternalWriter");
|
||||||
|
System.Reflection.ConstructorInfo ctor = jsonSerializerInternalWriterType.GetConstructors
|
||||||
|
(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public)[0];
|
||||||
|
SerializerWriter = ctor.Invoke(new object[] { JsonSerializer });
|
||||||
|
#else
|
||||||
|
SerializerWriter = new JsonSerializerInternalWriter(JsonSerializer);
|
||||||
|
#endif
|
||||||
StringBuilder = new StringBuilder(256);
|
StringBuilder = new StringBuilder(256);
|
||||||
StringWriter = new StringWriter(StringBuilder, CultureInfo.InvariantCulture);
|
StringWriter = new StringWriter(StringBuilder, CultureInfo.InvariantCulture);
|
||||||
SerializerWriter = new JsonSerializerInternalWriter(JsonSerializer);
|
|
||||||
MemoryStream = new UnmanagedMemoryStream((byte*)0, 0);
|
MemoryStream = new UnmanagedMemoryStream((byte*)0, 0);
|
||||||
Reader = new StreamReader(MemoryStream, Encoding.UTF8, false);
|
Reader = new StreamReader(MemoryStream, Encoding.UTF8, false);
|
||||||
JsonWriter = new JsonTextWriter(StringWriter)
|
JsonWriter = new JsonTextWriter(StringWriter)
|
||||||
@@ -107,7 +121,72 @@ namespace FlaxEngine.Json
|
|||||||
return sceneObjA.PrefabObjectID == sceneObjB.PrefabObjectID;
|
return sceneObjA.PrefabObjectID == sceneObjB.PrefabObjectID;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
return Newtonsoft.Json.Utilities.MiscellaneousUtils.DefaultValueEquals(objA, objB);
|
// Based on Newtonsoft.Json MiscellaneousUtils-class ValueEquals-method
|
||||||
|
bool DefaultValueEquals(object objA_, object objB_)
|
||||||
|
{
|
||||||
|
bool IsInteger(object value)
|
||||||
|
{
|
||||||
|
var type = value.GetType();
|
||||||
|
return type == typeof(SByte) ||
|
||||||
|
type == typeof(Byte) ||
|
||||||
|
type == typeof(Int16) ||
|
||||||
|
type == typeof(UInt16) ||
|
||||||
|
type == typeof(Int32) ||
|
||||||
|
type == typeof(UInt32) ||
|
||||||
|
type == typeof(Int64) ||
|
||||||
|
type == typeof(SByte) ||
|
||||||
|
type == typeof(UInt64);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objA_ == objB_)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (objA_ == null || objB_ == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// comparing an Int32 and Int64 both of the same value returns false
|
||||||
|
// make types the same then compare
|
||||||
|
if (objA_.GetType() != objB_.GetType())
|
||||||
|
{
|
||||||
|
if (IsInteger(objA_) && IsInteger(objB_))
|
||||||
|
{
|
||||||
|
return Convert.ToDecimal(objA_, CultureInfo.CurrentCulture).Equals(Convert.ToDecimal(objB_, CultureInfo.CurrentCulture));
|
||||||
|
}
|
||||||
|
else if ((objA_ is double || objA_ is float || objA_ is decimal) && (objB_ is double || objB_ is float || objB_ is decimal))
|
||||||
|
{
|
||||||
|
return Mathd.NearEqual(Convert.ToDouble(objA_, CultureInfo.CurrentCulture), Convert.ToDouble(objB_, CultureInfo.CurrentCulture));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Diff on collections
|
||||||
|
if (objA_ is System.Collections.IList aList && objB_ is System.Collections.IList bList)
|
||||||
|
{
|
||||||
|
if (aList.Count != bList.Count)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (objA_ is System.Collections.IEnumerable aEnumerable && objB_ is System.Collections.IEnumerable bEnumerable)
|
||||||
|
{
|
||||||
|
var aEnumerator = aEnumerable.GetEnumerator();
|
||||||
|
var bEnumerator = bEnumerable.GetEnumerator();
|
||||||
|
while (aEnumerator.MoveNext())
|
||||||
|
{
|
||||||
|
if (!bEnumerator.MoveNext() || !ValueEquals(aEnumerator.Current, bEnumerator.Current))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !bEnumerator.MoveNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
return objA_.Equals(objB_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return /*Newtonsoft.Json.Utilities.MiscellaneousUtils.*/DefaultValueEquals(objA, objB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -124,7 +203,17 @@ namespace FlaxEngine.Json
|
|||||||
|
|
||||||
cache.StringBuilder.Clear();
|
cache.StringBuilder.Clear();
|
||||||
cache.IsDuringSerialization = true;
|
cache.IsDuringSerialization = true;
|
||||||
|
#if !USE_NETCORE
|
||||||
cache.SerializerWriter.Serialize(cache.JsonWriter, obj, type);
|
cache.SerializerWriter.Serialize(cache.JsonWriter, obj, type);
|
||||||
|
#else
|
||||||
|
Type jsonSerializerInternalWriterType =
|
||||||
|
typeof(Newtonsoft.Json.Serialization.IValueProvider).Assembly.GetType(
|
||||||
|
"Newtonsoft.Json.Serialization.JsonSerializerInternalWriter");
|
||||||
|
|
||||||
|
System.Reflection.MethodInfo Serialize = jsonSerializerInternalWriterType.GetMethod("Serialize",
|
||||||
|
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
|
||||||
|
Serialize.Invoke(cache.SerializerWriter, new object[] { cache.JsonWriter, obj, type });
|
||||||
|
#endif
|
||||||
|
|
||||||
return cache.StringBuilder.ToString();
|
return cache.StringBuilder.ToString();
|
||||||
}
|
}
|
||||||
@@ -143,7 +232,17 @@ namespace FlaxEngine.Json
|
|||||||
|
|
||||||
cache.StringBuilder.Clear();
|
cache.StringBuilder.Clear();
|
||||||
cache.IsDuringSerialization = true;
|
cache.IsDuringSerialization = true;
|
||||||
|
#if !USE_NETCORE
|
||||||
cache.SerializerWriter.Serialize(cache.JsonWriter, obj, type);
|
cache.SerializerWriter.Serialize(cache.JsonWriter, obj, type);
|
||||||
|
#else
|
||||||
|
Type jsonSerializerInternalWriterType =
|
||||||
|
typeof(Newtonsoft.Json.Serialization.IValueProvider).Assembly.GetType(
|
||||||
|
"Newtonsoft.Json.Serialization.JsonSerializerInternalWriter");
|
||||||
|
|
||||||
|
System.Reflection.MethodInfo Serialize = jsonSerializerInternalWriterType.GetMethod("Serialize",
|
||||||
|
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
|
||||||
|
Serialize.Invoke(cache.SerializerWriter, new object[] { cache.JsonWriter, obj, type });
|
||||||
|
#endif
|
||||||
|
|
||||||
return cache.StringBuilder.ToString();
|
return cache.StringBuilder.ToString();
|
||||||
}
|
}
|
||||||
@@ -157,15 +256,25 @@ namespace FlaxEngine.Json
|
|||||||
/// <returns>The output json string.</returns>
|
/// <returns>The output json string.</returns>
|
||||||
public static string SerializeDiff(object obj, object other, bool isManagedOnly = false)
|
public static string SerializeDiff(object obj, object other, bool isManagedOnly = false)
|
||||||
{
|
{
|
||||||
Type type = obj.GetType();
|
|
||||||
var cache = isManagedOnly ? CacheManagedOnly.Value : Cache.Value;
|
var cache = isManagedOnly ? CacheManagedOnly.Value : Cache.Value;
|
||||||
Current.Value = cache;
|
Current.Value = cache;
|
||||||
|
|
||||||
cache.StringBuilder.Clear();
|
cache.StringBuilder.Clear();
|
||||||
cache.IsDuringSerialization = true;
|
cache.IsDuringSerialization = true;
|
||||||
cache.SerializerWriter.SerializeDiff(cache.JsonWriter, obj, type, other);
|
|
||||||
|
|
||||||
return cache.StringBuilder.ToString();
|
JObject jObj = JObject.FromObject(obj, cache.JsonSerializer);
|
||||||
|
JObject jOther = JObject.FromObject(other, cache.JsonSerializer);
|
||||||
|
JObject diff = new JObject();
|
||||||
|
foreach (KeyValuePair<string, JToken> prop in jObj)
|
||||||
|
{
|
||||||
|
JProperty otherProp = jOther.Property(prop.Key);
|
||||||
|
if (JToken.DeepEquals(prop.Value, otherProp.Value))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
diff.Add(prop.Key, prop.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return diff.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ using System.IO;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace FlaxEngine
|
namespace FlaxEngine
|
||||||
{
|
{
|
||||||
@@ -340,10 +342,22 @@ namespace FlaxEngine
|
|||||||
jsonWriter.StringEscapeHandling = jsonSerializer.StringEscapeHandling;
|
jsonWriter.StringEscapeHandling = jsonSerializer.StringEscapeHandling;
|
||||||
jsonWriter.Culture = jsonSerializer.Culture;
|
jsonWriter.Culture = jsonSerializer.Culture;
|
||||||
jsonWriter.DateFormatString = jsonSerializer.DateFormatString;
|
jsonWriter.DateFormatString = jsonSerializer.DateFormatString;
|
||||||
|
#if !USE_NETCORE
|
||||||
JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(jsonSerializer);
|
JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(jsonSerializer);
|
||||||
|
|
||||||
serializerWriter.Serialize(jsonWriter, _control, type);
|
serializerWriter.Serialize(jsonWriter, _control, type);
|
||||||
|
#else
|
||||||
|
Type jsonSerializerInternalWriterType =
|
||||||
|
typeof(Newtonsoft.Json.Serialization.IValueProvider).Assembly.GetType(
|
||||||
|
"Newtonsoft.Json.Serialization.JsonSerializerInternalWriter");
|
||||||
|
System.Reflection.ConstructorInfo ctor = jsonSerializerInternalWriterType.GetConstructors
|
||||||
|
(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public)[0];
|
||||||
|
object serializerWriter = ctor.Invoke(new object[] { jsonSerializer });
|
||||||
|
|
||||||
|
System.Reflection.MethodInfo Serialize = jsonSerializerInternalWriterType.GetMethod("Serialize",
|
||||||
|
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
|
||||||
|
Serialize.Invoke(serializerWriter, new object[] { jsonWriter, _control, type });
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
controlType = type.FullName;
|
controlType = type.FullName;
|
||||||
@@ -380,10 +394,25 @@ namespace FlaxEngine
|
|||||||
jsonWriter.StringEscapeHandling = jsonSerializer.StringEscapeHandling;
|
jsonWriter.StringEscapeHandling = jsonSerializer.StringEscapeHandling;
|
||||||
jsonWriter.Culture = jsonSerializer.Culture;
|
jsonWriter.Culture = jsonSerializer.Culture;
|
||||||
jsonWriter.DateFormatString = jsonSerializer.DateFormatString;
|
jsonWriter.DateFormatString = jsonSerializer.DateFormatString;
|
||||||
|
#if !USE_NETCORE
|
||||||
JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(jsonSerializer);
|
JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(jsonSerializer);
|
||||||
|
|
||||||
serializerWriter.SerializeDiff(jsonWriter, _control, type, other._control);
|
serializerWriter.SerializeDiff(jsonWriter, _control, type, other._control);
|
||||||
|
#else
|
||||||
|
JObject jObj = JObject.FromObject(_control, jsonSerializer);
|
||||||
|
JObject jOther = JObject.FromObject(other._control, jsonSerializer);
|
||||||
|
JObject diff = new JObject();
|
||||||
|
foreach (KeyValuePair<string, JToken> prop in jObj)
|
||||||
|
{
|
||||||
|
JProperty otherProp = jOther.Property(prop.Key);
|
||||||
|
if (JToken.DeepEquals(prop.Value, otherProp.Value))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
diff.Add(prop.Key, prop.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff.WriteTo(jsonWriter);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
controlType = string.Empty;
|
controlType = string.Empty;
|
||||||
|
|||||||
@@ -6,13 +6,15 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
|
|
||||||
namespace FlaxEngine
|
namespace FlaxEngine
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class with helper functions.
|
/// Class with helper functions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Utils
|
public static partial class Utils
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copies data from one memory location to another using an unmanaged memory pointers.
|
/// Copies data from one memory location to another using an unmanaged memory pointers.
|
||||||
@@ -35,8 +37,8 @@ namespace FlaxEngine
|
|||||||
/// <param name="source">The source location.</param>
|
/// <param name="source">The source location.</param>
|
||||||
/// <param name="destination">The destination location.</param>
|
/// <param name="destination">The destination location.</param>
|
||||||
/// <param name="length">The length (amount of bytes to copy).</param>
|
/// <param name="length">The length (amount of bytes to copy).</param>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Utils::MemoryCopy")]
|
||||||
public static extern void MemoryCopy(IntPtr destination, IntPtr source, ulong length);
|
public static partial void MemoryCopy(IntPtr destination, IntPtr source, ulong length);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears the memory region with zeros.
|
/// Clears the memory region with zeros.
|
||||||
@@ -44,8 +46,8 @@ namespace FlaxEngine
|
|||||||
/// <remarks>Uses low-level platform impl.</remarks>
|
/// <remarks>Uses low-level platform impl.</remarks>
|
||||||
/// <param name="dst">Destination memory address</param>
|
/// <param name="dst">Destination memory address</param>
|
||||||
/// <param name="size">Size of the memory to clear in bytes</param>
|
/// <param name="size">Size of the memory to clear in bytes</param>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Utils::MemoryClear")]
|
||||||
public static extern void MemoryClear(IntPtr dst, ulong size);
|
public static partial void MemoryClear(IntPtr dst, ulong size);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Compares two blocks of the memory.
|
/// Compares two blocks of the memory.
|
||||||
@@ -54,8 +56,8 @@ namespace FlaxEngine
|
|||||||
/// <param name="buf1">The first buffer address.</param>
|
/// <param name="buf1">The first buffer address.</param>
|
||||||
/// <param name="buf2">The second buffer address.</param>
|
/// <param name="buf2">The second buffer address.</param>
|
||||||
/// <param name="size">Size of the memory to compare in bytes.</param>
|
/// <param name="size">Size of the memory to compare in bytes.</param>
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Utils::MemoryCompare")]
|
||||||
public static extern int MemoryCompare(IntPtr buf1, IntPtr buf2, ulong size);
|
public static partial int MemoryCompare(IntPtr buf1, IntPtr buf2, ulong size);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rounds the floating point value up to 1 decimal place.
|
/// Rounds the floating point value up to 1 decimal place.
|
||||||
@@ -94,7 +96,11 @@ namespace FlaxEngine
|
|||||||
/// <returns>The empty array object.</returns>
|
/// <returns>The empty array object.</returns>
|
||||||
public static T[] GetEmptyArray<T>()
|
public static T[] GetEmptyArray<T>()
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
return Array.Empty<T>();
|
||||||
|
#else
|
||||||
return Enumerable.Empty<T>() as T[];
|
return Enumerable.Empty<T>() as T[];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -209,10 +215,50 @@ namespace FlaxEngine
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the location of the assembly.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assembly">The assembly.</param>
|
||||||
|
/// <returns>Path in the filesystem</returns>
|
||||||
|
public static string GetAssemblyLocation(Assembly assembly)
|
||||||
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
if (!string.IsNullOrEmpty(assembly.Location))
|
||||||
|
return assembly.Location;
|
||||||
|
|
||||||
|
if (NativeInterop.AssemblyLocations.TryGetValue(assembly.FullName, out string assemblyLocation))
|
||||||
|
return assemblyLocation;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
#else
|
||||||
|
return assembly.Location;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
internal static T[] ExtractArrayFromList<T>(List<T> list)
|
internal static T[] ExtractArrayFromList<T>(List<T> list)
|
||||||
{
|
{
|
||||||
return list != null ? (T[])Internal_ExtractArrayFromList(list) : null;
|
return list != null ? (T[])Internal_ExtractArrayFromList(list) : null;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
private class ExtractArrayFromListContext<T>
|
||||||
|
{
|
||||||
|
public static FieldInfo? itemsField;
|
||||||
|
}
|
||||||
|
internal static T[] ExtractArrayFromList<T>(List<T> list)
|
||||||
|
{
|
||||||
|
if (list == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (ExtractArrayFromListContext<T>.itemsField == null)
|
||||||
|
{
|
||||||
|
Type listType = typeof(List<T>);
|
||||||
|
ExtractArrayFromListContext<T>.itemsField = listType.GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (T[])ExtractArrayFromListContext<T>.itemsField.GetValue(list); // boxing is slower;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
internal static Float2[] ConvertCollection(Vector2[] v)
|
internal static Float2[] ConvertCollection(Vector2[] v)
|
||||||
{
|
{
|
||||||
@@ -295,8 +341,9 @@ namespace FlaxEngine
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.Utils::Internal_ExtractArrayFromList")]
|
||||||
internal static extern Array Internal_ExtractArrayFromList(object list);
|
[return: MarshalUsing(typeof(FlaxEngine.SystemArrayMarshaller))]
|
||||||
|
internal static partial Array Internal_ExtractArrayFromList([MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))] object list);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads the color from the binary stream.
|
/// Reads the color from the binary stream.
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ using System;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
#if FLAX_EDITOR
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
|
#endif
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace FlaxEditor.Utilities
|
namespace FlaxEngine.Utilities
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Editor utilities and helper functions for Variant type.
|
/// Editor utilities and helper functions for Variant type.
|
||||||
@@ -76,6 +79,7 @@ namespace FlaxEditor.Utilities
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FLAX_EDITOR
|
||||||
internal static VariantType ToVariantType(this Type type)
|
internal static VariantType ToVariantType(this Type type)
|
||||||
{
|
{
|
||||||
VariantType variantType;
|
VariantType variantType;
|
||||||
@@ -107,7 +111,9 @@ namespace FlaxEditor.Utilities
|
|||||||
variantType = VariantType.Pointer;
|
variantType = VariantType.Pointer;
|
||||||
else if (type == typeof(string))
|
else if (type == typeof(string))
|
||||||
variantType = VariantType.String;
|
variantType = VariantType.String;
|
||||||
else if (type == typeof(Type) || type == typeof(ScriptType))
|
else if (type == typeof(Type))
|
||||||
|
variantType = VariantType.Typename;
|
||||||
|
else if (type == typeof(ScriptType))
|
||||||
variantType = VariantType.Typename;
|
variantType = VariantType.Typename;
|
||||||
else if (typeof(Asset).IsAssignableFrom(type))
|
else if (typeof(Asset).IsAssignableFrom(type))
|
||||||
variantType = VariantType.Asset;
|
variantType = VariantType.Asset;
|
||||||
@@ -1286,5 +1292,6 @@ namespace FlaxEditor.Utilities
|
|||||||
|
|
||||||
stream.WriteEndObject();
|
stream.WriteEndObject();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
6
Source/Engine/Visject/VisjectScript.cpp
Normal file
6
Source/Engine/Visject/VisjectScript.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "VisjectScript.h"
|
||||||
|
|
||||||
|
VisjectScript::VisjectScript(const SpawnParams& params)
|
||||||
|
: Script(params)
|
||||||
|
{
|
||||||
|
}
|
||||||
14
Source/Engine/Visject/VisjectScript.h
Normal file
14
Source/Engine/Visject/VisjectScript.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Engine/Scripting/Script.h"
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
API_CLASS(Namespace = "FlaxEngine.Visject") class FLAXENGINE_API VisjectScript : public Script
|
||||||
|
{
|
||||||
|
API_AUTO_SERIALIZATION();
|
||||||
|
DECLARE_SCRIPTING_TYPE(VisjectScript);
|
||||||
|
};
|
||||||
9
Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json
vendored
Normal file
9
Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net7.0",
|
||||||
|
"framework": {
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "7.0.0-rc.2.22472.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Source/ThirdParty/nethost/LICENSE.TXT
vendored
Normal file
23
Source/ThirdParty/nethost/LICENSE.TXT
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) .NET Foundation and Contributors
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
112
Source/ThirdParty/nethost/nethost.Build.cs
vendored
Normal file
112
Source/ThirdParty/nethost/nethost.Build.cs
vendored
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
using Flax.Build;
|
||||||
|
using Flax.Build.NativeCpp;
|
||||||
|
using Flax.Build.Platforms;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Module for nethost (.NET runtime host library)
|
||||||
|
/// </summary>
|
||||||
|
public class nethost : ThirdPartyModule
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
base.Init();
|
||||||
|
|
||||||
|
LicenseType = LicenseTypes.MIT;
|
||||||
|
LicenseFilePath = "LICENSE.TXT";
|
||||||
|
|
||||||
|
// Merge third-party modules into engine binary
|
||||||
|
BinaryModuleName = "FlaxEngine";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
private static Version ParseVersion(string version)
|
||||||
|
{
|
||||||
|
// Give precedence to final releases over release candidate / beta releases
|
||||||
|
int rev = 9999;
|
||||||
|
if (version.Contains("-")) // e.g. 7.0.0-rc.2.22472.3
|
||||||
|
{
|
||||||
|
version = version.Substring(0, version.IndexOf("-"));
|
||||||
|
rev = 0;
|
||||||
|
}
|
||||||
|
Version ver = new Version(version);
|
||||||
|
return new Version(ver.Major, ver.Minor, ver.Build, rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Setup(BuildOptions options)
|
||||||
|
{
|
||||||
|
base.Setup(options);
|
||||||
|
|
||||||
|
options.SourceFiles.Clear();
|
||||||
|
|
||||||
|
string arch = "x64"; //options.Architecture == TargetArchitecture.x64 ? "x64" : "x86";
|
||||||
|
|
||||||
|
string dotnetVersion;
|
||||||
|
string appHostRuntimePath;
|
||||||
|
|
||||||
|
// NOTE: nethost is bundled with SDK, not runtime. Should C# scripting have a hard requirement for SDK to be installed?
|
||||||
|
|
||||||
|
if (options.Platform.Target == TargetPlatform.Windows)
|
||||||
|
{
|
||||||
|
string os = $"win-{arch}";
|
||||||
|
|
||||||
|
using RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
|
||||||
|
|
||||||
|
using RegistryKey hostKey = baseKey.OpenSubKey(@$"SOFTWARE\dotnet\Setup\InstalledVersions\{arch}\sharedhost");
|
||||||
|
string dotnetPath = (string)hostKey.GetValue("Path");
|
||||||
|
|
||||||
|
using RegistryKey runtimeKey = baseKey.OpenSubKey(@$"SOFTWARE\WOW6432Node\dotnet\Setup\InstalledVersions\{arch}\sharedfx\Microsoft.NETCore.App");
|
||||||
|
string[] versions = runtimeKey.GetValueNames();
|
||||||
|
|
||||||
|
dotnetVersion = versions.OrderByDescending(x => ParseVersion(x)).FirstOrDefault();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(dotnetPath))
|
||||||
|
dotnetPath = Environment.GetEnvironmentVariable("DOTNET_ROOT");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(dotnetPath) || string.IsNullOrEmpty(dotnetVersion))
|
||||||
|
throw new Exception("Failed to find dotnet installation");
|
||||||
|
|
||||||
|
int majorVersion = int.Parse(dotnetVersion.Substring(0, dotnetVersion.IndexOf(".")));
|
||||||
|
if (majorVersion < 7)
|
||||||
|
throw new Exception($"Unsupported dotnet version found, minimum version required is .NET 7 (found {dotnetVersion})");
|
||||||
|
|
||||||
|
appHostRuntimePath = String.Format("{0}packs\\Microsoft.NETCore.App.Host.{1}\\{2}\\runtimes\\{1}\\native", dotnetPath, os, dotnetVersion);
|
||||||
|
options.OutputFiles.Add(Path.Combine(appHostRuntimePath, "nethost.lib"));
|
||||||
|
options.DependencyFiles.Add(Path.Combine(appHostRuntimePath, "nethost.dll"));
|
||||||
|
options.PublicIncludePaths.Add(appHostRuntimePath);
|
||||||
|
}
|
||||||
|
else if (options.Platform.Target == TargetPlatform.Linux)
|
||||||
|
{
|
||||||
|
// TODO: Support /etc/dotnet/install_location
|
||||||
|
string dotnetPath = "/usr/share/dotnet/";
|
||||||
|
string os = $"linux-{arch}";
|
||||||
|
|
||||||
|
string[] versions = Directory.GetDirectories($"{dotnetPath}host/fxr/").Select(x => Path.GetFileName(x)).ToArray();
|
||||||
|
|
||||||
|
dotnetVersion = versions.OrderByDescending(x => ParseVersion(x)).FirstOrDefault();
|
||||||
|
|
||||||
|
int majorVersion = int.Parse(dotnetVersion.Substring(0, dotnetVersion.IndexOf(".")));
|
||||||
|
if (majorVersion < 7)
|
||||||
|
throw new Exception($"Unsupported dotnet version found, minimum version required is .NET 7 (found {dotnetVersion})");
|
||||||
|
|
||||||
|
appHostRuntimePath = String.Format("{0}packs/Microsoft.NETCore.App.Host.{1}/{2}/runtimes/{1}/native", dotnetPath, os, dotnetVersion);
|
||||||
|
options.OutputFiles.Add(Path.Combine(appHostRuntimePath, "libnethost.a"));
|
||||||
|
options.DependencyFiles.Add(Path.Combine(appHostRuntimePath, "libnethost.so"));
|
||||||
|
options.PublicIncludePaths.Add(appHostRuntimePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new InvalidPlatformException(options.Platform.Target);
|
||||||
|
|
||||||
|
options.PublicIncludePaths.Add(appHostRuntimePath);
|
||||||
|
options.ScriptingAPI.Defines.Add("USE_NETCORE");
|
||||||
|
options.DependencyFiles.Add(Path.Combine(FolderPath, "FlaxEngine.CSharp.runtimeconfig.json"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using BuildData = Flax.Build.Builder.BuildData;
|
using BuildData = Flax.Build.Builder.BuildData;
|
||||||
|
|
||||||
namespace Flax.Build.Bindings
|
namespace Flax.Build.Bindings
|
||||||
@@ -171,7 +172,11 @@ namespace Flax.Build.Bindings
|
|||||||
|
|
||||||
// Skip for collections
|
// Skip for collections
|
||||||
if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer" || typeInfo.Type == "Dictionary" || typeInfo.Type == "HashSet") && typeInfo.GenericArgs != null)
|
if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer" || typeInfo.Type == "Dictionary" || typeInfo.Type == "HashSet") && typeInfo.GenericArgs != null)
|
||||||
|
#if !USE_NETCORE
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Skip for special types
|
// Skip for special types
|
||||||
if (typeInfo.GenericArgs == null)
|
if (typeInfo.GenericArgs == null)
|
||||||
@@ -219,6 +224,40 @@ namespace Flax.Build.Bindings
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
/// <summary>
|
||||||
|
/// Check if structure contains unblittable types that would require custom marshaller for the structure.
|
||||||
|
/// </summary>
|
||||||
|
public static bool UseCustomMarshalling(BuildData buildData, StructureInfo structureInfo, ApiTypeInfo caller)
|
||||||
|
{
|
||||||
|
if (structureInfo.Fields.Any(x => !x.IsStatic &&
|
||||||
|
(x.Type.IsObjectRef || x.Type.Type == "Dictionary" || x.Type.Type == "Version")
|
||||||
|
&& x.Type.Type != "uint8" && x.Type.Type != "byte"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var field in structureInfo.Fields)
|
||||||
|
{
|
||||||
|
if (field.Type.Type == structureInfo.FullNameNative)
|
||||||
|
continue;
|
||||||
|
if (field.IsStatic)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (field.Type.Type == "String")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var fieldApiType = FindApiTypeInfo(buildData, field.Type, caller);
|
||||||
|
if (fieldApiType is StructureInfo fieldStructureInfo && UseCustomMarshalling(buildData, fieldStructureInfo, caller))
|
||||||
|
return true;
|
||||||
|
else if (fieldApiType is ClassInfo)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the API type information.
|
/// Finds the API type information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -278,15 +278,15 @@ namespace Flax.Build.Bindings
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Object reference property
|
// Object reference property
|
||||||
if ((typeInfo.Type == "ScriptingObjectReference" ||
|
if (typeInfo.IsObjectRef)
|
||||||
typeInfo.Type == "AssetReference" ||
|
|
||||||
typeInfo.Type == "WeakAssetReference" ||
|
|
||||||
typeInfo.Type == "SoftAssetReference" ||
|
|
||||||
typeInfo.Type == "SoftObjectReference") && typeInfo.GenericArgs != null)
|
|
||||||
return GenerateCSharpNativeToManaged(buildData, typeInfo.GenericArgs[0], caller);
|
return GenerateCSharpNativeToManaged(buildData, typeInfo.GenericArgs[0], caller);
|
||||||
|
|
||||||
// Array or Span or DataContainer
|
// Array or Span or DataContainer
|
||||||
|
#if USE_NETCORE
|
||||||
|
if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer" || typeInfo.Type == "MonoArray") && typeInfo.GenericArgs != null)
|
||||||
|
#else
|
||||||
if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer") && typeInfo.GenericArgs != null)
|
if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer") && typeInfo.GenericArgs != null)
|
||||||
|
#endif
|
||||||
return GenerateCSharpNativeToManaged(buildData, typeInfo.GenericArgs[0], caller) + "[]";
|
return GenerateCSharpNativeToManaged(buildData, typeInfo.GenericArgs[0], caller) + "[]";
|
||||||
|
|
||||||
// Dictionary
|
// Dictionary
|
||||||
@@ -361,11 +361,7 @@ namespace Flax.Build.Bindings
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Object reference property
|
// Object reference property
|
||||||
if ((typeInfo.Type == "ScriptingObjectReference" ||
|
if (typeInfo.IsObjectRef)
|
||||||
typeInfo.Type == "AssetReference" ||
|
|
||||||
typeInfo.Type == "WeakAssetReference" ||
|
|
||||||
typeInfo.Type == "SoftAssetReference" ||
|
|
||||||
typeInfo.Type == "SoftObjectReference") && typeInfo.GenericArgs != null)
|
|
||||||
return "IntPtr";
|
return "IntPtr";
|
||||||
|
|
||||||
// Function
|
// Function
|
||||||
@@ -419,11 +415,7 @@ namespace Flax.Build.Bindings
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Object reference property
|
// Object reference property
|
||||||
if ((typeInfo.Type == "ScriptingObjectReference" ||
|
if (typeInfo.IsObjectRef)
|
||||||
typeInfo.Type == "AssetReference" ||
|
|
||||||
typeInfo.Type == "WeakAssetReference" ||
|
|
||||||
typeInfo.Type == "SoftAssetReference" ||
|
|
||||||
typeInfo.Type == "SoftObjectReference") && typeInfo.GenericArgs != null)
|
|
||||||
return "FlaxEngine.Object.GetUnmanagedPtr({0})";
|
return "FlaxEngine.Object.GetUnmanagedPtr({0})";
|
||||||
|
|
||||||
// Default
|
// Default
|
||||||
@@ -443,8 +435,38 @@ namespace Flax.Build.Bindings
|
|||||||
returnValueType = GenerateCSharpNativeToManaged(buildData, functionInfo.ReturnType, caller);
|
returnValueType = GenerateCSharpNativeToManaged(buildData, functionInfo.ReturnType, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
string returnMarshalType = "";
|
||||||
|
if (returnValueType == "bool")
|
||||||
|
returnMarshalType = "MarshalAs(UnmanagedType.U1)";
|
||||||
|
else if (returnValueType == "System.Type")
|
||||||
|
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.SystemTypeMarshaller))";
|
||||||
|
else if (returnValueType == "CultureInfo")
|
||||||
|
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.CultureInfoMarshaller))";
|
||||||
|
else if (functionInfo.ReturnType.Type == "Variant")
|
||||||
|
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))";
|
||||||
|
else if (FindApiTypeInfo(buildData, functionInfo.ReturnType, caller)?.IsInterface ?? false)
|
||||||
|
{
|
||||||
|
// Interfaces are not supported by NativeMarshallingAttribute, marshal the parameter
|
||||||
|
returnMarshalType = $"MarshalUsing(typeof({returnValueType}Marshaller))";
|
||||||
|
}
|
||||||
|
else if (returnValueType == "byte[]")
|
||||||
|
returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = \"returnCount\")";
|
||||||
|
else if (returnValueType == "bool[]")
|
||||||
|
{
|
||||||
|
// Boolean arrays does not support custom marshalling for some unkown reason...
|
||||||
|
returnMarshalType = $"MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = {functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters?.Count ?? 0)})";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !USE_NETCORE
|
||||||
contents.AppendLine().Append(indent).Append("[MethodImpl(MethodImplOptions.InternalCall)]");
|
contents.AppendLine().Append(indent).Append("[MethodImpl(MethodImplOptions.InternalCall)]");
|
||||||
contents.AppendLine().Append(indent).Append("internal static extern ");
|
contents.AppendLine().Append(indent).Append("internal static partial ");
|
||||||
|
#else
|
||||||
|
contents.AppendLine().Append(indent).Append($"[LibraryImport(\"FlaxEngine\", EntryPoint = \"{caller.FullNameManaged}::Internal_{functionInfo.UniqueName}\", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]");
|
||||||
|
if (!string.IsNullOrEmpty(returnMarshalType))
|
||||||
|
contents.AppendLine().Append(indent).Append($"[return: {returnMarshalType}]");
|
||||||
|
contents.AppendLine().Append(indent).Append("internal static partial ");
|
||||||
|
#endif
|
||||||
contents.Append(returnValueType).Append(" Internal_").Append(functionInfo.UniqueName).Append('(');
|
contents.Append(returnValueType).Append(" Internal_").Append(functionInfo.UniqueName).Append('(');
|
||||||
|
|
||||||
var separator = false;
|
var separator = false;
|
||||||
@@ -461,6 +483,30 @@ namespace Flax.Build.Bindings
|
|||||||
separator = true;
|
separator = true;
|
||||||
|
|
||||||
var nativeType = GenerateCSharpManagedToNativeType(buildData, parameterInfo.Type, caller);
|
var nativeType = GenerateCSharpManagedToNativeType(buildData, parameterInfo.Type, caller);
|
||||||
|
#if USE_NETCORE
|
||||||
|
string parameterMarshalType = "";
|
||||||
|
if (nativeType == "System.Type")
|
||||||
|
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.SystemTypeMarshaller))";
|
||||||
|
else if (parameterInfo.Type.Type == "CultureInfo")
|
||||||
|
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.CultureInfoMarshaller))";
|
||||||
|
else if (parameterInfo.Type.Type == "Variant") // object
|
||||||
|
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))";
|
||||||
|
else if (parameterInfo.Type.Type == "MonoArray")
|
||||||
|
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.SystemArrayMarshaller))";
|
||||||
|
else if (parameterInfo.Type.Type == "Array" && parameterInfo.Type.GenericArgs.Count > 0 && parameterInfo.Type.GenericArgs[0].Type == "bool")
|
||||||
|
parameterMarshalType = $"MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = {(!functionInfo.IsStatic ? 1 : 0) + functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters.FindIndex(x => x.Name == parameterInfo.Name + "Count"))})";
|
||||||
|
else if (parameterInfo.Type.Type == "Array" || parameterInfo.Type.Type == "Span" || parameterInfo.Type.Type == "DataContainer" || parameterInfo.Type.Type == "BytesContainer" || nativeType == "Array")
|
||||||
|
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = \"{parameterInfo.Name}Count\")";
|
||||||
|
else if (parameterInfo.Type.Type == "Dictionary")
|
||||||
|
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.DictionaryMarshaller<,>), ConstantElementCount = 0)";
|
||||||
|
else if (nativeType == "bool")
|
||||||
|
parameterMarshalType = "MarshalAs(UnmanagedType.U1)";
|
||||||
|
else if (nativeType == "char")
|
||||||
|
parameterMarshalType = "MarshalAs(UnmanagedType.I2)";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(parameterMarshalType))
|
||||||
|
contents.Append($"[{parameterMarshalType}] ");
|
||||||
|
#endif
|
||||||
if (parameterInfo.IsOut)
|
if (parameterInfo.IsOut)
|
||||||
contents.Append("out ");
|
contents.Append("out ");
|
||||||
else if (parameterInfo.IsRef || UsePassByReference(buildData, parameterInfo.Type, caller))
|
else if (parameterInfo.IsRef || UsePassByReference(buildData, parameterInfo.Type, caller))
|
||||||
@@ -484,6 +530,21 @@ namespace Flax.Build.Bindings
|
|||||||
separator = true;
|
separator = true;
|
||||||
|
|
||||||
var nativeType = GenerateCSharpManagedToNativeType(buildData, parameterInfo.Type, caller);
|
var nativeType = GenerateCSharpManagedToNativeType(buildData, parameterInfo.Type, caller);
|
||||||
|
#if USE_NETCORE
|
||||||
|
string parameterMarshalType = "";
|
||||||
|
if (parameterInfo.IsOut && parameterInfo.DefaultValue == "var resultAsRef")
|
||||||
|
{
|
||||||
|
if (functionInfo.Glue.UseResultReferenceCount)
|
||||||
|
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = \"{parameterInfo.Name}Count\")";
|
||||||
|
else if (parameterInfo.Type.Type == "Dictionary")
|
||||||
|
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.DictionaryMarshaller<,>), ConstantElementCount = 0)";
|
||||||
|
}
|
||||||
|
if (nativeType == "System.Type")
|
||||||
|
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.SystemTypeMarshaller))";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(parameterMarshalType))
|
||||||
|
contents.Append($"[{parameterMarshalType}] ");
|
||||||
|
#endif
|
||||||
if (parameterInfo.IsOut)
|
if (parameterInfo.IsOut)
|
||||||
contents.Append("out ");
|
contents.Append("out ");
|
||||||
else if (parameterInfo.IsRef || UsePassByReference(buildData, parameterInfo.Type, caller))
|
else if (parameterInfo.IsRef || UsePassByReference(buildData, parameterInfo.Type, caller))
|
||||||
@@ -500,6 +561,17 @@ namespace Flax.Build.Bindings
|
|||||||
|
|
||||||
private static void GenerateCSharpWrapperFunctionCall(BuildData buildData, StringBuilder contents, ApiTypeInfo caller, FunctionInfo functionInfo, bool isSetter = false)
|
private static void GenerateCSharpWrapperFunctionCall(BuildData buildData, StringBuilder contents, ApiTypeInfo caller, FunctionInfo functionInfo, bool isSetter = false)
|
||||||
{
|
{
|
||||||
|
#if USE_NETCORE
|
||||||
|
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
||||||
|
{
|
||||||
|
var parameterInfo = functionInfo.Parameters[i];
|
||||||
|
if (parameterInfo.Type.IsArray || parameterInfo.Type.Type == "Array" || parameterInfo.Type.Type == "Span" || parameterInfo.Type.Type == "BytesContainer" || parameterInfo.Type.Type == "DataContainer" || parameterInfo.Type.Type == "BitArray")
|
||||||
|
{
|
||||||
|
if (!parameterInfo.IsOut)
|
||||||
|
contents.Append($"var {parameterInfo.Name}Count = {(isSetter ? "value" : parameterInfo.Name)}?.Length ?? 0; ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (functionInfo.Glue.UseReferenceForResult)
|
if (functionInfo.Glue.UseReferenceForResult)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -613,6 +685,9 @@ namespace Flax.Build.Bindings
|
|||||||
{
|
{
|
||||||
// Write attribute for C++ calling code
|
// Write attribute for C++ calling code
|
||||||
contents.Append(indent).AppendLine("[Unmanaged]");
|
contents.Append(indent).AppendLine("[Unmanaged]");
|
||||||
|
|
||||||
|
// Skip boilerplate code when using debugger
|
||||||
|
//contents.Append(indent).AppendLine("[System.Diagnostics.DebuggerStepThrough]");
|
||||||
}
|
}
|
||||||
if (isDeprecated || apiTypeInfo.IsDeprecated)
|
if (isDeprecated || apiTypeInfo.IsDeprecated)
|
||||||
{
|
{
|
||||||
@@ -698,6 +773,15 @@ namespace Flax.Build.Bindings
|
|||||||
|
|
||||||
// Class begin
|
// Class begin
|
||||||
GenerateCSharpAttributes(buildData, contents, indent, classInfo, useUnmanaged);
|
GenerateCSharpAttributes(buildData, contents, indent, classInfo, useUnmanaged);
|
||||||
|
#if USE_NETCORE
|
||||||
|
string marshallerName = "";
|
||||||
|
if (!classInfo.IsStatic)
|
||||||
|
{
|
||||||
|
marshallerName = classInfo.Name + "Marshaller";
|
||||||
|
contents.Append(indent).AppendLine($"[NativeMarshalling(typeof({marshallerName}))]");
|
||||||
|
//contents.Append(indent).AppendLine($"[NativeMarshalling(typeof(FlaxEngine.GCHandleMarshaller2<{classInfo.Name}>.GCHandleMarshaller3<{classInfo.Name}>))]");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
contents.Append(indent);
|
contents.Append(indent);
|
||||||
GenerateCSharpAccessLevel(contents, classInfo.Access);
|
GenerateCSharpAccessLevel(contents, classInfo.Access);
|
||||||
if (classInfo.IsStatic)
|
if (classInfo.IsStatic)
|
||||||
@@ -862,11 +946,19 @@ namespace Flax.Build.Bindings
|
|||||||
contents.Append(indent).Append('}').AppendLine();
|
contents.Append(indent).Append('}').AppendLine();
|
||||||
|
|
||||||
contents.AppendLine();
|
contents.AppendLine();
|
||||||
|
#if !USE_NETCORE
|
||||||
contents.Append(indent).Append("[MethodImpl(MethodImplOptions.InternalCall)]").AppendLine();
|
contents.Append(indent).Append("[MethodImpl(MethodImplOptions.InternalCall)]").AppendLine();
|
||||||
contents.Append(indent).Append($"internal static extern void Internal_{eventInfo.Name}_Bind(");
|
contents.Append(indent).Append($"internal static extern void Internal_{eventInfo.Name}_Bind(");
|
||||||
if (!eventInfo.IsStatic)
|
if (!eventInfo.IsStatic)
|
||||||
contents.Append("IntPtr obj, ");
|
contents.Append("IntPtr obj, ");
|
||||||
contents.Append("bool bind);");
|
contents.Append("bool bind);");
|
||||||
|
#else
|
||||||
|
contents.Append(indent).Append($"[LibraryImport(\"FlaxEngine\", EntryPoint = \"{classInfo.FullNameManaged}::Internal_{eventInfo.Name}_Bind\", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]").AppendLine();
|
||||||
|
contents.Append(indent).Append($"internal static partial void Internal_{eventInfo.Name}_Bind(");
|
||||||
|
if (!eventInfo.IsStatic)
|
||||||
|
contents.Append("IntPtr obj, ");
|
||||||
|
contents.Append("[MarshalAs(UnmanagedType.U1)] bool bind);");
|
||||||
|
#endif
|
||||||
contents.AppendLine();
|
contents.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1100,6 +1192,51 @@ namespace Flax.Build.Bindings
|
|||||||
indent = indent.Substring(0, indent.Length - 4);
|
indent = indent.Substring(0, indent.Length - 4);
|
||||||
contents.AppendLine(indent + "}");
|
contents.AppendLine(indent + "}");
|
||||||
|
|
||||||
|
#if USE_NETCORE
|
||||||
|
if (!string.IsNullOrEmpty(marshallerName))
|
||||||
|
{
|
||||||
|
string marshallerDefinition = $$"""
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedIn, typeof({{marshallerName}}.ManagedToNative))]
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedOut, typeof({{marshallerName}}.ManagedToNative))]
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementIn, typeof({{marshallerName}}.ManagedToNative))]
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedOut, typeof({{marshallerName}}.NativeToManaged))]
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedIn, typeof({{marshallerName}}.NativeToManaged))]
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementOut, typeof({{marshallerName}}.NativeToManaged))]
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedRef, typeof({{marshallerName}}.Bidirectional))]
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedRef, typeof({{marshallerName}}.Bidirectional))]
|
||||||
|
[CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementRef, typeof({{marshallerName}}))]
|
||||||
|
internal static class {{marshallerName}}
|
||||||
|
{
|
||||||
|
public static class NativeToManaged
|
||||||
|
{
|
||||||
|
public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => ({{classInfo.Name}})GCHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged);
|
||||||
|
public static void Free(IntPtr unmanaged) => GCHandleMarshaller.NativeToManaged.Free(unmanaged);
|
||||||
|
}
|
||||||
|
public static class ManagedToNative
|
||||||
|
{
|
||||||
|
public static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => GCHandleMarshaller.ManagedToNative.ConvertToUnmanaged(managed);
|
||||||
|
public static void Free(IntPtr unmanaged) => GCHandleMarshaller.ManagedToNative.Free(unmanaged);
|
||||||
|
}
|
||||||
|
public struct Bidirectional
|
||||||
|
{
|
||||||
|
GCHandleMarshaller.Bidirectional marsh;
|
||||||
|
public void FromManaged({{classInfo.Name}} managed) => marsh.FromManaged(managed);
|
||||||
|
public IntPtr ToUnmanaged() => marsh.ToUnmanaged();
|
||||||
|
public void FromUnmanaged(IntPtr unmanaged) => marsh.FromUnmanaged(unmanaged);
|
||||||
|
public {{classInfo.Name}} ToManaged() => ({{classInfo.Name}})marsh.ToManaged();
|
||||||
|
public void Free() => marsh.Free();
|
||||||
|
}
|
||||||
|
internal static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => ({{classInfo.Name}})GCHandleMarshaller.ConvertToManaged(unmanaged);
|
||||||
|
internal static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => GCHandleMarshaller.ConvertToUnmanaged(managed);
|
||||||
|
internal static void Free(IntPtr unmanaged) => GCHandleMarshaller.Free(unmanaged);
|
||||||
|
|
||||||
|
internal static {{classInfo.Name}} ToManaged(IntPtr managed) => ({{classInfo.Name}})GCHandleMarshaller.ToManaged(managed);
|
||||||
|
internal static IntPtr ToNative({{classInfo.Name}} managed) => GCHandleMarshaller.ToNative(managed);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
contents.AppendLine(marshallerDefinition);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Namespace end
|
// Namespace end
|
||||||
if (!string.IsNullOrEmpty(classInfo.Namespace))
|
if (!string.IsNullOrEmpty(classInfo.Namespace))
|
||||||
{
|
{
|
||||||
@@ -1119,13 +1256,330 @@ namespace Flax.Build.Bindings
|
|||||||
contents.AppendLine("{");
|
contents.AppendLine("{");
|
||||||
indent += " ";
|
indent += " ";
|
||||||
}
|
}
|
||||||
|
#if USE_NETCORE
|
||||||
|
// Generate blittable structure
|
||||||
|
string structNativeMarshaling = "";
|
||||||
|
if (UseCustomMarshalling(buildData, structureInfo, structureInfo))
|
||||||
|
{
|
||||||
|
string marshallerName = structureInfo.Name + "Marshaller";
|
||||||
|
structNativeMarshaling = $"[NativeMarshalling(typeof({marshallerName}))]";
|
||||||
|
|
||||||
|
contents.Append(indent).AppendLine($"/// <summary>");
|
||||||
|
contents.Append(indent).AppendLine($"/// Marshaller for unblittable type <see cref=\"{structureInfo.Name}\"/>.");
|
||||||
|
contents.Append(indent).AppendLine($"/// </summary>");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.ManagedToUnmanagedIn, typeof({marshallerName}.ManagedToNative))]");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.UnmanagedToManagedOut, typeof({marshallerName}.ManagedToNative))]");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.ElementIn, typeof({marshallerName}.ManagedToNative))]");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.ManagedToUnmanagedOut, typeof({marshallerName}.NativeToManaged))]");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.UnmanagedToManagedIn, typeof({marshallerName}.NativeToManaged))]");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.ElementOut, typeof({marshallerName}.NativeToManaged))]");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.ManagedToUnmanagedRef, typeof({marshallerName}.Bidirectional))]");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.UnmanagedToManagedRef, typeof({marshallerName}.Bidirectional))]");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({structureInfo.Name}), MarshalMode.ElementRef, typeof({marshallerName}))]");
|
||||||
|
contents.Append(indent).AppendLine($"internal static unsafe class {marshallerName}");
|
||||||
|
contents.Append(indent).AppendLine("{");
|
||||||
|
|
||||||
|
indent += " ";
|
||||||
|
|
||||||
|
StringBuilder toManagedContent = new StringBuilder();
|
||||||
|
StringBuilder toNativeContent = new StringBuilder();
|
||||||
|
StringBuilder freeContents = new StringBuilder();
|
||||||
|
StringBuilder freeContents2 = new StringBuilder();
|
||||||
|
|
||||||
|
{
|
||||||
|
// Native struct begin
|
||||||
|
GenerateCSharpAttributes(buildData, contents, indent, structureInfo, true);
|
||||||
|
contents.Append(indent).AppendLine("[StructLayout(LayoutKind.Sequential)]");
|
||||||
|
contents.Append(indent);
|
||||||
|
contents.Append("internal struct ").Append(structureInfo.Name).Append("Internal");
|
||||||
|
if (structureInfo.BaseType != null && structureInfo.IsPod)
|
||||||
|
contents.Append(" : ").Append(GenerateCSharpNativeToManaged(buildData, new TypeInfo { Type = structureInfo.BaseType.Name }, structureInfo));
|
||||||
|
contents.AppendLine();
|
||||||
|
contents.Append(indent + "{");
|
||||||
|
indent += " ";
|
||||||
|
|
||||||
|
toNativeContent.Append($"return new {structureInfo.Name}Internal() {{ ");
|
||||||
|
toManagedContent.Append($"return new {structureInfo.Name}() {{ ");
|
||||||
|
|
||||||
|
bool useSeparator = false;
|
||||||
|
foreach (var fieldInfo in structureInfo.Fields)
|
||||||
|
{
|
||||||
|
if (fieldInfo.IsStatic || fieldInfo.IsConstexpr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
contents.AppendLine();
|
||||||
|
|
||||||
|
string type, originalType;
|
||||||
|
if (fieldInfo.Type.IsArray && (fieldInfo.NoArray || structureInfo.IsPod))
|
||||||
|
{
|
||||||
|
// Fixed-size array that needs to be inlined into structure instead of passing it as managed array
|
||||||
|
fieldInfo.Type.IsArray = false;
|
||||||
|
originalType = type = GenerateCSharpNativeToManaged(buildData, fieldInfo.Type, structureInfo);
|
||||||
|
fieldInfo.Type.IsArray = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
originalType = type = GenerateCSharpNativeToManaged(buildData, fieldInfo.Type, structureInfo);
|
||||||
|
|
||||||
|
contents.Append(indent);
|
||||||
|
if (fieldInfo.Access == AccessLevel.Public)
|
||||||
|
contents.Append("public ");
|
||||||
|
else if (fieldInfo.Access == AccessLevel.Protected)
|
||||||
|
contents.Append("protected ");
|
||||||
|
else if (fieldInfo.Access == AccessLevel.Private)
|
||||||
|
contents.Append("private ");
|
||||||
|
if (fieldInfo.IsConstexpr)
|
||||||
|
contents.Append("const ");
|
||||||
|
else if (fieldInfo.IsStatic)
|
||||||
|
contents.Append("static ");
|
||||||
|
|
||||||
|
var apiType = FindApiTypeInfo(buildData, fieldInfo.Type, structureInfo);
|
||||||
|
bool internalType = apiType is StructureInfo fieldStructureInfo && UseCustomMarshalling(buildData, fieldStructureInfo, structureInfo);
|
||||||
|
string internalTypeMarshaler = "";
|
||||||
|
|
||||||
|
if (fieldInfo.Type.IsArray && (fieldInfo.NoArray || structureInfo.IsPod))
|
||||||
|
{
|
||||||
|
contents.Append(type).Append(' ').Append(fieldInfo.Name + "0;").AppendLine();
|
||||||
|
for (int i = 1; i < fieldInfo.Type.ArraySize; i++)
|
||||||
|
{
|
||||||
|
contents.AppendLine();
|
||||||
|
GenerateCSharpAttributes(buildData, contents, indent, structureInfo, fieldInfo, fieldInfo.IsStatic);
|
||||||
|
contents.Append(indent);
|
||||||
|
if (fieldInfo.Access == AccessLevel.Public)
|
||||||
|
contents.Append("public ");
|
||||||
|
else if (fieldInfo.Access == AccessLevel.Protected)
|
||||||
|
contents.Append("protected ");
|
||||||
|
else if (fieldInfo.Access == AccessLevel.Private)
|
||||||
|
contents.Append("private ");
|
||||||
|
if (fieldInfo.IsStatic)
|
||||||
|
contents.Append("static ");
|
||||||
|
contents.Append(type).Append(' ').Append(fieldInfo.Name + i).Append(';').AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fieldInfo.Type.IsObjectRef || fieldInfo.Type.Type == "Dictionary")
|
||||||
|
type = "IntPtr";
|
||||||
|
else if (fieldInfo.Type.IsPtr && !originalType.EndsWith("*"))
|
||||||
|
type = "IntPtr";
|
||||||
|
else if (fieldInfo.Type.Type == "Array")
|
||||||
|
{
|
||||||
|
type = "IntPtr";
|
||||||
|
apiType = FindApiTypeInfo(buildData, fieldInfo.Type.GenericArgs[0], structureInfo);
|
||||||
|
internalType = apiType is StructureInfo elementStructureInfo && UseCustomMarshalling(buildData, elementStructureInfo, structureInfo);
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.Type == "Version")
|
||||||
|
type = "IntPtr";
|
||||||
|
else if (type == "string")
|
||||||
|
type = "IntPtr";
|
||||||
|
else if (type == "bool")
|
||||||
|
type = "byte";
|
||||||
|
else if (type == "object")
|
||||||
|
type = "VariantNative";
|
||||||
|
else if (internalType)
|
||||||
|
{
|
||||||
|
internalTypeMarshaler = type + "Marshaller";
|
||||||
|
type = $"{internalTypeMarshaler}.{type}Internal";
|
||||||
|
}
|
||||||
|
//else if (type == "Guid")
|
||||||
|
// type = "GuidNative";
|
||||||
|
|
||||||
|
contents.Append(type).Append(' ').Append(fieldInfo.Name);
|
||||||
|
contents.Append(';').AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate struct constructor/getter and deconstructor/setter function
|
||||||
|
if (fieldInfo.NoArray && fieldInfo.Type.IsArray)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (type == "VariantNative")
|
||||||
|
continue; // FIXME
|
||||||
|
|
||||||
|
if (useSeparator)
|
||||||
|
{
|
||||||
|
toManagedContent.Append(", ");
|
||||||
|
toNativeContent.Append(", ");
|
||||||
|
freeContents2.Append("");
|
||||||
|
freeContents.Append("");
|
||||||
|
}
|
||||||
|
useSeparator = true;
|
||||||
|
|
||||||
|
toManagedContent.Append(fieldInfo.Name);
|
||||||
|
toManagedContent.Append(" = ");
|
||||||
|
|
||||||
|
toNativeContent.Append(fieldInfo.Name);
|
||||||
|
toNativeContent.Append(" = ");
|
||||||
|
|
||||||
|
if (fieldInfo.Type.IsObjectRef)
|
||||||
|
{
|
||||||
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({fieldInfo.Type.GenericArgs[0].Type})GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
|
||||||
|
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
|
||||||
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
|
||||||
|
// Permanent ScriptingObject handle is passed from native side, do not release it
|
||||||
|
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.Type == "ScriptingObject")
|
||||||
|
{
|
||||||
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? (FlaxEngine.Object)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
|
||||||
|
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
|
||||||
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
|
||||||
|
// Permanent ScriptingObject handle is passed from native side, do not release it
|
||||||
|
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.IsPtr && originalType != "IntPtr" && !originalType.EndsWith("*"))
|
||||||
|
{
|
||||||
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
|
||||||
|
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
|
||||||
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
|
||||||
|
// Permanent ScriptingObject handle is passed from native side, do not release it
|
||||||
|
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.Type == "Dictionary")
|
||||||
|
{
|
||||||
|
string dictionaryArgs = String.Join(", ",
|
||||||
|
fieldInfo.Type.GenericArgs.Select(x => CSharpNativeToManagedBasicTypes.ContainsKey(x.Type) ? CSharpNativeToManagedBasicTypes[x.Type] : x.Type).ToArray());
|
||||||
|
toManagedContent.Append(
|
||||||
|
$"managed.{fieldInfo.Name} != IntPtr.Zero ? (System.Collections.Generic.{fieldInfo.Type.Type}<{dictionaryArgs}>)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
|
||||||
|
toNativeContent.Append(
|
||||||
|
$"GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak))");
|
||||||
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.Type == "Array")
|
||||||
|
{
|
||||||
|
if (internalType)
|
||||||
|
{
|
||||||
|
// Marshal blittable array elements back to original non-blittable elements
|
||||||
|
string originalElementType = originalType.Substring(0, originalType.Length - 2);
|
||||||
|
string originalElementTypeMarshaller = originalElementType + "Marshaller";
|
||||||
|
string internalElementType = $"{originalElementTypeMarshaller}.{originalElementType}Internal";
|
||||||
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.NativeArrayToManagedArray<{originalElementType}, {internalElementType}>(((ManagedArray)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).array as {internalElementType}[], {originalElementTypeMarshaller}.ToManaged) : null");
|
||||||
|
toNativeContent.Append($"GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(managed.{fieldInfo.Name}), GCHandleType.Weak))");
|
||||||
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); {internalElementType}[] values = ({internalElementType}[])(((ManagedArray)handle.Target).array); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Release(); handle.Free(); }}");
|
||||||
|
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); {internalElementType}[] values = ({internalElementType}[])(((ManagedArray)handle.Target).array); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Release(); handle.Free(); }}");
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.GenericArgs[0].IsObjectRef)
|
||||||
|
{
|
||||||
|
// Array elements passed as GCHandles
|
||||||
|
string originalElementType = originalType.Substring(0, originalType.Length - 2);
|
||||||
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<{originalElementType}>((ManagedArray)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target) : null");
|
||||||
|
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(NativeInterop.ManagedArrayToGCHandleArray(managed.{fieldInfo.Name})), GCHandleType.Weak)) : IntPtr.Zero");
|
||||||
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); IntPtr[] ptrs = (IntPtr[])(((ManagedArray)handle.Target).array); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ GCHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Release(); handle.Free(); }}");
|
||||||
|
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); IntPtr[] ptrs = (IntPtr[])(((ManagedArray)handle.Target).array); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ GCHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Release(); handle.Free(); }}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Blittable array elements
|
||||||
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})(((ManagedArray)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).array) : null");
|
||||||
|
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(managed.{fieldInfo.Name}), GCHandleType.Weak)) : IntPtr.Zero");
|
||||||
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Release(); handle.Free(); }}");
|
||||||
|
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Release(); handle.Free(); }}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.Type == "Version")
|
||||||
|
{
|
||||||
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
|
||||||
|
toNativeContent.Append($"GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak))");
|
||||||
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
|
||||||
|
}
|
||||||
|
else if (originalType == "string")
|
||||||
|
{
|
||||||
|
toManagedContent.Append($"ManagedString.ToManaged(managed.{fieldInfo.Name})");
|
||||||
|
toNativeContent.Append($"ManagedString.ToNative(managed.{fieldInfo.Name})");
|
||||||
|
freeContents.AppendLine($"ManagedString.Free(unmanaged.{fieldInfo.Name});");
|
||||||
|
freeContents2.AppendLine($"ManagedString.Free(unmanaged.{fieldInfo.Name});");
|
||||||
|
}
|
||||||
|
else if (originalType == "bool")
|
||||||
|
{
|
||||||
|
toManagedContent.Append($"managed.{fieldInfo.Name} != 0");
|
||||||
|
toNativeContent.Append($"managed.{fieldInfo.Name} ? (byte)1 : (byte)0");
|
||||||
|
}
|
||||||
|
else if (internalType)
|
||||||
|
{
|
||||||
|
toManagedContent.Append($"{internalTypeMarshaler}.ToManaged(managed.{fieldInfo.Name})");
|
||||||
|
toNativeContent.Append($"{internalTypeMarshaler}.ToNative(managed.{fieldInfo.Name})");
|
||||||
|
freeContents.AppendLine($"{internalTypeMarshaler}.Free(unmanaged.{fieldInfo.Name});");
|
||||||
|
freeContents2.AppendLine($"{internalTypeMarshaler}.Free(unmanaged.{fieldInfo.Name});");
|
||||||
|
}
|
||||||
|
/*else if (originalType == "Guid")
|
||||||
|
{
|
||||||
|
toManagedContent.Append("(Guid)managed.").Append(fieldInfo.Name);
|
||||||
|
toNativeContent.Append("(GuidNative)managed.").Append(fieldInfo.Name);
|
||||||
|
}*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toManagedContent.Append("managed.").Append(fieldInfo.Name);
|
||||||
|
toNativeContent.Append("managed.").Append(fieldInfo.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Native struct end
|
||||||
|
indent = indent.Substring(0, indent.Length - 4);
|
||||||
|
contents.AppendLine(indent + "}").AppendLine();
|
||||||
|
|
||||||
|
toManagedContent.AppendLine(" };");
|
||||||
|
toNativeContent.AppendLine(" };");
|
||||||
|
}
|
||||||
|
|
||||||
|
var indent2 = indent + " ";
|
||||||
|
var indent3 = indent2 + " ";
|
||||||
|
|
||||||
|
// NativeToManaged stateless shape
|
||||||
|
// NOTE: GCHandles of FlaxEngine.Object must not be released in this case
|
||||||
|
contents.Append(indent).AppendLine($"public static class NativeToManaged").Append(indent).AppendLine("{");
|
||||||
|
contents.Append(indent2).AppendLine($"public static {structureInfo.Name} ConvertToManaged({structureInfo.Name}Internal unmanaged) => {marshallerName}.ToManaged(unmanaged);");
|
||||||
|
contents.Append(indent2).AppendLine($"public static void Free({structureInfo.Name}Internal unmanaged)");
|
||||||
|
contents.Append(indent2).AppendLine("{").Append(indent3).AppendLine(freeContents2.Replace("\n", "\n" + indent3).ToString().TrimEnd()).Append(indent2).AppendLine("}");
|
||||||
|
contents.Append(indent).AppendLine("}");
|
||||||
|
|
||||||
|
// ManagedToNative stateless shape
|
||||||
|
contents.Append(indent).AppendLine($"public static class ManagedToNative").Append(indent).AppendLine("{");
|
||||||
|
contents.Append(indent2).AppendLine($"public static {structureInfo.Name}Internal ConvertToUnmanaged({structureInfo.Name} managed) => {marshallerName}.ToNative(managed);");
|
||||||
|
contents.Append(indent2).AppendLine($"public static void Free({structureInfo.Name}Internal unmanaged) => {marshallerName}.Free(unmanaged);");
|
||||||
|
contents.Append(indent).AppendLine("}");
|
||||||
|
|
||||||
|
// Bidirectional stateful shape
|
||||||
|
// NOTE: GCHandles of FlaxEngine.Object must not be released unless they were allocated by this marshaller
|
||||||
|
contents.Append(indent).AppendLine($"public struct Bidirectional").Append(indent).AppendLine("{");
|
||||||
|
contents.Append(indent2).AppendLine($"{structureInfo.Name} managed;");
|
||||||
|
contents.Append(indent2).AppendLine($"{structureInfo.Name}Internal? unmanaged;");
|
||||||
|
contents.Append(indent2).AppendLine($"public void FromManaged({structureInfo.Name} managed) {{ this.managed = managed; }}");
|
||||||
|
contents.Append(indent2).AppendLine($"public {structureInfo.Name}Internal ToUnmanaged() {{ unmanaged = {marshallerName}.ToNative(managed); return unmanaged.Value; }}");
|
||||||
|
//contents.Append(indent2).AppendLine($"public void FromUnmanaged({structureInfo.Name}Internal unmanaged) {{ {marshallerName}.Free(this.unmanaged.Value); this.unmanaged = unmanaged; }}");
|
||||||
|
contents.Append(indent2).AppendLine($"public void FromUnmanaged({structureInfo.Name}Internal unmanaged) {{ this.unmanaged = unmanaged; }}");
|
||||||
|
contents.Append(indent2).AppendLine($"public {structureInfo.Name} ToManaged() {{ managed = {marshallerName}.ToManaged(unmanaged.Value); return managed; }}");
|
||||||
|
contents.Append(indent2).AppendLine($"public void Free() {{ if (unmanaged.HasValue) {{ NativeToManaged.Free(unmanaged.Value); unmanaged = null; }} }}");
|
||||||
|
contents.Append(indent).AppendLine("}");
|
||||||
|
|
||||||
|
// Bidirectional stateless shape
|
||||||
|
contents.Append(indent).AppendLine($"internal static {structureInfo.Name} ConvertToManaged({structureInfo.Name}Internal unmanaged) => ToManaged(unmanaged);");
|
||||||
|
contents.Append(indent).AppendLine($"internal static {structureInfo.Name}Internal ConvertToUnmanaged({structureInfo.Name} managed) => ToNative(managed);");
|
||||||
|
contents.Append(indent).AppendLine($"internal static void Free({structureInfo.Name}Internal unmanaged)");
|
||||||
|
contents.Append(indent).AppendLine("{").Append(indent2).AppendLine(freeContents.Replace("\n", "\n" + indent2).ToString().TrimEnd()).Append(indent).AppendLine("}");
|
||||||
|
|
||||||
|
// Managed/native converters
|
||||||
|
contents.Append(indent).AppendLine($"internal static {structureInfo.Name} ToManaged({structureInfo.Name}Internal managed)");
|
||||||
|
contents.Append(indent).AppendLine("{").Append(indent2).AppendLine(toManagedContent.Replace("\n", "\n" + indent2).ToString().TrimEnd()).Append(indent).AppendLine("}");
|
||||||
|
contents.Append(indent).AppendLine($"internal static {structureInfo.Name}Internal ToNative({structureInfo.Name} managed)");
|
||||||
|
contents.Append(indent).AppendLine("{").Append(indent2).AppendLine(toNativeContent.Replace("\n", "\n" + indent2).ToString().TrimEnd()).Append(indent).AppendLine("}");
|
||||||
|
|
||||||
|
indent = indent.Substring(0, indent.Length - 4);
|
||||||
|
contents.Append(indent).AppendLine("}");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Struct docs
|
// Struct docs
|
||||||
GenerateCSharpComment(contents, indent, structureInfo.Comment);
|
GenerateCSharpComment(contents, indent, structureInfo.Comment);
|
||||||
|
|
||||||
// Struct begin
|
// Struct begin
|
||||||
GenerateCSharpAttributes(buildData, contents, indent, structureInfo, true);
|
GenerateCSharpAttributes(buildData, contents, indent, structureInfo, true);
|
||||||
contents.Append(indent).AppendLine("[StructLayout(LayoutKind.Sequential)]");
|
contents.Append(indent).AppendLine("[StructLayout(LayoutKind.Sequential)]");
|
||||||
|
#if USE_NETCORE
|
||||||
|
if (!string.IsNullOrEmpty(structNativeMarshaling))
|
||||||
|
contents.Append(indent).AppendLine(structNativeMarshaling);
|
||||||
|
#endif
|
||||||
contents.Append(indent);
|
contents.Append(indent);
|
||||||
GenerateCSharpAccessLevel(contents, structureInfo.Access);
|
GenerateCSharpAccessLevel(contents, structureInfo.Access);
|
||||||
contents.Append("unsafe partial struct ").Append(structureInfo.Name);
|
contents.Append("unsafe partial struct ").Append(structureInfo.Name);
|
||||||
@@ -1142,6 +1596,12 @@ namespace Flax.Build.Bindings
|
|||||||
contents.AppendLine();
|
contents.AppendLine();
|
||||||
GenerateCSharpComment(contents, indent, fieldInfo.Comment);
|
GenerateCSharpComment(contents, indent, fieldInfo.Comment);
|
||||||
GenerateCSharpAttributes(buildData, contents, indent, structureInfo, fieldInfo, fieldInfo.IsStatic, fieldInfo.DefaultValue, fieldInfo.Type);
|
GenerateCSharpAttributes(buildData, contents, indent, structureInfo, fieldInfo, fieldInfo.IsStatic, fieldInfo.DefaultValue, fieldInfo.Type);
|
||||||
|
#if USE_NETCORE
|
||||||
|
if (fieldInfo.Type.Type == "String")
|
||||||
|
contents.Append(indent).AppendLine("[MarshalAs(UnmanagedType.LPWStr)]");
|
||||||
|
else if (fieldInfo.Type.Type == "bool")
|
||||||
|
contents.Append(indent).AppendLine("[MarshalAs(UnmanagedType.U1)]");
|
||||||
|
#endif
|
||||||
contents.Append(indent);
|
contents.Append(indent);
|
||||||
GenerateCSharpAccessLevel(contents, fieldInfo.Access);
|
GenerateCSharpAccessLevel(contents, fieldInfo.Access);
|
||||||
if (fieldInfo.IsConstexpr)
|
if (fieldInfo.IsConstexpr)
|
||||||
@@ -1153,21 +1613,32 @@ namespace Flax.Build.Bindings
|
|||||||
|
|
||||||
if (fieldInfo.Type.IsArray && (fieldInfo.NoArray || structureInfo.IsPod))
|
if (fieldInfo.Type.IsArray && (fieldInfo.NoArray || structureInfo.IsPod))
|
||||||
{
|
{
|
||||||
// Fixed-size array that needs to be inlined into structure instead of passing it as managed array
|
|
||||||
fieldInfo.Type.IsArray = false;
|
fieldInfo.Type.IsArray = false;
|
||||||
type = GenerateCSharpNativeToManaged(buildData, fieldInfo.Type, structureInfo);
|
type = GenerateCSharpNativeToManaged(buildData, fieldInfo.Type, structureInfo);
|
||||||
fieldInfo.Type.IsArray = true;
|
fieldInfo.Type.IsArray = true;
|
||||||
contents.Append(type).Append(' ').Append(fieldInfo.Name + "0;").AppendLine();
|
#if USE_NETCORE
|
||||||
for (int i = 1; i < fieldInfo.Type.ArraySize; i++)
|
// Use fixed statement with primitive types of buffers
|
||||||
|
if (type == "char")
|
||||||
{
|
{
|
||||||
contents.AppendLine();
|
// char's are not blittable, store as short instead
|
||||||
GenerateCSharpComment(contents, indent, fieldInfo.Comment);
|
contents.Append($"fixed short {fieldInfo.Name}0[{fieldInfo.Type.ArraySize}]; // {type}*").AppendLine();
|
||||||
GenerateCSharpAttributes(buildData, contents, indent, structureInfo, fieldInfo, fieldInfo.IsStatic);
|
}
|
||||||
contents.Append(indent);
|
else
|
||||||
GenerateCSharpAccessLevel(contents, fieldInfo.Access);
|
#endif
|
||||||
if (fieldInfo.IsStatic)
|
{
|
||||||
contents.Append("static ");
|
// Padding in structs for fixed-size array
|
||||||
contents.Append(type).Append(' ').Append(fieldInfo.Name + i).Append(';').AppendLine();
|
contents.Append(type).Append(' ').Append(fieldInfo.Name + "0;").AppendLine();
|
||||||
|
for (int i = 1; i < fieldInfo.Type.ArraySize; i++)
|
||||||
|
{
|
||||||
|
contents.AppendLine();
|
||||||
|
GenerateCSharpComment(contents, indent, fieldInfo.Comment);
|
||||||
|
GenerateCSharpAttributes(buildData, contents, indent, structureInfo, fieldInfo, fieldInfo.IsStatic);
|
||||||
|
contents.Append(indent);
|
||||||
|
GenerateCSharpAccessLevel(contents, fieldInfo.Access);
|
||||||
|
if (fieldInfo.IsStatic)
|
||||||
|
contents.Append("static ");
|
||||||
|
contents.Append(type).Append(' ').Append(fieldInfo.Name + i).Append(';').AppendLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1393,6 +1864,23 @@ namespace Flax.Build.Bindings
|
|||||||
contents.AppendLine(indent + "}");
|
contents.AppendLine(indent + "}");
|
||||||
if (!string.IsNullOrEmpty(interfaceInfo.Namespace))
|
if (!string.IsNullOrEmpty(interfaceInfo.Namespace))
|
||||||
contents.AppendLine("}");
|
contents.AppendLine("}");
|
||||||
|
#if USE_NETCORE
|
||||||
|
{
|
||||||
|
string marshallerName = interfaceInfo.Name + "Marshaller";
|
||||||
|
contents.AppendLine();
|
||||||
|
|
||||||
|
contents.Append(indent).AppendLine("/// <summary>");
|
||||||
|
contents.Append(indent).AppendLine("/// ");
|
||||||
|
contents.Append(indent).AppendLine("/// </summary>");
|
||||||
|
contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({interfaceInfo.Name}), MarshalMode.Default, typeof({marshallerName}))]");
|
||||||
|
contents.Append(indent).AppendLine($"internal static class {marshallerName}");
|
||||||
|
contents.Append(indent).AppendLine("{");
|
||||||
|
contents.Append(indent + " ").AppendLine($"internal static {interfaceInfo.Name} ConvertToManaged(IntPtr unmanaged) => ({interfaceInfo.Name})GCHandleMarshaller.ConvertToManaged(unmanaged);");
|
||||||
|
contents.Append(indent + " ").AppendLine($"internal static IntPtr ConvertToUnmanaged({interfaceInfo.Name} managed) => GCHandleMarshaller.ConvertToUnmanaged(managed);");
|
||||||
|
contents.Append(indent + " ").AppendLine("internal static void Free(IntPtr unmanaged) => GCHandleMarshaller.Free(unmanaged);");
|
||||||
|
contents.Append(indent).AppendLine("}");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool GenerateCSharpType(BuildData buildData, StringBuilder contents, string indent, object type)
|
private static bool GenerateCSharpType(BuildData buildData, StringBuilder contents, string indent, object type)
|
||||||
@@ -1456,6 +1944,9 @@ namespace Flax.Build.Bindings
|
|||||||
CSharpUsedNamespaces.Add("System.Globalization");
|
CSharpUsedNamespaces.Add("System.Globalization");
|
||||||
CSharpUsedNamespaces.Add("System.Runtime.CompilerServices");
|
CSharpUsedNamespaces.Add("System.Runtime.CompilerServices");
|
||||||
CSharpUsedNamespaces.Add("System.Runtime.InteropServices");
|
CSharpUsedNamespaces.Add("System.Runtime.InteropServices");
|
||||||
|
#if USE_NETCORE
|
||||||
|
CSharpUsedNamespaces.Add("System.Runtime.InteropServices.Marshalling");
|
||||||
|
#endif
|
||||||
CSharpUsedNamespaces.Add("FlaxEngine");
|
CSharpUsedNamespaces.Add("FlaxEngine");
|
||||||
|
|
||||||
// Process all API types from the file
|
// Process all API types from the file
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user