Merge remote-tracking branch 'origin/master' into 1.7

This commit is contained in:
Wojtek Figat
2023-10-01 13:17:41 +02:00
58 changed files with 786 additions and 388 deletions

View File

@@ -1,15 +1,22 @@
@echo off
rem Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
:: Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
setlocal
pushd
echo Generating Flax Engine project files...
rem Run Flax.Build to generate Visual Studio solution and project files (also pass the arguments)
call "Development\Scripts\Windows\CallBuildTool.bat" -genproject %*
:: Change the path to the script root
cd /D "%~dp0"
:: Run Flax.Build to generate Visual Studio solution and project files (also pass the arguments)
call "Development\Scripts\Windows\CallBuildTool.bat" -genproject %*
if errorlevel 1 goto BuildToolFailed
:: Build bindings for all editor configurations
echo Building C# bindings...
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor,FlaxGame
popd
echo Done!
exit /B 0

View File

@@ -10,3 +10,8 @@ cd "`dirname "$0"`"
# Run Flax.Build to generate project files (also pass the arguments)
bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
# Build bindings for all editor configurations
echo Building C# bindings...
# TODO: Detect the correct architecture here
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor,FlaxGame

View File

@@ -10,3 +10,8 @@ cd "`dirname "$0"`"
# Run Flax.Build to generate project files (also pass the arguments)
bash ./Development/Scripts/Linux/CallBuildTool.sh --genproject "$@"
# Build bindings for all editor configurations
echo Building C# bindings...
# TODO: Detect the correct architecture here
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor,FlaxGame

View File

@@ -25,6 +25,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
private DragHandlers _dragHandlers;
private DragScriptItems _dragScripts;
private DragAssets _dragAssets;
private Button _addScriptsButton;
/// <summary>
/// The parent scripts editor.
@@ -40,16 +41,19 @@ namespace FlaxEditor.CustomEditors.Dedicated
AutoFocus = false;
// Add script button
float addScriptButtonWidth = 60.0f;
var addScriptButton = new Button
var buttonText = "Add script";
var textSize = Style.Current.FontMedium.MeasureText(buttonText);
float addScriptButtonWidth = (textSize.X < 60.0f) ? 60.0f : textSize.X + 4;
var buttonHeight = (textSize.Y < 18) ? 18 : textSize.Y + 4;
_addScriptsButton = new Button
{
TooltipText = "Add new scripts to the actor",
AnchorPreset = AnchorPresets.MiddleCenter,
Text = "Add script",
Text = buttonText,
Parent = this,
Bounds = new Rectangle((Width - addScriptButtonWidth) / 2, 1, addScriptButtonWidth, 18),
Bounds = new Rectangle((Width - addScriptButtonWidth) / 2, 1, addScriptButtonWidth, buttonHeight),
};
addScriptButton.ButtonClicked += OnAddScriptButtonClicked;
_addScriptsButton.ButtonClicked += OnAddScriptButtonClicked;
}
private void OnAddScriptButtonClicked(Button button)
@@ -82,7 +86,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var size = Size;
// Info
Render2D.DrawText(style.FontSmall, "Drag scripts here", new Rectangle(2, 22, size.X - 4, size.Y - 4 - 20), style.ForegroundDisabled, TextAlignment.Center, TextAlignment.Center);
Render2D.DrawText(style.FontSmall, "Drag scripts here", new Rectangle(2, _addScriptsButton.Height + 4, size.X - 4, size.Y - 4 - 20), style.ForegroundDisabled, TextAlignment.Center, TextAlignment.Center);
// Check if drag is over
if (IsDragOver && _dragHandlers != null && _dragHandlers.HasValidDrag)
@@ -554,8 +558,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
return;
for (int j = 0; j < e.Length; j++)
{
var t1 = scripts[j]?.TypeName;
var t2 = e[j]?.TypeName;
var t1 = scripts[j] != null ? scripts[j].TypeName : null;
var t2 = e[j] != null ? e[j].TypeName : null;
if (t1 != t2)
return;
}

View File

@@ -422,12 +422,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Set control type button
var space = layout.Space(20);
float setTypeButtonWidth = 60.0f;
var buttonText = "Set Type";
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.MeasureText(buttonText);
float setTypeButtonWidth = (textSize.X < 60.0f) ? 60.0f : textSize.X + 4;
var setTypeButton = new Button
{
TooltipText = "Sets the control to the given type",
AnchorPreset = AnchorPresets.MiddleCenter,
Text = "Set Type",
Text = buttonText,
Parent = space.Spacer,
Bounds = new Rectangle((space.Spacer.Width - setTypeButtonWidth) / 2, 1, setTypeButtonWidth, 18),
};

View File

@@ -88,20 +88,20 @@ namespace FlaxEditor.CustomEditors.Editors
LinkValues = Editor.Instance.Windows.PropertiesWin.ScaleLinked;
// Add button with the link icon
_linkButton = new Button
{
BackgroundBrush = new SpriteBrush(Editor.Instance.Icons.Link32),
Parent = LinkedLabel,
Width = 18,
Height = 18,
AnchorPreset = AnchorPresets.TopLeft,
AnchorPreset = AnchorPresets.MiddleLeft,
};
_linkButton.Clicked += ToggleLink;
ToggleEnabled();
SetLinkStyle();
var x = LinkedLabel.Text.Value.Length * 7 + 5;
_linkButton.LocalX += x;
_linkButton.LocalY += 1;
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.MeasureText(LinkedLabel.Text.Value);
_linkButton.LocalX += textSize.X + 10;
LinkedLabel.SetupContextMenu += (label, menu, editor) =>
{
menu.AddSeparator();

View File

@@ -34,7 +34,9 @@ namespace FlaxEditor.CustomEditors.Editors
}
else
{
element.CheckBox.Checked = (bool)Values[0];
var value = (bool?)Values[0];
if (value != null)
element.CheckBox.Checked = value.Value;
}
}
}

View File

@@ -623,13 +623,18 @@ namespace FlaxEditor.CustomEditors.Editors
{
_label = layout.ClickableLabel(GetText(out _)).CustomControl;
_label.RightClick += ShowPicker;
var buttonText = "...";
var button = new Button
{
Size = new Float2(16.0f),
Text = "...",
Text = buttonText,
TooltipText = "Edit...",
Parent = _label,
};
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.MeasureText(buttonText);
if (textSize.Y > button.Width)
button.Width = textSize.Y + 2;
button.SetAnchorPreset(AnchorPresets.MiddleRight, false, true);
button.Clicked += ShowPicker;
}

View File

@@ -36,7 +36,9 @@ namespace FlaxEditor
public static void OnEditorOptionsChanged(Options.EditorOptions options)
{
var param = _highlightMaterial?.GetParameter("Color");
if (!_highlightMaterial)
return;
var param = _highlightMaterial.GetParameter("Color");
if (param != null)
param.Value = options.Visual.HighlightColor;
}

View File

@@ -37,6 +37,9 @@ namespace FlaxEditor.GUI
: base(0, 0, 100, height)
{
Depth = -1;
if (Height < Style.Current.FontMedium.Height)
Height = Style.Current.FontMedium.Height + 4;
}
/// <inheritdoc />

View File

@@ -33,7 +33,7 @@ namespace FlaxEditor.GUI.Timeline
/// </summary>
public SceneAnimationPlayer Player
{
get => _player;
get => _player != null ? _player : null;
set
{
if (_player == value)
@@ -268,7 +268,7 @@ namespace FlaxEditor.GUI.Timeline
/// <inheritdoc />
public override void OnSeek(int frame)
{
if (_player?.Animation)
if (_player != null && _player.Animation)
{
_player.Animation.WaitForLoaded();
_player.Time = frame / _player.Animation.FramesPerSecond;

View File

@@ -129,6 +129,7 @@ namespace FlaxEditor.Modules
else
{
Editor.UI.UpdateProgress(string.Empty, 0);
Editor.UI.UpdateStatusBar();
}
}

View File

@@ -285,7 +285,7 @@ namespace FlaxEditor.Modules
Color color;
if (Editor.StateMachine.IsPlayMode)
color = Color.OrangeRed;
color = Style.Current.Statusbar.PlayMode;
else
color = Style.Current.BackgroundSelected;
@@ -299,6 +299,11 @@ namespace FlaxEditor.Modules
else
text = "Ready";
if(ProgressVisible)
{
color = Style.Current.Statusbar.Loading;
}
StatusBar.Text = text;
StatusBar.StatusColor = color;
_contentStats = contentStats;
@@ -344,7 +349,7 @@ namespace FlaxEditor.Modules
internal void ProgressFailed(string message)
{
_progressFailed = true;
StatusBar.StatusColor = Color.Red;
StatusBar.StatusColor = Style.Current.Statusbar.Failed;
StatusBar.Text = message;
_outputLogButton.Visible = true;
}
@@ -397,6 +402,10 @@ namespace FlaxEditor.Modules
{
UpdateStatusBar();
}
else if(ProgressVisible)
{
UpdateStatusBar();
}
}
private class CustomWindowBorderControl : Control
@@ -778,7 +787,7 @@ namespace FlaxEditor.Modules
HorizontalAlignment = TextAlignment.Far,
AnchorPreset = AnchorPresets.HorizontalStretchMiddle,
Parent = progressPanel,
Offsets = new Margin(progressBarRightMargin, progressBarWidth + progressBarLeftMargin + progressBarRightMargin, 0, 0),
Offsets = new Margin(progressBarRightMargin, progressBarWidth + progressBarLeftMargin + progressBarRightMargin, 0, 0)
};
UpdateStatusBar();

View File

@@ -721,7 +721,7 @@ namespace FlaxEditor.Modules
// Create main window
var settings = CreateWindowSettings.Default;
settings.Title = "Flax Editor";
//settings.Size = Platform.DesktopSize;
settings.Size = Platform.DesktopSize * 0.75f;
settings.StartPosition = WindowStartPosition.CenterScreen;
settings.ShowAfterFirstPaint = true;

View File

@@ -244,6 +244,13 @@ namespace FlaxEditor.Options
CollectionBackgroundColor = Color.FromBgra(0x14CCCCCC),
ProgressNormal = Color.FromBgra(0xFF0ad328),
Statusbar = new Style.StatusbarStyle()
{
PlayMode = Color.FromBgra(0xFF2F9135),
Failed = Color.FromBgra(0xFF9C2424),
Loading = Color.FromBgra(0xFF2D2D30)
},
// Fonts
FontTitle = options.Interface.TitleFont.GetFont(),
FontLarge = options.Interface.LargeFont.GetFont(),

View File

@@ -41,10 +41,8 @@ namespace FlaxEditor.Surface.Elements
}
// Calculate control points
var dst = (end - start) * new Float2(0.5f, 0.05f);
var control1 = new Float2(start.X + dst.X, start.Y + dst.Y);
var control2 = new Float2(end.X - dst.X, end.Y + dst.Y);
CalculateBezierControlPoints(start, end, out var control1, out var control2);
// Draw line
Render2D.DrawBezier(start, control1, control2, end, color, thickness);
@@ -56,6 +54,23 @@ namespace FlaxEditor.Surface.Elements
*/
}
private static void CalculateBezierControlPoints(Float2 start, Float2 end, out Float2 control1, out Float2 control2)
{
// Control points parameters
const float minControlLength = 100f;
const float maxControlLength = 150f;
var dst = (end - start).Length;
var yDst = Mathf.Abs(start.Y - end.Y);
// Calculate control points
var minControlDst = dst * 0.5f;
var maxControlDst = Mathf.Max(Mathf.Min(maxControlLength, dst), minControlLength);
var controlDst = Mathf.Lerp(minControlDst, maxControlDst, Mathf.Clamp(yDst / minControlLength, 0f, 1f));
control1 = new Float2(start.X + controlDst, start.Y);
control2 = new Float2(end.X - controlDst, end.Y);
}
/// <summary>
/// Checks if a point intersects a connection
/// </summary>
@@ -82,13 +97,9 @@ namespace FlaxEditor.Surface.Elements
float offset = Mathf.Sign(end.Y - start.Y) * distance;
if ((point.Y - (start.Y - offset)) * ((end.Y + offset) - point.Y) < 0) return false;
// Taken from the Render2D.DrawBezier code
float squaredDistance = distance;
var dst = (end - start) * new Float2(0.5f, 0.05f);
var control1 = new Float2(start.X + dst.X, start.Y + dst.Y);
var control2 = new Float2(end.X - dst.X, end.Y + dst.Y);
CalculateBezierControlPoints(start, end, out var control1, out var control2);
var d1 = control1 - start;
var d2 = control2 - control1;

