51 Commits

Author SHA1 Message Date
cd2e7140af _windows subwindow popup fix
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
2024-12-27 12:58:04 +02:00
d5b64aece4 _sdl binary 2024-12-27 12:22:50 +02:00
146cc13bad Update SDL3 2024-12-27 12:22:45 +02:00
865b430ab0 _sdl3 binary 2024-12-27 00:19:23 +02:00
a5ad7a4398 Update SDL3 2024-12-27 00:19:17 +02:00
89d1cc4270 _borderless maximize workarounds WIP 2024-12-26 22:12:02 +02:00
bd81e3e89e Fix workaround for maximizing Editor window 2024-12-25 19:45:17 +02:00
37acdc29ff _sdl3 binary 2024-12-25 19:44:25 +02:00
ccdc7a5e1d Update SDL3 2024-12-25 19:44:19 +02:00
fe313773d1 Fix casting error in CPU profiler tab
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
2024-12-19 20:09:43 +02:00
34346e4111 Force cursor to center of Game Window when tab handle is clicked 2024-12-19 20:09:43 +02:00
7cbe44c4e5 _update sdl 2024-12-19 20:09:43 +02:00
846f44b882 _sdl binary 2024-12-19 20:09:42 +02:00
68764580f2 Update SDL 2024-12-19 20:09:42 +02:00
Chandler Cox
cdf0e24c12 Fix rotation using SDL 2024-12-19 20:09:42 +02:00
ac7087c4ce Update SDL3 binaries 2024-12-19 20:09:41 +02:00
56e6e53d0c Update SDL to 3.1.3 preview 2024-12-19 20:09:41 +02:00
25b6605027 _window positioning that works on windows 2024-12-19 20:09:41 +02:00
c97f6f3b7e _lfsconfig 2024-12-19 20:09:40 +02:00
bc33d1a0f5 _noprog? 2024-12-19 20:09:40 +02:00
5e950833ff _works 0,0 primary screen, returned positions correct but visually wrong 2024-12-19 20:09:40 +02:00
9a04cee71f _works 2024-12-19 20:09:39 +02:00
b79c9402fd _wip parent-child positioning fixes 2024-12-19 20:09:39 +02:00
b0aed96d18 Fix Linux compilation without SDL 2024-12-19 20:09:39 +02:00
c003506906 Fix compilation 2024-12-19 20:09:38 +02:00
473dc4a1a0 Update SDL3 2024-12-19 20:09:38 +02:00
8d97e21b28 Fix compilation issues 2024-12-19 20:09:38 +02:00
ce932b1739 Fix windows not being hidden initially 2024-12-19 20:09:37 +02:00
506ad85cad Fix parent window position handling with popup/tooltip windows 2024-12-19 20:09:37 +02:00
e86ccefd3c Fix compilation errors in other platforms 2024-12-19 20:09:37 +02:00
71147cd4e9 Fix CI for Linux 2024-12-19 20:09:36 +02:00
d6fe1f0519 Prevent building with SDL in unsupported platforms 2024-12-19 20:09:36 +02:00
ed3d1ce366 Fallback to X11 message box implementation when SDL fails 2024-12-19 20:09:36 +02:00
37177edeaa Fix popup and context menus not working on Wayland 2024-12-19 20:09:35 +02:00
7981483a5b Hide warnings for unsupported SDL operations on Wayland 2024-12-19 20:09:35 +02:00
c3ca359b4b Log a warning for not implemented Wayland functionality 2024-12-19 20:09:35 +02:00
99cf7292aa Fix compilation in Linux 2024-12-19 20:09:34 +02:00
4c6f39d489 Enable warning sound in question dialogs 2024-12-19 20:09:34 +02:00
dcfc265433 Enable modern Windows dialog boxes 2024-12-19 20:09:34 +02:00
4a7f6c34f3 Implement relative mouse mode (raw input) for SDL platform 2024-12-19 20:09:33 +02:00
ba248a61bd Add flag for Window types 2024-12-19 20:09:33 +02:00
eacd23bdbb Enable native windowing system settings with SDL platform 2024-12-19 20:09:33 +02:00
62df728452 Add command-line switches to force X11 and Wayland SDL drivers 2024-12-19 20:09:32 +02:00
fe0d97aad1 Implement SDL platform, windowing and input handling 2024-12-19 20:09:32 +02:00
7f7d839f23 Refactor application window class name 2024-12-19 20:09:32 +02:00
c445bfd5d4 Move Window related enums to separate header file 2024-12-19 20:09:31 +02:00
62843476b7 Refactor Windows drag and drop implementation 2024-12-19 20:09:31 +02:00
7595c572d7 Refactor ScreenUtilities 2024-12-19 20:09:31 +02:00
13ae091273 Add more helper methods for managing Git repos 2024-12-19 20:09:31 +02:00
a9dccd2949 Fix centered window location on X11 2024-12-19 20:09:30 +02:00
f8dd3f23c6 Fix initial position of Tooltips 2024-12-19 20:09:30 +02:00
952 changed files with 22806 additions and 40740 deletions

View File

@@ -1,13 +1,12 @@
name: Continuous Deployment
on:
schedule:
- cron: '15 6 * * *'
- cron: '15 4 * * *'
workflow_dispatch:
env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: false
GIT_LFS_PULL_OPTIONS: '-c lfs.concurrenttransfers=1 -c lfs.transfer.maxretries=2 -c http.version="HTTP/1.1" -c lfs.activitytimeout=60'
jobs:
@@ -21,7 +20,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
git lfs pull
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET
@@ -36,12 +35,12 @@ jobs:
run: |
.\PackageEditor.bat -arch=x64 -platform=Windows -deployOutput=Output
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Windows-Editor
path: Output/Editor.zip
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Windows-EditorDebugSymbols
path: Output/EditorDebugSymbols.zip
@@ -54,7 +53,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
git lfs pull
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET
@@ -69,7 +68,7 @@ jobs:
run: |
.\PackagePlatforms.bat -arch=x64 -platform=Windows -deployOutput=Output
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Windows-Game
path: Output/Windows.zip
@@ -84,7 +83,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
git lfs pull
- name: Install dependencies
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
@@ -102,7 +101,7 @@ jobs:
run: |
./PackageEditor.sh -arch=x64 -platform=Linux -deployOutput=Output
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Linux-Editor
path: Output/FlaxEditorLinux.zip
@@ -115,7 +114,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
git lfs pull
- name: Install dependencies
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
@@ -133,7 +132,7 @@ jobs:
run: |
./PackagePlatforms.sh -arch=x64 -platform=Linux -deployOutput=Output
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Linux-Game
path: Output/Linux.zip
@@ -148,7 +147,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
git lfs pull
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET
@@ -163,7 +162,7 @@ jobs:
run: |
./PackageEditor.command -arch=ARM64 -platform=Mac -deployOutput=Output
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Mac-Editor
path: Output/FlaxEditorMac.zip
@@ -176,7 +175,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
git lfs pull
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET
@@ -191,7 +190,7 @@ jobs:
run: |
./PackagePlatforms.command -arch=ARM64 -platform=Mac -deployOutput=Output
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Mac-Game
path: Output/Mac.zip

