Merge branch '1.5' into dotnet7

This commit is contained in:
2022-12-21 10:35:58 +01:00
330 changed files with 3405 additions and 1555 deletions
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.
@@ -2,6 +2,7 @@
// Version: @0
#define MATERIAL 1
#define USE_PER_VIEW_CONSTANTS 1
@3
#include "./Flax/Common.hlsl"
@@ -10,17 +11,9 @@
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float4x4 InvWorld;
float4x4 SVPositionToWorld;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
@1META_CB_END
// Use depth buffer for per-pixel decal layering
@@ -2,6 +2,7 @@
// Version: @0
#define MATERIAL 1
#define USE_PER_VIEW_CONSTANTS 1
@3
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
@@ -9,23 +10,14 @@
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 LocalMatrix;
float4x4 ViewMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
float3 Dummy0;
float WorldDeterminantSign;
float MeshMinZ;
float Segment;
float ChunksPerSegment;
float PerInstanceRandom;
float4 TemporalAAJitter;
float3 GeometrySize;
float MeshMaxZ;
@1META_CB_END
@@ -2,6 +2,7 @@
// Version: @0
#define MATERIAL 1
#define USE_PER_VIEW_CONSTANTS 1
@3
// Ribbons don't use sorted indices so overlap the segment distances buffer on the slot
#define HAS_SORTED_INDICES (!defined(_VS_Ribbon))
@@ -19,15 +20,7 @@ struct SpriteInput
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
uint SortedIndicesOffset;
float PerInstanceRandom;
int ParticleStride;
@@ -2,6 +2,7 @@
// Version: @0
#define MATERIAL 1
#define USE_PER_VIEW_CONSTANTS 1
@3
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
@@ -9,23 +10,11 @@
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float4x4 PrevViewProjectionMatrix;
float4x4 PrevWorldMatrix;
float4x4 MainViewProjectionMatrix;
float4 MainScreenSize;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
float2 Dummy0;
float LODDitherFactor;
float PerInstanceRandom;
float4 TemporalAAJitter;
float3 GeometrySize;
float WorldDeterminantSign;
@1META_CB_END
@@ -2,6 +2,7 @@
// Version: @0
#define MATERIAL 1
#define USE_PER_VIEW_CONSTANTS 1
@3
// Enables/disables smooth terrain chunks LOD transitions (with morphing higher LOD near edges to the lower LOD in the neighbour)
#define USE_SMOOTH_LOD_TRANSITION 1
@@ -16,15 +17,7 @@
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
float3 WorldInvScale;
float WorldDeterminantSign;
float PerInstanceRandom;
@@ -2,6 +2,7 @@
// Version: @0
#define MATERIAL 1
#define USE_PER_VIEW_CONSTANTS 1
@3
#include "./Flax/Common.hlsl"
@@ -11,17 +12,9 @@
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 InverseViewProjectionMatrix;
float4x4 ViewMatrix;
float4x4 WorldMatrix;
float4x4 WorldMatrixInverseTransposed;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
float3 GridSize;
float PerInstanceRandom;
float Dummy0;
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.
@@ -7,6 +7,7 @@
#include "Engine/Core/Log.h"
#include "Engine/Core/Math/Vector2.h"
#include "Engine/Core/Types/DateTime.h"
#include "Engine/Core/Types/TimeSpan.h"
#include "Editor/Editor.h"
#include "Editor/ProjectInfo.h"
#include "Engine/Engine/EngineService.h"
@@ -497,6 +497,8 @@ bool UWPPlatformTools::OnPerformAOT(CookingData& data, AotConfig& config, const
bool UWPPlatformTools::OnPostProcess(CookingData& data)
{
LOG(Error, "UWP (Windows Store) platform has been deprecated and soon will be removed!");
// Special case for UWP
// FlaxEngine.dll cannot be added to the solution as `Content` item (due to conflicts with C++ /CX FlaxEngine.dll)
// Use special directory for it (generated UWP project handles this case and copies lib to the output)
@@ -115,6 +115,8 @@ bool DeployDataStep::Perform(CookingData& data)
auto& buildSettings = *BuildSettings::Get();
for (auto& e : buildSettings.AdditionalAssets)
data.AddRootAsset(e.GetID());
for (auto& e : buildSettings.AdditionalScenes)
data.AddRootAsset(e.ID);
Array<String> files;
for (auto& e : buildSettings.AdditionalAssetFolders)
{
@@ -225,7 +225,8 @@ namespace FlaxEditor.CustomEditors.Editors
}
private static HashSet<PropertiesList> _visibleIfPropertiesListsCache;
private static Dictionary<string, GroupElement> _groups;
private static Stack<Dictionary<string, GroupElement>> _groups;
private static List<Dictionary<string, GroupElement>> _groupsPool;
private VisibleIfCache[] _visibleIfCaches;
private bool _isNull;
@@ -514,17 +515,38 @@ namespace FlaxEditor.CustomEditors.Editors
menu.Show(groupPanel, location);
}
internal static void OnGroupUsage()
internal static void OnGroupsBegin()
{
if (_groups != null)
_groups.Clear();
if (_groups == null)
_groups = new Stack<Dictionary<string, GroupElement>>();
if (_groupsPool == null)
_groupsPool = new List<Dictionary<string, GroupElement>>();
Dictionary<string, GroupElement> group;
if (_groupsPool.Count != 0)
{
group = _groupsPool[0];
_groupsPool.RemoveAt(0);
}
else
{
group = new Dictionary<string, GroupElement>();
}
_groups.Push(group);
}
internal static void OnGroupsEnd()
{
var groups = _groups.Pop();
groups.Clear();
_groupsPool.Add(groups);
}
internal static LayoutElementsContainer OnGroup(LayoutElementsContainer layout, EditorDisplayAttribute display)
{
if (display?.Group != null)
{
if (_groups != null && _groups.TryGetValue(display.Group, out var group))
var groups = _groups.Peek();
if (groups.TryGetValue(display.Group, out var group))
{
// Reuse group
layout = group;
@@ -532,12 +554,10 @@ namespace FlaxEditor.CustomEditors.Editors
else
{
// Add new group
if (_groups == null)
_groups = new Dictionary<string, GroupElement>();
group = layout.Group(display.Group);
group.Panel.Tag = group;
group.Panel.MouseButtonRightClicked += OnGroupPanelMouseButtonRightClicked;
_groups.Add(display.Group, group);
groups.Add(display.Group, group);
layout = group;
}
}
@@ -713,7 +733,7 @@ namespace FlaxEditor.CustomEditors.Editors
items.Sort();
// Add items
OnGroupUsage();
OnGroupsBegin();
for (int i = 0; i < items.Count; i++)
{
var item = items[i];
@@ -759,7 +779,7 @@ namespace FlaxEditor.CustomEditors.Editors
} while (c != null);
}
}
OnGroupUsage();
OnGroupsEnd();
}
/// <inheritdoc />
@@ -37,6 +37,16 @@ namespace FlaxEditor.GUI.Docking
// Focus window
window.Focus();
// Check if window is maximized and restore window.
if (window.IsMaximized)
{
// Restore window and set position to mouse.
var mousePos = window.MousePosition;
var previousSize = window.Size;
window.Restore();
window.Position = FlaxEngine.Input.MouseScreenPosition - mousePos * window.Size / previousSize;
}
// Calculate dragging offset and move window to the destination position
var mouseScreenPosition = FlaxEngine.Input.MouseScreenPosition;
@@ -51,10 +51,6 @@ namespace FlaxEditor.GUI.Docking
if (_window == null)
return;
// Check if window is maximized
if (_window.IsMaximized)
return;
// Create docking hint window
DockHintWindow.Create(this);
}
+14
View File
@@ -81,6 +81,20 @@ namespace FlaxEditor.GUI
private bool IsInputValid => !string.IsNullOrWhiteSpace(_inputField.Text) && (_inputField.Text == _startValue || Validate == null || Validate(this, _inputField.Text));
/// <inheritdoc />
public override void Update(float deltaTime)
{
var mouseLocation = Root.MousePosition;
if (!ContainsPoint(ref mouseLocation) && RootWindow.ContainsFocus && Text != _startValue)
{
// rename item before closing if left mouse button in clicked
if (FlaxEngine.Input.GetMouseButtonDown(MouseButton.Left))
OnEnd();
}
base.Update(deltaTime);
}
private void OnTextChanged()
{
if (Validate == null)
+89
View File
@@ -1,5 +1,6 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using System;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -192,4 +193,92 @@ namespace FlaxEditor.GUI
}
}
}
/// <summary>
/// The table row that contains events for mouse interaction.
/// </summary>
[HideInEditor]
public class ClickableRow : Row
{
private bool _leftClick;
private bool _isRightDown;
/// <summary>
/// The double click event.
/// </summary>
public Action DoubleClick;
/// <summary>
/// The left mouse button click event.
/// </summary>
public Action LeftClick;
/// <summary>
/// The right mouse button click event.
/// </summary>
public Action RightClick;
/// <summary>
/// The double click event.
/// </summary>
public Action<ClickableRow> RowDoubleClick;
/// <summary>
/// The left mouse button click event.
/// </summary>
public Action<ClickableRow> RowLeftClick;
/// <summary>
/// The right mouse button click event.
/// </summary>
public Action<ClickableRow> RowRightClick;
/// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{
DoubleClick?.Invoke();
RowDoubleClick?.Invoke(this);
return base.OnMouseDoubleClick(location, button);
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
if (button == MouseButton.Left)
_leftClick = true;
else if (button == MouseButton.Right)
_isRightDown = true;
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _leftClick)
{
_leftClick = false;
LeftClick?.Invoke();
RowLeftClick?.Invoke(this);
}
else if (button == MouseButton.Right && _isRightDown)
{
_isRightDown = false;
RightClick?.Invoke();
RowRightClick?.Invoke(this);
}
return base.OnMouseUp(location, button);
}
/// <inheritdoc />
public override void OnMouseLeave()
{
_leftClick = false;
_isRightDown = false;
base.OnMouseLeave();
}
}
}
@@ -25,7 +25,7 @@ namespace FlaxEditor.SceneGraph.Actors
{
base.OnContextMenu(contextMenu);
contextMenu.AddButton("Add mesh collider", OnAddMeshCollider).Enabled = ((StaticModel)Actor).Model != null;
contextMenu.AddButton("Add collider", OnAddMeshCollider).Enabled = ((StaticModel)Actor).Model != null;
}
private void OnAddMeshCollider()
@@ -33,6 +33,56 @@ namespace FlaxEditor.SceneGraph.Actors
var model = ((StaticModel)Actor).Model;
if (!model)
return;
// Special case for in-built Editor models that can use analytical collision
var modelPath = model.Path;
if (modelPath.EndsWith("/Primitives/Cube.flax", StringComparison.Ordinal))
{
var actor = new BoxCollider
{
StaticFlags = Actor.StaticFlags,
Transform = Actor.Transform,
};
Editor.Instance.SceneEditing.Spawn(actor, Actor);
return;
}
if (modelPath.EndsWith("/Primitives/Sphere.flax", StringComparison.Ordinal))
{
var actor = new SphereCollider
{
StaticFlags = Actor.StaticFlags,
Transform = Actor.Transform,
};
Editor.Instance.SceneEditing.Spawn(actor, Actor);
return;
}
if (modelPath.EndsWith("/Primitives/Plane.flax", StringComparison.Ordinal))
{
var actor = new BoxCollider
{
StaticFlags = Actor.StaticFlags,
Transform = Actor.Transform,
Size = new Float3(100.0f, 100.0f, 1.0f),
};
Editor.Instance.SceneEditing.Spawn(actor, Actor);
return;
}
if (modelPath.EndsWith("/Primitives/Capsule.flax", StringComparison.Ordinal))
{
var actor = new CapsuleCollider
{
StaticFlags = Actor.StaticFlags,
Transform = Actor.Transform,
Radius = 25.0f,
Height = 50.0f,
};
Editor.Instance.SceneEditing.Spawn(actor, Actor);
actor.LocalPosition = new Vector3(0, 50.0f, 0);
actor.LocalOrientation = Quaternion.Euler(0, 0, 90.0f);
return;
}
// Create collision data (or reuse) and add collision actor
Action<CollisionData> created = collisionData =>
{
var actor = new MeshCollider
+10 -1
View File
@@ -148,7 +148,16 @@ namespace FlaxEditor.Surface
public void GetConnectionColor(ScriptType type, ConnectionsHint hint, out Color color)
{
if (type == ScriptType.Null)
color = Colors.Default;
{
if (hint == ConnectionsHint.Vector)
color = Colors.Vector;
else if (hint == ConnectionsHint.Scalar)
color = Colors.Float;
else if (hint == ConnectionsHint.Enum)
color = Colors.Enum;
else
color = Colors.Default;
}
else if (type.IsPointer || type.IsReference)
{
// Find underlying type without `*` or `&`
+2 -2
View File
@@ -286,7 +286,7 @@ namespace FlaxEditor.Surface
internal static void DisplayGraphParameters(LayoutElementsContainer layout, GraphParameterData[] data, GetGraphParameterDelegate getter, SetGraphParameterDelegate setter, ValueContainer values, GetGraphParameterDelegate defaultValueGetter = null, CustomPropertySpawnDelegate propertySpawn = null)
{
CustomEditors.Editors.GenericEditor.OnGroupUsage();
CustomEditors.Editors.GenericEditor.OnGroupsBegin();
for (int i = 0; i < data.Length; i++)
{
ref var e = ref data[i];
@@ -333,7 +333,7 @@ namespace FlaxEditor.Surface
else
propertySpawn(itemLayout, valueContainer, ref e);
}
CustomEditors.Editors.GenericEditor.OnGroupUsage();
CustomEditors.Editors.GenericEditor.OnGroupsEnd();
}
internal static string GetMethodDisplayName(string methodName)
@@ -372,7 +372,7 @@ namespace FlaxEditor.Surface
return;
}
var parameters = window.VisjectSurface.Parameters;
CustomEditors.Editors.GenericEditor.OnGroupUsage();
CustomEditors.Editors.GenericEditor.OnGroupsBegin();
for (int i = 0; i < parameters.Count; i++)
{
var p = parameters[i];
@@ -429,7 +429,7 @@ namespace FlaxEditor.Surface
var property = itemLayout.AddPropertyItem(propertyLabel, tooltipText);
property.Property("Value", propertyValue);
}
CustomEditors.Editors.GenericEditor.OnGroupUsage();
CustomEditors.Editors.GenericEditor.OnGroupsEnd();
// Parameters creating
var newParameterTypes = window.NewParameterTypes;
+14 -2
View File
@@ -131,7 +131,7 @@ namespace FlaxEditor.Windows
ScrollBars = ScrollBars.Both,
Parent = _split.Panel1,
};
// Content structure tree
_tree = new Tree(false)
{
@@ -179,7 +179,7 @@ namespace FlaxEditor.Windows
ScrollBars = ScrollBars.Vertical,
Parent = _split.Panel2,
};
// Content View
_view = new ContentView
{
@@ -895,6 +895,18 @@ namespace FlaxEditor.Windows
}
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
// Navigate through directories using the side mouse buttons
if (button == MouseButton.Extended1)
NavigateBackward();
else if (button == MouseButton.Extended2)
NavigateForward();
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
@@ -257,6 +257,7 @@ namespace FlaxEditor.Windows
break;
case PlatformType.UWP:
name = "Windows Store";
layout.Label("UWP (Windows Store) platform has been deprecated and soon will be removed!", TextAlignment.Center).Label.TextColor = Color.Red;
break;
case PlatformType.Linux:
name = "Linux";
@@ -113,6 +113,17 @@ namespace FlaxEditor.Windows
set => MainRenderTask.Instance.RenderingPercentage = value;
}
[NoSerialize, DefaultValue(RenderingUpscaleLocation.AfterAntiAliasingPass), VisibleIf(nameof(UpscaleLocation_Visible))]
[EditorOrder(1401), EditorDisplay("Quality")]
[Tooltip("The image resolution upscale location within rendering pipeline.")]
public RenderingUpscaleLocation UpscaleLocation
{
get => MainRenderTask.Instance.UpscaleLocation;
set => MainRenderTask.Instance.UpscaleLocation = value;
}
private bool UpscaleLocation_Visible => MainRenderTask.Instance.RenderingPercentage < 1.0f;
[NoSerialize, DefaultValue(1.0f), Limit(0, 1)]
[EditorOrder(1500), EditorDisplay("Quality"), Tooltip("The global density scale for all foliage instances. The default value is 1. Use values from range 0-1. Lower values decrease amount of foliage instances in-game. Use it to tweak game performance for slower devices.")]
public float FoliageDensityScale
+293
View File
@@ -0,0 +1,293 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.Text;
using FlaxEditor.GUI;
using FlaxEngine;
using FlaxEngine.Json;
using FlaxEngine.GUI;
using FlaxEditor.GUI.ContextMenu;
namespace FlaxEditor.Windows.Profiler
{
/// <summary>
/// The Assets profiling mode.
/// </summary>
/// <seealso cref="FlaxEditor.Windows.Profiler.ProfilerMode" />
internal sealed class Assets : ProfilerMode
{
private struct Resource
{
public string Name;
public string TypeName;
public int ReferencesCount;
public ulong MemoryUsage;
public Guid AssetId;
}
private readonly SingleChart _memoryUsageChart;
private readonly Table _table;
private SamplesBuffer<Resource[]> _resources;
private List<ClickableRow> _tableRowsCache;
private Dictionary<Guid, Resource> _resourceCache;
private StringBuilder _stringBuilder;
public Assets()
: base("Assets")
{
// Layout
var panel = new Panel(ScrollBars.Vertical)
{
AnchorPreset = AnchorPresets.StretchAll,
Offsets = Margin.Zero,
Parent = this,
};
var layout = new VerticalPanel
{
AnchorPreset = AnchorPresets.HorizontalStretchTop,
Offsets = Margin.Zero,
IsScrollable = true,
Parent = panel,
};
// Chart
_memoryUsageChart = new SingleChart
{
Title = "Assets Memory Usage (CPU)",
FormatSample = v => Utilities.Utils.FormatBytesCount((int)v),
Parent = layout,
};
_memoryUsageChart.SelectedSampleChanged += OnSelectedSampleChanged;
// Table
var headerColor = Style.Current.LightBackground;
_table = new Table
{
Columns = new[]
{
new ColumnDefinition
{
UseExpandCollapseMode = true,
CellAlignment = TextAlignment.Near,
Title = "Resource",
TitleBackgroundColor = headerColor,
},
new ColumnDefinition
{
Title = "Type",
CellAlignment = TextAlignment.Center,
TitleBackgroundColor = headerColor,
},
new ColumnDefinition
{
Title = "References",
TitleBackgroundColor = headerColor,
},
new ColumnDefinition
{
Title = "Memory Usage",
TitleBackgroundColor = headerColor,
FormatValue = v => Utilities.Utils.FormatBytesCount((ulong)v),
},
},
Parent = layout,
};
_table.Splits = new[]
{
0.6f,
0.2f,
0.08f,
0.12f,
};
}
/// <inheritdoc />
public override void Clear()
{
_memoryUsageChart.Clear();
_resources?.Clear();
_resourceCache?.Clear();
}
/// <inheritdoc />
public override void Update(ref SharedUpdateData sharedData)
{
if (_resourceCache == null)
_resourceCache = new Dictionary<Guid, Resource>();
if (_stringBuilder == null)
_stringBuilder = new StringBuilder();
// Capture current assets usage info
var assets = FlaxEngine.Content.Assets;
var sb = _stringBuilder;
var resources = new Resource[assets.Length];
var contentDatabase = Editor.Instance.ContentDatabase;
ulong totalMemoryUsage = 0;
for (int i = 0; i < resources.Length; i++)
{
var asset = assets[i];
if (!asset)
continue;
// Try to reuse cached resource info
var assetId = asset.ID;
if (!_resourceCache.TryGetValue(assetId, out var resource))
{
resource = new Resource
{
Name = asset.Path,
TypeName = asset.TypeName,
AssetId = assetId,
};
var typeNameEnding = asset.TypeName.LastIndexOf('.');
if (typeNameEnding != -1)
resource.TypeName = resource.TypeName.Substring(typeNameEnding + 1);
var assetItem = Editor.Instance.ContentDatabase.FindAsset(assetId);
if (assetItem != null)
{
resource.Name = assetItem.NamePath;
}
if (string.IsNullOrEmpty(resource.Name) && asset.IsVirtual)
resource.Name = "<virtual>";
_resourceCache.Add(assetId, resource);
}
resource.MemoryUsage = asset.MemoryUsage;
totalMemoryUsage += resource.MemoryUsage;
resource.ReferencesCount = asset.ReferencesCount;
resources[i] = resource;
}
_memoryUsageChart.AddSample((float)totalMemoryUsage);
Array.Sort(resources, SortResources);
if (_resources == null)
_resources = new SamplesBuffer<Resource[]>();
_resources.Add(resources);
}
/// <inheritdoc />
public override void UpdateView(int selectedFrame, bool showOnlyLastUpdateEvents)
{
_memoryUsageChart.SelectedSampleIndex = selectedFrame;
if (_resources == null)
return;
if (_tableRowsCache == null)
_tableRowsCache = new List<ClickableRow>();
UpdateTable();
}
/// <inheritdoc />
public override void OnDestroy()
{
_resources?.Clear();
_resourceCache?.Clear();
_tableRowsCache?.Clear();
_stringBuilder?.Clear();
base.OnDestroy();
}
private static int SortResources(Resource a, Resource b)
{
return (int)(b.MemoryUsage - a.MemoryUsage);
}
private void UpdateTable()
{
_table.IsLayoutLocked = true;
int idx = 0;
while (_table.Children.Count > idx)
{
var child = _table.Children[idx];
if (child is ClickableRow row)
{
_tableRowsCache.Add(row);
child.Parent = null;
}
else
{
idx++;
}
}
_table.LockChildrenRecursive();
UpdateTableInner();
_table.UnlockChildrenRecursive();
_table.PerformLayout();
}
private void UpdateTableInner()
{
if (_resources.Count == 0)
return;
var resources = _resources.Get(_memoryUsageChart.SelectedSampleIndex);
if (resources == null || resources.Length == 0)
return;
// Add rows
var rowColor2 = Style.Current.Background * 1.4f;
for (int i = 0; i < resources.Length; i++)
{
ref var e = ref resources[i];
ClickableRow row;
if (_tableRowsCache.Count != 0)
{
// Reuse row
var last = _tableRowsCache.Count - 1;
row = _tableRowsCache[last];
_tableRowsCache.RemoveAt(last);
}
else
{
// Allocate new row
row = new ClickableRow { Values = new object[4] };
row.RowDoubleClick = OnRowDoubleClick;
row.RowRightClick = OnRowRightClick;
}
// Setup row data
row.Tag = e.AssetId;
row.Values[0] = e.Name;
row.Values[1] = e.TypeName;
row.Values[2] = e.ReferencesCount;
row.Values[3] = e.MemoryUsage;
// Add row to the table
row.Width = _table.Width;
row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent;
row.Parent = _table;
}
}
private void OnRowDoubleClick(ClickableRow row)
{
var assetId = (Guid)row.Tag;
var assetItem = Editor.Instance.ContentDatabase.FindAsset(assetId);
if (assetItem != null)
Editor.Instance.ContentEditing.Open(assetItem);
}
private void OnRowRightClick(ClickableRow row)
{
var assetId = (Guid)row.Tag;
var assetItem = Editor.Instance.ContentDatabase.FindAsset(assetId);
if (assetItem != null)
{
var cm = new ContextMenu();
ContextMenuButton b;
b = cm.AddButton("Open", () => Editor.Instance.ContentEditing.Open(assetItem));
cm.AddButton("Show in content window", () => Editor.Instance.Windows.ContentWin.Select(assetItem));
cm.AddButton("Show in explorer", () => FileSystem.ShowFileExplorer(System.IO.Path.GetDirectoryName(assetItem.Path)));
cm.AddButton("Select actors using this asset", () => Editor.Instance.SceneEditing.SelectActorsUsingAsset(assetItem.ID));
cm.AddButton("Show asset references graph", () => Editor.Instance.Windows.Open(new AssetReferencesGraphWindow(Editor.Instance, assetItem)));
cm.AddButton("Copy name", () => Clipboard.Text = assetItem.NamePath);
cm.AddButton("Copy path", () => Clipboard.Text = assetItem.Path);
cm.AddButton("Copy asset ID", () => Clipboard.Text = JsonSerializer.GetStringID(assetItem.ID));
cm.Show(row, row.PointFromScreen(Input.MouseScreenPosition));
}
}
}
}
-1
View File
@@ -205,7 +205,6 @@ namespace FlaxEditor.Windows.Profiler
/// <inheritdoc />
public override void OnDestroy()
{
Clear();
_timelineLabelsCache?.Clear();
_timelineEventsCache?.Clear();
_tableRowsCache?.Clear();
-1
View File
@@ -166,7 +166,6 @@ namespace FlaxEditor.Windows.Profiler
/// <inheritdoc />
public override void OnDestroy()
{
Clear();
_timelineEventsCache?.Clear();
_tableRowsCache?.Clear();
+327
View File
@@ -0,0 +1,327 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.Text;
using FlaxEditor.GUI;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.Windows.Profiler
{
/// <summary>
/// The GPU Memory profiling mode.
/// </summary>
/// <seealso cref="FlaxEditor.Windows.Profiler.ProfilerMode" />
internal sealed class MemoryGPU : ProfilerMode
{
private struct Resource
{
public string Name;
public string Tooltip;
public GPUResourceType Type;
public ulong MemoryUsage;
public Guid AssetId;
public bool IsAssetItem;
}
private readonly SingleChart _memoryUsageChart;
private readonly Table _table;
private SamplesBuffer<Resource[]> _resources;
private List<ClickableRow> _tableRowsCache;
private string[] _resourceTypesNames;
private Dictionary<string, Guid> _assetPathToId;
private Dictionary<Guid, Resource> _resourceCache;
private StringBuilder _stringBuilder;
public MemoryGPU()
: base("GPU Memory")
{
// Layout
var panel = new Panel(ScrollBars.Vertical)
{
AnchorPreset = AnchorPresets.StretchAll,
Offsets = Margin.Zero,
Parent = this,
};
var layout = new VerticalPanel
{
AnchorPreset = AnchorPresets.HorizontalStretchTop,
Offsets = Margin.Zero,
IsScrollable = true,
Parent = panel,
};
// Chart
_memoryUsageChart = new SingleChart
{
Title = "GPU Memory Usage",
FormatSample = v => Utilities.Utils.FormatBytesCount((int)v),
Parent = layout,
};
_memoryUsageChart.SelectedSampleChanged += OnSelectedSampleChanged;
// Table
var headerColor = Style.Current.LightBackground;
_table = new Table
{
Columns = new[]
{
new ColumnDefinition
{
UseExpandCollapseMode = true,
CellAlignment = TextAlignment.Near,
Title = "Resource",
TitleBackgroundColor = headerColor,
},
new ColumnDefinition
{
Title = "Type",
CellAlignment = TextAlignment.Center,
TitleBackgroundColor = headerColor,
},
new ColumnDefinition
{
Title = "Memory Usage",
TitleBackgroundColor = headerColor,
FormatValue = v => Utilities.Utils.FormatBytesCount((ulong)v),
},
},
Parent = layout,
};
_table.Splits = new[]
{
0.6f,
0.2f,
0.2f,
};
}
/// <inheritdoc />
public override void Clear()
{
_memoryUsageChart.Clear();
_resources?.Clear();
_assetPathToId?.Clear();
_resourceCache?.Clear();
}
/// <inheritdoc />
public override void Update(ref SharedUpdateData sharedData)
{
_memoryUsageChart.AddSample(sharedData.Stats.MemoryGPU.Used);
if (_resourceCache == null)
_resourceCache = new Dictionary<Guid, Resource>();
if (_assetPathToId == null)
_assetPathToId = new Dictionary<string, Guid>();
if (_stringBuilder == null)
_stringBuilder = new StringBuilder();
// Capture current GPU resources usage info
var contentDatabase = Editor.Instance.ContentDatabase;
var gpuResources = GPUDevice.Instance.Resources;
var resources = new Resource[gpuResources.Length];
var sb = _stringBuilder;
for (int i = 0; i < resources.Length; i++)
{
var gpuResource = gpuResources[i];
// Try to reuse cached resource info
var gpuResourceId = gpuResource.ID;
if (!_resourceCache.TryGetValue(gpuResourceId, out var resource))
{
resource = new Resource
{
Name = gpuResource.Name,
Type = gpuResource.ResourceType,
};
// Create tooltip
sb.Clear();
if (gpuResource is GPUTexture gpuTexture)
{
var desc = gpuTexture.Description;
sb.Append("Format: ").Append(desc.Format).AppendLine();
sb.Append("Size: ").Append(desc.Width).Append('x').Append(desc.Height);
if (desc.Depth != 1)
sb.Append('x').Append(desc.Depth);
if (desc.ArraySize != 1)
sb.Append('[').Append(desc.ArraySize).Append(']');
sb.AppendLine();
sb.Append("Mip Levels: ").Append(desc.MipLevels).AppendLine();
if (desc.IsMultiSample)
sb.Append("MSAA: ").Append('x').Append((int)desc.MultiSampleLevel).AppendLine();
sb.Append("Flags: ").Append(desc.Flags).AppendLine();
sb.Append("Usage: ").Append(desc.Usage);
}
else if (gpuResource is GPUBuffer gpuBuffer)
{
var desc = gpuBuffer.Description;
sb.Append("Format: ").Append(desc.Format).AppendLine();
sb.Append("Stride: ").Append(desc.Stride).AppendLine();
sb.Append("Elements: ").Append(desc.ElementsCount).AppendLine();
sb.Append("Flags: ").Append(desc.Flags).AppendLine();
sb.Append("Usage: ").Append(desc.Usage);
}
resource.Tooltip = _stringBuilder.ToString();
// Detect asset path in the resource name
int ext = resource.Name.LastIndexOf(".flax", StringComparison.OrdinalIgnoreCase);
if (ext != -1)
{
var assetPath = resource.Name.Substring(0, ext + 5);
if (!_assetPathToId.TryGetValue(assetPath, out resource.AssetId))
{
var asset = FlaxEngine.Content.GetAsset(assetPath);
if (asset != null)
resource.AssetId = asset.ID;
_assetPathToId.Add(assetPath, resource.AssetId);
}
var assetItem = contentDatabase.FindAsset(resource.AssetId);
if (assetItem != null)
{
resource.IsAssetItem = true;
resource.Name = assetItem.NamePath + resource.Name.Substring(ext + 5); // Use text after asset path to display (eg. subobject)
}
}
_resourceCache.Add(gpuResourceId, resource);
}
resource.MemoryUsage = gpuResource.MemoryUsage;
if (resource.MemoryUsage == 1)
resource.MemoryUsage = 0; // Sometimes GPU backend fakes memory usage as 1 to mark as allocated but not resided in actual GPU memory
resources[i] = resource;
}
Array.Sort(resources, SortResources);
if (_resources == null)
_resources = new SamplesBuffer<Resource[]>();
_resources.Add(resources);
}
/// <inheritdoc />
public override void UpdateView(int selectedFrame, bool showOnlyLastUpdateEvents)
{
_memoryUsageChart.SelectedSampleIndex = selectedFrame;
if (_resources == null)
return;
if (_tableRowsCache == null)
_tableRowsCache = new List<ClickableRow>();
if (_resourceTypesNames == null)
_resourceTypesNames = new string[(int)GPUResourceType.MAX]
{
"Render Target",
"Texture",
"Cube Texture",
"Volume Texture",
"Buffer",
"Shader",
"Pipeline State",
"Descriptor",
"Query",
"Sampler",
};
UpdateTable();
}
/// <inheritdoc />
public override void OnDestroy()
{
_resources?.Clear();
_resourceCache?.Clear();
_assetPathToId?.Clear();
_tableRowsCache?.Clear();
_stringBuilder?.Clear();
base.OnDestroy();
}
private static int SortResources(Resource a, Resource b)
{
return (int)(b.MemoryUsage - a.MemoryUsage);
}
private void UpdateTable()
{
_table.IsLayoutLocked = true;
int idx = 0;
while (_table.Children.Count > idx)
{
var child = _table.Children[idx];
if (child is ClickableRow row)
{
_tableRowsCache.Add(row);
child.Parent = null;
}
else
{
idx++;
}
}
_table.LockChildrenRecursive();
UpdateTableInner();
_table.UnlockChildrenRecursive();
_table.PerformLayout();
}
private void UpdateTableInner()
{
if (_resources.Count == 0)
return;
var resources = _resources.Get(_memoryUsageChart.SelectedSampleIndex);
if (resources == null || resources.Length == 0)
return;
// Add rows
var rowColor2 = Style.Current.Background * 1.4f;
for (int i = 0; i < resources.Length; i++)
{
ref var e = ref resources[i];
ClickableRow row;
if (_tableRowsCache.Count != 0)
{
// Reuse row
var last = _tableRowsCache.Count - 1;
row = _tableRowsCache[last];
_tableRowsCache.RemoveAt(last);
}
else
{
// Allocate new row
row = new ClickableRow { Values = new object[3] };
}
// Setup row data
row.Values[0] = e.Name;
row.Values[1] = _resourceTypesNames[(int)e.Type];
row.Values[2] = e.MemoryUsage;
// Setup row interactions
row.Tag = e;
row.TooltipText = e.Tooltip;
row.RowDoubleClick = null;
if (e.IsAssetItem)
{
row.RowDoubleClick = OnRowDoubleClickAsset;
}
// Add row to the table
row.Width = _table.Width;
row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent;
row.Parent = _table;
}
}
private void OnRowDoubleClickAsset(ClickableRow row)
{
var e = (Resource)row.Tag;
var assetItem = Editor.Instance.ContentDatabase.FindAsset(e.AssetId);
Editor.Instance.ContentEditing.Open(assetItem);
}
}
}
+87
View File
@@ -0,0 +1,87 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.Windows.Profiler
{
/// <summary>
/// The network profiling mode.
/// </summary>
/// <seealso cref="FlaxEditor.Windows.Profiler.ProfilerMode" />
internal sealed class Network : ProfilerMode
{
private readonly SingleChart _dataSentChart;
private readonly SingleChart _dataReceivedChart;
private FlaxEngine.Networking.NetworkDriverStats _prevStats;
public Network()
: base("Network")
{
// Layout
var panel = new Panel(ScrollBars.Vertical)
{
AnchorPreset = AnchorPresets.StretchAll,
Offsets = Margin.Zero,
Parent = this,
};
var layout = new VerticalPanel
{
AnchorPreset = AnchorPresets.HorizontalStretchTop,
Offsets = Margin.Zero,
IsScrollable = true,
Parent = panel,
};
// Charts
_dataSentChart = new SingleChart
{
Title = "Data Sent",
FormatSample = FormatSampleBytes,
Parent = layout,
};
_dataSentChart.SelectedSampleChanged += OnSelectedSampleChanged;
_dataReceivedChart = new SingleChart
{
Title = "Data Received",
FormatSample = FormatSampleBytes,
Parent = layout,
};
_dataReceivedChart.SelectedSampleChanged += OnSelectedSampleChanged;
}
private static string FormatSampleBytes(float v)
{
return (uint)v + " bytes";
}
/// <inheritdoc />
public override void Clear()
{
_dataSentChart.Clear();
_dataReceivedChart.Clear();
}
/// <inheritdoc />
public override void Update(ref SharedUpdateData sharedData)
{
var peer = FlaxEngine.Networking.NetworkManager.Peer;
if (peer == null)
{
_prevStats = new FlaxEngine.Networking.NetworkDriverStats();
return;
}
var stats = peer.NetworkDriver.GetStats();
_dataSentChart.AddSample(Mathf.Max((long)stats.TotalDataSent - (long)_prevStats.TotalDataSent, 0));
_dataReceivedChart.AddSample(Mathf.Max((long)stats.TotalDataReceived - (long)_prevStats.TotalDataReceived, 0));
_prevStats = stats;
}
/// <inheritdoc />
public override void UpdateView(int selectedFrame, bool showOnlyLastUpdateEvents)
{
_dataSentChart.SelectedSampleIndex = selectedFrame;
_dataReceivedChart.SelectedSampleIndex = selectedFrame;
}
}
}
@@ -83,6 +83,14 @@ namespace FlaxEditor.Windows.Profiler
{
}
/// <inheritdoc />
public override void OnDestroy()
{
Clear();
base.OnDestroy();
}
/// <summary>
/// Initializes this instance.
/// </summary>
@@ -52,10 +52,8 @@ namespace FlaxEditor.Windows.Profiler
if (_frameIndex != value)
{
_frameIndex = value;
UpdateButtons();
if (_tabs.SelectedTab is ProfilerMode mode)
mode.UpdateView(_frameIndex, _showOnlyLastUpdateEvents);
UpdateView();
}
}
}
@@ -71,10 +69,8 @@ namespace FlaxEditor.Windows.Profiler
if (_showOnlyLastUpdateEvents != value)
{
_showOnlyLastUpdateEvents = value;
UpdateButtons();
if (_tabs.SelectedTab is ProfilerMode mode)
mode.UpdateView(_frameIndex, _showOnlyLastUpdateEvents);
UpdateView();
}
}
}
@@ -152,7 +148,9 @@ namespace FlaxEditor.Windows.Profiler
if (_tabs.Children[i] is ProfilerMode mode)
{
mode.Clear();
FlaxEngine.Profiler.BeginEvent("ProfilerWindow.UpdateView");
mode.UpdateView(ViewFrameIndex, _showOnlyLastUpdateEvents);
FlaxEngine.Profiler.EndEvent();
}
}
@@ -162,7 +160,11 @@ namespace FlaxEditor.Windows.Profiler
private void OnSelectedTabChanged(Tabs tabs)
{
if (tabs.SelectedTab is ProfilerMode mode)
{
FlaxEngine.Profiler.BeginEvent("ProfilerWindow.UpdateView");
mode.UpdateView(ViewFrameIndex, _showOnlyLastUpdateEvents);
FlaxEngine.Profiler.EndEvent();
}
}
private void UpdateButtons()
@@ -174,6 +176,16 @@ namespace FlaxEditor.Windows.Profiler
_showOnlyLastUpdateEventsButton.Checked = _showOnlyLastUpdateEvents;
}
private void UpdateView()
{
if (_tabs.SelectedTab is ProfilerMode mode)
{
FlaxEngine.Profiler.BeginEvent("ProfilerWindow.UpdateView");
mode.UpdateView(_frameIndex, _showOnlyLastUpdateEvents);
FlaxEngine.Profiler.EndEvent();
}
}
/// <inheritdoc />
public override void OnInit()
{
@@ -181,7 +193,10 @@ namespace FlaxEditor.Windows.Profiler
AddMode(new Overall());
AddMode(new CPU());
AddMode(new GPU());
AddMode(new MemoryGPU());
AddMode(new Memory());
AddMode(new Assets());
AddMode(new Network());
// Init view
_frameIndex = -1;
@@ -192,6 +207,8 @@ namespace FlaxEditor.Windows.Profiler
}
UpdateButtons();
ScriptsBuilder.ScriptsReloadEnd += Clear; // Prevent crashes if any of the profiler tabs has some scripting types cached (eg. asset type info)
}
/// <inheritdoc />
@@ -206,11 +223,19 @@ namespace FlaxEditor.Windows.Profiler
for (int i = 0; i < _tabs.ChildrenCount; i++)
{
if (_tabs.Children[i] is ProfilerMode mode)
{
FlaxEngine.Profiler.BeginEvent(mode.GetType().FullName);
mode.Update(ref sharedData);
FlaxEngine.Profiler.EndEvent();
}
}
{
if (_tabs.SelectedTab is ProfilerMode mode)
{
FlaxEngine.Profiler.BeginEvent("ProfilerWindow.UpdateView");
mode.UpdateView(_frameIndex, _showOnlyLastUpdateEvents);
FlaxEngine.Profiler.EndEvent();
}
}
sharedData.End();
+103 -67
View File
@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FlaxEditor.GUI.Tabs;
using FlaxEditor.GUI.Tree;
using FlaxEditor.Scripting;
@@ -100,6 +99,7 @@ namespace FlaxEditor.Windows
private TextBox _searchBox;
private ContainerControl _groupSearch;
private Tabs _actorGroups;
/// <summary>
/// The editor instance.
@@ -117,8 +117,9 @@ namespace FlaxEditor.Windows
Editor = editor;
Selected += tab => Editor.Windows.EditWin.Viewport.SetActiveMode<TransformGizmoMode>();
ScriptsBuilder.ScriptsReload += OnScriptsReload;
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
var actorGroups = new Tabs
_actorGroups = new Tabs
{
Orientation = Orientation.Vertical,
UseScroll = true,
@@ -128,74 +129,19 @@ namespace FlaxEditor.Windows
Parent = this,
};
_groupSearch = CreateGroupWithList(actorGroups, "Search", 26);
_groupSearch = CreateGroupWithList(_actorGroups, "Search", 26);
_searchBox = new TextBox
{
AnchorPreset = AnchorPresets.HorizontalStretchTop,
WatermarkText = "Search...",
Parent = _groupSearch.Parent.Parent,
Bounds = new Rectangle(4, 4, actorGroups.Width - 8, 18),
Bounds = new Rectangle(4, 4, _actorGroups.Width - 8, 18),
};
_searchBox.TextChanged += OnSearchBoxTextChanged;
var groupBasicModels = CreateGroupWithList(actorGroups, "Basic Models");
groupBasicModels.AddChild(CreateEditorAssetItem("Cube", "Primitives/Cube.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Sphere", "Primitives/Sphere.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Plane", "Primitives/Plane.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Cylinder", "Primitives/Cylinder.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Cone", "Primitives/Cone.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Capsule", "Primitives/Capsule.flax"));
RefreshActorTabs();
var groupLights = CreateGroupWithList(actorGroups, "Lights");
groupLights.AddChild(CreateActorItem("Directional Light", typeof(DirectionalLight)));
groupLights.AddChild(CreateActorItem("Point Light", typeof(PointLight)));
groupLights.AddChild(CreateActorItem("Spot Light", typeof(SpotLight)));
groupLights.AddChild(CreateActorItem("Sky Light", typeof(SkyLight)));
var groupVisuals = CreateGroupWithList(actorGroups, "Visuals");
groupVisuals.AddChild(CreateActorItem("Camera", typeof(Camera)));
groupVisuals.AddChild(CreateActorItem("Environment Probe", typeof(EnvironmentProbe)));
groupVisuals.AddChild(CreateActorItem("Skybox", typeof(Skybox)));
groupVisuals.AddChild(CreateActorItem("Sky", typeof(Sky)));
groupVisuals.AddChild(CreateActorItem("Exponential Height Fog", typeof(ExponentialHeightFog)));
groupVisuals.AddChild(CreateActorItem("PostFx Volume", typeof(PostFxVolume)));
groupVisuals.AddChild(CreateActorItem("Decal", typeof(Decal)));
groupVisuals.AddChild(CreateActorItem("Particle Effect", typeof(ParticleEffect)));
var groupPhysics = CreateGroupWithList(actorGroups, "Physics");
groupPhysics.AddChild(CreateActorItem("Rigid Body", typeof(RigidBody)));
groupPhysics.AddChild(CreateActorItem("Character Controller", typeof(CharacterController)));
groupPhysics.AddChild(CreateActorItem("Box Collider", typeof(BoxCollider)));
groupPhysics.AddChild(CreateActorItem("Sphere Collider", typeof(SphereCollider)));
groupPhysics.AddChild(CreateActorItem("Capsule Collider", typeof(CapsuleCollider)));
groupPhysics.AddChild(CreateActorItem("Mesh Collider", typeof(MeshCollider)));
groupPhysics.AddChild(CreateActorItem("Fixed Joint", typeof(FixedJoint)));
groupPhysics.AddChild(CreateActorItem("Distance Joint", typeof(DistanceJoint)));
groupPhysics.AddChild(CreateActorItem("Slider Joint", typeof(SliderJoint)));
groupPhysics.AddChild(CreateActorItem("Spherical Joint", typeof(SphericalJoint)));
groupPhysics.AddChild(CreateActorItem("Hinge Joint", typeof(HingeJoint)));
groupPhysics.AddChild(CreateActorItem("D6 Joint", typeof(D6Joint)));
var groupOther = CreateGroupWithList(actorGroups, "Other");
groupOther.AddChild(CreateActorItem("Animated Model", typeof(AnimatedModel)));
groupOther.AddChild(CreateActorItem("Bone Socket", typeof(BoneSocket)));
groupOther.AddChild(CreateActorItem("CSG Box Brush", typeof(BoxBrush)));
groupOther.AddChild(CreateActorItem("Audio Source", typeof(AudioSource)));
groupOther.AddChild(CreateActorItem("Audio Listener", typeof(AudioListener)));
groupOther.AddChild(CreateActorItem("Empty Actor", typeof(EmptyActor)));
groupOther.AddChild(CreateActorItem("Scene Animation", typeof(SceneAnimationPlayer)));
groupOther.AddChild(CreateActorItem("Nav Mesh Bounds Volume", typeof(NavMeshBoundsVolume)));
groupOther.AddChild(CreateActorItem("Nav Link", typeof(NavLink)));
groupOther.AddChild(CreateActorItem("Nav Modifier Volume", typeof(NavModifierVolume)));
groupOther.AddChild(CreateActorItem("Spline", typeof(Spline)));
var groupGui = CreateGroupWithList(actorGroups, "GUI");
groupGui.AddChild(CreateActorItem("UI Control", typeof(UIControl)));
groupGui.AddChild(CreateActorItem("UI Canvas", typeof(UICanvas)));
groupGui.AddChild(CreateActorItem("Text Render", typeof(TextRender)));
groupGui.AddChild(CreateActorItem("Sprite Render", typeof(SpriteRender)));
actorGroups.SelectedTabIndex = 1;
_actorGroups.SelectedTabIndex = 1;
}
private void OnScriptsReload()
@@ -206,6 +152,91 @@ namespace FlaxEditor.Windows
_groupSearch.PerformLayout();
}
private void OnScriptsReloadEnd()
{
RefreshActorTabs();
}
private void RefreshActorTabs()
{
// Remove tabs
var tabs = new List<Tab>();
foreach (var child in _actorGroups.Children)
{
if (child is Tab tab)
{
if (tab.Text != "Search")
tabs.Add(tab);
}
}
foreach (var tab in tabs)
{
var group = _actorGroups.Children.Find(T => T == tab);
group.Dispose();
}
// Setup primitives tabs
var groupBasicModels = CreateGroupWithList(_actorGroups, "Basic Models");
groupBasicModels.AddChild(CreateEditorAssetItem("Cube", "Primitives/Cube.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Sphere", "Primitives/Sphere.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Plane", "Primitives/Plane.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Cylinder", "Primitives/Cylinder.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Cone", "Primitives/Cone.flax"));
groupBasicModels.AddChild(CreateEditorAssetItem("Capsule", "Primitives/Capsule.flax"));
// Created first to order specific tabs
CreateGroupWithList(_actorGroups, "Lights");
CreateGroupWithList(_actorGroups, "Visuals");
CreateGroupWithList(_actorGroups, "Physics");
CreateGroupWithList(_actorGroups, "GUI");
CreateGroupWithList(_actorGroups, "Other");
// Add other actor types to respective tab based on attribute
foreach (var actorType in Editor.CodeEditing.Actors.Get())
{
if (actorType.IsAbstract)
continue;
ActorToolboxAttribute attribute = null;
foreach (var e in actorType.GetAttributes(false))
{
if (e is ActorToolboxAttribute actorToolboxAttribute)
{
attribute = actorToolboxAttribute;
break;
}
}
if (attribute == null)
continue;
var groupName = attribute.Group.Trim();
// Check if tab already exists and add it to the tab
var actorTabExists = false;
foreach (var child in _actorGroups.Children)
{
if (child is Tab tab)
{
if (string.Equals(tab.Text, groupName, StringComparison.OrdinalIgnoreCase))
{
var tree = tab.GetChild<Panel>().GetChild<Tree>();
if (tree != null)
{
tree.AddChild(string.IsNullOrEmpty(attribute.Name) ? CreateActorItem(Utilities.Utils.GetPropertyNameUI(actorType.Name), actorType) : CreateActorItem(attribute.Name, actorType));
tree.SortChildren();
}
actorTabExists = true;
break;
}
}
}
if (actorTabExists)
continue;
var group = CreateGroupWithList(_actorGroups, groupName);
group.AddChild(string.IsNullOrEmpty(attribute.Name) ? CreateActorItem(Utilities.Utils.GetPropertyNameUI(actorType.Name), actorType) : CreateActorItem(attribute.Name, actorType));
group.SortChildren();
}
}
private void OnSearchBoxTextChanged()
{
// Skip events during setup or init stuff
@@ -218,7 +249,17 @@ namespace FlaxEditor.Windows
foreach (var actorType in Editor.CodeEditing.Actors.Get())
{
var text = actorType.Name;
ActorToolboxAttribute attribute = null;
foreach (var e in actorType.GetAttributes(true))
{
if (e is ActorToolboxAttribute actorToolboxAttribute)
{
attribute = actorToolboxAttribute;
break;
}
}
var text = (attribute == null) ? actorType.Name : string.IsNullOrEmpty(attribute.Name) ? actorType.Name : attribute.Name;
if (!QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges))
continue;
@@ -249,11 +290,6 @@ namespace FlaxEditor.Windows
return new Item(name, GUI.Drag.DragItems.GetDragData(path));
}
private Item CreateActorItem(string name, Type type)
{
return CreateActorItem(name, new ScriptType(type));
}
private Item CreateActorItem(string name, ScriptType type)
{
return new ScriptTypeItem(name, type, GUI.Drag.DragActorType.GetDragData(type));
+13
View File
@@ -86,6 +86,11 @@ public:
{
return Position.GetKeyframes().Count() + Rotation.GetKeyframes().Count() + Scale.GetKeyframes().Count();
}
uint64 GetMemoryUsage() const
{
return NodeName.Length() * sizeof(Char) + Position.GetMemoryUsage() + Rotation.GetMemoryUsage() + Scale.GetMemoryUsage();
}
};
/// <summary>
@@ -131,6 +136,14 @@ public:
return static_cast<float>(Duration / FramesPerSecond);
}
uint64 GetMemoryUsage() const
{
uint64 result = RootNodeName.Length() * sizeof(Char) + Channels.Capacity() * sizeof(NodeAnimationData);
for (const auto& e : Channels)
result += e.GetMemoryUsage();
return result;
}
/// <summary>
/// Gets the total amount of keyframes in the all animation channels.
/// </summary>
+5
View File
@@ -733,6 +733,11 @@ public:
_keyframes[i].Time = _keyframes[i].Time * timeScale + timeOffset;;
}
uint64 GetMemoryUsage() const
{
return _keyframes.Capacity() * sizeof(KeyFrame);
}
public:
FORCE_INLINE KeyFrame& operator[](int32 index)
{
@@ -11,7 +11,8 @@
/// <summary>
/// The scene animation playback actor.
/// </summary>
API_CLASS(Attributes = "ActorContextMenu(\"New/Other/Scene Animation\")") class FLAXENGINE_API SceneAnimationPlayer : public Actor, public IPostFxSettingsProvider
API_CLASS(Attributes="ActorContextMenu(\"New/Other/Scene Animation\"), ActorToolbox(\"Other\", \"Scene Animation\")")
class FLAXENGINE_API SceneAnimationPlayer : public Actor, public IPostFxSettingsProvider
{
DECLARE_SCENE_OBJECT(SceneAnimationPlayer);
+2 -1
View File
@@ -7,7 +7,8 @@
/// <summary>
/// Represents a listener that hears audio sources. For spatial audio the volume and pitch of played audio is determined by the distance, orientation and velocity differences between the source and the listener.
/// </summary>
API_CLASS(Attributes="ActorContextMenu(\"New/Audio/Audio Listener\")") class FLAXENGINE_API AudioListener : public Actor
API_CLASS(Attributes="ActorContextMenu(\"New/Audio/Audio Listener\"), ActorToolbox(\"Other\")")
class FLAXENGINE_API AudioListener : public Actor
{
DECLARE_SCENE_OBJECT(AudioListener);
private:
+1 -1
View File
@@ -132,7 +132,7 @@ void AudioSource::Play()
Clip->RequestStreamingUpdate();
// If we are looping and streaming also update streaming buffers
if (_loop)
if (_loop || state == States::Stopped)
RequestStreamingBuffersUpdate();
}
}
+2 -1
View File
@@ -13,7 +13,8 @@
/// <remarks>
/// Whether or not an audio source is spatial is controlled by the assigned AudioClip.The volume and the pitch of a spatial audio source is controlled by its position and the AudioListener's position/direction/velocity.
/// </remarks>
API_CLASS(Attributes="ActorContextMenu(\"New/Audio/Audio Source\")") class FLAXENGINE_API AudioSource : public Actor
API_CLASS(Attributes="ActorContextMenu(\"New/Audio/Audio Source\"), ActorToolbox(\"Other\")")
class FLAXENGINE_API AudioSource : public Actor
{
DECLARE_SCENE_OBJECT(AudioSource);
friend class AudioStreamingHandler;
+11
View File
@@ -314,6 +314,17 @@ bool Asset::ShouldDeleteFileOnUnload() const
#endif
uint64 Asset::GetMemoryUsage() const
{
uint64 result = sizeof(Asset);
Locker.Lock();
if (_loadingTask)
result += sizeof(ContentLoadTask);
result += (OnLoaded.Capacity() + OnReloading.Capacity() + OnUnloaded.Capacity()) * sizeof(EventType::FunctionType);
Locker.Unlock();
return result;
}
void Asset::Reload()
{
// Virtual assets are memory-only so reloading them makes no sense
+5 -4
View File
@@ -128,14 +128,17 @@ public:
}
#if USE_EDITOR
/// <summary>
/// Determines whether this asset was marked to be deleted on unload.
/// </summary>
API_PROPERTY() bool ShouldDeleteFileOnUnload() const;
#endif
/// <summary>
/// Gets amount of CPU memory used by this resource (in bytes). It's a rough estimation. Memory may be fragmented, compressed or sub-allocated so the actual memory pressure from this resource may vary.
/// </summary>
API_PROPERTY() virtual uint64 GetMemoryUsage() const;
public:
/// <summary>
/// Reloads the asset.
@@ -160,7 +163,6 @@ public:
virtual void CancelStreaming();
#if USE_EDITOR
/// <summary>
/// Gets the asset references. Supported only in Editor.
/// </summary>
@@ -184,7 +186,6 @@ public:
/// </remarks>
/// <returns>The collection of the asset ids referenced by this asset.</returns>
API_FUNCTION() Array<Guid, HeapAllocation> GetReferences() const;
#endif
/// <summary>
+1 -4
View File
@@ -54,8 +54,5 @@ public:
/// Gets the string.
/// </summary>
/// <returns>The string.</returns>
String ToString() const
{
return String::Format(TEXT("ID: {0}, TypeName: {1}, Path: \'{2}\'"), ID, TypeName, Path);
}
String ToString() const;
};
@@ -569,6 +569,23 @@ void Animation::OnSkinnedModelUnloaded(Asset* obj)
MappingCache.Remove(i);
}
uint64 Animation::GetMemoryUsage() const
{
Locker.Lock();
uint64 result = BinaryAsset::GetMemoryUsage();
result += sizeof(Animation) - sizeof(BinaryAsset);
result += Data.GetMemoryUsage();
result += Events.Capacity() * sizeof(Pair<String, StepCurve<AnimEventData>>);
for (const auto& e : Events)
result += e.First.Length() * sizeof(Char) + e.Second.GetMemoryUsage();
result += NestedAnims.Capacity() * sizeof(Pair<String, NestedAnimData>);
result += MappingCache.Capacity() * sizeof(Pair<String, StepCurve<AnimEventData>>);
for (const auto& e : MappingCache)
result += e.Value.Capacity() * sizeof(int32);
Locker.Unlock();
return result;
}
void Animation::OnScriptingDispose()
{
// Dispose any events to prevent crashes (scripting is released before content)
+1 -2
View File
@@ -152,7 +152,6 @@ public:
const NodeToChannel* GetMapping(SkinnedModel* obj);
#if USE_EDITOR
/// <summary>
/// Gets the animation as serialized timeline data. Used to show it in Editor.
/// </summary>
@@ -173,7 +172,6 @@ public:
/// <remarks>The cannot be used by virtual assets.</remarks>
/// <returns><c>true</c> failed to save data; otherwise, <c>false</c>.</returns>
bool Save(const StringView& path = StringView::Empty);
#endif
private:
@@ -181,6 +179,7 @@ private:
public:
// [BinaryAsset]
uint64 GetMemoryUsage() const override;
void OnScriptingDispose() override;
protected:
+1 -1
View File
@@ -482,7 +482,7 @@ void Material::InitCompilationOptions(ShaderCompilationOptions& options)
options.Macros.Add({ "MATERIAL_TESSELLATION", "MATERIAL_TESSELLATION_PHONG" });
break;
}
options.Macros.Add({ "MAX_TESSELLATION_FACTOR", Numbers[info.MaxTessellationFactor] });
options.Macros.Add({ "MAX_TESSELLATION_FACTOR", Numbers[Math::Min<int32>(info.MaxTessellationFactor, ARRAY_COUNT(Numbers) - 1)] });
}
// Helper macros (used by the parser)
+9 -1
View File
@@ -722,6 +722,7 @@ bool Model::Init(const Span<int32>& meshesCountPerLod)
{
auto& lod = LODs[lodIndex];
lod._model = this;
lod._lodIndex = lodIndex;
lod.ScreenSize = 1.0f;
const int32 meshesCount = meshesCountPerLod[lodIndex];
if (meshesCount <= 0 || meshesCount > MODEL_MAX_MESHES)
@@ -922,6 +923,7 @@ Asset::LoadResult Model::load()
{
auto& lod = LODs[lodIndex];
lod._model = this;
lod._lodIndex = lodIndex;
// Screen Size
stream->ReadFloat(&lod.ScreenSize);
@@ -977,7 +979,13 @@ Asset::LoadResult Model::load()
ModelSDFHeader data;
sdfStream.ReadBytes(&data, sizeof(data));
if (!SDF.Texture)
SDF.Texture = GPUTexture::New();
{
String name;
#if !BUILD_RELEASE
name = GetPath() + TEXT(".SDF");
#endif
SDF.Texture = GPUDevice::Instance->CreateTexture(name);
}
if (SDF.Texture->Init(GPUTextureDescription::New3D(data.Width, data.Height, data.Depth, data.Format, GPUTextureFlags::ShaderResource, data.MipLevels)))
return LoadResult::Failed;
SDF.LocalToUVWMul = data.LocalToUVWMul;
@@ -64,6 +64,16 @@ bool RawDataAsset::Save(const StringView& path)
#endif
uint64 RawDataAsset::GetMemoryUsage() const
{
Locker.Lock();
uint64 result = BinaryAsset::GetMemoryUsage();
result += sizeof(RawDataAsset) - sizeof(BinaryAsset);
result += Data.Count();
Locker.Unlock();
return result;
}
Asset::LoadResult RawDataAsset::load()
{
auto chunk0 = GetChunk(0);
@@ -28,6 +28,10 @@ public:
#endif
public:
// [BinaryAsset]
uint64 GetMemoryUsage() const override;
protected:
// [BinaryAsset]
LoadResult load() override;
+16
View File
@@ -452,6 +452,22 @@ const String& BinaryAsset::GetPath() const
#endif
}
uint64 BinaryAsset::GetMemoryUsage() const
{
Locker.Lock();
uint64 result = Asset::GetMemoryUsage();
result += sizeof(BinaryAsset) - sizeof(Asset);
result += _dependantAssets.Capacity() * sizeof(BinaryAsset*);
for (int32 i = 0; i < ASSET_FILE_DATA_CHUNKS; i++)
{
auto chunk = _header.Chunks[i];
if (chunk != nullptr && chunk->IsLoaded())
result += chunk->Size();
}
Locker.Unlock();
return result;
}
/// <summary>
/// Helper task used to initialize binary asset and upgrade it if need to in background.
/// </summary>
+1 -9
View File
@@ -41,7 +41,6 @@ public:
FlaxStorage* Storage;
#if USE_EDITOR
/// <summary>
/// The asset metadata information. Stored in a Json format.
/// </summary>
@@ -51,14 +50,12 @@ public:
/// Asset dependencies list used by the asset for tracking (eg. material functions used by material asset). The pair of asset ID and cached file edit time (for tracking modification).
/// </summary>
Array<Pair<Guid, DateTime>> Dependencies;
#endif
public:
/// <summary>
/// Gets the asset serialized version.
/// </summary>
/// <returns>Version number.</returns>
virtual uint32 GetSerializedVersion() const = 0;
/// <summary>
@@ -84,14 +81,11 @@ public:
public:
#if USE_EDITOR
#if COMPILE_WITH_ASSETS_IMPORTER
/// <summary>
/// Reimports asset from the source file.
/// </summary>
API_FUNCTION() void Reimport() const;
#endif
/// <summary>
@@ -130,7 +124,6 @@ protected:
virtual void OnDependencyModified(BinaryAsset* asset)
{
}
#endif
protected:
@@ -255,7 +248,6 @@ public:
bool LoadChunks(AssetChunksFlag chunks);
#if USE_EDITOR
/// <summary>
/// Saves this asset to the storage container.
/// </summary>
@@ -281,7 +273,6 @@ public:
/// <param name="silentMode">In silent mode don't reload opened storage container that is using target file.</param>
/// <returns>True if failed, otherwise false.</returns>
static bool SaveToAsset(const StringView& path, AssetInitData& data, bool silentMode = false);
#endif
protected:
@@ -302,6 +293,7 @@ public:
void OnDeleteObject() override;
#endif
const String& GetPath() const final override;
uint64 GetMemoryUsage() const override;
protected:
// [Asset]
+5
View File
@@ -34,6 +34,11 @@ TimeSpan Content::AssetsUnloadInterval = TimeSpan::FromSeconds(10);
Delegate<Asset*> Content::AssetDisposing;
Delegate<Asset*> Content::AssetReloading;
String AssetInfo::ToString() const
{
return String::Format(TEXT("ID: {0}, TypeName: {1}, Path: \'{2}\'"), ID, TypeName, Path);
}
namespace
{
// Assets
+22
View File
@@ -93,6 +93,17 @@ const String& JsonAssetBase::GetPath() const
#endif
}
uint64 JsonAssetBase::GetMemoryUsage() const
{
Locker.Lock();
uint64 result = Asset::GetMemoryUsage();
result += sizeof(JsonAssetBase) - sizeof(Asset);
if (Data)
result += Document.GetAllocator().Capacity();
Locker.Unlock();
return result;
}
#if USE_EDITOR
void FindIds(ISerializable::DeserializeStream& node, Array<Guid>& output)
@@ -248,6 +259,17 @@ JsonAsset::JsonAsset(const SpawnParams& params, const AssetInfo* info)
{
}
uint64 JsonAsset::GetMemoryUsage() const
{
Locker.Lock();
uint64 result = JsonAssetBase::GetMemoryUsage();
result += sizeof(JsonAsset) - sizeof(JsonAssetBase);
if (Instance && InstanceType)
result += InstanceType.GetType().Size;
Locker.Unlock();
return result;
}
Asset::LoadResult JsonAsset::loadAsset()
{
const auto result = JsonAssetBase::loadAsset();
+5
View File
@@ -77,6 +77,7 @@ public:
public:
// [Asset]
const String& GetPath() const override;
uint64 GetMemoryUsage() const override;
#if USE_EDITOR
void GetReferences(Array<Guid, HeapAllocation>& output) const override;
#endif
@@ -122,6 +123,10 @@ public:
return Instance && InstanceType.IsAssignableFrom(T::TypeInitializer) ? (T*)Instance : nullptr;
}
public:
// [JsonAssetBase]
uint64 GetMemoryUsage() const override;
protected:
// [JsonAssetBase]
LoadResult loadAsset() override;
@@ -3,7 +3,6 @@
#pragma once
#include "Engine/Threading/Task.h"
#include "Engine/Core/Types/String.h"
class Asset;
class LoadingThread;
@@ -46,7 +45,6 @@ public:
/// <summary>
/// Gets a task type.
/// </summary>
/// <returns>The type.</returns>
FORCE_INLINE Type GetType() const
{
return _type;
@@ -68,13 +66,7 @@ protected:
public:
// [Task]
String ToString() const override
{
return String::Format(TEXT("Content Load Task {0} ({1})"),
ToString(GetType()),
::ToString(GetState())
);
}
String ToString() const override;
protected:
// [Task]
@@ -211,6 +211,11 @@ void ContentLoadingManagerService::Dispose()
Tasks.CancelAll();
}
String ContentLoadTask::ToString() const
{
return String::Format(TEXT("Content Load Task {0} ({1})"), ToString(GetType()), (int32)GetState());
}
void ContentLoadTask::Enqueue()
{
Tasks.Add(this);
+18
View File
@@ -0,0 +1,18 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/Guid.h"
/// <summary>
/// Represents the reference to the scene asset. Stores the unique ID of the scene to reference. Can be used to load the selected scene.
/// </summary>
API_STRUCT(NoDefault) struct FLAXENGINE_API SceneReference
{
DECLARE_SCRIPTING_TYPE_STRUCTURE(SceneReference);
/// <summary>
/// The identifier of the scene asset (and the scene object).
/// </summary>
API_FIELD() Guid ID;
};
+3 -3
View File
@@ -509,14 +509,14 @@ public:
_deletedCount = _elementsCount = 0;
if (capacity != 0 && (capacity & (capacity - 1)) != 0)
{
// Align capacity value to the next power of two (if it's not)
capacity++;
// Align capacity value to the next power of two (http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2)
capacity--;
capacity |= capacity >> 1;
capacity |= capacity >> 2;
capacity |= capacity >> 4;
capacity |= capacity >> 8;
capacity |= capacity >> 16;
capacity = capacity + 1;
capacity++;
}
if (capacity)
{
+3 -3
View File
@@ -380,14 +380,14 @@ public:
_deletedCount = _elementsCount = 0;
if (capacity != 0 && (capacity & (capacity - 1)) != 0)
{
// Align capacity value to the next power of two (if it's not)
capacity++;
// Align capacity value to the next power of two (http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2)
capacity--;
capacity |= capacity >> 1;
capacity |= capacity >> 2;
capacity |= capacity >> 4;
capacity |= capacity >> 8;
capacity |= capacity >> 16;
capacity = capacity + 1;
capacity++;
}
if (capacity)
{
@@ -6,6 +6,7 @@
#include "Engine/Serialization/Serialization.h"
#include "Engine/Content/Asset.h"
#include "Engine/Content/AssetReference.h"
#include "Engine/Content/SceneReference.h"
/// <summary>
/// The game building rendering settings.
@@ -50,6 +51,12 @@ public:
/// </summary>
API_FIELD(Attributes="EditorOrder(1000), EditorDisplay(\"Additional Data\")")
Array<AssetReference<Asset>> AdditionalAssets;
/// <summary>
/// The list of additional scenes to include into build (into root assets set).
/// </summary>
API_FIELD(Attributes="EditorOrder(1000), EditorDisplay(\"Additional Data\")")
Array<SceneReference> AdditionalScenes;
/// <summary>
/// The list of additional folders with assets to include into build (into root assets set). Paths relative to the project directory (or absolute).
+8
View File
@@ -557,6 +557,14 @@ public:
return count;
}
/// <summary>
/// Gets the current capacity of delegate table (amount of function to store before resizing).
/// </summary>
int32 Capacity() const
{
return (int32)Platform::AtomicRead((intptr volatile*)&_size);
}
/// <summary>
/// Determines whether any function is binded.
/// </summary>
+5 -5
View File
@@ -105,14 +105,16 @@ public:
FORCE_INLINE int32 CalculateCapacityGrow(int32 capacity, int32 minCapacity) const
{
if (capacity == 0)
if (capacity < minCapacity)
capacity = minCapacity;
if (capacity < 8)
{
capacity = 8;
}
else
{
// Round up to the next power of 2 and multiply by 2
capacity++;
// Round up to the next power of 2 and multiply by 2 (http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2)
capacity--;
capacity |= capacity >> 1;
capacity |= capacity >> 2;
capacity |= capacity >> 4;
@@ -120,8 +122,6 @@ public:
capacity |= capacity >> 16;
capacity = (capacity + 1) * 2;
}
if (capacity < minCapacity)
capacity = minCapacity;
return capacity;
}
+4 -12
View File
@@ -88,22 +88,14 @@ public:
}
public:
// Compares two Guids for equality
// @param left The first Guid to compare
// @param right The second Guid to compare
// @returns True if the Guids are equal, otherwise false
friend bool operator==(const Guid& left, const Guid& right)
bool operator==(const Guid& other) const
{
return ((left.A ^ right.A) | (left.B ^ right.B) | (left.C ^ right.C) | (left.D ^ right.D)) == 0;
return ((A ^ other.A) | (B ^ other.B) | (C ^ other.C) | (D ^ other.D)) == 0;
}
// Compares two Guids for inequality
// @param left The first Guid to compare
// @param right The second Guid to compare
// @returns True if the GUIDs are not equal, otherwise false
friend bool operator!=(const Guid& left, const Guid& right)
bool operator!=(const Guid& other) const
{
return ((left.A ^ right.A) | (left.B ^ right.B) | (left.C ^ right.C) | (left.D ^ right.D)) != 0;
return ((A ^ other.A) | (B ^ other.B) | (C ^ other.C) | (D ^ other.D)) != 0;
}
// Provides access to the GUIDs components
+4 -4
View File
@@ -81,14 +81,14 @@ public:
return *this;
}
friend bool operator==(const Pair& a, const Pair& b)
bool operator==(const Pair& other) const
{
return a.First == b.First && a.Second == b.Second;
return First == other.First && Second == other.Second;
}
friend bool operator!=(const Pair& a, const Pair& b)
bool operator!=(const Pair& other) const
{
return a.First != b.First || a.Second != b.Second;
return First != other.First || Second != other.Second;
}
};
+1 -1
View File
@@ -2,7 +2,7 @@
#pragma once
#include "Engine/Core/Enums.h"
#include "Engine/Core/Types/BaseTypes.h"
/// <summary>
/// Build game header flags.
+1 -9
View File
@@ -4,16 +4,8 @@ using System;
namespace FlaxEngine
{
/// <summary>
/// Represents the reference to the scene asset. Stores the unique ID of the scene to reference. Can be used to load the selected scene.
/// </summary>
public struct SceneReference : IComparable, IComparable<Guid>, IComparable<SceneReference>
partial struct SceneReference : IComparable, IComparable<Guid>, IComparable<SceneReference>
{
/// <summary>
/// The identifier of the scene asset (and the scene object).
/// </summary>
public Guid ID;
/// <summary>
/// Initializes a new instance of the <see cref="SceneReference"/> class.
/// </summary>
+2 -2
View File
@@ -154,9 +154,9 @@ private:
const Mesh* Geo;
int32 Lightmap;
friend bool operator==(const DrawKey& lhs, const DrawKey& rhs)
bool operator==(const DrawKey& other) const
{
return lhs.Mat == rhs.Mat && lhs.Geo == rhs.Geo && lhs.Lightmap == rhs.Lightmap;
return Mat == other.Mat && Geo == other.Geo && Lightmap == other.Lightmap;
}
friend uint32 GetHash(const DrawKey& key)
@@ -3,6 +3,7 @@
#include "DefaultGPUTasksExecutor.h"
#include "GPUTasksContext.h"
#include "GPUTask.h"
#include "GPUTasksManager.h"
#include "Engine/Graphics/GPUDevice.h"
DefaultGPUTasksExecutor::DefaultGPUTasksExecutor()
@@ -30,7 +31,7 @@ void DefaultGPUTasksExecutor::FrameEnd()
// Default implementation performs async operations on end of the frame which is synchronized with a rendering thread
GPUTask* buffer[32];
const int32 count = GPUDevice::Instance->TasksManager.RequestWork(buffer, 32);
const int32 count = GPUDevice::Instance->GetTasksManager()->RequestWork(buffer, 32);
for (int32 i = 0; i < count; i++)
{
_context->Run(buffer[i]);
+2 -31
View File
@@ -4,7 +4,6 @@
#include "Engine/Threading/Task.h"
#include "Engine/Platform/Platform.h"
#include "Engine/Core/Log.h"
#include "GPUTasksContext.h"
class GPUResource;
@@ -89,32 +88,7 @@ public:
/// Executes this task.
/// </summary>
/// <param name="context">The context.</param>
void Execute(GPUTasksContext* context)
{
// Begin
ASSERT(IsQueued() && _context == nullptr);
_state = TaskState::Running;
// Perform an operation
const auto result = run(context);
// Process result
if (IsCancelRequested())
{
_state = TaskState::Canceled;
}
else if (result != Result::Ok)
{
LOG(Warning, "\'{0}\' failed with result: {1}", ToString(), ToString(result));
OnFail();
}
else
{
// Save task completion point (for synchronization)
_syncPoint = context->GetCurrentSyncPoint();
_context = context;
}
}
void Execute(GPUTasksContext* context);
/// <summary>
/// Action fired when asynchronous operation has been synchronized with a GPU
@@ -154,10 +128,7 @@ protected:
public:
// [Task]
String ToString() const override
{
return String::Format(TEXT("GPU Async Task {0} ({1})"), ToString(GetType()), ::ToString(GetState()));
}
String ToString() const override;
protected:
// [Task]
@@ -2,6 +2,7 @@
#include "GPUTasksContext.h"
#include "GPUTask.h"
#include "Engine/Core/Log.h"
#include "Engine/Graphics/GPUDevice.h"
#include "Engine/Threading/Threading.h"
@@ -1,6 +1,7 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#include "GPUTasksExecutor.h"
#include "Engine/Core/Log.h"
#include "Engine/Graphics/GPUDevice.h"
GPUTasksExecutor::~GPUTasksExecutor()
@@ -37,7 +37,6 @@ public:
/// <summary>
/// Gets the context list.
/// </summary>
/// <returns>GPU contexts</returns>
FORCE_INLINE const Array<GPUTasksContext*>* GetContextList() const
{
return &_contextList;

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