View File

@@ -137,14 +137,23 @@ namespace FlaxEditor.Tools.Foliage
Offsets = Margin.Zero,
Parent = _noFoliagePanel
};
var buttonText = "Create new foliage";
_createNewFoliage = new Button
{
Text = "Create new foliage",
Text = buttonText,
AnchorPreset = AnchorPresets.MiddleCenter,
Offsets = new Margin(-60, 120, -12, 24),
Parent = _noFoliagePanel,
Enabled = false
};
var textSize = Style.Current.FontMedium.MeasureText(buttonText);
if (_createNewFoliage.Width < textSize.X)
{
_createNewFoliage.LocalX -= (textSize.X - _createNewFoliage.Width) / 2;
_createNewFoliage.Width = textSize.X + 6;
}
_createNewFoliage.Clicked += OnCreateNewFoliageClicked;
}

View File

@@ -375,7 +375,7 @@ namespace FlaxEditor.Tools.Foliage
private void OnModified()
{
Editor.Instance.Scene.MarkSceneEdited(_proxy.Foliage?.Scene);
Editor.Instance.Scene.MarkSceneEdited(_proxy.Foliage != null ? _proxy.Foliage.Scene : null);
}
private void OnSelectedFoliageChanged()

View File

@@ -218,7 +218,7 @@ namespace FlaxEditor.Tools.Foliage
private void OnModified()
{
Editor.Instance.Scene.MarkSceneEdited(_proxy.Foliage?.Scene);
Editor.Instance.Scene.MarkSceneEdited(_proxy.Foliage != null ? _proxy.Foliage.Scene : null);
}
private void OnSelectedFoliageChanged()

View File

@@ -95,14 +95,23 @@ namespace FlaxEditor.Tools.Terrain
Offsets = Margin.Zero,
Parent = _noTerrainPanel
};
var buttonText = "Create new terrain";
_createTerrainButton = new Button
{
Text = "Create new terrain",
Text = buttonText,
AnchorPreset = AnchorPresets.MiddleCenter,
Offsets = new Margin(-60, 120, -12, 24),
Parent = _noTerrainPanel,
Enabled = false
};
var textSize = Style.Current.FontMedium.MeasureText(buttonText);
if (_createTerrainButton.Width < textSize.X)
{
_createTerrainButton.LocalX -= (textSize.X - _createTerrainButton.Width) / 2;
_createTerrainButton.Width = textSize.X + 6;
}
_createTerrainButton.Clicked += OnCreateNewTerrainClicked;
}

View File

@@ -545,7 +545,7 @@ namespace FlaxEditor.Tools
public override bool IsControllingMouse => IsPainting;
/// <inheritdoc />
public override BoundingSphere FocusBounds => _selectedModel?.Sphere ?? base.FocusBounds;
public override BoundingSphere FocusBounds => _selectedModel != null ? _selectedModel.Sphere : base.FocusBounds;
/// <inheritdoc />
public override void Update(float dt)

View File