View File

@@ -73,11 +73,8 @@ jobs:
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -dotnet=8 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
dotnet msbuild Source\Tools\Flax.Build.Tests\Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
- name: Test
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
.\Binaries\Editor\Win64\Development\FlaxTests.exe
if(!$?) { Write-Host "Tests failed with exit code $LastExitCode" -ForegroundColor Red; Exit $LastExitCode }
dotnet test -f net8.0 Binaries\Tests\Flax.Build.Tests.dll
xcopy /y Binaries\Editor\Win64\Development\FlaxEngine.CSharp.dll Binaries\Tests
xcopy /y Binaries\Editor\Win64\Development\FlaxEngine.CSharp.runtimeconfig.json Binaries\Tests

View File

@@ -1,4 +1,4 @@
# Redirect to our own Git LFS server
[lfs]
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
locksverify = false

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -83,12 +83,6 @@ float3 GetObjectSize(MaterialInput input)
return float3(1, 1, 1);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{

View File

@@ -207,20 +207,6 @@ float3 GetObjectSize(MaterialInput input)
return GeometrySize * float3(world._m00, world._m11, world._m22);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
float4x4 world = WorldMatrix;
// Extract scale from the world matrix
float3 scale;
scale.x = length(float3(world._11, world._12, world._13));
scale.y = length(float3(world._21, world._22, world._23));
scale.z = length(float3(world._31, world._32, world._33));
return scale;
}
// Get the current object random value
float GetPerInstanceRandom(MaterialInput input)
{
@@ -311,7 +297,7 @@ VertexOutput VS_SplineModel(ModelInput input)
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.Geometry.TexCoord = input.TexCoord0;
output.Geometry.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
output.Geometry.VertexColor = input.Color;
#endif

View File

@@ -140,7 +140,7 @@ void SetParticleVec4(uint particleIndex, int offset, float4 value)
bool AddParticle(out uint dstIndex)
{
// Acquire the particle index in the destination buffer
DstParticlesData.InterlockedAdd(ParticleCounterOffset, 1u, dstIndex);
DstParticlesData.InterlockedAdd(ParticleCounterOffset, 1, dstIndex);
// Prevent overflow
return dstIndex >= PARTICLE_CAPACITY;

View File

@@ -163,12 +163,6 @@ float3 GetObjectSize(MaterialInput input)
return float3(1, 1, 1);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{

View File

@@ -299,22 +299,24 @@ half3x3 CalcTangentToLocal(ModelInput input)
float3 normal = input.Normal.xyz * 2.0 - 1.0;
float3 tangent = input.Tangent.xyz * 2.0 - 1.0;
float3 bitangent = cross(normal, tangent) * bitangentSign;
return (half3x3)float3x3(tangent, bitangent, normal);
return float3x3(tangent, bitangent, normal);
}
half3x3 CalcTangentToWorld(in float4x4 world, in half3x3 tangentToLocal)
{
half3x3 localToWorld = (half3x3)RemoveScaleFromLocalToWorld((float3x3)world);
half3x3 localToWorld = RemoveScaleFromLocalToWorld((float3x3)world);
return mul(tangentToLocal, localToWorld);
}
float3 GetParticlePosition(uint particleIndex)
float3 GetParticlePosition(uint ParticleIndex)
{
return TransformParticlePosition(GetParticleVec3(particleIndex, PositionOffset));
return TransformParticlePosition(GetParticleVec3(ParticleIndex, PositionOffset));
}
// Vertex Shader function for Sprite Rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(POSITION, 0, R32G32_FLOAT, 0, 0, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
{
VertexOutput output;
@@ -405,7 +407,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = half3x3(axisX, axisY, axisZ);
half3x3 tangentToLocal = float3x3(axisX, axisY, axisZ);
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
output.TBN = tangentToWorld;
@@ -514,7 +516,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
output.Position = mul(float4(output.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.TexCoord = input.TexCoord0;
output.TexCoord = input.TexCoord;
output.ParticleIndex = particleIndex;
#if USE_VERTEX_COLOR
output.VertexColor = input.Color;
@@ -610,7 +612,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
{
output.TexCoord.x = (float)input.Order / (float)RibbonSegmentCount;
}
output.TexCoord.y = (float)((vertexIndex + 1) & 0x1);
output.TexCoord.y = (vertexIndex + 1) & 0x1;
output.TexCoord = output.TexCoord * RibbonUVScale + RibbonUVOffset;
// Compute world space vertex position
@@ -629,7 +631,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = half3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
output.TBN = tangentToWorld;

View File

@@ -2,7 +2,6 @@
// Version: @0
#define MATERIAL 1
#define MATERIAL_TEXCOORDS 4
#define USE_PER_VIEW_CONSTANTS 1
#define USE_PER_DRAW_CONSTANTS 1
@3
@@ -25,29 +24,21 @@ Buffer<float4> BoneMatrices : register(t1);
Buffer<float4> PrevBoneMatrices : register(t2);
#endif
#endif
// Geometry data passed though the graphics rendering stages up to the pixel shader
struct GeometryData
{
float3 WorldPosition : TEXCOORD0;
float4 TexCoords01 : TEXCOORD1;
float4 TexCoords23 : TEXCOORD2;
float2 LightmapUV : TEXCOORD3;
float2 TexCoord : TEXCOORD1;
float2 LightmapUV : TEXCOORD2;
#if USE_VERTEX_COLOR
half4 VertexColor : COLOR;
#endif
float3 WorldNormal : TEXCOORD4;
float4 WorldTangent : TEXCOORD5;
float3 WorldNormal : TEXCOORD3;
float4 WorldTangent : TEXCOORD4;
float3 PrevWorldPosition : TEXCOORD7;
nointerpolation uint ObjectIndex : TEXCOORD8;
};
float3 DecodeNormal(float4 normalMap)
{
float2 xy = normalMap.rg * 2.0 - 1.0;
return float3(xy, sqrt(1.0 - saturate(dot(xy, xy))));
}
// Interpolants passed from the vertex shader
struct VertexOutput
{
@@ -77,7 +68,7 @@ struct MaterialInput
{
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoords[MATERIAL_TEXCOORDS];
float2 TexCoord;
#if USE_LIGHTMAP
float2 LightmapUV;
#endif
@@ -95,18 +86,12 @@ struct MaterialInput
#endif
};
// Map access to the main texure coordinate channel as UV0
#define TexCoord TexCoords[0]
// Extracts geometry data to the material input
MaterialInput GetGeometryMaterialInput(GeometryData geometry)
{
MaterialInput output = (MaterialInput)0;
output.WorldPosition = geometry.WorldPosition;
output.TexCoords[0] = geometry.TexCoords01.xy;
output.TexCoords[1] = geometry.TexCoords01.zw;
output.TexCoords[2] = geometry.TexCoords23.xy;
output.TexCoords[3] = geometry.TexCoords23.zw;
output.TexCoord = geometry.TexCoord;
#if USE_LIGHTMAP
output.LightmapUV = geometry.LightmapUV;
#endif
@@ -141,8 +126,8 @@ MaterialInput GetGeometryMaterialInput(GeometryData geometry)
GeometryData InterpolateGeometry(GeometryData p0, float w0, GeometryData p1, float w1, GeometryData p2, float w2)
{
GeometryData output = (GeometryData)0;
output.TexCoords01 = p0.TexCoords01 * w0 + p1.TexCoords01 * w1 + p2.TexCoords01 * w2;
output.TexCoords23 = p0.TexCoords23 * w0 + p1.TexCoords23 * w1 + p2.TexCoords23 * w2;
output.TexCoord = p0.TexCoord * w0 + p1.TexCoord * w1 + p2.TexCoord * w2;
output.LightmapUV = p0.LightmapUV * w0 + p1.LightmapUV * w1 + p2.LightmapUV * w2;
#if USE_VERTEX_COLOR
output.VertexColor = p0.VertexColor * w0 + p1.VertexColor * w1 + p2.VertexColor * w2;
#endif
@@ -238,24 +223,6 @@ float3 GetObjectSize(MaterialInput input)
return input.Object.GeometrySize * float3(world._m00, world._m11, world._m22);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
float4x4 world = input.Object.WorldMatrix;
// Get the squares of the scale factors
float scaleXSquared = dot(world[0].xyz, world[0].xyz);
float scaleYSquared = dot(world[1].xyz, world[1].xyz);
float scaleZSquared = dot(world[2].xyz, world[2].xyz);
// Take square root to get actual scales
return float3(
sqrt(scaleXSquared),
sqrt(scaleYSquared),
sqrt(scaleZSquared)
);
}
// Get the current object random value (supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{
@@ -345,15 +312,14 @@ VertexOutput VS(ModelInput input)
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
output.Geometry.TexCoords23 = float4(input.TexCoord2, input.TexCoord3);
output.Geometry.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
output.Geometry.VertexColor = input.Color;
#endif
#if CAN_USE_LIGHTMAP
output.Geometry.LightmapUV = input.LightmapUV * object.LightmapArea.zw + object.LightmapArea.xy;
#else
output.Geometry.LightmapUV = float2(0, 0);
output.Geometry.LightmapUV = input.LightmapUV;
#endif
// Calculate tanget space to world space transformation matrix for unit vectors
@@ -493,7 +459,7 @@ META_VS_IN_ELEMENT(TEXCOORD, 0, R16G16_FLOAT, 0, ALIGN, PER_VERTEX, 0,
META_VS_IN_ELEMENT(NORMAL, 0, R10G10B10A2_UNORM, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TANGENT, 0, R10G10B10A2_UNORM, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(BLENDINDICES, 0, R8G8B8A8_UINT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(BLENDWEIGHTS, 0, R16G16B16A16_FLOAT,0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(BLENDWEIGHT, 0, R16G16B16A16_FLOAT,0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS_Skinned(ModelInput_Skinned input)
{
VertexOutput output;
@@ -520,10 +486,9 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
output.Geometry.TexCoords23 = float4(input.TexCoord2, input.TexCoord3);
output.Geometry.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
output.Geometry.VertexColor = input.Color;
output.Geometry.VertexColor = float4(0, 0, 0, 1);
#endif
output.Geometry.LightmapUV = float2(0, 0);

View File

@@ -236,12 +236,6 @@ float3 GetObjectSize(MaterialInput input)
return float3(1, 1, 1);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value
float GetPerInstanceRandom(MaterialInput input)
{
@@ -325,6 +319,8 @@ struct TerrainVertexInput
// Vertex Shader function for terrain rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 1, R8G8B8A8_UNORM, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS(TerrainVertexInput input)
{
VertexOutput output;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,25 +0,0 @@
%copyright%using System;
using System.Collections.Generic;
using FlaxEngine;
namespace %namespace%;
/// <summary>
/// %class% GamePlugin.
/// </summary>
public class %class% : GamePlugin
{
/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();
}
/// <inheritdoc/>
public override void Deinitialize()
{
base.Deinitialize();
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,9 +2,9 @@
"Name": "Flax",
"Version": {
"Major": 1,
"Minor": 10,
"Minor": 9,
"Revision": 0,
"Build": 6702
"Build": 6606
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",

View File

@@ -237,7 +237,6 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/GrammarAndSpelling/GrammarChecking/Exceptions/=Try_0020to_0020scripting/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/GrammarAndSpelling/GrammarChecking/RulesStates/=LanguageTool_002EEN_002EE_005FG/@EntryIndexedValue">DisabledByUser</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/Color/@EntryValue">Blue</s:String>

View File

@@ -31,7 +31,7 @@ Follow the instructions below to compile and run the engine from source.
* Install Visual Studio 2022 or newer
* Install Windows 8.1 SDK or newer (via Visual Studio Installer)
* Install Microsoft Visual C++ 2015 v140 toolset or newer (via Visual Studio Installer)
* Install .NET 8 or 9 SDK for **Windows x64** (via Visual Studio Installer or [from web](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install .NET 8 SDK for **Windows x64** (via Visual Studio Installer or [from web](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install Git with LFS
* Clone repo (with LFS)
* Run **GenerateProjectFiles.bat**
@@ -44,9 +44,8 @@ Follow the instructions below to compile and run the engine from source.
## Linux
* Install Visual Studio Code
* Install .NET 8 or 9 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install .NET 8 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Ubuntu: `sudo apt install dotnet-sdk-8.0`
* Arch: `sudo pacman -S dotnet-sdk-8.0 dotnet-runtime-8.0 dotnet-targeting-pack-8.0 dotnet-host`
* Install Vulkan SDK ([https://vulkan.lunarg.com/](https://vulkan.lunarg.com/))
* Ubuntu: `sudo apt install vulkan-sdk`
* Arch: `sudo pacman -S spirv-tools vulkan-headers vulkan-tools vulkan-validation-layers`
@@ -68,12 +67,12 @@ Follow the instructions below to compile and run the engine from source.
## Mac
* Install XCode
* Install .NET 8 or 9 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install .NET 8 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install Vulkan SDK ([https://vulkan.lunarg.com/](https://vulkan.lunarg.com/))
* Clone repo (with LFS)
* Run `GenerateProjectFiles.command`
* Open workspace with XCode or Visual Studio Code
* Build and run (configuration `Editor.Mac.Development`)
* Build and run (configuration `Editor.Mac.Development`)
#### Troubleshooting

View File

@@ -750,8 +750,7 @@ namespace FlaxEditor.Content
// Draw short name
Render2D.PushClip(ref textRect);
var scale = 0.95f * view.ViewScale;
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, scale);
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, 0.95f);
Render2D.PopClip();
if (IsBeingCut)

View File

@@ -20,7 +20,7 @@ namespace FlaxEditor.Content
}
/// <inheritdoc />
public override string TypeDescription => Path.EndsWith(".h") || Path.EndsWith(".hpp") ? "C++ Header File" : "C++ Source Code";
public override string TypeDescription => Path.EndsWith(".h") ? "C++ Header File" : "C++ Source Code";
/// <inheritdoc />
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CPPScript128;

View File

@@ -106,23 +106,6 @@ namespace FlaxEditor.Content
}
}
/// <summary>
/// Context proxy object for C# GamePlugin files.
/// </summary>
/// <seealso cref="FlaxEditor.Content.CSharpProxy" />
[ContentContextMenu("New/C#/C# GamePlugin")]
public class CSharpGamePluginProxy : CSharpProxy
{
/// <inheritdoc />
public override string Name => "C# GamePlugin";
/// <inheritdoc />
protected override void GetTemplatePath(out string path)
{
path = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/GamePluginTemplate.cs");
}
}
/// <summary>
/// Context proxy object for empty C# files.
/// </summary>

View File

@@ -1,11 +1,9 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using System.Linq;
using FlaxEditor.Content.Create;
using FlaxEditor.CustomEditors;
using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.Scripting;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
@@ -86,67 +84,18 @@ namespace FlaxEditor.Content
if (_element != null)
{
_element.CustomControl.CheckValid += OnCheckValidJsonAssetType;
// Define the rule for the types that can be used to create a json data asset
_element.CustomControl.CheckValid += type =>
type.Type != null &&
type.IsClass &&
type.Type.IsVisible &&
!type.IsAbstract &&
!type.IsGenericType &&
type.Type.GetConstructor(Type.EmptyTypes) != null &&
!typeof(FlaxEngine.GUI.Control).IsAssignableFrom(type.Type) &&
!typeof(FlaxEngine.Object).IsAssignableFrom(type.Type);
}
}
private static Type[] BlacklistedClasses =
[
typeof(System.Attribute),
typeof(FlaxEngine.Object),
typeof(FlaxEngine.GUI.Control),
];
private static Type[] BlacklistedStructs =
[
typeof(Float2),
typeof(Float3),
typeof(Float4),
typeof(Double2),
typeof(Double3),
typeof(Double4),
typeof(Vector2),
typeof(Vector3),
typeof(Vector4),
typeof(Half2),
typeof(Half3),
typeof(Half4),
typeof(Int2),
typeof(Int3),
typeof(Int4),
typeof(Transform),
typeof(Quaternion),
typeof(BoundingBox),
typeof(BoundingSphere),
typeof(BoundingFrustum),
typeof(Ray),
typeof(Plane),
typeof(Matrix),
typeof(Color),
typeof(Color32),
typeof(FloatR11G11B10),
typeof(FloatR10G10B10A2),
typeof(FlaxEngine.Half),
];
private static bool OnCheckValidJsonAssetType(ScriptType type)
{
// Define the rule for the types that can be used to create a json data asset
var mType = type.Type;
if (mType == null ||
type.IsAbstract ||
type.IsStatic ||
type.IsGenericType ||
!mType.IsVisible)
return false;
if (type.IsClass)
return mType.GetConstructor(Type.EmptyTypes) != null && BlacklistedClasses.FirstOrDefault(x => x.IsAssignableFrom(mType)) == null;
if (type.IsStructure)
return !type.IsPrimitive &&
!type.IsVoid &&
!BlacklistedStructs.Contains(mType);
return false;
}
}
}
@@ -226,7 +175,7 @@ namespace FlaxEditor.Content
{
_thumbnail = SpriteHandle.Invalid;
}
/// <summary>
/// Constructor with overriden thumbnail.
/// </summary>
@@ -247,7 +196,7 @@ namespace FlaxEditor.Content
{
Editor.SaveJsonAsset(outputPath, new T());
}
/// <inheritdoc />
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
{

View File

@@ -496,7 +496,7 @@ namespace FlaxEditor.Content.Thumbnails
// Prepare requests
bool isAnyReady = false;
int checks = Mathf.Min(10, _requests.Count);
for (int i = 0; i < checks && i < _requests.Count; i++)
for (int i = 0; i < checks; i++)
{
var request = _requests[i];
try

View File

@@ -671,14 +671,11 @@ bool GameCookerImpl::Build()
MCore::Thread::Attach();
// Build Started
if (!EnumHasAnyFlags(data.Options, BuildOptions::NoCook))
{
CallEvent(GameCooker::EventType::BuildStarted);
data.Tools->OnBuildStarted(data);
for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++)
Steps[stepIndex]->OnBuildStarted(data);
data.InitProgress(Steps.Count());
}
CallEvent(GameCooker::EventType::BuildStarted);
data.Tools->OnBuildStarted(data);
for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++)
Steps[stepIndex]->OnBuildStarted(data);
data.InitProgress(Steps.Count());
// Execute all steps in a sequence
bool failed = false;
@@ -744,13 +741,10 @@ bool GameCookerImpl::Build()
}
IsRunning = false;
CancelFlag = 0;
if (!EnumHasAnyFlags(data.Options, BuildOptions::NoCook))
{
for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++)
Steps[stepIndex]->OnBuildEnded(data, failed);
data.Tools->OnBuildEnded(data, failed);
CallEvent(failed ? GameCooker::EventType::BuildFailed : GameCooker::EventType::BuildDone);
}
for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++)
Steps[stepIndex]->OnBuildEnded(data, failed);
data.Tools->OnBuildEnded(data, failed);
CallEvent(failed ? GameCooker::EventType::BuildFailed : GameCooker::EventType::BuildDone);
Delete(Data);
Data = nullptr;

View File

@@ -364,33 +364,6 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
}
#endif
const bool distributionPackage = buildSettings->ForDistribution || data.Configuration == BuildConfiguration::Release;
if (platformSettings->BuildAAB)
{
// .aab
{
CreateProcessSettings procSettings;
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT(":app:bundle") : TEXT(":app:bundleDebug"));
procSettings.WorkingDirectory = data.OriginalOutputPath;
const int32 result = Platform::CreateProcess(procSettings);
if (result != 0)
{
data.Error(String::Format(TEXT("Failed to build Gradle project into .aab package (result code: {0}). See log for more info."), result));
return true;
}
}
// Copy result package
const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/bundle/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab"));
const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab");
if (FileSystem::CopyFile(outputAab, aab))
{
LOG(Error, "Failed to copy .aab package from {0} to {1}", aab, outputAab);
return true;
}
LOG(Info, "Output Android AAB application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024);
}
// .apk
{
CreateProcessSettings procSettings;
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
@@ -398,20 +371,20 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
const int32 result = Platform::CreateProcess(procSettings);
if (result != 0)
{
data.Error(String::Format(TEXT("Failed to build Gradle project into .apk package (result code: {0}). See log for more info."), result));
data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result));
return true;
}
}
// Copy result package
const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk"));
const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk");
if (FileSystem::CopyFile(outputApk, apk))
{
LOG(Error, "Failed to copy .apk package from {0} to {1}", apk, outputApk);
LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk);
return true;
}
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
return false;
}

View File

@@ -8,7 +8,6 @@
#include "Engine/Core/Math/Color32.h"
#include "Engine/Core/Config/GameSettings.h"
#include "Editor/Utilities/EditorUtilities.h"
#include "Engine/Graphics/PixelFormatSampler.h"
#include "Engine/Graphics/Textures/TextureData.h"
#include "Engine/Tools/TextureTool/TextureTool.h"
#include "Engine/Content/Content.h"
@@ -241,7 +240,7 @@ void UpdateIconData(uint8* iconData, const TextureData* icon)
const TextureMipData* srcPixels = icon->GetData(0, srcPixelsMip);
const Color32* srcPixelsData = (Color32*)srcPixels->Data.Get();
const Int2 srcPixelsSize(Math::Max(1, icon->Width >> srcPixelsMip), Math::Max(1, icon->Height >> srcPixelsMip));
const auto sampler = PixelFormatSampler::Get(icon->Format);
const auto sampler = TextureTool::GetSampler(icon->Format);
ASSERT_LOW_LAYER(sampler);
// Write colors
@@ -253,7 +252,7 @@ void UpdateIconData(uint8* iconData, const TextureData* icon)
for (uint32 x = 0; x < width; x++)
{
float u = (float)x / width;
const Color c = sampler->SampleLinear(srcPixelsData, Float2(u, v), srcPixelsSize, srcPixels->RowPitch);
const Color c = TextureTool::SampleLinear(sampler, Float2(u, v), srcPixelsData, srcPixelsSize, srcPixels->RowPitch);
colorData[idx++] = Color32(c).GetAsBGRA();
}
}
@@ -272,7 +271,7 @@ void UpdateIconData(uint8* iconData, const TextureData* icon)
{
uint32 x = packedX * 8 + pixelIdx;
float u = (float)x / width;
const Color c = sampler->SampleLinear(srcPixelsData, Float2(u, v), srcPixelsSize, srcPixels->RowPitch);
const Color c = TextureTool::SampleLinear(sampler, Float2(u, v), srcPixelsData, srcPixelsSize, srcPixels->RowPitch);
if (c.A < 0.25f)
mask |= 1 << (7 - pixelIdx);
}
@@ -323,7 +322,7 @@ bool UpdateExeIcon(const String& path, const TextureData& icon)
const TextureData* iconRGBA8 = &icon;
TextureData tmpData1;
//if (icon.Format != PixelFormat::R8G8B8A8_UNorm)
if (PixelFormatSampler::Get(icon.Format) == nullptr)
if (TextureTool::GetSampler(icon.Format) == nullptr)
{
if (TextureTool::Convert(tmpData1, *iconRGBA8, PixelFormat::R8G8B8A8_UNorm))
{

View File

@@ -137,7 +137,10 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
if (!FileSystem::DirectoryExists(CacheFolder))
FileSystem::CreateDirectory(CacheFolder);
if (!FileSystem::FileExists(HeaderFilePath))
{
LOG(Warning, "Missing incremental build cooking assets cache.");
return;
}
auto file = FileReadStream::Open(HeaderFilePath);
if (file == nullptr)
@@ -155,7 +158,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
LOG(Info, "Loading incremental build cooking cache (entries count: {0})", entriesCount);
file->ReadBytes(&Settings, sizeof(Settings));
Entries.EnsureCapacity(entriesCount);
Entries.EnsureCapacity(Math::RoundUpToPowerOf2(static_cast<int32>(entriesCount * 3.0f)));
Array<Pair<String, DateTime>> fileDependencies;
for (int32 i = 0; i < entriesCount; i++)
@@ -163,7 +166,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
Guid id;
file->Read(id);
String typeName;
file->Read(typeName);
file->ReadString(&typeName);
DateTime fileModified;
file->Read(fileModified);
int32 fileDependenciesCount;
@@ -173,7 +176,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
for (int32 j = 0; j < fileDependenciesCount; j++)
{
Pair<String, DateTime>& f = fileDependencies[j];
file->Read(f.First, 10);
file->ReadString(&f.First, 10);
file->Read(f.Second);
}
@@ -308,9 +311,9 @@ void CookAssetsStep::CacheData::Save(CookingData& data)
{
auto& e = i->Value;
file->Write(e.ID);
file->Write(e.TypeName);
file->WriteString(e.TypeName);
file->Write(e.FileModified);
file->Write(e.FileDependencies.Count());
file->WriteInt32(e.FileDependencies.Count());
for (auto& f : e.FileDependencies)
{
file->Write(f.First, 10);
@@ -362,27 +365,17 @@ bool CookAssetsStep::ProcessDefaultAsset(AssetCookData& options)
bool CookAssetsStep::Process(CookingData& data, CacheData& cache, Asset* asset)
{
PROFILE_CPU_ASSET(asset);
// Validate asset
if (asset->IsVirtual())
{
// Virtual assets are not included into the build
return false;
}
const bool wasLoaded = asset->IsLoaded();
if (asset->WaitForLoaded())
{
LOG(Error, "Failed to load asset \'{0}\'", asset->ToString());
return true;
}
if (!wasLoaded)
{
// HACK: give some time to resave any old assets in Asset::onLoad after it's loaded
// This assumes that if Load Thread enters Asset::Save then it will get asset lock and hold it until asset is saved
// So we can take the same lock to wait for save end but first we need to wait for it to get that lock
// (in future try to handle it in a better way)
Platform::Sleep(5);
}
ScopeLock lock(asset->Locker);
// Switch based on an asset type
const auto asBinaryAsset = dynamic_cast<BinaryAsset*>(asset);
@@ -800,10 +793,7 @@ bool CookAssetsStep::Process(CookingData& data, CacheData& cache, BinaryAsset* a
// Prepare asset data
AssetInitData initData;
if (asset->Storage->LoadAssetHeader(asset->GetID(), initData))
{
LOG(Warning, "Failed to load asset {} header from storage '{}'", asset->GetID(), asset->Storage->GetPath());
return true;
}
initData.Header.UnlinkChunks();
initData.Metadata.Release();
for (auto& e : initData.Dependencies)
@@ -1175,7 +1165,7 @@ bool CookAssetsStep::Perform(CookingData& data)
assetRef = Content::LoadAsync<Asset>(assetId);
if (assetRef == nullptr)
{
LOG(Error, "Failed to load asset {} included in build", assetId);
data.Error(TEXT("Failed to load asset included in build."));
return true;
}
e.Info.TypeName = assetRef->GetTypeName();
@@ -1183,7 +1173,6 @@ bool CookAssetsStep::Perform(CookingData& data)
// Cook asset
if (Process(data, cache, assetRef.Get()))
{
LOG(Error, "Failed to process asset {}", assetRef->ToString());
cache.Save(data);
return true;
}
@@ -1216,17 +1205,10 @@ bool CookAssetsStep::Perform(CookingData& data)
// Copy file
if (!FileSystem::FileExists(cookedPath) || FileSystem::GetFileLastEditTime(cookedPath) >= FileSystem::GetFileLastEditTime(filePath))
{
const String cookedFolder = StringUtils::GetDirectoryName(cookedPath);
if (FileSystem::CreateDirectory(cookedFolder))
{
LOG(Error, "Failed to create directory '{}'", cookedFolder);
if (FileSystem::CreateDirectory(StringUtils::GetDirectoryName(cookedPath)))
return true;
}
if (FileSystem::CopyFile(cookedPath, filePath))
{
LOG(Error, "Failed to copy file from '{}' to '{}'", filePath, cookedPath);
return true;
}
}
// Count stats of file extension
@@ -1267,7 +1249,7 @@ bool CookAssetsStep::Perform(CookingData& data)
*(int32*)(bytes.Get() + 804) = contentKey;
*(Guid*)(bytes.Get() + 808) = gameSettings->SplashScreen;
Encryption::EncryptBytes(bytes.Get(), bytes.Count());
stream->Write(bytes);
stream->WriteArray(bytes);
Delete(stream);
}

View File

@@ -213,59 +213,11 @@ bool DeployDataStep::Perform(CookingData& data)
}
FileSystem::NormalizePath(srcDotnet);
LOG(Info, "Using .NET Runtime {} at {}", TEXT("Host"), srcDotnet);
const bool srcDotnetFromEngine = srcDotnet.Contains(TEXT("Source/Platforms"));
String packFolder = srcDotnet / TEXT("../../../");
// Get .NET runtime version
String version;
{
// Detect from path provided by build tool
Array<String> pathParts;
srcDotnet.Split('/', pathParts);
for (int32 i = 1; i < pathParts.Count(); i++)
{
if (pathParts[i] == TEXT("runtimes"))
{
Array<String> versionParts;
pathParts[i - 1].Split('.', versionParts);
if (!versionParts.IsEmpty())
{
const String majorVersion = versionParts[0].TrimTrailing();
int32 versionNum;
StringUtils::Parse(*majorVersion, majorVersion.Length(), &versionNum);
if (Math::IsInRange(versionNum, GAME_BUILD_DOTNET_RUNTIME_MIN_VER, GAME_BUILD_DOTNET_RUNTIME_MAX_VER)) // Check for major part
version = majorVersion;
}
}
}
if (version.IsEmpty())
{
if (srcDotnetFromEngine)
{
// Detect version from runtime files inside Engine Platform folder
for (int32 i = GAME_BUILD_DOTNET_RUNTIME_MAX_VER; i >= GAME_BUILD_DOTNET_RUNTIME_MIN_VER; i--)
{
// Check runtime files inside Engine Platform folder
String testPath1 = srcDotnet / String::Format(TEXT("lib/net{}.0"), i);
String testPath2 = packFolder / String::Format(TEXT("Dotnet/lib/net{}.0"), i);
if ((FileSystem::DirectoryExists(testPath1) && FileSystem::GetDirectorySize(testPath1) > 0) ||
(FileSystem::DirectoryExists(testPath2) && FileSystem::GetDirectorySize(testPath2) > 0))
{
version = StringUtils::ToString(i);
break;
}
}
}
if (version.IsEmpty())
{
data.Error(TEXT("Failed to find supported .NET version for the current host platform."));
return true;
}
}
}
// Deploy runtime files
const Char* corlibPrivateName = TEXT("System.Private.CoreLib.dll");
const bool srcDotnetFromEngine = srcDotnet.Contains(TEXT("Source/Platforms"));
String packFolder = srcDotnet / TEXT("../../../");
String dstDotnetLibs = dstDotnet, srcDotnetLibs = srcDotnet;
StringUtils::PathRemoveRelativeParts(packFolder);
if (usAOT)
@@ -274,14 +226,14 @@ bool DeployDataStep::Perform(CookingData& data)
{
// AOT runtime files inside Engine Platform folder
packFolder /= TEXT("Dotnet");
dstDotnetLibs /= String::Format(TEXT("lib/net{}.0"), version);
srcDotnetLibs = packFolder / String::Format(TEXT("lib/net{}.0"), version);
dstDotnetLibs /= TEXT("lib/net8.0");
srcDotnetLibs = packFolder / TEXT("lib/net8.0");
}
else
{
// Runtime files inside Dotnet SDK folder but placed for AOT
dstDotnetLibs /= String::Format(TEXT("lib/net{}.0"), version);
srcDotnetLibs /= String::Format(TEXT("../lib/net{}.0"), version);
dstDotnetLibs /= TEXT("lib/net8.0");
srcDotnetLibs /= TEXT("../lib/net8.0");
}
}
else
@@ -289,14 +241,14 @@ bool DeployDataStep::Perform(CookingData& data)
if (srcDotnetFromEngine)
{
// Runtime files inside Engine Platform folder
dstDotnetLibs /= String::Format(TEXT("lib/net{}.0"), version);
srcDotnetLibs /= String::Format(TEXT("lib/net{}.0"), version);
dstDotnetLibs /= TEXT("lib/net8.0");
srcDotnetLibs /= TEXT("lib/net8.0");
}
else
{
// Runtime files inside Dotnet SDK folder
dstDotnetLibs /= TEXT("shared/Microsoft.NETCore.App");
srcDotnetLibs /= String::Format(TEXT("../lib/net{}.0"), version);
srcDotnetLibs /= TEXT("../lib/net8.0");
}
}
LOG(Info, "Copying .NET files from {} to {}", packFolder, dstDotnet);
@@ -321,7 +273,6 @@ bool DeployDataStep::Perform(CookingData& data)
DEPLOY_NATIVE_FILE("libmonosgen-2.0.so");
DEPLOY_NATIVE_FILE("libSystem.IO.Compression.Native.so");
DEPLOY_NATIVE_FILE("libSystem.Native.so");
DEPLOY_NATIVE_FILE("libSystem.Globalization.Native.so");
DEPLOY_NATIVE_FILE("libSystem.Security.Cryptography.Native.Android.so");
break;
case BuildPlatform::iOSARM64:

View File

@@ -883,7 +883,7 @@ namespace FlaxEditor.CustomEditors
/// </summary>
protected virtual void ClearToken()
{
ParentEditor?.ClearToken();
ParentEditor.ClearToken();
}
}
}

View File

@@ -39,9 +39,14 @@ CustomEditorsUtilService CustomEditorsUtilServiceInstance;
struct Entry
{
MClass* DefaultEditor = nullptr;
MClass* CustomEditor = nullptr;
MType* CustomEditorType = nullptr;
MClass* DefaultEditor;
MClass* CustomEditor;
Entry()
{
DefaultEditor = nullptr;
CustomEditor = nullptr;
}
};
Dictionary<MType*, Entry> Cache(512);
@@ -58,11 +63,11 @@ MTypeObject* CustomEditorsUtil::GetCustomEditor(MTypeObject* refType)
Entry result;
if (Cache.TryGet(type, result))
{
if (result.CustomEditorType)
return INTERNAL_TYPE_GET_OBJECT(result.CustomEditorType);
MClass* editor = result.CustomEditor ? result.CustomEditor : result.DefaultEditor;
if (editor)
{
return MUtils::GetType(editor);
}
}
return nullptr;
}
@@ -152,7 +157,7 @@ void OnAssemblyLoaded(MAssembly* assembly)
else if (typeClass)
{
auto& entry = Cache[mclass->GetType()];
entry.CustomEditorType = type;
entry.CustomEditor = typeClass;
//LOG(Info, "Custom Editor {0} for type {1}", String(typeClass->GetFullName()), String(mclass->GetFullName()));
}

View File

@@ -9,7 +9,6 @@ using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.GUI;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.GUI.Tree;
using FlaxEditor.Modules;
using FlaxEditor.Scripting;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
@@ -68,15 +67,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Use default prefab instance as a reference for the editor
Values.SetReferenceValue(prefabInstance);
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
prefab.GetNestedObject(ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId);
var panel = layout.CustomContainer<UniformGridPanel>();
panel.CustomControl.Height = 20.0f;
panel.CustomControl.SlotsVertically = 1;
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter || nestedPrefab)
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
{
var targetPrefab = nestedPrefab ?? prefab;
// Add some UI
var panel = layout.CustomContainer<UniformGridPanel>();
panel.CustomControl.Height = 20.0f;
panel.CustomControl.SlotsVertically = 1;
panel.CustomControl.SlotsHorizontally = 3;
// Selecting actor prefab asset
@@ -84,21 +80,22 @@ namespace FlaxEditor.CustomEditors.Dedicated
selectPrefab.Button.Clicked += () =>
{
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
Editor.Instance.Windows.ContentWin.Select(targetPrefab);
Editor.Instance.Windows.ContentWin.Select(prefab);
};
// Edit selected prefab asset
var editPrefab = panel.Button("Edit Prefab");
editPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(targetPrefab.ID));
}
else
{
panel.CustomControl.SlotsHorizontally = 1;
}
editPrefab.Button.Clicked += () =>
{
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
Editor.Instance.Windows.ContentWin.Select(prefab);
Editor.Instance.Windows.ContentWin.Open(Editor.Instance.Windows.ContentWin.View.Selection[0]);
};
// Viewing changes applied to this actor
var viewChanges = panel.Button("View Changes");
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
// Viewing changes applied to this actor
var viewChanges = panel.Button("View Changes");
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
}
// Link event to update editor on prefab apply
_linkedPrefabId = prefab.ID;

View File

@@ -1,7 +1,6 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using System.Linq;
using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.Surface;
using FlaxEngine;
@@ -36,8 +35,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
(instance, parameter, tag) => ((AnimatedModel)instance).GetParameterValue(parameter.Identifier),
(instance, value, parameter, tag) => ((AnimatedModel)instance).SetParameterValue(parameter.Identifier, value),
Values);
if (!parameters.Any())
group.Label("No parameters", TextAlignment.Center);
_parametersAdded = true;
}
}

View File

@@ -15,23 +15,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
private int _firstTimeShow;
private BezierCurveEditor<T> _curve;
private Splitter _splitter;
private string _heightCachedPath;
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var item = layout.CustomContainer<BezierCurveEditor<T>>();
_curve = item.CustomControl;
var height = 120.0f;
var presenter = Presenter;
if (presenter != null && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
{
// Try to restore curve height
_heightCachedPath = layout.GetLayoutCachePath("Height");
if (Editor.Instance.ProjectCache.TryGetCustomData(_heightCachedPath, out float cachedHeight) && cachedHeight > 10.0f)
height = cachedHeight;
}
_curve.Height = height;
_curve.Height = 120.0f;
_curve.Edited += OnCurveEdited;
_firstTimeShow = 4; // For some weird reason it needs several frames of warmup (probably due to sliders smoothing)
_splitter = new Splitter
@@ -55,11 +45,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
private void OnSplitterMoved(Float2 location)
{
_curve.Height = Mathf.Clamp(_splitter.PointToParent(location).Y, 50.0f, 1000.0f);
// Cache curve height
if (_heightCachedPath != null)
Editor.Instance.ProjectCache.SetCustomData(_heightCachedPath, _curve.Height);
_curve.Height = Mathf.Clamp(_splitter.PointToParent(location).Y, 50.0f, 1000.0f);
}
/// <inheritdoc />
@@ -147,23 +133,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
private int _firstTimeShow;
private LinearCurveEditor<T> _curve;
private Splitter _splitter;
private string _heightCachedPath;
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var item = layout.CustomContainer<LinearCurveEditor<T>>();
_curve = item.CustomControl;
var height = 120.0f;
var presenter = Presenter;
if (presenter != null && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
{
// Try to restore curve height
_heightCachedPath = layout.GetLayoutCachePath("Height");
if (Editor.Instance.ProjectCache.TryGetCustomData(_heightCachedPath, out float cachedHeight) && cachedHeight > 10.0f)
height = cachedHeight;
}
_curve.Height = height;
_curve.Height = 120.0f;
_curve.Edited += OnCurveEdited;
_firstTimeShow = 4; // For some weird reason it needs several frames of warmup (probably due to sliders smoothing)
_splitter = new Splitter
@@ -188,10 +164,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
private void OnSplitterMoved(Float2 location)
{
_curve.Height = Mathf.Clamp(_splitter.PointToParent(location).Y, 50.0f, 1000.0f);
// Cache curve height
if (_heightCachedPath != null)
Editor.Instance.ProjectCache.SetCustomData(_heightCachedPath, _curve.Height);
}
/// <inheritdoc />

View File

@@ -186,12 +186,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
foreach (var file in files)
FindNewKeysCSharp(file, newKeys, allKeys);
// C/C++
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.cpp", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.c", SearchOption.AllDirectories)).ToArray();
// C++
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.cpp", SearchOption.AllDirectories);
filesCount += files.Length;
foreach (var file in files)
FindNewKeysCpp(file, newKeys, allKeys);
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.hpp", SearchOption.AllDirectories)).ToArray();;
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories);
filesCount += files.Length;
foreach (var file in files)
FindNewKeysCpp(file, newKeys, allKeys);

