Compare commits

...

14 Commits

Author SHA1 Message Date
Pieter-Jan Briers
32fa6ebb53 Version: 136.0.2 2024-03-10 20:47:22 +01:00
Pieter-Jan Briers
27378d3620 Backport 859f150404
(cherry picked from commit 24d5c26fa6)
(cherry picked from commit b89d13d39ffa53b9ca687946c6b56e86449d50bd)
2024-03-10 20:47:22 +01:00
Vera Aguilera Puerto
dd12110c34 Version: 136.0.1 2023-07-12 08:55:01 +02:00
Vera Aguilera Puerto
a811cfc1a1 Changelog for CEF bugfix 2023-07-12 08:53:51 +02:00
Amy
229a45bea2 Enables debugging and error handling on Linux with CEF enabled (#4181)
Co-authored-by: amylizzle <amylizzle@users.noreply.github.com>
2023-07-12 08:42:30 +02:00
metalgearsloth
78376ccca1 Fix grid fixture warnings (#4180) 2023-07-10 18:09:18 +10:00
metalgearsloth
e4a1415627 Fix erroneous Vector2.Length call (#4178) 2023-07-10 17:53:54 +10:00
metalgearsloth
69589195e0 MapLoader perf stuff (#4179) 2023-07-10 17:53:46 +10:00
Leon Friedrich
ce3b92aea2 Try prevent infinite measure/arrange loops (#4176) 2023-07-10 17:36:22 +10:00
Leon Friedrich
5dc980ae92 Revert #3827 (#4177) 2023-07-10 17:35:55 +10:00
ElectroJr
6edeafeed1 Version: 136.0.0 2023-07-08 22:22:28 -04:00
Leon Friedrich
623aa6a0ae More StyleBox UiScale fixes. (#4175) 2023-07-09 12:19:42 +10:00
ElectroJr
1399b71572 Version: 135.0.0 2023-07-08 15:02:31 -04:00
eoineoineoin
bbf8827efd Make StyleBoxTexture respect UI zoom level (#4165) 2023-07-09 04:49:25 +10:00
35 changed files with 398 additions and 221 deletions

View File

@@ -1,4 +1,4 @@
<Project>
<!-- This file automatically reset by Tools/version.py -->
<!-- This file automatically reset by Tools/version.py -->

View File

@@ -54,11 +54,39 @@ END TEMPLATE-->
*None yet*
## 136.0.2
## 136.0.1
### Bugfixes
* Fixed debugging on Linux when CEF is enabled.
## 136.0.0
### New features
* Several more style box properties now scale with UI scale. Signature of some stylebox methods have been changed.
### Bugfixes
* Fixed OutputPanel scroll-bar not functioning properly.
## 135.0.0
### Breaking changes
* Style boxes now scale with the current UI scale. This affects how the the margins, padding, and style box textures are drawn and how controls are arranged. Various style box methods now need to be provided with the current UI scale.
## 134.0.0
### Breaking changes
* Several methods were moved out of the `UserInterface` components and into the UI system.
* Several methods were moved out of the `UserInterface` components and into the UI system.
* The BUI constructor arguments have changed and now require an EntityUid to be given instead of a component.

View File

@@ -85,12 +85,10 @@ namespace Robust.Client.WebView.Cef
_app = new RobustCefApp(_sawmill);
// We pass no main arguments...
CefRuntime.Initialize(new CefMainArgs(null), settings, _app, IntPtr.Zero);
// TODO CEF: After this point, debugging breaks. No, literally. My client crashes but ONLY with the debugger.
// I have tried using the DEBUG and RELEASE versions of libcef.so, stripped or non-stripped...
// And nothing seemed to work. Odd.
// So these arguments look like nonsense, but it turns out CEF is just *like that*.
// The first argument is literally nonsense, but it needs to be there as otherwise the second argument doesn't apply
// The second argument turns off CEF's bullshit error handling, which breaks dotnet's error handling.
CefRuntime.Initialize(new CefMainArgs(new string[]{"binary","--disable-in-process-stack-traces"}), settings, _app, IntPtr.Zero);
if (_cfg.GetCVar(WCVars.WebResProtocol))
{

View File

@@ -47,7 +47,7 @@ namespace Robust.Client.GameObjects
LayoutContainer.SetPosition(_label, screenPos + new Vector2(0, 50));
_label.Visible = true;
_label.Text = $"Speed: {body.LinearVelocity.Length:0.00}\nLinear: {body.LinearVelocity.X:0.00}, {body.LinearVelocity.Y:0.00}\nAngular: {body.AngularVelocity}";
_label.Text = $"Speed: {body.LinearVelocity.Length():0.00}\nLinear: {body.LinearVelocity.X:0.00}, {body.LinearVelocity.Y:0.00}\nAngular: {body.AngularVelocity}";
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Numerics;
using JetBrains.Annotations;
using Robust.Shared.Maths;
@@ -38,10 +38,16 @@ namespace Robust.Client.Graphics
_paddingTop = other._paddingTop;
}
/// <summary>
/// Minimum size, in virtual pixels.
/// </summary>
public Vector2 MinimumSize =>
new(GetContentMargin(Margin.Left) + GetContentMargin(Margin.Right),
GetContentMargin(Margin.Top) + GetContentMargin(Margin.Bottom));
/// <summary>
/// Left content margin, in virtual pixels.
/// </summary>
public float? ContentMarginLeftOverride
{
get => _contentMarginLeftOverride;
@@ -56,6 +62,9 @@ namespace Robust.Client.Graphics
}
}
/// <summary>
/// Top content margin, in virtual pixels.
/// </summary>
public float? ContentMarginTopOverride
{
get => _contentMarginTopOverride;
@@ -70,6 +79,9 @@ namespace Robust.Client.Graphics
}
}
/// <summary>
/// Right content margin, in virtual pixels.
/// </summary>
public float? ContentMarginRightOverride
{
get => _contentMarginRightOverride;
@@ -84,6 +96,9 @@ namespace Robust.Client.Graphics
}
}
/// <summary>
/// Bottom content margin, in virtual pixels.
/// </summary>
public float? ContentMarginBottomOverride
{
get => _contentMarginBottomOverride;
@@ -98,6 +113,9 @@ namespace Robust.Client.Graphics
}
}
/// <summary>
/// Left padding, in virtual pixels.
/// </summary>
public float PaddingLeft
{
get => _paddingLeft;
@@ -112,6 +130,9 @@ namespace Robust.Client.Graphics
}
}
/// <summary>
/// Bottom padding, in virtual pixels.
/// </summary>
public float PaddingBottom
{
get => _paddingBottom;
@@ -126,6 +147,9 @@ namespace Robust.Client.Graphics
}
}
/// <summary>
/// Right padding, in virtual pixels.
/// </summary>
public float PaddingRight
{
get => _paddingRight;
@@ -140,6 +164,9 @@ namespace Robust.Client.Graphics
}
}
/// <summary>
/// Top padding, in virtual pixels.
/// </summary>
public float PaddingTop
{
get => _paddingTop;
@@ -154,6 +181,9 @@ namespace Robust.Client.Graphics
}
}
/// <summary>
/// Padding, in virtual pixels.
/// </summary>
public Thickness Padding
{
set
@@ -166,11 +196,11 @@ namespace Robust.Client.Graphics
}
/// <summary>
/// Draw this style box to the screen at the specified coordinates.
/// Draw this style box to the screen at the specified coordinates. This is using physical pixels, not virtual pixels.
/// </summary>
/// <param name="handle"></param>
/// <param name="box"></param>
public void Draw(DrawingHandleScreen handle, UIBox2 box)
public void Draw(DrawingHandleScreen handle, UIBox2 box, float uiScale)
{
box = new UIBox2(
box.Left + PaddingLeft,
@@ -179,11 +209,11 @@ namespace Robust.Client.Graphics
box.Bottom - PaddingBottom
);
DoDraw(handle, box);
DoDraw(handle, box, uiScale);
}
/// <summary>
/// Gets the offset from a margin of the box to where content should actually be drawn.
/// Gets the offset from a margin of the box to where content should actually be drawn. This is in virtual pixels.
/// </summary>
/// <exception cref="ArgumentException">
/// Thrown if <paramref name="margin"/> is a compound is not a single margin flag.
@@ -213,6 +243,9 @@ namespace Robust.Client.Graphics
return contentMargin + GetPadding(margin);
}
/// <summary>
/// Gets the padding. This is in virtual pixels.
/// </summary>
public float GetPadding(Margin margin)
{
switch (margin)
@@ -231,26 +264,27 @@ namespace Robust.Client.Graphics
}
/// <summary>
/// Returns the offsets of the content region of this box,
/// if this box is drawn from the given position.
/// Returns the offsets of the content region of this box when drawn from the given position. Input and
/// output positions are in real pixels, though virtual pixels can also be used if the ui scale is set to 1.
/// </summary>
public Vector2 GetContentOffset(Vector2 basePosition)
public Vector2 GetContentOffset(Vector2 basePosition, float uiScale)
{
return basePosition + new Vector2(GetContentMargin(Margin.Left), GetContentMargin(Margin.Top));
return basePosition + uiScale * new Vector2(GetContentMargin(Margin.Left), GetContentMargin(Margin.Top));
}
/// <summary>
/// Gets the box considered the "contents" of this style box, when drawn at a specific size.
/// Gets the box considered the "contents" of this style box, when drawn at a specific size. Input and output
/// boxes are in virtual pixels, though virtual pixels can also be used if the ui scale is set to 1.
/// </summary>
/// <exception cref="ArgumentException">
/// <paramref name="baseBox"/> is too small and the resultant box would have negative dimensions.
/// </exception>
public UIBox2 GetContentBox(UIBox2 baseBox)
public UIBox2 GetContentBox(UIBox2 baseBox, float uiScale)
{
var left = baseBox.Left + GetContentMargin(Margin.Left);
var top = baseBox.Top + GetContentMargin(Margin.Top);
var right = baseBox.Right - GetContentMargin(Margin.Right);
var bottom = baseBox.Bottom - GetContentMargin(Margin.Bottom);
var left = baseBox.Left + GetContentMargin(Margin.Left) * uiScale;
var top = baseBox.Top + GetContentMargin(Margin.Top) * uiScale;
var right = baseBox.Right - GetContentMargin(Margin.Right) * uiScale;
var bottom = baseBox.Bottom - GetContentMargin(Margin.Bottom) * uiScale;
return new UIBox2(left, top, right, bottom);
}
@@ -258,19 +292,22 @@ namespace Robust.Client.Graphics
/// <summary>
/// Gets the draw box, positioned at <paramref name="position"/>,
/// that envelops a box with the given dimensions perfectly given this box's content margins.
/// Input and output values are in physical pixels, though virtual pixels can also be used if the ui scale
/// is set to 1.
/// </summary>
/// <remarks>
/// It's basically a reverse <see cref="GetContentBox"/>.
/// </remarks>
/// <param name="position">The position at which the new box should be drawn.</param>
/// <param name="dimensions">The dimensions of the content box inside this new box.</param>
/// <param name="uiScale">Scales the content margin border size</param>
/// <returns>
/// A box that, when ran through <see cref="GetContentBox"/>,
/// has a content box of size <paramref name="dimensions"/>
/// </returns>
public UIBox2 GetEnvelopBox(Vector2 position, Vector2 dimensions)
public UIBox2 GetEnvelopBox(Vector2 position, Vector2 dimensions, float uiScale)
{
return UIBox2.FromDimensions(position, dimensions + MinimumSize);
return UIBox2.FromDimensions(position, dimensions + MinimumSize * uiScale);
}
public void SetContentMarginOverride(Margin margin, float value)
@@ -319,7 +356,13 @@ namespace Robust.Client.Graphics
}
}
protected abstract void DoDraw(DrawingHandleScreen handle, UIBox2 box);
/// <summary>
/// Draw the style box in the given UI Box.
/// </summary>
/// <param name="handle"></param>
/// <param name="box">The area to draw in, in physical pixels</param>
/// <param name="uiScale">The UI scale to use.</param>
protected abstract void DoDraw(DrawingHandleScreen handle, UIBox2 box, float uiScale);
protected virtual float GetDefaultContentMargin(Margin margin)
{

View File

@@ -4,7 +4,7 @@ namespace Robust.Client.Graphics
{
public sealed class StyleBoxEmpty : StyleBox
{
protected override void DoDraw(DrawingHandleScreen handle, UIBox2 box)
protected override void DoDraw(DrawingHandleScreen handle, UIBox2 box, float uiScale)
{
// It's empty what more do you want?
}

View File

@@ -7,11 +7,16 @@ namespace Robust.Client.Graphics
{
public Color BackgroundColor { get; set; }
public Color BorderColor { get; set; }
/// <summary>
/// Thickness of the border, in virtual pixels.
/// </summary>
public Thickness BorderThickness { get; set; }
protected override void DoDraw(DrawingHandleScreen handle, UIBox2 box)
protected override void DoDraw(DrawingHandleScreen handle, UIBox2 box, float uiScale)
{
var (btl, btt, btr, btb) = BorderThickness;
var thickness = BorderThickness.Scale(uiScale);
var (btl, btt, btr, btb) = thickness;
if (btl > 0)
handle.DrawRect(new UIBox2(box.Left, box.Top, box.Left + btl, box.Bottom), BorderColor);
@@ -24,7 +29,7 @@ namespace Robust.Client.Graphics
if (btb > 0)
handle.DrawRect(new UIBox2(box.Left, box.Bottom - btb, box.Right, box.Bottom), BorderColor);
handle.DrawRect(BorderThickness.Deflate(box), BackgroundColor);
handle.DrawRect(thickness.Deflate(box), BackgroundColor);
}
public StyleBoxFlat()

View File

@@ -38,21 +38,57 @@ namespace Robust.Client.Graphics
Texture = copy.Texture;
Modulate = copy.Modulate;
TextureScale = copy.TextureScale;
}
/// <summary>
/// Left expansion size, in virtual pixels.
/// </summary>
/// <remarks>
/// This expands the size of the area where the patches get drawn. This will cause the drawn texture to
/// extend beyond the box passed to the <see cref="StyleBox.Draw"/> function. This is not affected by
/// <see cref="TextureScale"/>.
/// </remarks>
public float ExpandMarginLeft { get; set; }
/// <summary>
/// Top expansion size, in virtual pixels.
/// </summary>
/// <remarks>
/// This expands the size of the area where the patches get drawn. This will cause the drawn texture to
/// extend beyond the box passed to the <see cref="StyleBox.Draw"/> function. This is not affected by
/// <see cref="TextureScale"/>.
/// </remarks>
public float ExpandMarginTop { get; set; }
/// <summary>
/// Bottom expansion size, in virtual pixels.
/// </summary>
/// <remarks>
/// This expands the size of the area where the patches get drawn. This will cause the drawn texture to
/// extend beyond the box passed to the <see cref="StyleBox.Draw"/> function. This is not affected by
/// <see cref="TextureScale"/>.
/// </remarks>
public float ExpandMarginBottom { get; set; }
/// <summary>
/// Right expansion size, in virtual pixels.
/// </summary>
/// <remarks>
/// This expands the size of the area where the patches get drawn. This will cause the drawn texture to
/// extend beyond the box passed to the <see cref="StyleBox.Draw"/> function. This is not affected by
/// <see cref="TextureScale"/>.
/// </remarks>
public float ExpandMarginRight { get; set; }
public StretchMode Mode { get; set; } = StretchMode.Stretch;
private float _patchMarginLeft;
// Distance of the left patch margin from the image. In texture space.
/// <summary>
/// Distance of the left patch margin from the image. In texture space.
/// The size of this patch in virtual pixels can be obtained by scaling this with <see cref="TextureScale"/>.
/// </summary>
public float PatchMarginLeft
{
get => _patchMarginLeft;
@@ -69,7 +105,10 @@ namespace Robust.Client.Graphics
private float _patchMarginRight;
// Distance of the right patch margin from the image. In texture space.
/// <summary>
/// Distance of the right patch margin from the image. In texture space.
/// The size of this patch in virtual pixels can be obtained by scaling this with <see cref="TextureScale"/>.
/// </summary>
public float PatchMarginRight
{
get => _patchMarginRight;
@@ -86,7 +125,10 @@ namespace Robust.Client.Graphics
private float _patchMarginTop;
// Distance of the top patch margin from the image. In texture space.
/// <summary>
/// Distance of the top patch margin from the image. In texture space.
/// The size of this patch in virtual pixels can be obtained by scaling this with <see cref="TextureScale"/>.
/// </summary>
public float PatchMarginTop
{
get => _patchMarginTop;
@@ -103,7 +145,10 @@ namespace Robust.Client.Graphics
private float _patchMarginBottom;
// Distance of the bottom patch margin from the image. In texture space.
/// <summary>
/// Distance of the bottom patch margin from the image. In texture space.
/// The size of this patch in virtual pixels can be obtained by scaling this with <see cref="TextureScale"/>.
/// </summary>
public float PatchMarginBottom
{
get => _patchMarginBottom;
@@ -122,7 +167,9 @@ namespace Robust.Client.Graphics
public Texture? Texture { get; set; }
// Applies an additional x/y scale to the teture
/// <summary>
/// Additional scaling to use when drawing the texture.
/// </summary>
public Vector2 TextureScale { get; set; } = Vector2.One;
public void SetPatchMargin(Margin margin, float value)
@@ -171,7 +218,7 @@ namespace Robust.Client.Graphics
}
}
protected override void DoDraw(DrawingHandleScreen handle, UIBox2 box)
protected override void DoDraw(DrawingHandleScreen handle, UIBox2 box, float uiScale)
{
if (Texture == null)
{
@@ -179,13 +226,13 @@ namespace Robust.Client.Graphics
}
box = new UIBox2(
box.Left - ExpandMarginLeft,
box.Top - ExpandMarginTop,
box.Right + ExpandMarginRight,
box.Bottom + ExpandMarginBottom);
box.Left - ExpandMarginLeft * uiScale,
box.Top - ExpandMarginTop * uiScale,
box.Right + ExpandMarginRight * uiScale,
box.Bottom + ExpandMarginBottom * uiScale);
var scaledMargin = new UIBox2(PatchMarginLeft * TextureScale.X, PatchMarginTop * TextureScale.Y,
PatchMarginRight * TextureScale.X, PatchMarginBottom * TextureScale.Y);
var scaledMargin = new UIBox2(PatchMarginLeft * TextureScale.X * uiScale, PatchMarginTop * TextureScale.Y * uiScale,
PatchMarginRight * TextureScale.X * uiScale, PatchMarginBottom * TextureScale.Y * uiScale);
if (PatchMarginLeft > 0)
{
@@ -204,7 +251,7 @@ namespace Robust.Client.Graphics
new UIBox2(0, scaledMargin.Top, scaledMargin.Left, box.Height - scaledMargin.Bottom)
.Translated(box.TopLeft);
DrawStretchingArea(handle, leftBox,
new UIBox2(0, PatchMarginTop, PatchMarginLeft, Texture.Height - PatchMarginBottom));
new UIBox2(0, PatchMarginTop, PatchMarginLeft, Texture.Height - PatchMarginBottom), uiScale);
}
if (PatchMarginBottom > 0)
@@ -239,7 +286,7 @@ namespace Robust.Client.Graphics
DrawStretchingArea(handle, rightBox,
new UIBox2(Texture.Width - PatchMarginRight, PatchMarginTop,
Texture.Width,
Texture.Height - PatchMarginBottom));
Texture.Height - PatchMarginBottom), uiScale);
}
if (PatchMarginBottom > 0)
@@ -261,7 +308,7 @@ namespace Robust.Client.Graphics
new UIBox2(scaledMargin.Left, 0, box.Width - scaledMargin.Right, scaledMargin.Top)
.Translated(box.TopLeft);
DrawStretchingArea(handle, topBox,
new UIBox2(PatchMarginLeft, 0, Texture.Width - PatchMarginRight, PatchMarginTop));
new UIBox2(PatchMarginLeft, 0, Texture.Width - PatchMarginRight, PatchMarginTop), uiScale);
}
if (PatchMarginBottom > 0)
@@ -275,7 +322,7 @@ namespace Robust.Client.Graphics
DrawStretchingArea(handle, bottomBox,
new UIBox2(PatchMarginLeft, Texture.Height - PatchMarginBottom,
Texture.Width - PatchMarginRight,
Texture.Height));
Texture.Height), uiScale);
}
// Draw center
@@ -284,11 +331,11 @@ namespace Robust.Client.Graphics
box.Height - scaledMargin.Bottom).Translated(box.TopLeft);
DrawStretchingArea(handle, centerBox, new UIBox2(PatchMarginLeft, PatchMarginTop, Texture.Width - PatchMarginRight,
Texture.Height - PatchMarginBottom));
Texture.Height - PatchMarginBottom), uiScale);
}
}
private void DrawStretchingArea(DrawingHandleScreen handle, UIBox2 area, UIBox2 texCoords)
private void DrawStretchingArea(DrawingHandleScreen handle, UIBox2 area, UIBox2 texCoords, float uiScale)
{
if (Mode == StretchMode.Stretch)
{
@@ -301,8 +348,8 @@ namespace Robust.Client.Graphics
// TODO: this is an insanely expensive way to do tiling, seriously.
// This should 100% be implemented in a shader instead.
var sectionWidth = texCoords.Width * TextureScale.X;
var sectionHeight = texCoords.Height * TextureScale.Y;
var sectionWidth = texCoords.Width * TextureScale.X * uiScale;
var sectionHeight = texCoords.Height * TextureScale.Y * uiScale;
var invScale = Vector2.One / TextureScale;
for (var x = area.Left; area.Right - x > 0; x += sectionWidth)
@@ -328,13 +375,13 @@ namespace Robust.Client.Graphics
switch (margin)
{
case Margin.Top:
return PatchMarginTop;
return PatchMarginTop * TextureScale.Y;
case Margin.Bottom:
return PatchMarginBottom;
return PatchMarginBottom * TextureScale.Y;
case Margin.Right:
return PatchMarginRight;
return PatchMarginRight * TextureScale.X;
case Margin.Left:
return PatchMarginLeft;
return PatchMarginLeft * TextureScale.X;
default:
throw new ArgumentOutOfRangeException(nameof(margin), margin, null);
}

View File

@@ -14,6 +14,7 @@ namespace Robust.Client.Physics
{
[Dependency] private readonly IOverlayManager _overlay = default!;
[Dependency] private readonly IMapManager _map = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public bool EnableDebug
{
@@ -27,7 +28,7 @@ namespace Robust.Client.Physics
if (_enableDebug)
{
var overlay = new GridSplitNodeOverlay(EntityManager, _map, this);
var overlay = new GridSplitNodeOverlay(_map, this, _transform);
_overlay.AddOverlay(overlay);
RaiseNetworkEvent(new RequestGridNodesMessage());
}
@@ -39,7 +40,7 @@ namespace Robust.Client.Physics
}
}
private bool _enableDebug = false;
private bool _enableDebug;
private readonly Dictionary<EntityUid, Dictionary<Vector2i, List<List<Vector2i>>>> _nodes = new();
private readonly Dictionary<EntityUid, List<(Vector2, Vector2)>> _connections = new();
@@ -69,71 +70,76 @@ namespace Robust.Client.Physics
{
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private IEntityManager _entManager;
private IMapManager _mapManager;
private GridFixtureSystem _system;
private readonly IMapManager _mapManager;
private readonly GridFixtureSystem _system;
private readonly SharedTransformSystem _transform;
public GridSplitNodeOverlay(IEntityManager entManager, IMapManager mapManager, GridFixtureSystem system)
public GridSplitNodeOverlay(IMapManager mapManager, GridFixtureSystem system, SharedTransformSystem transform)
{
_entManager = entManager;
_mapManager = mapManager;
_system = system;
_transform = transform;
}
protected internal override void Draw(in OverlayDrawArgs args)
{
var worldHandle = args.WorldHandle;
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
foreach (var iGrid in _mapManager.FindGridsIntersecting(args.MapId, args.WorldBounds))
{
// May not have received nodes yet.
if (!_system._nodes.TryGetValue(iGrid.Owner, out var nodes)) continue;
var state = (_system, _transform, args.WorldBounds, worldHandle);
var gridXform = xformQuery.GetComponent(iGrid.Owner);
worldHandle.SetTransform(gridXform.WorldMatrix);
var chunkEnumerator = iGrid.GetMapChunks(args.WorldBounds);
while (chunkEnumerator.MoveNext(out var chunk))
_mapManager.FindGridsIntersecting(args.MapId, args.WorldBounds, ref state,
static (EntityUid uid, MapGridComponent grid,
ref (GridFixtureSystem system, SharedTransformSystem transform, Box2Rotated worldBounds, DrawingHandleWorld worldHandle) tuple) =>
{
if (!nodes.TryGetValue(chunk.Indices, out var chunkNodes)) continue;
// May not have received nodes yet.
if (!tuple.system._nodes.TryGetValue(uid, out var nodes))
return true;
for (var i = 0; i < chunkNodes.Count; i++)
tuple.worldHandle.SetTransform(tuple.transform.GetWorldMatrix(uid));
var chunkEnumerator = grid.GetMapChunks(tuple.worldBounds);
while (chunkEnumerator.MoveNext(out var chunk))
{
var group = chunkNodes[i];
var offset = chunk.Indices * chunk.ChunkSize;
var color = GetColor(chunk, i);
if (!nodes.TryGetValue(chunk.Indices, out var chunkNodes)) continue;
foreach (var index in group)
for (var i = 0; i < chunkNodes.Count; i++)
{
worldHandle.DrawRect(new Box2(offset + index, offset + index + 1).Enlarged(-0.1f), color);
var group = chunkNodes[i];
var offset = chunk.Indices * chunk.ChunkSize;
var color = GetColor(chunk, i);
foreach (var index in group)
{
tuple.worldHandle.DrawRect(new Box2(offset + index, offset + index + 1).Enlarged(-0.1f), color);
}
}
}
}
var connections = _system._connections[iGrid.Owner];
var connections = tuple.system._connections[uid];
foreach (var (start, end) in connections)
{
worldHandle.DrawLine(start, end, Color.Aquamarine);
}
}
foreach (var (start, end) in connections)
{
tuple.worldHandle.DrawLine(start, end, Color.Aquamarine);
}
static Color GetColor(MapChunk chunk, int index)
{
// Just want something that doesn't give similar indices at 0,0 but is also deterministic.
// Add an offset to yIndex so we at least have some colour that isn't grey at 0,0
var actualIndex = chunk.Indices.X * 20 + (chunk.Indices.Y + 20) * 35 + index * 50;
var red = (byte) (actualIndex % 255);
var green = (byte) (actualIndex * 20 % 255);
var blue = (byte) (actualIndex * 30 % 255);
return new Color(red, green, blue, 85);
}
return true;
}, true);
worldHandle.SetTransform(Matrix3.Identity);
}
private Color GetColor(MapChunk chunk, int index)
{
// Just want something that doesn't give similar indices at 0,0 but is also deterministic.
// Add an offset to yIndex so we at least have some colour that isn't grey at 0,0
var actualIndex = chunk.Indices.X * 20 + (chunk.Indices.Y + 20) * 35 + index * 50;
var red = (byte) (actualIndex % 255);
var green = (byte) (actualIndex * 20 % 255);
var blue = (byte) (actualIndex * 30 % 255);
return new Color(red, green, blue, 85);
}
}
}
}