@@ -144,7 +144,7 @@ namespace FlaxEditor.Actions
{
var node = nodeParents[i];
var actor = node.Actor;
var parent = actor?.Parent;
var parent = actor != null ? actor.Parent : null;
if (parent != null)
{
bool IsNameValid(string name)

View File

@@ -441,6 +441,9 @@ namespace FlaxEditor.Viewport
if (useWidgets)
{
var largestText = "Invert Panning";
var textSize = Style.Current.FontMedium.MeasureText(largestText);
var xLocationForExtras = textSize.X + 5;
// Camera speed widget
var camSpeed = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
var camSpeedCM = new ContextMenu();
@@ -541,7 +544,7 @@ namespace FlaxEditor.Viewport
{
var ortho = ViewWidgetButtonMenu.AddButton("Orthographic");
ortho.CloseMenuOnClick = false;
var orthoValue = new CheckBox(90, 2, _isOrtho)
var orthoValue = new CheckBox(xLocationForExtras, 2, _isOrtho)
{
Parent = ortho
};
@@ -581,7 +584,7 @@ namespace FlaxEditor.Viewport
{
var fov = ViewWidgetButtonMenu.AddButton("Field Of View");
fov.CloseMenuOnClick = false;
var fovValue = new FloatValueBox(1, 90, 2, 70.0f, 35.0f, 160.0f, 0.1f)
var fovValue = new FloatValueBox(1, xLocationForExtras, 2, 70.0f, 35.0f, 160.0f, 0.1f)
{
Parent = fov
};
@@ -598,7 +601,7 @@ namespace FlaxEditor.Viewport
{
var orthoSize = ViewWidgetButtonMenu.AddButton("Ortho Scale");
orthoSize.CloseMenuOnClick = false;
var orthoSizeValue = new FloatValueBox(_orthoSize, 90, 2, 70.0f, 0.001f, 100000.0f, 0.01f)
var orthoSizeValue = new FloatValueBox(_orthoSize, xLocationForExtras, 2, 70.0f, 0.001f, 100000.0f, 0.01f)
{
Parent = orthoSize
};
@@ -615,7 +618,7 @@ namespace FlaxEditor.Viewport
{
var nearPlane = ViewWidgetButtonMenu.AddButton("Near Plane");
nearPlane.CloseMenuOnClick = false;
var nearPlaneValue = new FloatValueBox(2.0f, 90, 2, 70.0f, 0.001f, 1000.0f)
var nearPlaneValue = new FloatValueBox(2.0f, xLocationForExtras, 2, 70.0f, 0.001f, 1000.0f)
{
Parent = nearPlane
};
@@ -627,7 +630,7 @@ namespace FlaxEditor.Viewport
{
var farPlane = ViewWidgetButtonMenu.AddButton("Far Plane");
farPlane.CloseMenuOnClick = false;
var farPlaneValue = new FloatValueBox(1000, 90, 2, 70.0f, 10.0f)
var farPlaneValue = new FloatValueBox(1000, xLocationForExtras, 2, 70.0f, 10.0f)
{
Parent = farPlane
};
@@ -639,7 +642,7 @@ namespace FlaxEditor.Viewport
{
var brightness = ViewWidgetButtonMenu.AddButton("Brightness");
brightness.CloseMenuOnClick = false;
var brightnessValue = new FloatValueBox(1.0f, 90, 2, 70.0f, 0.001f, 10.0f, 0.001f)
var brightnessValue = new FloatValueBox(1.0f, xLocationForExtras, 2, 70.0f, 0.001f, 10.0f, 0.001f)
{
Parent = brightness
};
@@ -651,7 +654,7 @@ namespace FlaxEditor.Viewport
{
var resolution = ViewWidgetButtonMenu.AddButton("Resolution");
resolution.CloseMenuOnClick = false;
var resolutionValue = new FloatValueBox(1.0f, 90, 2, 70.0f, 0.1f, 4.0f, 0.001f)
var resolutionValue = new FloatValueBox(1.0f, xLocationForExtras, 2, 70.0f, 0.1f, 4.0f, 0.001f)
{
Parent = resolution
};
@@ -663,7 +666,7 @@ namespace FlaxEditor.Viewport
{
var invert = ViewWidgetButtonMenu.AddButton("Invert Panning");
invert.CloseMenuOnClick = false;
var invertValue = new CheckBox(90, 2, _invertPanning)
var invertValue = new CheckBox(xLocationForExtras, 2, _invertPanning)
{
Parent = invert
};

View File

@@ -68,7 +68,7 @@ namespace FlaxEditor.Viewport.Previews
/// </summary>
public bool ShowBounds
{
get => _boundsModel?.IsActive ?? false;
get => _boundsModel != null ? _boundsModel.IsActive : false;
set
{
if (value == ShowBounds)
@@ -110,7 +110,7 @@ namespace FlaxEditor.Viewport.Previews
/// </summary>
public bool ShowOrigin
{
get => _originModel?.IsActive ?? false;
get => _originModel != null ? _originModel.IsActive : false;
set
{
if (value == ShowOrigin)

View File

@@ -500,7 +500,7 @@ namespace FlaxEditor.Viewport.Previews
/// <inheritdoc />
protected override void CalculateTextureRect(out Rectangle rect)
{
CalculateTextureRect(_asset?.Size ?? new Float2(100), Size, out rect);
CalculateTextureRect(_asset != null ? _asset.Size : new Float2(100), Size, out rect);
}
/// <inheritdoc />
@@ -549,7 +549,7 @@ namespace FlaxEditor.Viewport.Previews
/// <inheritdoc />
protected override void CalculateTextureRect(out Rectangle rect)
{
CalculateTextureRect(_asset?.Size ?? new Float2(100), Size, out rect);
CalculateTextureRect(_asset != null ? _asset.Size : new Float2(100), Size, out rect);
}
/// <inheritdoc />
@@ -604,7 +604,7 @@ namespace FlaxEditor.Viewport.Previews
/// <inheritdoc />
protected override void CalculateTextureRect(out Rectangle rect)
{
CalculateTextureRect(_asset?.Size ?? new Float2(100), Size, out rect);
CalculateTextureRect(_asset != null ? _asset.Size : new Float2(100), Size, out rect);
}
/// <inheritdoc />
@@ -659,7 +659,7 @@ namespace FlaxEditor.Viewport.Previews
/// <inheritdoc />
protected override void CalculateTextureRect(out Rectangle rect)
{
CalculateTextureRect(_asset?.Size ?? new Float2(100), Size, out rect);
CalculateTextureRect(_asset != null ? _asset.Size : new Float2(100), Size, out rect);
}
/// <inheritdoc />

View File

@@ -52,9 +52,11 @@ namespace FlaxEditor.Windows
VerticalAlignment = TextAlignment.Near,
Parent = this
};
var copyVersionButton = new Button(Width - 104, 6, 100, 20)
var buttonText = "Copy version info";
var fontSize = Style.Current.FontMedium.MeasureText(buttonText);
var copyVersionButton = new Button(Width - fontSize.X - 8, 6, fontSize.X + 4, 20)
{
Text = "Copy version info",
Text = buttonText,
TooltipText = "Copies the current engine version information to system clipboard.",
Parent = this
};

View File

@@ -200,6 +200,7 @@ namespace FlaxEditor.Windows.Assets
ViewportCamera = new FPSCamera(),
Parent = _split.Panel1
};
_preview.Task.ViewFlags &= ~ViewFlags.Sky & ~ViewFlags.Bloom;
// Asset properties
_propertiesPresenter = new CustomEditorPresenter(null);

View File

@@ -69,7 +69,7 @@ namespace FlaxEditor.Windows.Assets
[EditorDisplay("General"), Tooltip("The base material used to override it's properties")]
public MaterialBase BaseMaterial
{
get => Window?.Asset?.BaseMaterial;
get => Window?.Asset != null ? Window?.Asset.BaseMaterial : null;
set
{
var asset = Window?.Asset;
@@ -101,10 +101,12 @@ namespace FlaxEditor.Windows.Assets
[HideInEditor]
public object[] Values
{
get => Window?.Asset?.Parameters.Select(x => x.Value).ToArray();
get => Window?.Asset != null ? Window?.Asset.Parameters.Select(x => x.Value).ToArray() : null;
set
{
var parameters = Window?.Asset?.Parameters;
if (Window?.Asset == null)
return;
var parameters = Window?.Asset.Parameters;
if (value != null && parameters != null)
{
if (value.Length != parameters.Length)
@@ -131,9 +133,11 @@ namespace FlaxEditor.Windows.Assets
[HideInEditor]
public FlaxEngine.Object[] ValuesRef
{
get => Window?.Asset?.Parameters.Select(x => x.Value as FlaxEngine.Object).ToArray();
get => Window?.Asset != null ? Window?.Asset.Parameters.Select(x => x.Value as FlaxEngine.Object).ToArray() : null;
set
{
if (Window?.Asset == null)
return;
var parameters = Window?.Asset?.Parameters;
if (value != null && parameters != null)
{
@@ -293,7 +297,7 @@ namespace FlaxEditor.Windows.Assets
var p = (MaterialParameter)e.Tag;
// Try to get default value (from the base material)
var pBase = baseMaterial?.GetParameter(p.Name);
var pBase = baseMaterial != null ? baseMaterial.GetParameter(p.Name) : null;
if (pBase != null && pBase.ParameterType == p.ParameterType)
{
valueContainer.SetDefaultValue(pBase.Value);

View File

@@ -134,7 +134,7 @@ namespace FlaxEditor.Windows.Assets
if (Window._skipEffectsGuiEvents)
return;
Window._isolateIndex = mesh?.MaterialSlotIndex ?? -1;
Window._isolateIndex = mesh != null ? mesh.MaterialSlotIndex : -1;
Window.UpdateEffectsOnAsset();
UpdateEffectsOnUI();
}
@@ -144,7 +144,7 @@ namespace FlaxEditor.Windows.Assets
if (Window._skipEffectsGuiEvents)
return;
Window._highlightIndex = mesh?.MaterialSlotIndex ?? -1;
Window._highlightIndex = mesh != null ? mesh.MaterialSlotIndex : -1;
Window.UpdateEffectsOnAsset();
UpdateEffectsOnUI();
}
@@ -326,7 +326,7 @@ namespace FlaxEditor.Windows.Assets
[EditorOrder(10), EditorDisplay("Materials", EditorDisplayAttribute.InlineStyle)]
public MaterialSlot[] MaterialSlots
{
get => Asset?.MaterialSlots;
get => Asset != null ? Asset.MaterialSlots : null;
set
{
if (Asset != null)

View File

@@ -187,7 +187,7 @@ namespace FlaxEditor.Windows.Assets
base.Initialize(layout);
var emitterTrack = Values[0] as EmitterTrackProxy;
if (emitterTrack?._effect?.Parameters == null)
if (emitterTrack?._effect == null || emitterTrack?._effect.Parameters == null)
return;
var group = layout.Group("Parameters");

View File

@@ -792,7 +792,7 @@ namespace FlaxEditor.Windows.Assets
{
if (_previewButton.Checked)
return;
_previewPlayerPicker.Value = _timeline.Player;
_previewPlayerPicker.Value = _timeline.Player != null ? _timeline.Player : null;
_cachedPlayerId = _timeline.Player?.ID ?? Guid.Empty;
}
@@ -821,7 +821,7 @@ namespace FlaxEditor.Windows.Assets
if (_timeline.IsModified)
{
var time = _timeline.CurrentTime;
var isPlaying = _previewPlayer?.IsPlaying ?? false;
var isPlaying = _previewPlayer != null ? _previewPlayer.IsPlaying : false;
_timeline.Save(_asset);
if (_previewButton.Checked && _previewPlayer != null)
{

View File

@@ -151,7 +151,7 @@ namespace FlaxEditor.Windows.Assets
if (Window._skipEffectsGuiEvents)
return;
Window._isolateIndex = mesh?.MaterialSlotIndex ?? -1;
Window._isolateIndex = mesh != null ? mesh.MaterialSlotIndex : -1;
Window.UpdateEffectsOnAsset();
UpdateEffectsOnUI();
}
@@ -165,7 +165,7 @@ namespace FlaxEditor.Windows.Assets
if (Window._skipEffectsGuiEvents)
return;
Window._highlightIndex = mesh?.MaterialSlotIndex ?? -1;
Window._highlightIndex = mesh != null ? mesh.MaterialSlotIndex : -1;
Window.UpdateEffectsOnAsset();
UpdateEffectsOnUI();
}
@@ -415,7 +415,7 @@ namespace FlaxEditor.Windows.Assets
[EditorOrder(10), EditorDisplay("Materials", EditorDisplayAttribute.InlineStyle)]
public MaterialSlot[] MaterialSlots
{
get => Asset?.MaterialSlots;
get => Asset != null ? Asset.MaterialSlots : null;
set
{
if (Asset != null)

View File

@@ -160,7 +160,7 @@ namespace FlaxEditor.Windows
Parent = this,
};
_viewDropdown.Clicked += OnViewButtonClicked;
_searchBox = new SearchBox(false, _viewDropdown.Right + 2, 2, Width - _viewDropdown.Right - 2 - _scrollSize)
_searchBox = new SearchBox(false, _viewDropdown.Right + 2, 2, Width - _viewDropdown.Right - 4)
{
Parent = this,
};
@@ -171,11 +171,12 @@ namespace FlaxEditor.Windows
Maximum = 0,
};
_hScroll.ValueChanged += OnHScrollValueChanged;
_vScroll = new VScrollBar(this, Width - _scrollSize, Height, _scrollSize)
_vScroll = new VScrollBar(this, Width - _scrollSize, Height - _viewDropdown.Height - 2, _scrollSize)
{
ThumbThickness = 10,
Maximum = 0,
};
_vScroll.Y += _viewDropdown.Height + 2;
_vScroll.ValueChanged += OnVScrollValueChanged;
_output = new OutputTextBox
{
@@ -409,7 +410,7 @@ namespace FlaxEditor.Windows
if (_output != null)
{
_searchBox.Width = Width - _viewDropdown.Right - 2 - _scrollSize;
_searchBox.Width = Width - _viewDropdown.Right - 4;
_output.Size = new Float2(_vScroll.X - 2, _hScroll.Y - 4 - _viewDropdown.Bottom);
}
}

View File

@@ -173,6 +173,9 @@ namespace FlaxEditor.Windows
// Spawn it
Editor.SceneEditing.Spawn(actor, parentActor);
Editor.SceneEditing.Select(actor);
Rename();
}
/// <summary>

View File

@@ -18,21 +18,21 @@ const Char* SplashScreenQuotes[] =
TEXT("Loading"),
TEXT("Unloading"),
TEXT("Reloading"),
TEXT("Reloading gun"),
TEXT("Downloading more RAM"),
TEXT("Consuming your RAM"),
TEXT("Burning your CPU"),
TEXT("#BetterThanUnity"),
TEXT("Rendering buttons"),
TEXT("Collecting crash data"),
TEXT("Downloading porn"),
#if PLATFORM_WINDOWS
TEXT("Removing 'C:\\Windows\\'"),
TEXT("We're getting everything ready for you."),
#elif PLATFORM_LINUX
TEXT("Time to switch to Windows?"),
TEXT("Installing Windows 10"),
TEXT("Try it on a Raspberry"),
TEXT("Trying to exit vim"),
TEXT("Sudo flax --loadproject"),
#elif PLATFORM_MAC
TEXT("Hacking your iPhone"),
TEXT("don't compare Macbooks to oranges."),
TEXT("Why does macbook heat up?\nBecause it doesn't have windows"),
TEXT("Starting Direc... um, Vulkan renderer."),
#endif
TEXT("Kappa!"),
TEXT("How you doin'?"),
@@ -40,12 +40,10 @@ const Char* SplashScreenQuotes[] =
TEXT("Bond. James Bond."),
TEXT("To infinity and beyond!"),
TEXT("Houston, we have a problem"),
TEXT("NotImplementedEngineException"),
TEXT("Made in Poland"),
TEXT("We like you"),
TEXT("Compiling the compiler"),
TEXT("Flax it up!"),
TEXT("Fun fact: Fortnite runs on Flax"),
TEXT("Toss a coin to your Witcher!!!"),
TEXT("Holy Moly!"),
TEXT("Just Read the Instructions"),
@@ -60,7 +58,6 @@ const Char* SplashScreenQuotes[] =
TEXT("They see me loadin'"),
TEXT("Loadin' loadin' and loadin' loadin'"),
TEXT("Procedurally generating buttons"),
TEXT("Out of Memory Exception!"),
TEXT("Running Big Bang simulation"),
TEXT("Calculating infinity"),
TEXT("Dividing infinity by zero"),
@@ -70,10 +67,7 @@ const Char* SplashScreenQuotes[] =
TEXT("Whatever you do, do it well.\n~Walt Disney"),
TEXT("Here's Johnny!"),
TEXT("Did you see that? No... I don't think so"),
TEXT("Collecting unreal power"),
TEXT("Stay safe, friend"),
TEXT("trolololololololololololo"),
TEXT("xD"),
TEXT("Come to the dark side"),
TEXT("Flax Facts: This is a loading screen"),
TEXT("Don't Stop Me Now"),
@@ -81,61 +75,58 @@ const Char* SplashScreenQuotes[] =
TEXT("Made with Flax"),
TEXT("This is the way"),
TEXT("The quick brown fox jumps over the lazy dog"),
TEXT("Hit The Road Jack"),
TEXT("You have 7 lives left"),
TEXT("May the Force be with you"),
TEXT("A martini. Shaken, not stirred"),
TEXT("Hasta la vista, baby"),
TEXT("Winter is coming"),
TEXT("You know nothing, Jon Snow"),
TEXT("Create something awesome!"),
TEXT("Well Polished Engine"),
TEXT("Error 404: Joke Not Found"),
TEXT("Rushing B"),
TEXT("Putting pineapple on pizza"),
TEXT("Loading Simulation"),
TEXT("Entering the Matrix"),
TEXT("Get ready for a surprise!"),
TEXT("Coffee is my fuel"),
TEXT("Installing a free copy of Cyberpunk 2077"),
TEXT("With great power comes great electricity bill"),
TEXT("Flax was made in the same city as Witcher 3"),
TEXT("So JavaScript is a scripting version of Java"),
TEXT("Good things take time.\n~Someone"),
TEXT("Get shit done"),
TEXT("Hold Tight! Loading Flax"),
TEXT("That's one small step for a man,\none giant leap for mankind"),
TEXT("Remember to save your work frequently"),
TEXT("In case of fire:\ngit commit, git push, leave building"),
TEXT("Keep calm and make games"),
TEXT("You're breathtaking!!!"),
TEXT("Do regular dogs see police dogs & think,\nOh no it's a cop?"),
TEXT("Dear Santa,\nDefine naughty."),
TEXT("Blah, blah"),
TEXT("My PRECIOUS!!!!"),
TEXT("YOU SHALL NOT PASS!"),
TEXT("You have my bow.\nAnd my axe!"),
TEXT("To the bridge of Khazad-dum."),
TEXT("One ring to rule them all.\nOne ring to find them."),
TEXT("Ladies and gentelman, we got him"),
TEXT("Cyberpunk of game engines"),
TEXT("That's what she said"),
TEXT("Compiling Shaders (93,788)"),
TEXT("We could be compiling shaders here"),
TEXT("Hello There"),
TEXT("BAGUETTE"),
TEXT("All we had to do was follow the damn train, CJ"),
TEXT("Here we go again"),
TEXT("@everyone"),
TEXT("Potato"),
TEXT("Python is a programming snek"),
TEXT("Flax will start when pigs will fly"),
TEXT("I'm the android sent by CyberLife"),
TEXT("Fancy-ass ray tracing, rtx on, lighting"),
TEXT("ZOINKS"),
TEXT("Scooby dooby doo"),
TEXT("You shall not load!"),
TEXT("The roof, the roof, the roof is on fire!"),
TEXT("I've seen better documentation...\nFrom ransomware gangs!"),
TEXT("Slava Ukraini!"),
TEXT("RTX off... for now!"),
TEXT("Increasing Fiber count"),
TEXT("Now this is podracing!"),
TEXT("Weird flax, but ok"),
TEXT("Reticulating Splines"),
TEXT("Discombobulating"),
TEXT("Who is signing all these integers?!"),
TEXT("Flax fact: Flax was called Celelej once."),
TEXT("Changing text overflow setti-"),
};
SplashScreen::~SplashScreen()

View File

@@ -905,7 +905,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3
MException ex(exception);
ex.Log(LogType::Error, TEXT("Property"));
}
else if (!MCore::Type::IsPointer(valueType))
else if (!MCore::Type::IsPointer(valueType) && !MCore::Type::IsReference(valueType))
{
if (boxed)
Platform::MemoryCopy(value, MCore::Object::Unbox(boxed), valueSize);

View File

@@ -58,6 +58,7 @@ using Mathr = FlaxEngine.Mathf;
*/
using System;
using System.Globalization;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -953,6 +954,91 @@ namespace FlaxEngine
return result;
}
/// <summary>
/// Performs a gradual change of a vector towards a specified target over time
/// </summary>
/// <param name="current">Current vector.</param>
/// <param name="target">Target vector.</param>
/// <param name="currentVelocity">Used to store the current velocity.</param>
/// <param name="smoothTime">Determines the approximate time it should take to reach the target vector.</param>
/// <param name="maxSpeed">Defines the upper limit on the speed of the Smooth Damp.</param>
public static Vector2 SmoothDamp(Vector2 current, Vector2 target, ref Vector2 currentVelocity, float smoothTime, float maxSpeed)
{
return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, Time.DeltaTime);
}
/// <summary>
/// Performs a gradual change of a vector towards a specified target over time
/// </summary>
/// <param name="current">Current vector.</param>
/// <param name="target">Target vector.</param>
/// <param name="currentVelocity">Used to store the current velocity.</param>
/// <param name="smoothTime">Determines the approximate time it should take to reach the target vector.</param>
public static Vector2 SmoothDamp(Vector2 current, Vector2 target, ref Vector2 currentVelocity, float smoothTime)
{
return SmoothDamp(current, target, ref currentVelocity, smoothTime, float.PositiveInfinity, Time.DeltaTime);
}
/// <summary>
/// Performs a gradual change of a vector towards a specified target over time
/// </summary>
/// <param name="current">Current vector.</param>
/// <param name="target">Target vector.</param>
/// <param name="currentVelocity">Used to store the current velocity.</param>
/// <param name="smoothTime">Determines the approximate time it should take to reach the target vector.</param>
/// <param name="maxSpeed">Defines the upper limit on the speed of the Smooth Damp.</param>
/// <param name="deltaTime">Delta Time, represents the time elapsed since last frame.</param>
public static Vector2 SmoothDamp(Vector2 current, Vector2 target, ref Vector2 currentVelocity, float smoothTime, [DefaultValue("float.PositiveInfinity")] float maxSpeed, [DefaultValue("Time.DeltaTime")] float deltaTime)
{
smoothTime = Mathf.Max(0.0001f, smoothTime);
Real a = 2f / smoothTime;
Real b = a * deltaTime;
Real e = 1f / (1f + b + 0.48f * b * b + 0.235f * b * b * b);
Real change_x = current.X - target.X;
Real change_y = current.Y - target.Y;
Vector2 originalTo = target;
Real maxChangeSpeed = maxSpeed * smoothTime;
Real changeSq = maxChangeSpeed * maxChangeSpeed;
Real sqrDist = change_x * change_x + change_y * change_y;
if (sqrDist > changeSq)
{
var dist = (Real)Math.Sqrt(sqrDist);
change_x = change_x / dist * maxChangeSpeed;
change_y = change_y / dist * maxChangeSpeed;
}
target.X = current.X - change_x;
target.Y = current.Y - change_y;
Real temp_x = (currentVelocity.X + a * change_x) * deltaTime;
Real temp_y = (currentVelocity.Y + a * change_y) * deltaTime;
currentVelocity.X = (currentVelocity.X - a * temp_x) * e;
currentVelocity.Y = (currentVelocity.Y - a * temp_y) * e;
Real output_x = target.X + (change_x + temp_x) * e;
Real output_y = target.Y + (change_y + temp_y) * e;
Real x1 = originalTo.X - current.X;
Real y1 = originalTo.Y - current.Y;
Real x2 = output_x - originalTo.X;
Real y2 = output_y - originalTo.Y;
if (x1 * x2 + y1 * y2 > 0)
{
output_x = originalTo.X;
output_y = originalTo.Y;
currentVelocity.X = (output_x - originalTo.X) / deltaTime;
currentVelocity.Y = (output_y - originalTo.Y) / deltaTime;
}
return new Vector2(output_x, output_y);
}
/// <summary>
/// Performs a cubic interpolation between two vectors.
/// </summary>

View File

@@ -58,6 +58,7 @@ using Mathr = FlaxEngine.Mathf;
*/
using System;
using System.Globalization;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -1042,6 +1043,103 @@ namespace FlaxEngine
return result;
}
/// <summary>
/// Performs a gradual change of a vector towards a specified target over time
/// </summary>
/// <param name="current">Current vector.</param>
/// <param name="target">Target vector.</param>
/// <param name="currentVelocity">Used to store the current velocity.</param>
/// <param name="smoothTime">Determines the approximate time it should take to reach the target vector.</param>
/// <param name="maxSpeed">Defines the upper limit on the speed of the Smooth Damp.</param>
public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime, float maxSpeed)
{
return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, Time.DeltaTime);
}
/// <summary>
/// Performs a gradual change of a vector towards a specified target over time
/// </summary>
/// <param name="current">Current vector.</param>
/// <param name="target">Target vector.</param>
/// <param name="currentVelocity">Used to store the current velocity.</param>
/// <param name="smoothTime">Determines the approximate time it should take to reach the target vector.</param>
public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime)
{
return SmoothDamp(current, target, ref currentVelocity, smoothTime, float.PositiveInfinity, Time.DeltaTime);
}
/// <summary>
/// Performs a gradual change of a vector towards a specified target over time
/// </summary>
/// <param name="current">Current vector.</param>
/// <param name="target">Target vector.</param>
/// <param name="currentVelocity">Used to store the current velocity.</param>
/// <param name="smoothTime">Determines the approximate time it should take to reach the target vector.</param>
/// <param name="maxSpeed">Defines the upper limit on the speed of the Smooth Damp.</param>
/// <param name="deltaTime">Delta Time, represents the time elapsed since last frame.</param>
public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime, [DefaultValue("float.PositiveInfinity")] float maxSpeed, [DefaultValue("Time.DeltaTime")] float deltaTime)
{
smoothTime = Mathf.Max(0.0001f, smoothTime);
Real a = 2f / smoothTime;
Real b = a * deltaTime;
Real e = 1f / (1f + b + 0.48f * b * b + 0.235f * b * b * b);
Real change_x = current.X - target.X;
Real change_y = current.Y - target.Y;
Real change_z = current.Z - target.Z;
Vector3 originalTo = target;
Real maxChangeSpeed = maxSpeed * smoothTime;
Real changeSq = maxChangeSpeed * maxChangeSpeed;
Real sqrLen = change_x * change_x + change_y * change_y + change_z * change_z;
if (sqrLen > changeSq)
{
var len = (Real)Math.Sqrt(sqrLen);
change_x = change_x / len * maxChangeSpeed;
change_y = change_y / len * maxChangeSpeed;
change_z = change_z / len * maxChangeSpeed;
}
target.X = current.X - change_x;
target.Y = current.Y - change_y;
target.Z = current.Z - change_z;
Real temp_x = (currentVelocity.X + a * change_x) * deltaTime;
Real temp_y = (currentVelocity.Y + a * change_y) * deltaTime;
Real temp_z = (currentVelocity.Z + a * change_z) * deltaTime;
currentVelocity.X = (currentVelocity.X - a * temp_x) * e;
currentVelocity.Y = (currentVelocity.Y - a * temp_y) * e;
currentVelocity.Z = (currentVelocity.Z - a * temp_z) * e;
Real output_x = target.X + (change_x + temp_x) * e;
Real output_y = target.Y + (change_y + temp_y) * e;
Real output_z = target.Z + (change_z + temp_z) * e;
Real x1 = originalTo.X - current.X;
Real y1 = originalTo.Y - current.Y;
Real z1 = originalTo.Z - current.Z;
Real x2 = output_x - originalTo.X;
Real y2 = output_y - originalTo.Y;
Real z2 = output_z - originalTo.Z;
if (x1 * x2 + y1 * y2 + z1 * z2 > 0)
{
output_x = originalTo.X;
output_y = originalTo.Y;
output_z = originalTo.Z;
currentVelocity.X = (output_x - originalTo.X) / deltaTime;
currentVelocity.Y = (output_y - originalTo.Y) / deltaTime;
currentVelocity.Z = (output_z - originalTo.Z) / deltaTime;
}
return new Vector3(output_x, output_y, output_z);
}
/// <summary>
/// Performs a cubic interpolation between two vectors.
/// </summary>

View File

@@ -1230,7 +1230,7 @@ namespace FlaxEngine.Interop
internal static bool GetTypeIsReference(ManagedHandle typeHandle)
{
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
return type.IsByRef;
return !type.IsValueType; // Maybe also type.IsByRef?
}
[UnmanagedCallersOnly]

View File

@@ -181,6 +181,11 @@ void Screen::SetGameWindowMode(GameWindowMode windowMode)
#endif
}
Window* Screen::GetMainWindow()
{
return Engine::MainWindow;
}
void ScreenService::Update()
{
#if USE_EDITOR

View File

@@ -96,4 +96,10 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Screen);
/// </remarks>
/// <param name="windowMode">The window mode.</param>
API_PROPERTY() static void SetGameWindowMode(GameWindowMode windowMode);
/// <summary>
/// Gets the main window.
/// </summary>
/// <returns>The current window. Will be null if fails.</returns>
API_PROPERTY() static Window* GetMainWindow();
};

View File

@@ -364,13 +364,20 @@ namespace FlaxEngine
/// <param name="point">The point (world-space).</param>
/// <param name="axis">The axis (normalized).</param>
/// <param name="angle">The angle (in degrees).</param>
public void RotateAround(Vector3 point, Vector3 axis, float angle)
/// /// <param name="orientActor">Whether to orient the actor the same amount as rotation.</param>
public void RotateAround(Vector3 point, Vector3 axis, float angle, bool orientActor = true)
{
var transform = Transform;
var q = Quaternion.RotationAxis(axis, angle * Mathf.DegreesToRadians);
var dif = (transform.Translation - point) * q;
transform.Translation = point + dif;
transform.Orientation = q;
if (Vector3.NearEqual(point, transform.Translation) && orientActor)
transform.Orientation *= q;
else
{
var dif = (transform.Translation - point) * q;
transform.Translation = point + dif;
if (orientActor)
transform.Orientation *= q;
}
Transform = transform;
}

View File

@@ -129,8 +129,15 @@ void ProfilerCPU::Thread::EndEvent()
{
const double time = Platform::GetTimeSeconds() * 1000.0;
_depth--;
Event& e = (Buffer.Last()--).Event();
e.End = time;
for (auto i = Buffer.Last(); i != Buffer.Begin(); --i)
{
Event& e = i.Event();
if (e.End <= 0)
{
e.End = time;
break;
}
}
}
bool ProfilerCPU::IsProfilingCurrentThread()

View File

@@ -121,15 +121,39 @@ public:
EventBuffer* _buffer;
int32 _index;
Iterator(EventBuffer* buffer, const int32 index)
FORCE_INLINE Iterator(EventBuffer* buffer, const int32 index)
: _buffer(buffer)
, _index(index)
{
}
Iterator(const Iterator& i) = default;
public:
FORCE_INLINE Iterator(const Iterator& other)
: _buffer(other._buffer)
, _index(other._index)
{
}
FORCE_INLINE Iterator(Iterator&& other) noexcept
: _buffer(other._buffer)
, _index(other._index)
{
}
FORCE_INLINE Iterator& operator=(Iterator&& other)
{
_buffer = other._buffer;
_index = other._index;
return *this;
}
FORCE_INLINE Iterator& operator=(const Iterator& other)
{
_buffer = other._buffer;
_index = other._index;
return *this;
}
FORCE_INLINE int32 Index() const
{
return _index;
@@ -141,15 +165,13 @@ public:
return _buffer->Get(_index);
}
bool IsEnd() const
FORCE_INLINE bool IsEnd() const
{
ASSERT_LOW_LAYER(_buffer);
return _index == _buffer->_head;
}
bool IsNotEnd() const
FORCE_INLINE bool IsNotEnd() const
{
ASSERT_LOW_LAYER(_buffer);
return _index != _buffer->_head;
}
@@ -164,31 +186,27 @@ public:
}
public:
Iterator& operator++()
FORCE_INLINE Iterator& operator++()
{
ASSERT(_buffer);
_index = (_index + 1) & _buffer->_capacityMask;
return *this;
}
Iterator operator++(int)
FORCE_INLINE Iterator operator++(int)
{
ASSERT(_buffer);
Iterator temp = *this;
_index = (_index + 1) & _buffer->_capacityMask;
return temp;
}
Iterator& operator--()
FORCE_INLINE Iterator& operator--()
{
ASSERT(_buffer);
_index = (_index - 1) & _buffer->_capacityMask;
return *this;
}
Iterator operator--(int)
FORCE_INLINE Iterator operator--(int)
{
ASSERT(_buffer);
Iterator temp = *this;
_index = (_index - 1) & _buffer->_capacityMask;
return temp;

View File

@@ -1240,8 +1240,12 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
return true;
}
#if USE_NETCORE
mInstance = instanceObject;
#else
// For value-types instance is the actual boxed object data, not te object itself
mInstance = instanceObjectClass->IsValueType() ? MCore::Object::Unbox(instanceObject) : instanceObject;
#endif
}
// Marshal parameters

View File

@@ -104,7 +104,7 @@ namespace
MMethod* _method_LateFixedUpdate = nullptr;
MMethod* _method_Draw = nullptr;
MMethod* _method_Exit = nullptr;
Array<BinaryModule*, InlinedAllocation<64>> _nonNativeModules;
Dictionary<StringAnsi, BinaryModule*, InlinedAllocation<64>> _nonNativeModules;
#if USE_EDITOR
bool LastBinariesLoadTriggeredCompilation = false;
#endif
@@ -329,6 +329,8 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde
// Check if that module has been already registered
BinaryModule* module = BinaryModule::GetModule(nameAnsi);
if (!module)
_nonNativeModules.TryGet(nameAnsi, module);
if (!module)
{
// C++
@@ -398,7 +400,7 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde
{
// Create module if native library is not used
module = New<ManagedBinaryModule>(nameAnsi);
_nonNativeModules.Add(module);
_nonNativeModules.Add(nameAnsi, module);
}
}

View File

@@ -282,6 +282,12 @@ namespace FlaxEngine
TextBoxBackgroundSelected = Color.FromBgra(0xFF3F3F46),
CollectionBackgroundColor = Color.FromBgra(0x14CCCCCC),
SharedTooltip = new Tooltip(),
Statusbar = new Style.StatusbarStyle()
{
PlayMode = Color.FromBgra(0xFF2F9135),
Failed = Color.FromBgra(0xFF9C2424),
Loading = Color.FromBgra(0xFF2D2D30)
}
};
style.DragWindow = style.BackgroundSelected * 0.7f;

View File

@@ -37,7 +37,7 @@ namespace FlaxEngine.GUI
}
/// <inheritdoc />
public Float2 Size => Texture?.Size ?? Float2.Zero;
public Float2 Size => Texture != null ? Texture.Size : Float2.Zero;
/// <inheritdoc />
public void Draw(Rectangle rect, Color color)

View File

@@ -104,7 +104,7 @@ namespace FlaxEngine.GUI
}
/// <inheritdoc />
public Float2 Size => Texture?.Size ?? Float2.Zero;
public Float2 Size => Texture != null ? Texture.Size : Float2.Zero;
/// <inheritdoc />
public unsafe void Draw(Rectangle rect, Color color)

View File

@@ -74,10 +74,16 @@ namespace FlaxEngine.GUI
[EditorDisplay("Text Style"), EditorOrder(2022), Tooltip("The text wrapping within the control bounds.")]
public TextWrapping Wrapping { get; set; } = TextWrapping.NoWrap;
/// <summary>
/// Gets or sets the text wrapping within the control bounds.
/// </summary>
[EditorDisplay("Text Style"), EditorOrder(2023), Tooltip("The gap between lines when wrapping and more than a single line is displayed."), Limit(0f)]
public float BaseLinesGapScale { get; set; } = 1.0f;
/// <summary>
/// Gets or sets the font.
/// </summary>
[EditorDisplay("Text Style"), EditorOrder(2023)]
[EditorDisplay("Text Style"), EditorOrder(2024)]
public FontReference Font
{
get => _font;
@@ -99,7 +105,7 @@ namespace FlaxEngine.GUI
/// <summary>
/// Gets or sets the custom material used to render the text. It must has domain set to GUI and have a public texture parameter named Font used to sample font atlas texture with font characters data.
/// </summary>
[EditorDisplay("Text Style"), EditorOrder(2024)]
[EditorDisplay("Text Style"), EditorOrder(2025)]
public MaterialBase Material { get; set; }
/// <summary>
@@ -227,7 +233,7 @@ namespace FlaxEngine.GUI
}
}
Render2D.DrawText(_font.GetFont(), Material, _text, rect, color, hAlignment, wAlignment, Wrapping, 1.0f, scale);
Render2D.DrawText(_font.GetFont(), Material, _text, rect, color, hAlignment, wAlignment, Wrapping, BaseLinesGapScale, scale);
if (ClipText)
Render2D.PopClip();
@@ -249,6 +255,7 @@ namespace FlaxEngine.GUI
else if (_autoWidth && !_autoHeight)
layout.Bounds.Size.Y = Height - Margin.Height;
_textSize = font.MeasureText(_text, ref layout);
_textSize.Y *= BaseLinesGapScale;
// Check if size is controlled via text
if (_autoWidth || _autoHeight)

View File

@@ -11,7 +11,7 @@ namespace FlaxEngine.GUI
/// <summary>
/// Gets or sets the blur strength. Defines how blurry the background is. Larger numbers increase blur, resulting in a larger runtime cost on the GPU.
/// </summary>
[EditorOrder(0), Limit(0, 100, 0.0f)]
[EditorOrder(0), Limit(0, 100, 0.1f)]
public float BlurStrength { get; set; }
/// <summary>
@@ -29,10 +29,9 @@ namespace FlaxEngine.GUI
}
/// <inheritdoc />
public override void Draw()
public override void DrawSelf()
{
base.Draw();
base.DrawSelf();
var size = Size;
var strength = BlurStrength;
if (BlurScaleWithSize)

View File

@@ -164,6 +164,12 @@ namespace FlaxEngine.GUI
[EditorOrder(200)]
public Color ProgressNormal;
/// <summary>
/// The status bar style
/// </summary>
[EditorOrder(210)]
public StatusbarStyle Statusbar;
/// <summary>
/// The arrow right icon.
/// </summary>
@@ -241,5 +247,27 @@ namespace FlaxEngine.GUI
/// </summary>
[EditorOrder(340)]
public Tooltip SharedTooltip;
/// <summary>
/// Style for the Statusbar
/// </summary>
[System.Serializable, ShowInEditor]
public struct StatusbarStyle
{
/// <summary>
/// Color of the Statusbar when in Play Mode
/// </summary>
public Color PlayMode;
/// <summary>
/// Color of the Statusbar when in loading state (e.g. when importing assets)
/// </summary>
public Color Loading;
/// <summary>
/// Color of the Statusbar in its failed state (e.g. with compilation errors)
/// </summary>
public Color Failed;
}
}
}

View File

@@ -181,6 +181,9 @@ namespace FlaxEngine.GUI
private void WrapPosition(ref Float2 locationSS, float flipOffset = 0.0f)
{
if (_showTarget?.RootWindow == null)
return;
// Calculate popup direction
var dpiScale = _showTarget.RootWindow.DpiScale;
var dpiSize = Size * dpiScale;
@@ -207,7 +210,8 @@ namespace FlaxEngine.GUI
// Move window with mouse location
var mousePos = Input.MouseScreenPosition;
WrapPosition(ref mousePos, 10);
_window.Position = mousePos + new Float2(15, 10);
if (_window)
_window.Position = mousePos + new Float2(15, 10);
// Auto hide if mouse leaves control area
var location = _showTarget.PointFromScreen(mousePos);

View File

@@ -493,7 +493,8 @@ namespace FlaxEngine
if (_renderer)
{
#if FLAX_EDITOR
_editorTask?.RemoveCustomPostFx(_renderer);
if (_editorTask != null)
_editorTask.RemoveCustomPostFx(_renderer);
#endif
SceneRenderTask.RemoveGlobalCustomPostFx(_renderer);
_renderer.Canvas = null;

View File

@@ -204,7 +204,7 @@ namespace FlaxEngine
up = value;
Internal_SetNavTargets(__unmanagedPtr, GetUnmanagedPtr(up), GetUnmanagedPtr(down), GetUnmanagedPtr(left), GetUnmanagedPtr(right));
if (_control != null)
_control.NavTargetUp = value?.Control;
_control.NavTargetUp = value != null ? value.Control : null;
}
}
@@ -228,7 +228,7 @@ namespace FlaxEngine
down = value;
Internal_SetNavTargets(__unmanagedPtr, GetUnmanagedPtr(up), GetUnmanagedPtr(down), GetUnmanagedPtr(left), GetUnmanagedPtr(right));
if (_control != null)
_control.NavTargetDown = value?.Control;
_control.NavTargetDown = value != null ? value.Control : null;
}
}
@@ -252,7 +252,7 @@ namespace FlaxEngine
left = value;
Internal_SetNavTargets(__unmanagedPtr, GetUnmanagedPtr(up), GetUnmanagedPtr(down), GetUnmanagedPtr(left), GetUnmanagedPtr(right));
if (_control != null)
_control.NavTargetLeft = value?.Control;
_control.NavTargetLeft = value != null ? value.Control : null;
}
}
@@ -276,7 +276,7 @@ namespace FlaxEngine
right = value;
Internal_SetNavTargets(__unmanagedPtr, GetUnmanagedPtr(up), GetUnmanagedPtr(down), GetUnmanagedPtr(left), GetUnmanagedPtr(right));
if (_control != null)
_control.NavTargetRight = value?.Control;
_control.NavTargetRight = value != null ? value.Control : null;
}
}