View File

@@ -53,9 +53,6 @@ public class ModelPrefabEditor : GenericEditor
}
}
// Creates the import path UI
Utilities.Utils.CreateImportPathUI(layout, modelPrefab.ImportPath, false);
var button = layout.Button("Reimport", "Reimports the source asset as prefab.");
_reimportButton = button.Button;
_reimportButton.Clicked += OnReimport;

View File

@@ -117,9 +117,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
var data = SurfaceUtils.InitGraphParameters(parametersGroup);
SurfaceUtils.DisplayGraphParameters(group, data, ParameterGet, ParameterSet, Values, ParameterDefaultValue);
}
if (!parameters.Any())
groups.Label("No parameters", TextAlignment.Center);
}
/// <inheritdoc />

View File

@@ -92,7 +92,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
{
if (IsLinearTangentMode(spline, index) || IsSmoothInTangentMode(spline, index) || IsSmoothOutTangentMode(spline, index))
{
SetPointSmooth(Editor, spline, index);
SetPointSmooth(spline, index);
}
}
}
@@ -145,7 +145,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
{
if (!IsAlignedTangentMode(spline, index))
{
SetPointSmooth(Editor, spline, index);
SetPointSmooth(spline, index);
}
}
@@ -176,7 +176,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
/// <inheritdoc/>
public override void OnSetMode(Spline spline, int index)
{
SetTangentSmoothIn(Editor, spline, index);
SetTangentSmoothIn(spline, index);
Editor.SetSelectTangentIn(spline, index);
}
}
@@ -190,7 +190,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
/// <inheritdoc/>
public override void OnSetMode(Spline spline, int index)
{
SetTangentSmoothOut(Editor, spline, index);
SetTangentSmoothOut(spline, index);
Editor.SetSelectTangentOut(spline, index);
}
}
@@ -756,15 +756,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
spline.UpdateSpline();
}
private static void SetTangentSmoothIn(SplineEditor editor, Spline spline, int index)
private static void SetTangentSmoothIn(Spline spline, int index)
{
var keyframe = spline.GetSplineKeyframe(index);
// Auto smooth tangent if's linear
if (keyframe.TangentIn.Translation.Length == 0)
{
var cameraTransform = editor.Presenter.Owner.PresenterViewport.ViewTransform.Translation;
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplineTangent(index, false).Translation, 10f, cameraTransform);
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplineTangent(index, false).Translation, 10f);
var previousKeyframe = spline.GetSplineKeyframe(index - 1);
var tangentDirection = keyframe.Value.WorldToLocalVector(previousKeyframe.Value.Translation - keyframe.Value.Translation);
tangentDirection = tangentDirection.Normalized * smoothRange;
@@ -776,15 +775,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
spline.UpdateSpline();
}
private static void SetTangentSmoothOut(SplineEditor editor, Spline spline, int index)
private static void SetTangentSmoothOut(Spline spline, int index)
{
var keyframe = spline.GetSplineKeyframe(index);
// Auto smooth tangent if's linear
if (keyframe.TangentOut.Translation.Length == 0)
{
var cameraTransform = editor.Presenter.Owner.PresenterViewport.ViewTransform.Translation;
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplineTangent(index, false).Translation, 10f, cameraTransform);
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplineTangent(index, false).Translation, 10f);
var nextKeyframe = spline.GetSplineKeyframe(index + 1);
var tangentDirection = keyframe.Value.WorldToLocalVector(nextKeyframe.Value.Translation - keyframe.Value.Translation);
tangentDirection = tangentDirection.Normalized * smoothRange;
@@ -797,7 +795,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
spline.UpdateSpline();
}
private static void SetPointSmooth(SplineEditor editor, Spline spline, int index)
private static void SetPointSmooth(Spline spline, int index)
{
var keyframe = spline.GetSplineKeyframe(index);
var tangentInSize = keyframe.TangentIn.Translation.Length;
@@ -805,8 +803,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var isLastKeyframe = index >= spline.SplinePointsCount - 1;
var isFirstKeyframe = index <= 0;
var cameraTransform = editor.Presenter.Owner.PresenterViewport.ViewTransform.Translation;
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplinePoint(index), 10f, cameraTransform);
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplinePoint(index), 10f);
// Force smooth it's linear point
if (tangentInSize == 0f)

