mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
* Add VisibilityChanged virtual to Control * Defer updating invisible OutputPanels on UIScale change DebugConsole falls under this when not hidden, and it significantly improves perf of e.g. resizing the window when there's a lot of stuff in there. * Avoid redundant UI Scale updates on window resize. Window resizing can change the UI scale, due to the auto-scaling system. This system had multiple perf issues: UI scale was set and propagated even if it didn't change (system disabled, not effective, etc). This was just wasted processing. UI scale was updated for every window resize event. When the game is lagging (due to the aforementioned UI scale updates being expensive...) this means multiple window resize events in a single frame ALL cause a UI scale update, which is useless. UI scale updates from resizing now avoid doing *nothing* and are deferred until later in the frame for natural batching. * Reduce allocations/memory usage of various rich-text related things Just allocate a buncha dictionaries what could possibly go wrong. I kept to non-breaking-changes which means this couldn't as effective as it should be. There's some truly repulsive stuff here. Ugh. * Cap debug console content size. It's a CVar. OutputPanel has been switched to use a new RingBufferList datastructure to make removal of the oldest entry efficient. --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
141 lines
3.8 KiB
C#
141 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using Robust.Shared.Maths;
|
|
using Robust.Shared.Serialization;
|
|
|
|
namespace Robust.Shared.Utility;
|
|
|
|
[Serializable, NetSerializable]
|
|
public sealed class MarkupNode : IComparable<MarkupNode>
|
|
{
|
|
public readonly string? Name;
|
|
public readonly MarkupParameter Value;
|
|
public readonly Dictionary<string, MarkupParameter> Attributes;
|
|
public readonly bool Closing;
|
|
|
|
/// <summary>
|
|
/// Creates a nameless tag for plaintext
|
|
/// </summary>
|
|
/// <param name="text">The plaintext the tag will consist of</param>
|
|
public MarkupNode(string text)
|
|
{
|
|
Attributes = new Dictionary<string, MarkupParameter>();
|
|
Value = new MarkupParameter(text);
|
|
}
|
|
|
|
public MarkupNode(string? name, MarkupParameter? value, Dictionary<string, MarkupParameter>? attributes, bool closing = false)
|
|
{
|
|
Name = name;
|
|
Value = value ?? new MarkupParameter();
|
|
Attributes = attributes ?? new Dictionary<string, MarkupParameter>();
|
|
Closing = closing;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
if(Name == null)
|
|
return Value.StringValue ?? "";
|
|
|
|
var attributesString = "";
|
|
foreach (var (k, v) in Attributes)
|
|
{
|
|
attributesString += $"{k}{v}";
|
|
}
|
|
|
|
return $"[{(Closing ? "/" : "")}{Name}{Value.ToString().ReplaceLineEndings("\\n") ?? ""}{attributesString}]";
|
|
}
|
|
|
|
public override bool Equals(object? obj)
|
|
{
|
|
return obj is MarkupNode node && Equals(node);
|
|
}
|
|
|
|
public bool Equals(MarkupNode node)
|
|
{
|
|
var equal = Name == node.Name;
|
|
equal &= Value.Equals(node.Value);
|
|
equal &= Attributes.Count == 0 && node.Attributes.Count == 0 || Attributes.Equals(node.Attributes);
|
|
equal &= Closing == node.Closing;
|
|
|
|
return equal;
|
|
}
|
|
|
|
public int CompareTo(MarkupNode? other)
|
|
{
|
|
if (ReferenceEquals(this, other))
|
|
return 0;
|
|
if (ReferenceEquals(null, other))
|
|
return 1;
|
|
|
|
var nameComparison = string.Compare(Name, other.Name, StringComparison.Ordinal);
|
|
return nameComparison != 0 ? nameComparison : Closing.CompareTo(other.Closing);
|
|
}
|
|
}
|
|
|
|
[Serializable, NetSerializable]
|
|
public readonly record struct MarkupParameter(string? StringValue = null, long? LongValue = null, Color? ColorValue = null)
|
|
{
|
|
public MarkupParameter(string? stringValue) : this(StringValue: stringValue)
|
|
{
|
|
}
|
|
|
|
public MarkupParameter(long? longValue) : this(LongValue: longValue)
|
|
{
|
|
}
|
|
|
|
public MarkupParameter(Color? colorValue) : this(ColorValue: colorValue)
|
|
{
|
|
}
|
|
|
|
public bool TryGetString([NotNullWhen(true)] out string? value)
|
|
{
|
|
value = StringValue;
|
|
return StringValue != null;
|
|
}
|
|
|
|
public bool TryGetLong([NotNullWhen(true)] out long? value)
|
|
{
|
|
value = LongValue;
|
|
return LongValue.HasValue;
|
|
}
|
|
|
|
public bool TryGetColor([NotNullWhen(true)] out Color? value)
|
|
{
|
|
value = ColorValue;
|
|
return ColorValue.HasValue;
|
|
}
|
|
|
|
|
|
public override string ToString()
|
|
{
|
|
if (StringValue != null)
|
|
return $"=\"{StringValue}\"";
|
|
|
|
if (LongValue.HasValue)
|
|
return LongValue?.ToString().Insert(0, "=") ?? "";
|
|
|
|
if (ColorValue?.Name() != null)
|
|
return ColorValue.Value.Name()!.Insert(0, "=");
|
|
|
|
return ColorValue?.ToHex().Insert(0, "=") ?? "";
|
|
}
|
|
|
|
public bool Equals(MarkupParameter? other)
|
|
{
|
|
if (!other.HasValue)
|
|
return false;
|
|
|
|
var equal = StringValue == other.Value.StringValue;
|
|
equal &= LongValue == other.Value.LongValue;
|
|
equal &= ColorValue == other.Value.ColorValue;
|
|
|
|
return equal;
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return HashCode.Combine(StringValue, LongValue, ColorValue);
|
|
}
|
|
}
|