View File

@@ -192,11 +192,9 @@ namespace Flax.Build
case TargetPlatform.Linux:
{
rid = $"linux-{arch}";
ridFallback = "";
ridFallback = Utilities.ReadProcessOutput("dotnet", "--info").Split('\n').FirstOrDefault(x => x.StartsWith(" RID:"), "").Replace("RID:", "").Trim();
if (string.IsNullOrEmpty(dotnetPath))
dotnetPath ??= SearchForDotnetLocationLinux();
if (dotnetPath == null)
ridFallback = Utilities.ReadProcessOutput("dotnet", "--info").Split('\n').FirstOrDefault(x => x.StartsWith(" RID:"), "").Replace("RID:", "").Trim();
break;
}
case TargetPlatform.Mac:

View File

@@ -166,12 +166,14 @@ namespace Flax.Build.Projects.VisualStudio
{
try
{
Regex projectRegex = new Regex(@"Project\(.*\) = \""(\S+)\"", \""(\S+)\"", \""{(\S+)}\""");
Regex projectRegex = new Regex(@"Project\(""{(\S+)}""\) = \""(\S+)\"", \""(\S+)\"", \""{(\S+)}\""");
MatchCollection matches = projectRegex.Matches(File.ReadAllText(path));
for (int i = 0; i < matches.Count; i++)
{
if (matches[i].Groups[1].Value == projectName)
return Guid.ParseExact(matches[i].Groups[3].Value, "D");
if (matches[i].Groups[1].Value.Equals("2150E333-8FDC-42A3-9474-1A3956D46DE8", StringComparison.OrdinalIgnoreCase))
continue;
if (matches[i].Groups[2].Value == projectName)
return Guid.ParseExact(matches[i].Groups[4].Value, "D");
}
}
catch
@@ -376,7 +378,8 @@ namespace Flax.Build.Projects.VisualStudio
{
if (!folderIds.TryGetValue(folderPath, out project.FolderGuid))
{
project.FolderGuid = Guid.NewGuid();
if (!folderIds.TryGetValue(folderParents[i], out project.FolderGuid))
project.FolderGuid = Guid.NewGuid();
folderIds.Add(folderPath, project.FolderGuid);
}
folderNames.Add(folderPath);
@@ -479,7 +482,7 @@ namespace Flax.Build.Projects.VisualStudio
{
SolutionConfiguration projectConfiguration;
bool build = false;
int firstFullMatch = -1, firstPlatformMatch = -1;
int firstFullMatch = -1, firstPlatformMatch = -1, firstEditorMatch = -1;
for (int i = 0; i < project.Configurations.Count; i++)
{
var e = new SolutionConfiguration(project.Configurations[i]);
@@ -492,18 +495,31 @@ namespace Flax.Build.Projects.VisualStudio
{
firstPlatformMatch = i;
}
if (firstEditorMatch == -1 && e.Configuration == configuration.Configuration)
{
firstEditorMatch = i;
}
}
if (firstFullMatch != -1)
{
projectConfiguration = configuration;
build = solution.MainProject == project || (solution.MainProject == null && project.Name == solution.Name);
}
else if (firstPlatformMatch != -1)
else if (firstPlatformMatch != -1 && !configuration.Name.StartsWith("Editor."))
{
// No exact match, pick the first configuration for matching platform
projectConfiguration = new SolutionConfiguration(project.Configurations[firstPlatformMatch]);
}
else if (firstEditorMatch != -1 && configuration.Name.StartsWith("Editor."))
{
// No exact match, pick the matching editor configuration for different platform.
// As an example, Editor configuration for Android projects should be remapped
// to desktop platform in order to provide working Intellisense information.
projectConfiguration = new SolutionConfiguration(project.Configurations[firstEditorMatch]);
}
else
{
// No match
projectConfiguration = new SolutionConfiguration(project.Configurations[0]);
}

View File

@@ -155,122 +155,122 @@ namespace Flax.Build.Projects.VisualStudioCode
{
foreach (var project in solution.Projects)
{
// C++ project
if (project.Type == TargetType.NativeCpp)
if (project.Name == "BuildScripts")
continue;
// Skip duplicate build tasks
if (project.Name == "FlaxEngine" || (solution.MainProject.Name != "Flax" && solution.MainProject != project))
continue;
bool defaultTask = project == solution.MainProject;
foreach (var configuration in project.Configurations)
{
bool defaultTask = project == solution.MainProject;
foreach (var configuration in project.Configurations)
var target = configuration.Target;
var name = project.Name + '|' + configuration.Name;
json.BeginObject();
json.AddField("label", name);
bool isDefaultTask = defaultTask && configuration.Configuration == TargetConfiguration.Development && configuration.Platform == Platform.BuildPlatform.Target;
json.BeginObject("group");
{
var target = configuration.Target;
var name = project.Name + '|' + configuration.Name;
json.BeginObject();
json.AddField("label", name);
if (defaultTask && configuration.Configuration == TargetConfiguration.Development && configuration.Platform == Platform.BuildPlatform.Target)
{
defaultTask = false;
json.BeginObject("group");
{
json.AddField("kind", "build");
json.AddField("isDefault", true);
}
json.EndObject();
}
else
{
json.AddField("group", "build");
}
switch (Platform.BuildPlatform.Target)
{
case TargetPlatform.Windows:
{
json.AddField("command", buildToolPath);
json.BeginArray("args");
{
json.AddUnnamedField("-build");
json.AddUnnamedField("-log");
json.AddUnnamedField("-mutex");
json.AddUnnamedField(string.Format("\\\"-workspace={0}\\\"", buildToolWorkspace));
json.AddUnnamedField(string.Format("-arch={0}", configuration.ArchitectureName));
json.AddUnnamedField(string.Format("-configuration={0}", configuration.ConfigurationName));
json.AddUnnamedField(string.Format("-platform={0}", configuration.PlatformName));
json.AddUnnamedField(string.Format("-buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("-compiler={0}", Configuration.Compiler));
}
json.EndArray();
json.AddField("type", "shell");
json.BeginObject("options");
{
json.AddField("cwd", buildToolWorkspace);
}
json.EndObject();
break;
}
case TargetPlatform.Linux:
{
json.AddField("command", buildToolPath);
json.BeginArray("args");
{
json.AddUnnamedField("--build");
json.AddUnnamedField("--log");
json.AddUnnamedField("--mutex");
json.AddUnnamedField(string.Format("--workspace=\\\"{0}\\\"", buildToolWorkspace));
json.AddUnnamedField(string.Format("--arch={0}", configuration.Architecture));
json.AddUnnamedField(string.Format("--configuration={0}", configuration.ConfigurationName));
json.AddUnnamedField(string.Format("--platform={0}", configuration.PlatformName));
json.AddUnnamedField(string.Format("--buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("--compiler={0}", Configuration.Compiler));
}
json.EndArray();
json.AddField("type", "shell");
json.BeginObject("options");
{
json.AddField("cwd", buildToolWorkspace);
}
json.EndObject();
break;
}
case TargetPlatform.Mac:
{
json.AddField("command", buildToolPath);
json.BeginArray("args");
{
json.AddUnnamedField("--build");
json.AddUnnamedField("--log");
json.AddUnnamedField("--mutex");
json.AddUnnamedField(string.Format("--workspace=\\\"{0}\\\"", buildToolWorkspace));
json.AddUnnamedField(string.Format("--arch={0}", configuration.Architecture));
json.AddUnnamedField(string.Format("--configuration={0}", configuration.ConfigurationName));
json.AddUnnamedField(string.Format("--platform={0}", configuration.PlatformName));
json.AddUnnamedField(string.Format("--buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("--compiler={0}", Configuration.Compiler));
}
json.EndArray();
json.AddField("type", "shell");
json.BeginObject("options");
{
json.AddField("cwd", buildToolWorkspace);
}
json.EndObject();
break;
}
default: throw new Exception("Visual Code project generator does not support current platform.");
}
json.EndObject();
json.AddField("kind", "build");
json.AddField("isDefault", isDefaultTask);
}
json.EndObject();
if (isDefaultTask)
defaultTask = false;
switch (Platform.BuildPlatform.Target)
{
case TargetPlatform.Windows:
{
json.AddField("command", buildToolPath);
json.BeginArray("args");
{
json.AddUnnamedField("-build");
json.AddUnnamedField("-log");
json.AddUnnamedField("-mutex");
json.AddUnnamedField(string.Format("\\\"-workspace={0}\\\"", buildToolWorkspace));
json.AddUnnamedField(string.Format("-arch={0}", configuration.ArchitectureName));
json.AddUnnamedField(string.Format("-configuration={0}", configuration.ConfigurationName));
json.AddUnnamedField(string.Format("-platform={0}", configuration.PlatformName));
json.AddUnnamedField(string.Format("-buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("-compiler={0}", Configuration.Compiler));
}
json.EndArray();
json.AddField("type", "shell");
json.BeginObject("options");
{
json.AddField("cwd", buildToolWorkspace);
}
json.EndObject();
break;
}
case TargetPlatform.Linux:
{
json.AddField("command", buildToolPath);
json.BeginArray("args");
{
json.AddUnnamedField("--build");
json.AddUnnamedField("--log");
json.AddUnnamedField("--mutex");
json.AddUnnamedField(string.Format("--workspace=\\\"{0}\\\"", buildToolWorkspace));
json.AddUnnamedField(string.Format("--arch={0}", configuration.Architecture));
json.AddUnnamedField(string.Format("--configuration={0}", configuration.ConfigurationName));
json.AddUnnamedField(string.Format("--platform={0}", configuration.PlatformName));
json.AddUnnamedField(string.Format("--buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("--compiler={0}", Configuration.Compiler));
}
json.EndArray();
json.AddField("type", "shell");
json.BeginObject("options");
{
json.AddField("cwd", buildToolWorkspace);
}
json.EndObject();
break;
}
case TargetPlatform.Mac:
{
json.AddField("command", buildToolPath);
json.BeginArray("args");
{
json.AddUnnamedField("--build");
json.AddUnnamedField("--log");
json.AddUnnamedField("--mutex");
json.AddUnnamedField(string.Format("--workspace=\\\"{0}\\\"", buildToolWorkspace));
json.AddUnnamedField(string.Format("--arch={0}", configuration.Architecture));
json.AddUnnamedField(string.Format("--configuration={0}", configuration.ConfigurationName));
json.AddUnnamedField(string.Format("--platform={0}", configuration.PlatformName));
json.AddUnnamedField(string.Format("--buildTargets={0}", target.Name));
if (!string.IsNullOrEmpty(Configuration.Compiler))
json.AddUnnamedField(string.Format("--compiler={0}", Configuration.Compiler));
}
json.EndArray();
json.AddField("type", "shell");
json.BeginObject("options");
{
json.AddField("cwd", buildToolWorkspace);
}
json.EndObject();
break;
}
default: throw new Exception("Visual Code project generator does not support current platform.");
}
json.EndObject();
}
}
}
@@ -281,6 +281,10 @@ namespace Flax.Build.Projects.VisualStudioCode
json.Save(Path.Combine(vsCodeFolder, "tasks.json"));
}
bool hasNativeProjects = solution.Projects.Any(x => x.Type == TargetType.NativeCpp);
bool hasMonoProjects = solution.Projects.Any(x => x.Type == TargetType.DotNet);
bool hasDotnetProjects = solution.Projects.Any(x => x.Type == TargetType.DotNetCore);
// Create launch file
using (var json = new JsonWriter())
{
@@ -292,9 +296,15 @@ namespace Flax.Build.Projects.VisualStudioCode
{
foreach (var project in solution.Projects)
{
if (project.Name == "BuildScripts")
continue;
// C++ project
if (project.Type == TargetType.NativeCpp)
{
// Skip generating launch profiles for plugins and dependencies
if (solution.MainProject.Name != "Flax" && project.Name != "Flax.Build" && solution.MainProject.WorkspaceRootPath != project.WorkspaceRootPath)
continue;
foreach (var configuration in project.Configurations)
{
var name = project.Name + '|' + configuration.Name;
@@ -314,115 +324,49 @@ namespace Flax.Build.Projects.VisualStudioCode
json.AddField("preLaunchTask", name);
json.AddField("cwd", buildToolWorkspace);
switch (Platform.BuildPlatform.Target)
WriteNativePlatformLaunchSettings(json, configuration.Platform);
if (outputType != TargetOutputType.Executable && configuration.Name.StartsWith("Editor."))
{
case TargetPlatform.Windows:
if (configuration.Platform == TargetPlatform.Windows && outputType != TargetOutputType.Executable && configuration.Name.StartsWith("Editor."))
if (configuration.Platform == TargetPlatform.Windows)
{
var editorFolder = configuration.Architecture == TargetArchitecture.x64 ? "Win64" : "Win32";
json.AddField("program", Path.Combine(Globals.EngineRoot, "Binaries", "Editor", editorFolder, configuration.ConfigurationName, "FlaxEditor.exe"));
json.BeginArray("args");
}
else if (configuration.Platform == TargetPlatform.Linux)
json.AddField("program", Path.Combine(Globals.EngineRoot, "Binaries", "Editor", "Linux", configuration.ConfigurationName, "FlaxEditor"));
else if (configuration.Platform == TargetPlatform.Mac)
json.AddField("program", Path.Combine(Globals.EngineRoot, "Binaries", "Editor", "Mac", configuration.ConfigurationName, "FlaxEditor"));
json.BeginArray("args");
{
json.AddUnnamedField("-project");
json.AddUnnamedField(buildToolWorkspace);
json.AddUnnamedField("-skipCompile");
if (hasMonoProjects)
{
json.AddUnnamedField("-project");
json.AddUnnamedField(buildToolWorkspace);
json.AddUnnamedField("-skipCompile");
json.AddUnnamedField("-debug");
json.AddUnnamedField("127.0.0.1:55555");
}
json.EndArray();
}
else
{
json.AddField("program", outputTargetFilePath);
}
break;
case TargetPlatform.Linux:
if (configuration.Platform == TargetPlatform.Linux && (outputType != TargetOutputType.Executable || project.BaseName == "Flax") && configuration.Name.StartsWith("Editor."))
{
json.AddField("program", Path.Combine(Globals.EngineRoot, "Binaries", "Editor", "Linux", configuration.ConfigurationName, "FlaxEditor"));
}
else
{
json.AddField("program", outputTargetFilePath);
}
if (configuration.Platform == TargetPlatform.Linux)
{
json.AddField("MIMode", "gdb");
json.BeginArray("setupCommands");
{
json.BeginObject();
json.AddField("description", "Enable pretty-printing for gdb");
json.AddField("text", "-enable-pretty-printing");
json.AddField("ignoreFailures", true);
json.EndObject();
// Ignore signals used by C# runtime
json.BeginObject();
json.AddField("description", "ignore SIG34 signal");
json.AddField("text", "handle SIG34 nostop noprint pass");
json.EndObject();
json.BeginObject();
json.AddField("description", "ignore SIG35 signal");
json.AddField("text", "handle SIG35 nostop noprint pass");
json.EndObject();
json.BeginObject();
json.AddField("description", "ignore SIG36 signal");
json.AddField("text", "handle SIG36 nostop noprint pass");
json.EndObject();
json.BeginObject();
json.AddField("description", "ignore SIG357 signal");
json.AddField("text", "handle SIG37 nostop noprint pass");
json.EndObject();
}
json.EndArray();
json.BeginArray("args");
{
json.AddUnnamedField("--std");
if (outputType != TargetOutputType.Executable && configuration.Name.StartsWith("Editor."))
{
json.AddUnnamedField("--project");
json.AddUnnamedField(buildToolWorkspace);
json.AddUnnamedField("--skipCompile");
}
}
json.EndArray();
}
break;
case TargetPlatform.Mac:
if (configuration.Platform == TargetPlatform.Mac && (outputType != TargetOutputType.Executable || project.BaseName == "Flax") && configuration.Name.StartsWith("Editor."))
{
json.AddField("program", Path.Combine(Globals.EngineRoot, "Binaries", "Editor", "Mac", configuration.ConfigurationName, "FlaxEditor"));
}
else
{
json.AddField("program", outputTargetFilePath);
}
if (configuration.Platform == TargetPlatform.Mac)
{
json.AddField("MIMode", "lldb");
json.BeginArray("args");
{
json.AddUnnamedField("--std");
if (outputType != TargetOutputType.Executable && configuration.Name.StartsWith("Editor."))
{
json.AddUnnamedField("--project");
json.AddUnnamedField(buildToolWorkspace);
json.AddUnnamedField("--skipCompile");
}
}
json.EndArray();
}
break;
json.EndArray();
}
switch (configuration.Platform)
else
{
case TargetPlatform.Windows:
json.AddField("stopAtEntry", false);
json.AddField("externalConsole", true);
break;
case TargetPlatform.Linux:
break;
json.AddField("program", outputTargetFilePath);
json.BeginArray("args");
{
if (configuration.Platform == TargetPlatform.Linux || configuration.Platform == TargetPlatform.Mac)
json.AddUnnamedField("--std");
if (hasMonoProjects)
{
json.AddUnnamedField("-debug");
json.AddUnnamedField("127.0.0.1:55555");
}
}
json.EndArray();
}
json.AddField("visualizerFile", Path.Combine(Globals.EngineRoot, "Source", "flax.natvis"));
}
json.EndObject();
@@ -431,16 +375,9 @@ namespace Flax.Build.Projects.VisualStudioCode
// C# project
else if (project.Type == TargetType.DotNetCore)
{
// TODO: Skip generating launch profiles for plugins and dependencies
json.BeginObject();
{
json.AddField("type", "coreclr");
json.AddField("name", project.Name + " (C# attach Editor)");
json.AddField("request", "attach");
json.AddField("processName", "FlaxEditor");
}
json.EndObject();
// Skip generating launch profiles for plugins and dependencies
if (solution.MainProject.WorkspaceRootPath != project.WorkspaceRootPath)
continue;
foreach (var configuration in project.Configurations)
{
@@ -484,24 +421,54 @@ namespace Flax.Build.Projects.VisualStudioCode
json.EndObject();
}
}
// Mono C# project
else if (project.Type == TargetType.DotNet)
{
foreach (var configuration in project.Configurations)
{
json.BeginObject();
{
json.AddField("type", "mono");
json.AddField("name", project.Name + " (C# attach)" + '|' + configuration.Name);
json.AddField("request", "attach");
json.AddField("address", "localhost");
json.AddField("port", 55555);
}
json.EndObject();
}
}
}
}
if (hasNativeProjects)
{
foreach (var platform in solution.Projects.SelectMany(x => x.Configurations).Select(x => x.Platform).Distinct())
{
json.BeginObject();
{
if (platform == TargetPlatform.Windows)
json.AddField("type", "cppvsdbg");
else
json.AddField("type", "cppdbg");
json.AddField("name", solution.Name + " (Attach Editor)");
json.AddField("request", "attach");
json.AddField("processId", "${command:pickProcess}"); // Does not seem to be possible to attach by process name?
WriteNativePlatformLaunchSettings(json, platform);
json.AddField("visualizerFile", Path.Combine(Globals.EngineRoot, "Source", "flax.natvis"));
}
json.EndObject();
}
}
if (hasDotnetProjects)
{
json.BeginObject();
{
json.AddField("type", "coreclr");
json.AddField("name", solution.Name + " (C# Attach Editor)");
json.AddField("request", "attach");
json.AddField("processName", "FlaxEditor");
}
json.EndObject();
}
if (hasMonoProjects)
{
json.BeginObject();
{
json.AddField("type", "mono");
json.AddField("name", solution.Name + " (C# Attach)");
json.AddField("request", "attach");
json.AddField("address", "localhost");
json.AddField("port", 55555);
}
json.EndObject();
}
json.EndArray();
}
json.EndRootObject();
@@ -509,6 +476,59 @@ namespace Flax.Build.Projects.VisualStudioCode
json.Save(Path.Combine(vsCodeFolder, "launch.json"));
}
static void WriteNativePlatformLaunchSettings(JsonWriter json, TargetPlatform platform)
{
switch (Platform.BuildPlatform.Target)
{
case TargetPlatform.Linux:
if (platform == TargetPlatform.Linux)
{
json.AddField("MIMode", "gdb");
json.BeginArray("setupCommands");
{
json.BeginObject();
json.AddField("description", "Enable pretty-printing for gdb");
json.AddField("text", "-enable-pretty-printing");
json.AddField("ignoreFailures", true);
json.EndObject();
// Ignore signals used by C# runtime
json.BeginObject();
json.AddField("description", "ignore SIG34 signal");
json.AddField("text", "handle SIG34 nostop noprint pass");
json.EndObject();
json.BeginObject();
json.AddField("description", "ignore SIG35 signal");
json.AddField("text", "handle SIG35 nostop noprint pass");
json.EndObject();
json.BeginObject();
json.AddField("description", "ignore SIG36 signal");
json.AddField("text", "handle SIG36 nostop noprint pass");
json.EndObject();
json.BeginObject();
json.AddField("description", "ignore SIG357 signal");
json.AddField("text", "handle SIG37 nostop noprint pass");
json.EndObject();
}
json.EndArray();
}
break;
case TargetPlatform.Mac:
if (platform == TargetPlatform.Mac)
{
json.AddField("MIMode", "lldb");
}
break;
}
switch (platform)
{
case TargetPlatform.Windows:
json.AddField("stopAtEntry", false);
json.AddField("externalConsole", true);
break;
}
}
// Create C++ properties file
using (var json = new JsonWriter())
{