View File

@@ -4,7 +4,6 @@ using System;
using System.Linq;
using FlaxEditor.Content;
using FlaxEditor.GUI;
using FlaxEditor.GUI.Drag;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -95,7 +94,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (assetReference != null)
{
if (assetReference.UseSmallPicker)
height = 36;
height = 32;
if (string.IsNullOrEmpty(assetReference.TypeName))
{
}
@@ -123,9 +122,7 @@ namespace FlaxEditor.CustomEditors.Editors
{
base.Refresh();
var differentValues = HasDifferentValues;
Picker.DifferentValues = differentValues;
if (!differentValues)
if (!HasDifferentValues)
{
_isRefreshing = true;
var value = Values[0];
@@ -159,17 +156,6 @@ namespace FlaxEditor.CustomEditors.Editors
private Rectangle DropdownRect => new Rectangle(Width - DropdownIconSize - DropdownIconMargin, DropdownIconMargin, DropdownIconSize, DropdownIconSize);
public Action ShowPicker;
public Action<ContentItem> OnAssetDropped;
private DragItems _dragItems;
private DragHandlers _dragHandlers;
private bool _hasValidDragOver;
private Func<ContentItem, bool> _validate;
public void SetValidationMethod(Func<ContentItem, bool> validate)
{
_validate = validate;
}
public override void Draw()
{
@@ -178,14 +164,6 @@ namespace FlaxEditor.CustomEditors.Editors
var style = FlaxEngine.GUI.Style.Current;
var dropdownRect = DropdownRect;
Render2D.DrawSprite(style.ArrowDown, dropdownRect, Enabled ? (DropdownRect.Contains(PointFromWindow(RootWindow.MousePosition)) ? style.BorderSelected : style.Foreground) : style.ForegroundDisabled);
// Check if drag is over
if (IsDragOver && _hasValidDragOver)
{
var bounds = new Rectangle(Float2.Zero, Size);
Render2D.FillRectangle(bounds, style.Selection);
Render2D.DrawRectangle(bounds, style.SelectionBorder);
}
}
public override bool OnMouseDown(Float2 location, MouseButton button)
@@ -229,68 +207,6 @@ namespace FlaxEditor.CustomEditors.Editors
return result;
}
}
private DragDropEffect DragEffect => _hasValidDragOver ? DragDropEffect.Move : DragDropEffect.None;
/// <inheritdoc />
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
{
base.OnDragEnter(ref location, data);
// Ensure to have valid drag helpers (uses lazy init)
if (_dragItems == null)
_dragItems = new DragItems(ValidateDragAsset);
if (_dragHandlers == null)
{
_dragHandlers = new DragHandlers
{
_dragItems,
};
}
_hasValidDragOver = _dragHandlers.OnDragEnter(data) != DragDropEffect.None;
return DragEffect;
}
private bool ValidateDragAsset(ContentItem contentItem)
{
// Load or get asset
return _validate?.Invoke(contentItem) ?? false;
}
/// <inheritdoc />
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
{
base.OnDragMove(ref location, data);
return DragEffect;
}
/// <inheritdoc />
public override void OnDragLeave()
{
_hasValidDragOver = false;
_dragHandlers.OnDragLeave();
base.OnDragLeave();
}
/// <inheritdoc />
public override DragDropEffect OnDragDrop(ref Float2 location, DragData data)
{
var result = DragEffect;
base.OnDragDrop(ref location, data);
if (_dragItems.HasValidDrag)
{
OnAssetDropped(_dragItems.Objects[0]);
}
return result;
}
}
private TextBoxWithPicker _textBox;
@@ -305,21 +221,13 @@ namespace FlaxEditor.CustomEditors.Editors
{
if (HasDifferentTypes)
return;
_validator = new AssetPickerValidator(ScriptType.Null);
_textBox = layout.Custom<TextBoxWithPicker>().CustomControl;
_textBox.ShowPicker = OnShowPicker;
_textBox.OnAssetDropped = OnItemDropped;
_textBox.EditEnd += OnEditEnd;
_textBox.SetValidationMethod(_validator.IsValid);
_validator = new AssetPickerValidator(ScriptType.Null);
AssetRefEditor.ApplyAssetReferenceAttribute(Values, out _, _validator);
}
private void OnItemDropped(ContentItem item)
{
SetPickerPath(item);
}
private void OnShowPicker()
{
if (_validator.AssetType != ScriptType.Null)
@@ -377,9 +285,12 @@ namespace FlaxEditor.CustomEditors.Editors
{
base.Refresh();
_isRefreshing = true;
_textBox.Text = HasDifferentValues ? "Multiple Values" : GetPath();
_isRefreshing = false;
if (!HasDifferentValues)
{
_isRefreshing = true;
_textBox.Text = GetPath();
_isRefreshing = false;
}
}
/// <inheritdoc />

Some files were not shown because too many files have changed in this diff Show More