View File

@@ -17,7 +17,7 @@
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.2" Condition="'$(UseSystemSqlite)' != 'True'" />
<PackageReference Include="SpaceWizards.NFluidsynth" Version="0.1.1" />
<PackageReference Include="NVorbis" Version="0.10.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.7" />
<PackageReference Include="OpenToolkit.Graphics" Version="4.0.0-pre9.1" />
<PackageReference Include="OpenTK.OpenAL" Version="4.7.5" />
<PackageReference Include="SpaceWizards.SharpFont" Version="1.0.1" />

View File

@@ -32,6 +32,7 @@ namespace Robust.Client.UserInterface
private VAlignment _verticalAlignment = VAlignment.Stretch;
private Thickness _margin;
private bool _measuring;
private bool _arranging;
/// <summary>
/// The desired minimum size this control needs for layout to avoid cutting off content or such.
@@ -469,13 +470,12 @@ namespace Robust.Client.UserInterface
/// </summary>
public void InvalidateMeasure()
{
if (!IsMeasureValid)
if (!IsMeasureValid || _measuring)
return;
IsMeasureValid = false;
IsArrangeValid = false;
UserInterfaceManagerInternal.QueueMeasureUpdate(this);
InvalidateArrange();
}
/// <summary>
@@ -484,7 +484,7 @@ namespace Robust.Client.UserInterface
/// </summary>
public void InvalidateArrange()
{
if (!IsArrangeValid)
if (!IsArrangeValid || _arranging)
{
// Already queued for a layout update, don't bother.
return;
@@ -508,7 +508,16 @@ namespace Robust.Client.UserInterface
if (!IsMeasureValid || PreviousMeasure != availableSize)
{
IsMeasureValid = true;
var desired = MeasureCore(availableSize);
_measuring = true;
Vector2 desired;
try
{
desired = MeasureCore(availableSize);
}
finally
{
_measuring = false;
}
if (desired.X < 0 || desired.Y < 0 || !float.IsFinite(desired.X) || !float.IsFinite(desired.Y))
throw new InvalidOperationException("Invalid size returned from Measure()");
@@ -540,16 +549,7 @@ namespace Robust.Client.UserInterface
var constrained = ApplySizeConstraints(this, withoutMargin);
Vector2 measured;
try
{
_measuring = true;
measured = MeasureOverride(constrained);
}
finally
{
_measuring = false;
}
var measured = MeasureOverride(constrained);
if (!float.IsNaN(SetWidth))
{
@@ -604,14 +604,22 @@ namespace Robust.Client.UserInterface
/// </summary>
public void Arrange(UIBox2 finalRect)
{
if (!IsMeasureValid)
Measure(PreviousMeasure ?? finalRect.Size);
if (!IsArrangeValid || PreviousArrange != finalRect)
_arranging = true;
try
{
IsArrangeValid = true;
ArrangeCore(finalRect);
PreviousArrange = finalRect;
if (!IsMeasureValid)
Measure(PreviousMeasure ?? finalRect.Size);
if (!IsArrangeValid || PreviousArrange != finalRect)
{
IsArrangeValid = true;
ArrangeCore(finalRect);
PreviousArrange = finalRect;
}
}
finally
{
_arranging = false;
}
}

View File

@@ -148,7 +148,6 @@ namespace Robust.Client.UserInterface
internal void DoStyleUpdate()
{
_stylingDirty = false;
_styleProperties.Clear();
if (_stylesheetUpdateNeeded)
@@ -229,6 +228,10 @@ namespace Robust.Client.UserInterface
}
StylePropertiesChanged();
// Setting this at the end of the function to prevent style updates from ever re-queueing a style update,
// which would cause an infinite loop.
_stylingDirty = false;
}
protected virtual void StylePropertiesChanged()

View File

@@ -35,7 +35,7 @@ namespace Robust.Client.UserInterface.Controls
protected override Vector2 MeasureOverride(Vector2 availableSize)
{
var boxSize = ActualStyleBox.MinimumSize / UIScale;
var boxSize = ActualStyleBox.MinimumSize;
var childBox = Vector2.Max(availableSize - boxSize, Vector2.Zero);
var min = Vector2.Zero;
foreach (var child in Children)
@@ -49,11 +49,12 @@ namespace Robust.Client.UserInterface.Controls
protected override Vector2 ArrangeOverride(Vector2 finalSize)
{
var contentBox = ActualStyleBox.GetContentBox(UIBox2.FromDimensions(Vector2.Zero, finalSize * UIScale));
var box = UIBox2.FromDimensions(Vector2.Zero, finalSize);
var contentBox = ActualStyleBox.GetContentBox(box, 1);
foreach (var child in Children)
{
child.ArrangePixel((UIBox2i) contentBox);
child.Arrange(contentBox);
}
return finalSize;
@@ -65,7 +66,7 @@ namespace Robust.Client.UserInterface.Controls
var style = ActualStyleBox;
var drawBox = PixelSizeBox;
style.Draw(handle, drawBox);
style.Draw(handle, drawBox, UIScale);
}
protected override void DrawModeChanged()

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
@@ -14,6 +14,7 @@ namespace Robust.Client.UserInterface.Controls
public class ItemList : Control, IList<ItemList.Item>
{
private bool _isAtBottom = true;
/// The size of all the child widgets, in pixels
private int _totalContentHeight;
private VScrollBar _scrollBar;
@@ -63,7 +64,7 @@ namespace Robust.Client.UserInterface.Controls
}
itemHeight = Math.Max(itemHeight, ActualFont.GetHeight(UIScale));
itemHeight += ActualItemBackground.MinimumSize.Y;
itemHeight += ActualItemBackground.MinimumSize.Y * UIScale;
_totalContentHeight += (int)Math.Ceiling(itemHeight);
}
@@ -333,7 +334,7 @@ namespace Robust.Client.UserInterface.Controls
var offset = -_scrollBar.Value;
listBg.Draw(handle, PixelSizeBox);
listBg.Draw(handle, PixelSizeBox, UIScale);
foreach (var item in _itemList)
{
@@ -354,16 +355,16 @@ namespace Robust.Client.UserInterface.Controls
}
itemHeight = Math.Max(itemHeight, font.GetHeight(UIScale));
itemHeight += ActualItemBackground.MinimumSize.Y;
itemHeight += ActualItemBackground.MinimumSize.Y * UIScale;
var region = UIBox2.FromDimensions(0, offset, PixelWidth, itemHeight);
item.Region = region;
if (region.Intersects(sizeBox))
{
bg.Draw(handle, item.Region.Value);
bg.Draw(handle, item.Region.Value, UIScale);
var contentBox = bg.GetContentBox(item.Region.Value);
var contentBox = bg.GetContentBox(item.Region.Value, UIScale);
var drawOffset = contentBox.TopLeft;
if (item.Icon != null)
{
@@ -420,7 +421,7 @@ namespace Robust.Client.UserInterface.Controls
var size = Vector2.Zero;
if (ActualBackground != null)
{
size += ActualBackground.MinimumSize / UIScale;
size += ActualBackground.MinimumSize;
}
return size;
@@ -496,19 +497,11 @@ namespace Robust.Client.UserInterface.Controls
return font.GetHeight(UIScale) * 2;
}
[Pure]
private UIBox2 _getContentBox()
{
var style = ActualBackground;
return style?.GetContentBox(SizeBox) ?? SizeBox;
}
protected override void Resized()
{
base.Resized();
var styleBoxSize = ActualBackground?.MinimumSize.Y ?? 0;
var styleBoxSize = (ActualBackground?.MinimumSize.Y ?? 0) * UIScale;
_scrollBar.Page = PixelSize.Y - styleBoxSize;
RecalculateContentHeight();
}
@@ -522,7 +515,7 @@ namespace Robust.Client.UserInterface.Controls
private void _updateScrollbarVisibility()
{
_scrollBar.Visible = _totalContentHeight + ActualBackground.MinimumSize.Y > PixelHeight;
_scrollBar.Visible = _totalContentHeight + ActualBackground.MinimumSize.Y > Height;
}
public abstract class ItemListEventArgs : EventArgs

View File

@@ -261,7 +261,7 @@ namespace Robust.Client.UserInterface.Controls
if (_mouseSelectingText)
{
var style = _getStyleBox();
var contentBox = style.GetContentBox(PixelSizeBox);
var contentBox = style.GetContentBox(PixelSizeBox, UIScale);
if (_lastMousePosition < contentBox.Left)
{
@@ -283,16 +283,14 @@ namespace Robust.Client.UserInterface.Controls
{
var font = _getFont();
var style = _getStyleBox();
return new Vector2(0, font.GetHeight(UIScale) / UIScale) + style.MinimumSize / UIScale;
return new Vector2(0, font.GetHeight(1.0f)) + style.MinimumSize;
}
protected override Vector2 ArrangeOverride(Vector2 finalSize)
{
var style = _getStyleBox();
_renderBox.ArrangePixel(
(UIBox2i) style.GetContentBox(
UIBox2.FromDimensions(Vector2.Zero, finalSize * UIScale)));
var box = UIBox2.FromDimensions(Vector2.Zero, finalSize);
_renderBox.Arrange(style.GetContentBox(box, 1));
return finalSize;
}
@@ -750,7 +748,7 @@ namespace Robust.Client.UserInterface.Controls
private int GetIndexAtPos(float horizontalPos)
{
var style = _getStyleBox();
var contentBox = style.GetContentBox(PixelSizeBox);
var contentBox = style.GetContentBox(PixelSizeBox, UIScale);
var clickPosX = horizontalPos * UIScale;
@@ -807,7 +805,7 @@ namespace Robust.Client.UserInterface.Controls
public float GetOffsetAtIndex(int index)
{
var style = _getStyleBox();
var contentBox = style.GetContentBox(PixelSizeBox);
var contentBox = style.GetContentBox(PixelSizeBox, UIScale);
var font = _getFont();
var i = 0;
@@ -897,7 +895,7 @@ namespace Robust.Client.UserInterface.Controls
{
base.Draw(handle);
_getStyleBox().Draw(handle, PixelSizeBox);
_getStyleBox().Draw(handle, PixelSizeBox, UIScale);
}
public sealed class LineEditEventArgs : EventArgs

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.InteropServices;
@@ -124,7 +124,7 @@ namespace Robust.Client.UserInterface.Controls
var style = _getStyleBox();
var font = _getFont();
style?.Draw(handle, PixelSizeBox);
style?.Draw(handle, PixelSizeBox, UIScale);
var contentBox = _getContentBox();
var entryOffset = -_scrollBar.Value;
@@ -171,7 +171,7 @@ namespace Robust.Client.UserInterface.Controls
var styleBoxSize = _getStyleBox()?.MinimumSize.Y ?? 0;
_scrollBar.Page = PixelSize.Y - styleBoxSize;
_scrollBar.Page = UIScale * (Height - styleBoxSize);
_invalidateEntries();
}
@@ -224,6 +224,7 @@ namespace Robust.Client.UserInterface.Controls
[System.Diagnostics.Contracts.Pure]
private float _getScrollSpeed()
{
// The scroll speed depends on the UI scale because the scroll bar is working with physical pixels.
return GetScrollSpeed(_getFont(), UIScale);
}
@@ -231,7 +232,7 @@ namespace Robust.Client.UserInterface.Controls
private UIBox2 _getContentBox()
{
var style = _getStyleBox();
var box = style?.GetContentBox(PixelSizeBox) ?? PixelSizeBox;
var box = style?.GetContentBox(PixelSizeBox, UIScale) ?? PixelSizeBox;
box.Right = Math.Max(box.Left, box.Right - _scrollBar.DesiredPixelSize.X);
return box;
}

View File

@@ -16,12 +16,12 @@ namespace Robust.Client.UserInterface.Controls
base.Draw(handle);
var style = _getStyleBox();
style?.Draw(handle, PixelSizeBox);
style?.Draw(handle, PixelSizeBox, UIScale);
}
protected override Vector2 MeasureOverride(Vector2 availableSize)
{
var styleSize = (_getStyleBox()?.MinimumSize ?? Vector2.Zero) / UIScale;
var styleSize = _getStyleBox()?.MinimumSize ?? Vector2.Zero;
var measureSize = Vector2.Max(availableSize - styleSize, Vector2.Zero);
var childSize = Vector2.Zero;
foreach (var child in Children)
@@ -35,13 +35,12 @@ namespace Robust.Client.UserInterface.Controls
protected override Vector2 ArrangeOverride(Vector2 finalSize)
{
var pixelSize = finalSize * UIScale;
var ourSize = UIBox2.FromDimensions(Vector2.Zero, pixelSize);
var contentBox = _getStyleBox()?.GetContentBox(ourSize) ?? ourSize;
var ourSize = UIBox2.FromDimensions(Vector2.Zero, finalSize);
var contentBox = _getStyleBox()?.GetContentBox(ourSize, 1) ?? ourSize;
foreach (var child in Children)
{
child.ArrangePixel((UIBox2i) contentBox);
child.Arrange(contentBox);
}
return finalSize;

View File

@@ -63,7 +63,7 @@ namespace Robust.Client.UserInterface.Controls
base.Draw(handle);
var bg = _getBackground();
bg?.Draw(handle, PixelSizeBox);
bg?.Draw(handle, PixelSizeBox, UIScale);
var fg = _getForeground();
if (fg == null)
@@ -74,7 +74,7 @@ namespace Robust.Client.UserInterface.Controls
var size = PixelWidth * GetAsRatio() - minSize.X;
if (size > 0)
{
fg.Draw(handle, UIBox2.FromDimensions(0, 0, minSize.X + size, PixelHeight));
fg.Draw(handle, UIBox2.FromDimensions(0, 0, minSize.X + size, PixelHeight), UIScale);
}
}

View File

@@ -82,7 +82,7 @@ namespace Robust.Client.UserInterface.Controls
protected internal override void Draw(DrawingHandleScreen handle)
{
var styleBox = _getGrabberStyleBox();
styleBox?.Draw(handle, _getGrabberBox());
styleBox?.Draw(handle, _getGrabberBox(), UIScale);
}
protected internal override void MouseExited()

View File

@@ -223,23 +223,8 @@ namespace Robust.Client.UserInterface.Controls
var first = GetChild(0);
var second = GetChild(1);
var firstDesiredSize = firstMinSize ?? (Vertical ? first.DesiredSize.Y : first.DesiredSize.X);
var secondDesiredSize = secondMinSize ?? (Vertical ? second.DesiredSize.Y : second.DesiredSize.X);
var firstOrientedMinSize = Vertical ? first.MinSize.Y : first.MinSize.X;
var secondOrientedMinSize = Vertical ? second.MinSize.Y : second.MinSize.X;
if (firstOrientedMinSize > firstDesiredSize && firstOrientedMinSize != 0)
{
first.Measure(controlSize);
}
if (secondOrientedMinSize > secondDesiredSize && secondOrientedMinSize != 0)
{
second.Measure(controlSize);
}
firstMinSize = Vertical ? first.DesiredSize.Y : first.DesiredSize.X;
secondMinSize = Vertical ? second.DesiredSize.Y : second.DesiredSize.X;
firstMinSize ??= (Vertical ? first.DesiredSize.Y : first.DesiredSize.X);
secondMinSize ??= (Vertical ? second.DesiredSize.Y : second.DesiredSize.X);
var size = Vertical ? controlSize.Y : controlSize.X;
_splitStart = MathHelper.Clamp(_splitStart, firstMinSize.Value,

View File

@@ -143,7 +143,7 @@ namespace Robust.Client.UserInterface.Controls
var panel = _getPanel();
var panelBox = new UIBox2(0, headerSize, PixelWidth, PixelHeight);
panel?.Draw(handle, panelBox);
panel?.Draw(handle, panelBox, UIScale);
var font = _getFont();
var boxActive = _getTabBoxActive();
@@ -185,10 +185,10 @@ namespace Robust.Client.UserInterface.Controls
if (box != null)
{
var drawBox = box.GetEnvelopBox(topLeft, size);
var drawBox = box.GetEnvelopBox(topLeft, size, UIScale);
boxAdvance = drawBox.Width;
box.Draw(handle, drawBox);
contentBox = box.GetContentBox(drawBox);
box.Draw(handle, drawBox, UIScale);
contentBox = box.GetContentBox(drawBox, UIScale);
}
else
{
@@ -223,7 +223,7 @@ namespace Robust.Client.UserInterface.Controls
}
var panel = _getPanel();
var panelSize = (panel?.MinimumSize ?? Vector2.Zero) / UIScale;
var panelSize = (panel?.MinimumSize ?? Vector2.Zero);
var contentsSize = availableSize - headerSize - panelSize;
@@ -252,7 +252,7 @@ namespace Robust.Client.UserInterface.Controls
var contentBox = new UIBox2i(0, headerSize, (int) (finalSize.X * UIScale), (int) (finalSize.Y * UIScale));
if (panel != null)
{
contentBox = (UIBox2i) panel.GetContentBox(contentBox);
contentBox = (UIBox2i) panel.GetContentBox(contentBox, UIScale);
}
var control = GetChild(_currentTab);
@@ -322,6 +322,7 @@ namespace Robust.Client.UserInterface.Controls
}
}
// Returns the size of the header, in real pixels
[System.Diagnostics.Contracts.Pure]
private int _getHeaderSize()
{
@@ -333,8 +334,8 @@ namespace Robust.Client.UserInterface.Controls
var inactive = _getTabBoxInactive();
var font = _getFont();
var activeSize = active?.MinimumSize ?? Vector2.Zero;
var inactiveSize = inactive?.MinimumSize ?? Vector2.Zero;
var activeSize = (active?.MinimumSize ?? Vector2.Zero) * UIScale;
var inactiveSize = (inactive?.MinimumSize ?? Vector2.Zero) * UIScale;
headerSize = (int) MathF.Max(activeSize.Y, inactiveSize.Y);
headerSize += font.GetHeight(UIScale);

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Numerics;
using Robust.Client.Graphics;
@@ -117,7 +117,7 @@ namespace Robust.Client.UserInterface.Controls
var background = _getBackground();
if (background != null)
{
position -= background.GetContentOffset(Vector2.Zero);
position -= background.GetContentOffset(Vector2.Zero, UIScale);
}
var vOffset = -_scrollBar.Value;
@@ -187,8 +187,8 @@ namespace Robust.Client.UserInterface.Controls
if (background != null)
{
background.Draw(handle, PixelSizeBox);
var (bho, bvo) = background.GetContentOffset(Vector2.Zero);
background.Draw(handle, PixelSizeBox, UIScale);
var (bho, bvo) = background.GetContentOffset(Vector2.Zero, UIScale);
vOffset += bvo;
hOffset += bho;
}
@@ -214,12 +214,13 @@ namespace Robust.Client.UserInterface.Controls
var selected = item.Index == _selectedIndex;
if (selected)
{
itemSelected.Draw(handle, UIBox2.FromDimensions(hOffset, vOffset, PixelWidth - hOffset, itemHeight));
var imageTarget = UIBox2.FromDimensions(hOffset, vOffset, PixelWidth - hOffset, itemHeight);
itemSelected.Draw(handle, imageTarget, UIScale);
}
if (!string.IsNullOrWhiteSpace(item.Text))
{
var offset = itemSelected.GetContentOffset(Vector2.Zero);
var offset = itemSelected.GetContentOffset(Vector2.Zero, UIScale);
var baseLine = offset + new Vector2(hOffset, vOffset + font.GetAscent(UIScale));
foreach (var rune in item.Text.EnumerateRunes())
{

View File

@@ -152,12 +152,17 @@ internal sealed partial class UserInterfaceManager
_styleUpdateQueue.Enqueue(control);
}
/// <summary>
/// Queues a control so that it gets remeasured in the next frame update. Does not queue an arrange update.
/// </summary>
public void QueueMeasureUpdate(Control control)
{
_measureUpdateQueue.Enqueue(control);
_arrangeUpdateQueue.Enqueue(control);
}
/// <summary>
/// Queues a control so that it gets rearranged in the next frame update. Does not queue a measure update.
/// </summary>
public void QueueArrangeUpdate(Control control)
{
_arrangeUpdateQueue.Enqueue(control);

View File

@@ -38,6 +38,7 @@ internal sealed partial class UserInterfaceManager
newRoot.StyleSheetUpdate();
newRoot.InvalidateMeasure();
QueueMeasureUpdate(newRoot);
QueueArrangeUpdate(newRoot);
if (window.IsFocused)
FocusRoot(newRoot);

View File

@@ -26,6 +26,7 @@ using Robust.Shared.Profiling;
using Robust.Shared.Prototypes;
using Robust.Shared.Reflection;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
namespace Robust.Client.UserInterface
@@ -54,6 +55,12 @@ namespace Robust.Client.UserInterface
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IRuntimeLog _runtime = default!;
/// <summary>
/// Upper limit on the number of times that controls can be measured / arranged each tick before being deferred
/// to the next frame update. This is just meant to prevent infinite loops from completely locking up the UI.
/// </summary>
public const int ControlUpdateLimit = 25_000;
[ViewVariables] public InterfaceTheme ThemeDefaults { get; private set; } = default!;
[ViewVariables]
public Stylesheet? Stylesheet
@@ -220,6 +227,12 @@ namespace Robust.Client.UserInterface
var total = 0;
while (_styleUpdateQueue.Count != 0)
{
if (total >= ControlUpdateLimit)
{
_sawmillUI.Warning($"Hit style update limit. Queued: {_styleUpdateQueue.Count}. Next in queue: {_styleUpdateQueue.Peek()}. Parent: {_styleUpdateQueue.Peek().Parent}");
break;
}
var control = _styleUpdateQueue.Dequeue();
if (control.Disposed)
@@ -237,12 +250,20 @@ namespace Robust.Client.UserInterface
var total = 0;
while (_measureUpdateQueue.Count != 0)
{
if (total >= ControlUpdateLimit)
{
_sawmillUI.Warning($"Hit measure update limit. Queued: {_measureUpdateQueue.Count}. Next in queue: {_measureUpdateQueue.Peek()}. Parent: {_measureUpdateQueue.Peek().Parent}");
break;
}
var control = _measureUpdateQueue.Dequeue();
if (control.Disposed)
continue;
RunMeasure(control);
if (!control.IsMeasureValid && control.IsInsideTree)
_sawmillUI.Warning($"Control's measure is invalid after measuring. Control: {control}. Parent: {control.Parent}.");
total += 1;
}
@@ -254,12 +275,19 @@ namespace Robust.Client.UserInterface
var total = 0;
while (_arrangeUpdateQueue.Count != 0)
{
if (total >= ControlUpdateLimit)
{
_sawmillUI.Warning($"Hit arrange update limit. Queued: {_arrangeUpdateQueue.Count}. Next in queue: {_arrangeUpdateQueue.Peek()}. Parent: {_arrangeUpdateQueue.Peek().Parent}");
break;
}
var control = _arrangeUpdateQueue.Dequeue();
if (control.Disposed)
continue;
RunArrange(control);
if (!control.IsArrangeValid && control.IsInsideTree)
_sawmillUI.Warning($"Control's arrangement is invalid after arranging. Control: {control}. Parent: {control.Parent}.");
total += 1;
}

View File

@@ -424,12 +424,16 @@ public sealed class MapLoaderSystem : EntitySystem
}
var entities = (SequenceDataNode) metaDef["entities"];
EntityPrototype? proto = null;
if (type != null)
_prototypeManager.TryIndex(type, out proto);
foreach (var entityDef in entities.Cast<MappingDataNode>())
{
var uid = entityDef.Get<ValueDataNode>("uid").AsInt();
var entity = _serverEntityManager.AllocEntity(type);
var entity = _serverEntityManager.AllocEntity(proto);
data.Entities.Add(entity);
data.UidEntityMap.Add(uid, entity);
data.EntitiesToDeserialize.Add(entity, entityDef);
@@ -462,11 +466,13 @@ public sealed class MapLoaderSystem : EntitySystem
}
else if (ev.RenamedPrototypes.TryGetValue(typeNode.Value, out var newType))
{
entity = _serverEntityManager.AllocEntity(newType);
_prototypeManager.TryIndex<EntityPrototype>(newType, out var prototype);
entity = _serverEntityManager.AllocEntity(prototype);
}
else
{
entity = _serverEntityManager.AllocEntity(typeNode.Value);
_prototypeManager.TryIndex<EntityPrototype>(typeNode.Value, out var prototype);
entity = _serverEntityManager.AllocEntity(prototype);
}
}
else

View File

@@ -8,7 +8,7 @@ namespace Robust.Server.GameObjects
// These methods are used by the map loader to do multi-stage entity construction during map load.
// I would recommend you refer to the MapLoader for usage.
EntityUid AllocEntity(string? prototypeName, EntityUid uid = default);
EntityUid AllocEntity(EntityPrototype? prototype, EntityUid uid = default);
void FinishEntityLoad(EntityUid entity, IEntityLoadContext? context = null);

View File

@@ -54,9 +54,9 @@ namespace Robust.Server.GameObjects
base.Initialize();
}
EntityUid IServerEntityManagerInternal.AllocEntity(string? prototypeName, EntityUid uid)
EntityUid IServerEntityManagerInternal.AllocEntity(EntityPrototype? prototype, EntityUid uid)
{
return AllocEntity(prototypeName, out _, uid);
return AllocEntity(prototype, out _, uid);
}
void IServerEntityManagerInternal.FinishEntityLoad(EntityUid entity, IEntityLoadContext? context)

View File

@@ -40,6 +40,11 @@ namespace Robust.Shared.Maths
Right = right;
Bottom = bottom;
}
public Thickness Scale(float scale)
{
return new Thickness(Left * scale, Top * scale, Right * scale, Bottom * scale);
}
[SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator")]
public readonly bool Equals(Thickness other)

View File

@@ -675,29 +675,20 @@ namespace Robust.Shared.GameObjects
/// Allocates an entity and stores it but does not load components or do initialization.
/// </summary>
private protected EntityUid AllocEntity(
string? prototypeName,
EntityPrototype? prototype,
out MetaDataComponent metadata,
EntityUid uid = default)
{
EntityPrototype? prototype = null;
if (!string.IsNullOrWhiteSpace(prototypeName))
{
// If the prototype doesn't exist then we throw BEFORE we allocate the entity.
prototype = PrototypeManager.Index<EntityPrototype>(prototypeName);
}
var entity = AllocEntity(out metadata, uid);
metadata._entityPrototype = prototype;
Dirty(metadata, metadata);
Dirty(entity, metadata, metadata);
return entity;
}
/// <summary>
/// Allocates an entity and stores it but does not load components or do initialization.
/// </summary>
private protected EntityUid AllocEntity(out MetaDataComponent metadata, EntityUid uid = default)
private EntityUid AllocEntity(out MetaDataComponent metadata, EntityUid uid = default)
{
if (uid == default)
{
@@ -735,7 +726,9 @@ namespace Robust.Shared.GameObjects
if (prototypeName == null)
return AllocEntity(out _, uid);
var entity = AllocEntity(prototypeName, out var metadata, uid);
PrototypeManager.TryIndex<EntityPrototype>(prototypeName, out var prototype);
var entity = AllocEntity(prototype, out var metadata, uid);
try
{
EntityPrototype.LoadEntity(metadata.EntityPrototype, entity, ComponentFactory, this, _serManager, context);

View File

@@ -131,6 +131,11 @@ namespace Robust.Shared.Map
void FindGridsIntersecting<TState>(MapId mapId, Box2 worldAABB, ref TState state, GridCallback<TState> callback, bool approx = false, bool includeMap = true);
void FindGridsIntersecting(MapId mapId, Box2Rotated worldBounds, GridCallback callback, bool approx = false, bool includeMap = true);
void FindGridsIntersecting<TState>(MapId mapId, Box2Rotated worldBounds, ref TState state, GridCallback<TState> callback, bool approx = false, bool includeMap = true);
/// <summary>
/// Returns the grids intersecting this AABB.
/// </summary>

View File

@@ -107,6 +107,18 @@ internal partial class MapManager
state = state2.state;
}
public void FindGridsIntersecting(MapId mapId, Box2Rotated worldBounds, GridCallback callback, bool approx = false,
bool includeMap = true)
{
FindGridsIntersecting(mapId, worldBounds.CalcBoundingBox(), callback, approx, includeMap);
}
public void FindGridsIntersecting<TState>(MapId mapId, Box2Rotated worldBounds, ref TState state, GridCallback<TState> callback,
bool approx = false, bool includeMap = true)
{
FindGridsIntersecting(mapId, worldBounds.CalcBoundingBox(), ref state, callback, approx, includeMap);
}
private static bool IsIntersecting(
Box2 aabb,
EntityUid gridUid,

View File

@@ -3,6 +3,7 @@ using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

View File

@@ -19,7 +19,7 @@
<PackageReference Include="Linguini.Bundle" Version="0.1.3" />
<PackageReference Include="SharpZstd.Interop" Version="1.5.2-beta2" />
<PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />

View File

@@ -16,7 +16,7 @@ namespace Robust.UnitTesting.Client.Graphics
var styleBox = new StyleBoxFlat();
Assert.That(
styleBox.GetEnvelopBox(Vector2.Zero, new Vector2(50, 50)),
styleBox.GetEnvelopBox(Vector2.Zero, new Vector2(50, 50), 1),
Is.EqualTo(new UIBox2(0, 0, 50, 50)));
styleBox.ContentMarginLeftOverride = 3;
@@ -25,12 +25,16 @@ namespace Robust.UnitTesting.Client.Graphics
styleBox.ContentMarginBottomOverride = 11;
Assert.That(
styleBox.GetEnvelopBox(Vector2.Zero, new Vector2(50, 50)),
styleBox.GetEnvelopBox(Vector2.Zero, new Vector2(50, 50), 1),
Is.EqualTo(new UIBox2(0, 0, 60, 66)));
Assert.That(
styleBox.GetEnvelopBox(new Vector2(10, 10), new Vector2(50, 50)),
styleBox.GetEnvelopBox(new Vector2(10, 10), new Vector2(50, 50), 1),
Is.EqualTo(new UIBox2(10, 10, 70, 76)));
Assert.That(
styleBox.GetEnvelopBox(new Vector2(10, 10), new Vector2(50, 50), 2.0f),
Is.EqualTo(new UIBox2(10, 10, 80, 92)));
}
}
}