Merge branch 'master' into sdl_platform
# Conflicts: # .github/workflows/build_linux.yml # .github/workflows/tests.yml # Source/Tools/Flax.Build/Projects/VisualStudio/VCProjectGenerator.cs
This commit is contained in:
@@ -16,7 +16,8 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ jobs:
|
|||||||
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
@@ -118,7 +119,8 @@ jobs:
|
|||||||
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
|
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection.Emit;
|
|
||||||
using FlaxEditor.CustomEditors.GUI;
|
using FlaxEditor.CustomEditors.GUI;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
|||||||
@@ -146,6 +146,10 @@ bool BinaryAssetFactoryBase::UpgradeAsset(const AssetInfo& info, FlaxStorage* st
|
|||||||
context.Input = context.Output;
|
context.Input = context.Output;
|
||||||
} while (upgrader->ShouldUpgrade(context.Input.SerializedVersion));
|
} while (upgrader->ShouldUpgrade(context.Input.SerializedVersion));
|
||||||
|
|
||||||
|
// Prevent other threads from loading the storage when it is upgrading
|
||||||
|
// It works because CriticalSection allows recursion
|
||||||
|
ScopeLock upgradeLock(storage->_loadLocker);
|
||||||
|
|
||||||
// Release storage internal data (should also close file handles)
|
// Release storage internal data (should also close file handles)
|
||||||
{
|
{
|
||||||
// HACK: file is locked by some tasks: the current one that called asset data upgrade (LoadAssetTask)
|
// HACK: file is locked by some tasks: the current one that called asset data upgrade (LoadAssetTask)
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
|
||||||
#define DLLEXPORT __attribute__ ((__visibility__ ("default")))
|
#define DLLEXPORT __attribute__((__visibility__("default")))
|
||||||
#define DLLIMPORT
|
#define DLLIMPORT
|
||||||
|
#define USED __attribute__((used))
|
||||||
#define THREADLOCAL __thread
|
#define THREADLOCAL __thread
|
||||||
#define STDCALL __attribute__((stdcall))
|
#define STDCALL __attribute__((stdcall))
|
||||||
#define CDECL __attribute__((cdecl))
|
#define CDECL __attribute__((cdecl))
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
#define PACK_BEGIN()
|
#define PACK_BEGIN()
|
||||||
#define PACK_END() __attribute__((__packed__))
|
#define PACK_END() __attribute__((__packed__))
|
||||||
#define ALIGN_BEGIN(_align)
|
#define ALIGN_BEGIN(_align)
|
||||||
#define ALIGN_END(_align) __attribute__( (aligned(_align) ) )
|
#define ALIGN_END(_align) __attribute__((aligned(_align)))
|
||||||
#define OFFSET_OF(X, Y) __builtin_offsetof(X, Y)
|
#define OFFSET_OF(X, Y) __builtin_offsetof(X, Y)
|
||||||
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS \
|
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS \
|
||||||
_Pragma("clang diagnostic push") \
|
_Pragma("clang diagnostic push") \
|
||||||
@@ -37,8 +38,9 @@
|
|||||||
|
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
|
|
||||||
#define DLLEXPORT __attribute__ ((__visibility__ ("default")))
|
#define DLLEXPORT __attribute__((__visibility__("default")))
|
||||||
#define DLLIMPORT
|
#define DLLIMPORT
|
||||||
|
#define USED __attribute__((used))
|
||||||
#define THREADLOCAL __thread
|
#define THREADLOCAL __thread
|
||||||
#define STDCALL __attribute__((stdcall))
|
#define STDCALL __attribute__((stdcall))
|
||||||
#define CDECL __attribute__((cdecl))
|
#define CDECL __attribute__((cdecl))
|
||||||
@@ -52,7 +54,7 @@
|
|||||||
#define PACK_BEGIN()
|
#define PACK_BEGIN()
|
||||||
#define PACK_END() __attribute__((__packed__))
|
#define PACK_END() __attribute__((__packed__))
|
||||||
#define ALIGN_BEGIN(_align)
|
#define ALIGN_BEGIN(_align)
|
||||||
#define ALIGN_END(_align) __attribute__( (aligned(_align) ) )
|
#define ALIGN_END(_align) __attribute__((aligned(_align)))
|
||||||
#define OFFSET_OF(X, Y) __builtin_offsetof(X, Y)
|
#define OFFSET_OF(X, Y) __builtin_offsetof(X, Y)
|
||||||
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||||
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||||
@@ -67,6 +69,7 @@
|
|||||||
|
|
||||||
#define DLLEXPORT __declspec(dllexport)
|
#define DLLEXPORT __declspec(dllexport)
|
||||||
#define DLLIMPORT __declspec(dllimport)
|
#define DLLIMPORT __declspec(dllimport)
|
||||||
|
#define USED
|
||||||
#define THREADLOCAL __declspec(thread)
|
#define THREADLOCAL __declspec(thread)
|
||||||
#define STDCALL __stdcall
|
#define STDCALL __stdcall
|
||||||
#define CDECL __cdecl
|
#define CDECL __cdecl
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ static bool CompareEngineServices(EngineService* const& a, EngineService* const&
|
|||||||
{ \
|
{ \
|
||||||
ZoneScoped; \
|
ZoneScoped; \
|
||||||
auto& services = GetServices(); \
|
auto& services = GetServices(); \
|
||||||
for (int32 i = 0; i < services.Count(); i++) \
|
for (int32 i = services.Count() - 1; i >= 0; i--) \
|
||||||
services[i]->name(); \
|
services[i]->name(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The high-level renderer context. Used to collect the draw calls for the scene rendering. Can be used to perform a custom rendering.
|
/// The high-level renderer context. Used to collect the draw calls for the scene rendering. Can be used to perform a custom rendering.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_STRUCT(NoDefault) struct RenderContext
|
API_STRUCT(NoDefault) struct FLAXENGINE_API RenderContext
|
||||||
{
|
{
|
||||||
DECLARE_SCRIPTING_TYPE_MINIMAL(RenderContext);
|
DECLARE_SCRIPTING_TYPE_MINIMAL(RenderContext);
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ API_STRUCT(NoDefault) struct RenderContext
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The high-level renderer context batch that encapsulates multiple rendering requests within a single task (eg. optimize main view scene rendering and shadow projections at once).
|
/// The high-level renderer context batch that encapsulates multiple rendering requests within a single task (eg. optimize main view scene rendering and shadow projections at once).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_STRUCT(NoDefault) struct RenderContextBatch
|
API_STRUCT(NoDefault) struct FLAXENGINE_API RenderContextBatch
|
||||||
{
|
{
|
||||||
DECLARE_SCRIPTING_TYPE_MINIMAL(RenderContextBatch);
|
DECLARE_SCRIPTING_TYPE_MINIMAL(RenderContextBatch);
|
||||||
|
|
||||||
|
|||||||
@@ -553,7 +553,7 @@ void GPUTextureDX11::initHandles()
|
|||||||
if (useDSV && useSRV && PixelFormatExtensions::HasStencil(format))
|
if (useDSV && useSRV && PixelFormatExtensions::HasStencil(format))
|
||||||
{
|
{
|
||||||
PixelFormat stencilFormat;
|
PixelFormat stencilFormat;
|
||||||
switch (_dxgiFormatDSV)
|
switch (static_cast<PixelFormat>(_dxgiFormatDSV))
|
||||||
{
|
{
|
||||||
case PixelFormat::D24_UNorm_S8_UInt:
|
case PixelFormat::D24_UNorm_S8_UInt:
|
||||||
srDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
|
srDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ public:
|
|||||||
/// <param name="device">The graphics device.</param>
|
/// <param name="device">The graphics device.</param>
|
||||||
/// <param name="name">The resource name.</param>
|
/// <param name="name">The resource name.</param>
|
||||||
GPUResourceDX12(GPUDeviceDX12* device, const StringView& name)
|
GPUResourceDX12(GPUDeviceDX12* device, const StringView& name)
|
||||||
: GPUResourceBase(device, name)
|
: GPUResourceBase<GPUDeviceDX12, BaseType>(device, name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -732,7 +732,7 @@ void GPUTextureDX12::initHandles()
|
|||||||
if (useDSV && useSRV && PixelFormatExtensions::HasStencil(format))
|
if (useDSV && useSRV && PixelFormatExtensions::HasStencil(format))
|
||||||
{
|
{
|
||||||
PixelFormat stencilFormat;
|
PixelFormat stencilFormat;
|
||||||
switch (_dxgiFormatDSV)
|
switch (static_cast<PixelFormat>(_dxgiFormatDSV))
|
||||||
{
|
{
|
||||||
case PixelFormat::D24_UNorm_S8_UInt:
|
case PixelFormat::D24_UNorm_S8_UInt:
|
||||||
srDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
|
srDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
|
||||||
|
|||||||
@@ -668,7 +668,11 @@ void AnimatedModel::RunBlendShapeDeformer(const MeshBase* mesh, MeshDeformationD
|
|||||||
{
|
{
|
||||||
if (q.First == blendShape.Name)
|
if (q.First == blendShape.Name)
|
||||||
{
|
{
|
||||||
const float weight = q.Second * blendShape.Weight;
|
float weight = q.Second;
|
||||||
|
if (!Math::IsZero(blendShape.Weight))
|
||||||
|
weight *= blendShape.Weight;
|
||||||
|
if (Math::IsZero(weight))
|
||||||
|
break;
|
||||||
blendShapes.Add(Pair<const BlendShape&, const float>(blendShape, weight));
|
blendShapes.Add(Pair<const BlendShape&, const float>(blendShape, weight));
|
||||||
minVertexIndex = Math::Min(minVertexIndex, blendShape.MinVertexIndex);
|
minVertexIndex = Math::Min(minVertexIndex, blendShape.MinVertexIndex);
|
||||||
maxVertexIndex = Math::Max(maxVertexIndex, blendShape.MaxVertexIndex);
|
maxVertexIndex = Math::Max(maxVertexIndex, blendShape.MaxVertexIndex);
|
||||||
|
|||||||
@@ -2787,7 +2787,8 @@ float PhysicsBackend::ComputeShapeSqrDistanceToPoint(void* shape, const Vector3&
|
|||||||
#if USE_LARGE_WORLDS
|
#if USE_LARGE_WORLDS
|
||||||
PxVec3 closestPointPx;
|
PxVec3 closestPointPx;
|
||||||
float result = PxGeometryQuery::pointDistance(C2P(point), shapePhysX->getGeometry(), trans, &closestPointPx);
|
float result = PxGeometryQuery::pointDistance(C2P(point), shapePhysX->getGeometry(), trans, &closestPointPx);
|
||||||
*closestPoint = P2C(closestPointPx);
|
if (closestPoint)
|
||||||
|
*closestPoint = P2C(closestPointPx);
|
||||||
return result;
|
return result;
|
||||||
#else
|
#else
|
||||||
return PxGeometryQuery::pointDistance(C2P(point), shapePhysX->getGeometry(), trans, (PxVec3*)closestPoint);
|
return PxGeometryQuery::pointDistance(C2P(point), shapePhysX->getGeometry(), trans, (PxVec3*)closestPoint);
|
||||||
|
|||||||
@@ -477,8 +477,8 @@ void ScriptingType::SetupScriptObjectVTable(void* object, ScriptingTypeHandle ba
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Duplicate vtable
|
// Duplicate vtable
|
||||||
Script.VTable = (void**)((byte*)Platform::Allocate(totalSize, 16) + prefixSize);
|
void** scriptVTable = (void**)((byte*)Platform::Allocate(totalSize, 16) + prefixSize);
|
||||||
Utilities::UnsafeMemoryCopy((byte*)Script.VTable - prefixSize, (byte*)vtable - prefixSize, prefixSize + size);
|
Utilities::UnsafeMemoryCopy((byte*)scriptVTable - prefixSize, (byte*)vtable - prefixSize, prefixSize + size);
|
||||||
|
|
||||||
// Override vtable entries
|
// Override vtable entries
|
||||||
if (interfacesCount)
|
if (interfacesCount)
|
||||||
@@ -492,7 +492,7 @@ void ScriptingType::SetupScriptObjectVTable(void* object, ScriptingTypeHandle ba
|
|||||||
if (eType.Script.SetupScriptObjectVTable)
|
if (eType.Script.SetupScriptObjectVTable)
|
||||||
{
|
{
|
||||||
// Override vtable entries for this class
|
// Override vtable entries for this class
|
||||||
eType.Script.SetupScriptObjectVTable(Script.ScriptVTable, Script.ScriptVTableBase, Script.VTable, entriesCount, wrapperIndex);
|
eType.Script.SetupScriptObjectVTable(Script.ScriptVTable, Script.ScriptVTableBase, scriptVTable, entriesCount, wrapperIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto interfaces = eType.Interfaces;
|
auto interfaces = eType.Interfaces;
|
||||||
@@ -511,13 +511,13 @@ void ScriptingType::SetupScriptObjectVTable(void* object, ScriptingTypeHandle ba
|
|||||||
const int32 interfaceSize = interfaceCount * sizeof(void*);
|
const int32 interfaceSize = interfaceCount * sizeof(void*);
|
||||||
|
|
||||||
// Duplicate interface vtable
|
// Duplicate interface vtable
|
||||||
Utilities::UnsafeMemoryCopy((byte*)Script.VTable + interfaceOffset, (byte*)vtableInterface - prefixSize, prefixSize + interfaceSize);
|
Utilities::UnsafeMemoryCopy((byte*)scriptVTable + interfaceOffset, (byte*)vtableInterface - prefixSize, prefixSize + interfaceSize);
|
||||||
|
|
||||||
// Override interface vtable entries
|
// Override interface vtable entries
|
||||||
const auto scriptOffset = interfaces->ScriptVTableOffset;
|
const auto scriptOffset = interfaces->ScriptVTableOffset;
|
||||||
const auto nativeOffset = interfaceOffset + prefixSize;
|
const auto nativeOffset = interfaceOffset + prefixSize;
|
||||||
void** interfaceVTable = (void**)((byte*)Script.VTable + nativeOffset);
|
void** interfaceVTable = (void**)((byte*)scriptVTable + nativeOffset);
|
||||||
interfaceType.Interface.SetupScriptObjectVTable(Script.ScriptVTable + scriptOffset, Script.ScriptVTableBase + scriptOffset, interfaceVTable, interfaceCount, wrapperIndex);
|
interfaceType.Interface.SetupScriptObjectVTable(scriptVTable + scriptOffset, Script.ScriptVTableBase + scriptOffset, interfaceVTable, interfaceCount, wrapperIndex);
|
||||||
|
|
||||||
Script.InterfacesOffsets[interfacesCount++] = (uint16)nativeOffset;
|
Script.InterfacesOffsets[interfacesCount++] = (uint16)nativeOffset;
|
||||||
interfaceOffset += prefixSize + interfaceSize;
|
interfaceOffset += prefixSize + interfaceSize;
|
||||||
@@ -527,6 +527,9 @@ void ScriptingType::SetupScriptObjectVTable(void* object, ScriptingTypeHandle ba
|
|||||||
}
|
}
|
||||||
e = eType.GetBaseType();
|
e = eType.GetBaseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assign once it's ready
|
||||||
|
Script.VTable = scriptVTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptingType::HackObjectVTable(void* object, ScriptingTypeHandle baseTypeHandle, int32 wrapperIndex)
|
void ScriptingType::HackObjectVTable(void* object, ScriptingTypeHandle baseTypeHandle, int32 wrapperIndex)
|
||||||
|
|||||||
@@ -204,6 +204,9 @@ public:
|
|||||||
{
|
{
|
||||||
return str.Length();
|
return str.Length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test parameter passing with non-cost ref
|
||||||
|
API_FUNCTION() virtual void StringParamRef(String& str) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test debug commands via static class.
|
// Test debug commands via static class.
|
||||||
|
|||||||
@@ -387,17 +387,7 @@ namespace Flax.Build.Bindings
|
|||||||
|
|
||||||
// Find namespace for this type to build a fullname
|
// Find namespace for this type to build a fullname
|
||||||
if (apiType != null)
|
if (apiType != null)
|
||||||
{
|
managedType = apiType.Namespace + '.' + managedType.Replace(".", "+");
|
||||||
var e = apiType.Parent;
|
|
||||||
while (!(e is FileInfo))
|
|
||||||
{
|
|
||||||
e = e.Parent;
|
|
||||||
}
|
|
||||||
if (e is FileInfo fileInfo && !managedType.StartsWith(fileInfo.Namespace))
|
|
||||||
{
|
|
||||||
managedType = fileInfo.Namespace + '.' + managedType.Replace(".", "+");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use runtime lookup from fullname of the C# class
|
// Use runtime lookup from fullname of the C# class
|
||||||
return "Scripting::FindClass(\"" + managedType + "\")";
|
return "Scripting::FindClass(\"" + managedType + "\")";
|
||||||
@@ -770,6 +760,11 @@ namespace Flax.Build.Bindings
|
|||||||
genericArgs += ", " + typeInfo.GenericArgs[1];
|
genericArgs += ", " + typeInfo.GenericArgs[1];
|
||||||
result = $"Array<{genericArgs}>({result})";
|
result = $"Array<{genericArgs}>({result})";
|
||||||
}
|
}
|
||||||
|
else if (arrayApiType?.Name == "bool")
|
||||||
|
{
|
||||||
|
type = "bool*";
|
||||||
|
result = "Array<bool>({0}, {1})";
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -925,7 +920,7 @@ namespace Flax.Build.Bindings
|
|||||||
|
|
||||||
// BytesContainer
|
// BytesContainer
|
||||||
if (typeInfo.Type == "BytesContainer" && typeInfo.GenericArgs == null)
|
if (typeInfo.Type == "BytesContainer" && typeInfo.GenericArgs == null)
|
||||||
return "MUtils::ToArray({0})";
|
return $"MUtils::ToArray({value})";
|
||||||
|
|
||||||
// Construct native typename for MUtils template argument
|
// Construct native typename for MUtils template argument
|
||||||
var nativeType = new StringBuilder(64);
|
var nativeType = new StringBuilder(64);
|
||||||
@@ -1244,8 +1239,12 @@ namespace Flax.Build.Bindings
|
|||||||
callParams += ", ";
|
callParams += ", ";
|
||||||
separator = true;
|
separator = true;
|
||||||
var name = parameterInfo.Name;
|
var name = parameterInfo.Name;
|
||||||
|
var countParamName = $"__{parameterInfo.Name}Count";
|
||||||
if (CppParamsThatNeedConversion[i] && (!FindApiTypeInfo(buildData, parameterInfo.Type, caller)?.IsStruct ?? false))
|
if (CppParamsThatNeedConversion[i] && (!FindApiTypeInfo(buildData, parameterInfo.Type, caller)?.IsStruct ?? false))
|
||||||
|
{
|
||||||
name = '*' + name;
|
name = '*' + name;
|
||||||
|
countParamName = '*' + countParamName;
|
||||||
|
}
|
||||||
|
|
||||||
string param = string.Empty;
|
string param = string.Empty;
|
||||||
if (string.IsNullOrWhiteSpace(CppParamsWrappersCache[i]))
|
if (string.IsNullOrWhiteSpace(CppParamsWrappersCache[i]))
|
||||||
@@ -1258,7 +1257,7 @@ namespace Flax.Build.Bindings
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Convert value
|
// Convert value
|
||||||
param += string.Format(CppParamsWrappersCache[i], name);
|
param += string.Format(CppParamsWrappersCache[i], name, countParamName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case for output result parameters that needs additional converting from native to managed format (such as non-POD structures or output array parameter)
|
// Special case for output result parameters that needs additional converting from native to managed format (such as non-POD structures or output array parameter)
|
||||||
@@ -1293,11 +1292,21 @@ namespace Flax.Build.Bindings
|
|||||||
callParams += parameterInfo.Name;
|
callParams += parameterInfo.Name;
|
||||||
callParams += "Temp";
|
callParams += "Temp";
|
||||||
}
|
}
|
||||||
// Instruct for more optoimized value move operation
|
// Instruct for more optimized value move operation
|
||||||
else if (parameterInfo.Type.IsMoveRef)
|
else if (parameterInfo.Type.IsMoveRef)
|
||||||
{
|
{
|
||||||
callParams += $"MoveTemp({param})";
|
callParams += $"MoveTemp({param})";
|
||||||
}
|
}
|
||||||
|
else if (parameterInfo.Type.IsRef && !parameterInfo.Type.IsConst)
|
||||||
|
{
|
||||||
|
// Non-const lvalue reference parameters needs to be passed via temporary value
|
||||||
|
if (parameterInfo.IsOut || parameterInfo.IsRef)
|
||||||
|
contents.Append(indent).AppendFormat("{2}& {0}Temp = {1};", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine();
|
||||||
|
else
|
||||||
|
contents.Append(indent).AppendFormat("{2} {0}Temp = {1};", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine();
|
||||||
|
callParams += parameterInfo.Name;
|
||||||
|
callParams += "Temp";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
callParams += param;
|
callParams += param;
|
||||||
@@ -2997,16 +3006,19 @@ namespace Flax.Build.Bindings
|
|||||||
header.Append("template<>").AppendLine();
|
header.Append("template<>").AppendLine();
|
||||||
header.AppendFormat("struct MConverter<{0}>", fullName).AppendLine();
|
header.AppendFormat("struct MConverter<{0}>", fullName).AppendLine();
|
||||||
header.Append('{').AppendLine();
|
header.Append('{').AppendLine();
|
||||||
header.AppendFormat(" MObject* Box(const {0}& data, const MClass* klass)", fullName).AppendLine();
|
|
||||||
|
header.AppendFormat(" DLLEXPORT USED MObject* Box(const {0}& data, const MClass* klass)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.Append(" auto managed = ToManaged(data);").AppendLine();
|
header.Append(" auto managed = ToManaged(data);").AppendLine();
|
||||||
header.Append(" return MCore::Object::Box((void*)&managed, klass);").AppendLine();
|
header.Append(" return MCore::Object::Box((void*)&managed, klass);").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
header.AppendFormat(" void Unbox({0}& result, MObject* data)", fullName).AppendLine();
|
|
||||||
|
header.AppendFormat(" DLLEXPORT USED void Unbox({0}& result, MObject* data)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.AppendFormat(" result = ToNative(*reinterpret_cast<{0}*>(MCore::Object::Unbox(data)));", wrapperName).AppendLine();
|
header.AppendFormat(" result = ToNative(*reinterpret_cast<{0}*>(MCore::Object::Unbox(data)));", wrapperName).AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
header.AppendFormat(" void ToManagedArray(MArray* result, const Span<{0}>& data)", fullName).AppendLine();
|
|
||||||
|
header.AppendFormat(" DLLEXPORT USED void ToManagedArray(MArray* result, const Span<{0}>& data)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.AppendFormat(" MClass* klass = {0}::TypeInitializer.GetClass();", fullName).AppendLine();
|
header.AppendFormat(" MClass* klass = {0}::TypeInitializer.GetClass();", fullName).AppendLine();
|
||||||
header.AppendFormat(" {0}* resultPtr = ({0}*)MCore::Array::GetAddress(result);", wrapperName).AppendLine();
|
header.AppendFormat(" {0}* resultPtr = ({0}*)MCore::Array::GetAddress(result);", wrapperName).AppendLine();
|
||||||
@@ -3016,7 +3028,8 @@ namespace Flax.Build.Bindings
|
|||||||
header.Append(" MCore::GC::WriteValue(&resultPtr[i], &managed, 1, klass);").AppendLine();
|
header.Append(" MCore::GC::WriteValue(&resultPtr[i], &managed, 1, klass);").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
header.AppendFormat(" void ToNativeArray(Span<{0}>& result, const MArray* data)", fullName).AppendLine();
|
|
||||||
|
header.AppendFormat(" DLLEXPORT USED void ToNativeArray(Span<{0}>& result, const MArray* data)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.AppendFormat(" {0}* dataPtr = ({0}*)MCore::Array::GetAddress(data);", wrapperName).AppendLine();
|
header.AppendFormat(" {0}* dataPtr = ({0}*)MCore::Array::GetAddress(data);", wrapperName).AppendLine();
|
||||||
header.Append(" for (int32 i = 0; i < result.Length(); i++)").AppendLine();
|
header.Append(" for (int32 i = 0; i < result.Length(); i++)").AppendLine();
|
||||||
@@ -3108,7 +3121,7 @@ namespace Flax.Build.Bindings
|
|||||||
header.AppendFormat("struct MConverter<{0}>", fullName).AppendLine();
|
header.AppendFormat("struct MConverter<{0}>", fullName).AppendLine();
|
||||||
header.Append('{').AppendLine();
|
header.Append('{').AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" static MObject* Box(const {0}& data, const MClass* klass)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED static MObject* Box(const {0}& data, const MClass* klass)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.Append(" MObject* obj = MCore::Object::New(klass);").AppendLine();
|
header.Append(" MObject* obj = MCore::Object::New(klass);").AppendLine();
|
||||||
for (var i = 0; i < fields.Count; i++)
|
for (var i = 0; i < fields.Count; i++)
|
||||||
@@ -3128,13 +3141,13 @@ namespace Flax.Build.Bindings
|
|||||||
header.Append(" return obj;").AppendLine();
|
header.Append(" return obj;").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" static MObject* Box(const {0}& data)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED static MObject* Box(const {0}& data)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.AppendFormat(" MClass* klass = {0}::TypeInitializer.GetClass();", fullName).AppendLine();
|
header.AppendFormat(" MClass* klass = {0}::TypeInitializer.GetClass();", fullName).AppendLine();
|
||||||
header.Append(" return Box(data, klass);").AppendLine();
|
header.Append(" return Box(data, klass);").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" static void Unbox({0}& result, MObject* obj)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED static void Unbox({0}& result, MObject* obj)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.Append(" MClass* klass = MCore::Object::GetClass(obj);").AppendLine();
|
header.Append(" MClass* klass = MCore::Object::GetClass(obj);").AppendLine();
|
||||||
header.Append(" void* v = nullptr;").AppendLine();
|
header.Append(" void* v = nullptr;").AppendLine();
|
||||||
@@ -3156,20 +3169,20 @@ namespace Flax.Build.Bindings
|
|||||||
}
|
}
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" static {0} Unbox(MObject* data)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED static {0} Unbox(MObject* data)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.AppendFormat(" {0} result;", fullName).AppendLine();
|
header.AppendFormat(" {0} result;", fullName).AppendLine();
|
||||||
header.Append(" Unbox(result, data);").AppendLine();
|
header.Append(" Unbox(result, data);").AppendLine();
|
||||||
header.Append(" return result;").AppendLine();
|
header.Append(" return result;").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" void ToManagedArray(MArray* result, const Span<{0}>& data)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED void ToManagedArray(MArray* result, const Span<{0}>& data)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.Append(" for (int32 i = 0; i < data.Length(); i++)").AppendLine();
|
header.Append(" for (int32 i = 0; i < data.Length(); i++)").AppendLine();
|
||||||
header.Append(" MCore::GC::WriteArrayRef(result, Box(data[i]), i);").AppendLine();
|
header.Append(" MCore::GC::WriteArrayRef(result, Box(data[i]), i);").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" void ToNativeArray(Span<{0}>& result, const MArray* data)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED void ToNativeArray(Span<{0}>& result, const MArray* data)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.Append(" MObject** dataPtr = (MObject**)MCore::Array::GetAddress(data);").AppendLine();
|
header.Append(" MObject** dataPtr = (MObject**)MCore::Array::GetAddress(data);").AppendLine();
|
||||||
header.Append(" for (int32 i = 0; i < result.Length(); i++)").AppendLine();
|
header.Append(" for (int32 i = 0; i < result.Length(); i++)").AppendLine();
|
||||||
|
|||||||
@@ -241,7 +241,11 @@ namespace Flax.Deploy
|
|||||||
|
|
||||||
if (!File.Exists(solutionFile))
|
if (!File.Exists(solutionFile))
|
||||||
{
|
{
|
||||||
throw new Exception(string.Format("Unable to build solution {0}. Solution file not found.", solutionFile));
|
// CMake VS2026 generator prefers .slnx solution files, just swap the extension for CMake dependencies
|
||||||
|
if (File.Exists(Path.ChangeExtension(solutionFile, "slnx")))
|
||||||
|
solutionFile = Path.ChangeExtension(solutionFile, "slnx");
|
||||||
|
else
|
||||||
|
throw new Exception(string.Format("Unable to build solution {0}. Solution file not found.", solutionFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
string cmdLine = string.Format("\"{0}\" /m /t:Restore,Build /p:Configuration=\"{1}\" /p:Platform=\"{2}\" {3} /nologo", solutionFile, buildConfig, buildPlatform, Verbosity);
|
string cmdLine = string.Format("\"{0}\" /m /t:Restore,Build /p:Configuration=\"{1}\" /p:Platform=\"{2}\" {3} /nologo", solutionFile, buildConfig, buildPlatform, Verbosity);
|
||||||
|
|||||||
@@ -47,6 +47,24 @@ namespace Flax.Deps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected static TargetPlatform BuildPlatform => Platform.BuildPlatform.Target;
|
protected static TargetPlatform BuildPlatform => Platform.BuildPlatform.Target;
|
||||||
|
|
||||||
|
|
||||||
|
private static Version? _cmakeVersion;
|
||||||
|
protected static Version CMakeVersion
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_cmakeVersion == null)
|
||||||
|
{
|
||||||
|
var versionOutput = Utilities.ReadProcessOutput("cmake", "--version");
|
||||||
|
var versionStart = versionOutput.IndexOf("cmake version ") + "cmake version ".Length;
|
||||||
|
var versionEnd = versionOutput.IndexOfAny(['-', '\n', '\r'], versionStart); // End of line or dash before Git hash
|
||||||
|
var versionString = versionOutput.Substring(versionStart, versionEnd - versionStart);
|
||||||
|
_cmakeVersion = new Version(versionString);
|
||||||
|
}
|
||||||
|
return _cmakeVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the platforms list supported by this dependency to build on the current build platform (based on <see cref="Platform.BuildPlatform"/>).
|
/// Gets the platforms list supported by this dependency to build on the current build platform (based on <see cref="Platform.BuildPlatform"/>).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -351,7 +369,13 @@ namespace Flax.Deps
|
|||||||
break;
|
break;
|
||||||
default: throw new InvalidArchitectureException(architecture);
|
default: throw new InvalidArchitectureException(architecture);
|
||||||
}
|
}
|
||||||
cmdLine = string.Format("CMakeLists.txt -G \"Visual Studio 17 2022\" -A {0}", arch);
|
if (CMakeVersion.Major > 4 || (CMakeVersion.Major == 4 && CMakeVersion.Minor >= 2))
|
||||||
|
{
|
||||||
|
// This generates both .sln and .slnx solution files
|
||||||
|
cmdLine = string.Format("CMakeLists.txt -G \"Visual Studio 17 2022\" -G \"Visual Studio 18 2026\" -A {0}", arch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cmdLine = string.Format("CMakeLists.txt -G \"Visual Studio 17 2022\" -A {0}", arch);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetPlatform.PS4:
|
case TargetPlatform.PS4:
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ namespace Flax.Build.Projects.VisualStudio
|
|||||||
// Configurations
|
// Configurations
|
||||||
foreach (var configuration in project.Configurations)
|
foreach (var configuration in project.Configurations)
|
||||||
{
|
{
|
||||||
|
if (configuration.Equals(defaultConfiguration))
|
||||||
|
continue;
|
||||||
WriteConfiguration(project, csProjectFileContent, projectDirectory, configuration);
|
WriteConfiguration(project, csProjectFileContent, projectDirectory, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,6 +311,7 @@ namespace Flax.Build.Projects.VisualStudio
|
|||||||
}
|
}
|
||||||
csProjectFileContent.AppendLine(string.Format(" <DocumentationFile>{0}\\{1}.CSharp.xml</DocumentationFile>", outputPath, project.BaseName));
|
csProjectFileContent.AppendLine(string.Format(" <DocumentationFile>{0}\\{1}.CSharp.xml</DocumentationFile>", outputPath, project.BaseName));
|
||||||
csProjectFileContent.AppendLine(" <UseVSHostingProcess>true</UseVSHostingProcess>");
|
csProjectFileContent.AppendLine(" <UseVSHostingProcess>true</UseVSHostingProcess>");
|
||||||
|
csProjectFileContent.AppendLine(string.Format(" <FlaxConfiguration>{0}</FlaxConfiguration>", configuration.ConfigurationName));
|
||||||
|
|
||||||
csProjectFileContent.AppendLine(" </PropertyGroup>");
|
csProjectFileContent.AppendLine(" </PropertyGroup>");
|
||||||
|
|
||||||
|
|||||||
@@ -380,6 +380,10 @@ namespace Flax.Build.Projects.VisualStudio
|
|||||||
|
|
||||||
if (platforms.Any(x => x.Target == TargetPlatform.Linux || x.Target == TargetPlatform.Mac))
|
if (platforms.Any(x => x.Target == TargetPlatform.Linux || x.Target == TargetPlatform.Mac))
|
||||||
{
|
{
|
||||||
|
var editorPath = Utilities.NormalizePath(Path.Combine(Globals.EngineRoot, Platform.GetEditorBinaryDirectory(), "$(Configuration.Split('.')[2])", $"FlaxEditor{Utilities.GetPlatformExecutableExt()}")).Replace('\\', '/');
|
||||||
|
var debuggerProjectPath = Globals.Project.Name == "Flax" ? "" : Globals.Project.ProjectFolderPath;
|
||||||
|
var debuggerWorkingDirectory = Globals.Project.ProjectFolderPath;
|
||||||
|
|
||||||
// Override MSBuild .targets file with one that runs NMake commands (workaround for Rider not finding "Microsoft.Cpp.Default.props" file)
|
// Override MSBuild .targets file with one that runs NMake commands (workaround for Rider not finding "Microsoft.Cpp.Default.props" file)
|
||||||
var cppTargetsFileContent = new StringBuilder();
|
var cppTargetsFileContent = new StringBuilder();
|
||||||
cppTargetsFileContent.AppendLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" TreatAsLocalProperty=\"Platform\">");
|
cppTargetsFileContent.AppendLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" TreatAsLocalProperty=\"Platform\">");
|
||||||
@@ -396,6 +400,12 @@ namespace Flax.Build.Projects.VisualStudio
|
|||||||
cppTargetsFileContent.AppendLine(" <TargetExt></TargetExt>");
|
cppTargetsFileContent.AppendLine(" <TargetExt></TargetExt>");
|
||||||
cppTargetsFileContent.AppendLine(" <TargetName>$(RootNamespace)$(Configuration.Split('.')[0])</TargetName>");
|
cppTargetsFileContent.AppendLine(" <TargetName>$(RootNamespace)$(Configuration.Split('.')[0])</TargetName>");
|
||||||
cppTargetsFileContent.AppendLine(" <TargetPath>$(OutDir)/$(TargetName)$(TargetExt)</TargetPath>");
|
cppTargetsFileContent.AppendLine(" <TargetPath>$(OutDir)/$(TargetName)$(TargetExt)</TargetPath>");
|
||||||
|
if (!string.IsNullOrEmpty(debuggerProjectPath))
|
||||||
|
cppTargetsFileContent.AppendLine(string.Format(" <LocalDebuggerCommandArguments>-project \"{0}\"</LocalDebuggerCommandArguments>", debuggerProjectPath));
|
||||||
|
else
|
||||||
|
cppTargetsFileContent.AppendLine(" <LocalDebuggerCommandArguments></LocalDebuggerCommandArguments>");
|
||||||
|
cppTargetsFileContent.AppendLine(string.Format(" <LocalDebuggerCommand>{0}</LocalDebuggerCommand>", editorPath));
|
||||||
|
cppTargetsFileContent.AppendLine(string.Format(" <LocalDebuggerWorkingDirectory>{0}</LocalDebuggerWorkingDirectory>", debuggerWorkingDirectory));
|
||||||
cppTargetsFileContent.AppendLine(" </PropertyGroup>");
|
cppTargetsFileContent.AppendLine(" </PropertyGroup>");
|
||||||
cppTargetsFileContent.AppendLine("</Project>");
|
cppTargetsFileContent.AppendLine("</Project>");
|
||||||
|
|
||||||
|
|||||||
@@ -630,9 +630,10 @@ namespace Flax.Build.Projects.VisualStudio
|
|||||||
{
|
{
|
||||||
var profiles = new Dictionary<string, string>();
|
var profiles = new Dictionary<string, string>();
|
||||||
var profile = new StringBuilder();
|
var profile = new StringBuilder();
|
||||||
var configuration = "Development";
|
var configuration = "$(FlaxConfiguration)";
|
||||||
var editorPath = Utilities.NormalizePath(Path.Combine(Globals.EngineRoot, Platform.GetEditorBinaryDirectory(), configuration, $"FlaxEditor{Utilities.GetPlatformExecutableExt()}")).Replace('\\', '/');
|
var editorPath = Utilities.NormalizePath(Path.Combine(Globals.EngineRoot, Platform.GetEditorBinaryDirectory(), configuration, $"FlaxEditor{Utilities.GetPlatformExecutableExt()}")).Replace('\\', '/');
|
||||||
var workspacePath = Utilities.NormalizePath(solutionDirectory).Replace('\\', '/');
|
var workspacePath = Utilities.NormalizePath(solutionDirectory).Replace('\\', '/');
|
||||||
|
var args = Globals.Project.Name == "Flax" ? "" : $"-project \\\"{workspacePath}\\\"";
|
||||||
foreach (var project in projects)
|
foreach (var project in projects)
|
||||||
{
|
{
|
||||||
if (project.Type == TargetType.DotNetCore)
|
if (project.Type == TargetType.DotNetCore)
|
||||||
@@ -645,7 +646,7 @@ namespace Flax.Build.Projects.VisualStudio
|
|||||||
profile.AppendLine(" \"commandName\": \"Executable\",");
|
profile.AppendLine(" \"commandName\": \"Executable\",");
|
||||||
profile.AppendLine($" \"workingDirectory\": \"{workspacePath}\",");
|
profile.AppendLine($" \"workingDirectory\": \"{workspacePath}\",");
|
||||||
profile.AppendLine($" \"executablePath\": \"{editorPath}\",");
|
profile.AppendLine($" \"executablePath\": \"{editorPath}\",");
|
||||||
profile.AppendLine($" \"commandLineArgs\": \"-project \\\"{workspacePath}\\\"\",");
|
profile.AppendLine($" \"commandLineArgs\": \"{args}\",");
|
||||||
profile.AppendLine(" \"nativeDebugging\": false");
|
profile.AppendLine(" \"nativeDebugging\": false");
|
||||||
profile.Append(" }");
|
profile.Append(" }");
|
||||||
if (profiles.ContainsKey(path))
|
if (profiles.ContainsKey(path))
|
||||||
|
|||||||
Reference in New Issue
Block a user