Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
… into color-equality
  • Loading branch information
ElectroJr committed Jun 23, 2024
2 parents ccccc73 + e2cf4ee commit 7b2c03d
Show file tree
Hide file tree
Showing 39 changed files with 1,574 additions and 367 deletions.
2 changes: 1 addition & 1 deletion MSBuild/Robust.Engine.Version.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<!-- This file automatically reset by Tools/version.py -->
<PropertyGroup><Version>226.0.0</Version></PropertyGroup>
<PropertyGroup><Version>226.3.0</Version></PropertyGroup>
</Project>
Expand Down
49 changes: 48 additions & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,60 @@ END TEMPLATE-->

### Other

* Fix internal networking logic
*None yet*

### Internal

*None yet*


## 226.3.0

### New features

* `System.Collections.IList` and `System.Collections.ICollection` are now sandbox safe, this fixes some collection expression cases.
* The sandboxing system will now report the methods responsible for references to illegal items.


## 226.2.0

### New features

* `Control.VisibilityChanged()` virtual function.
* Add some System.Random methods for NextFloat and NextPolarVector2.

### Bugfixes

* Fixes ContainerSystem failing client-side debug asserts when an entity gets unanchored & inserted into a container on the same tick.
* Remove potential race condition on server startup from invoking ThreadPool.SetMinThreads.

### Other

* Increase default value of res.rsi_atlas_size.
* Fix internal networking logic.
* Updates of `OutputPanel` contents caused by change in UI scale are now deferred until visible. Especially important to avoid updates from debug console.
* Debug console is now limited to only keep `con.max_entries` entries.
* Non-existent resources are cached by `IResourceCache.TryGetResource`. This avoids the game constantly trying to re-load non-existent resources in common patterns such as UI theme texture fallbacks.
* Default IPv4 MTU has been lowered to 700.
* Update Robust.LoaderApi.

### Internal

* Split out PVS serialization from compression and sending game states.
* Turn broadphase contacts into an IParallelRobustJob and remove unnecessary GetMapEntityIds for every contact.


## 226.1.0

### New features

* Add some GetLocalEntitiesIntersecting methods for `Entity<T>`.

### Other

* Fix internal networking logic


## 226.0.0

### Breaking changes
Expand Down
4 changes: 2 additions & 2 deletions Robust.Client/ResourceManagement/ResourceCache.Preload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ private void PreloadTextures(ISawmill sawmill)
{
sawmill.Debug("Preloading textures...");
var sw = Stopwatch.StartNew();
var resList = GetTypeDict<TextureResource>();
var resList = GetTypeData<TextureResource>().Resources;

var texList = _manager.ContentFindFiles("/Textures/")
// Skip PNG files inside RSIs.
Expand Down Expand Up @@ -119,7 +119,7 @@ private void PreloadTextures(ISawmill sawmill)
private void PreloadRsis(ISawmill sawmill)
{
var sw = Stopwatch.StartNew();
var resList = GetTypeDict<RSIResource>();
var resList = GetTypeData<RSIResource>().Resources;

var rsiList = _manager.ContentFindFiles("/Textures/")
.Where(p => p.ToString().EndsWith(".rsi/meta.json"))
Expand Down
52 changes: 30 additions & 22 deletions Robust.Client/ResourceManagement/ResourceCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ namespace Robust.Client.ResourceManagement;
/// </summary>
internal sealed partial class ResourceCache : ResourceManager, IResourceCacheInternal, IDisposable
{
private readonly Dictionary<Type, Dictionary<ResPath, BaseResource>> _cachedResources =
new();

private readonly Dictionary<Type, TypeData> _cachedResources = new();
private readonly Dictionary<Type, BaseResource> _fallbacks = new();

public T GetResource<T>(string path, bool useFallback = true) where T : BaseResource, new()
Expand All @@ -29,8 +27,8 @@ internal sealed partial class ResourceCache : ResourceManager, IResourceCacheInt

public T GetResource<T>(ResPath path, bool useFallback = true) where T : BaseResource, new()
{
var cache = GetTypeDict<T>();
if (cache.TryGetValue(path, out var cached))
var cache = GetTypeData<T>();
if (cache.Resources.TryGetValue(path, out var cached))
{
return (T) cached;
}
Expand All @@ -40,7 +38,7 @@ internal sealed partial class ResourceCache : ResourceManager, IResourceCacheInt
{
var dependencies = IoCManager.Instance!;
resource.Load(dependencies, path);
cache[path] = resource;
cache.Resources[path] = resource;
return resource;
}
catch (Exception e)
Expand All @@ -67,24 +65,31 @@ internal sealed partial class ResourceCache : ResourceManager, IResourceCacheInt

public bool TryGetResource<T>(ResPath path, [NotNullWhen(true)] out T? resource) where T : BaseResource, new()
{
var cache = GetTypeDict<T>();
if (cache.TryGetValue(path, out var cached))
var cache = GetTypeData<T>();
if (cache.Resources.TryGetValue(path, out var cached))
{
resource = (T) cached;
return true;
}

if (cache.NonExistent.Contains(path))
{
resource = null;
return false;
}

var _resource = new T();
try
{
var dependencies = IoCManager.Instance!;
_resource.Load(dependencies, path);
resource = _resource;
cache[path] = resource;
cache.Resources[path] = resource;
return true;
}
catch (FileNotFoundException)
{
cache.NonExistent.Add(path);
resource = null;
return false;
}
Expand All @@ -109,9 +114,9 @@ public bool TryGetResource(AudioStream stream, [NotNullWhen(true)] out AudioReso

public void ReloadResource<T>(ResPath path) where T : BaseResource, new()
{
var cache = GetTypeDict<T>();
var cache = GetTypeData<T>();

if (!cache.TryGetValue(path, out var res))
if (!cache.Resources.TryGetValue(path, out var res))
{
return;
}
Expand Down Expand Up @@ -145,7 +150,7 @@ public bool TryGetResource(AudioStream stream, [NotNullWhen(true)] out AudioReso

public void CacheResource<T>(ResPath path, T resource) where T : BaseResource, new()
{
GetTypeDict<T>()[path] = resource;
GetTypeData<T>().Resources[path] = resource;
}

public T GetFallback<T>() where T : BaseResource, new()
Expand All @@ -168,7 +173,7 @@ public bool TryGetResource(AudioStream stream, [NotNullWhen(true)] out AudioReso

public IEnumerable<KeyValuePair<ResPath, T>> GetAllResources<T>() where T : BaseResource, new()
{
return GetTypeDict<T>().Select(p => new KeyValuePair<ResPath, T>(p.Key, (T) p.Value));
return GetTypeData<T>().Resources.Select(p => new KeyValuePair<ResPath, T>(p.Key, (T) p.Value));
}

public event Action<TextureLoadedEventArgs>? OnRawTextureLoaded;
Expand All @@ -193,7 +198,7 @@ private void Dispose(bool disposing)

if (disposing)
{
foreach (var res in _cachedResources.Values.SelectMany(dict => dict.Values))
foreach (var res in _cachedResources.Values.SelectMany(dict => dict.Resources.Values))
{
res.Dispose();
}
Expand All @@ -210,15 +215,9 @@ private void Dispose(bool disposing)
#endregion IDisposable Members

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<ResPath, BaseResource> GetTypeDict<T>()
private TypeData GetTypeData<T>()
{
if (!_cachedResources.TryGetValue(typeof(T), out var ret))
{
ret = new Dictionary<ResPath, BaseResource>();
_cachedResources.Add(typeof(T), ret);
}

return ret;
return _cachedResources.GetOrNew(typeof(T));
}

public void TextureLoaded(TextureLoadedEventArgs eventArgs)
Expand All @@ -230,4 +229,13 @@ public void RsiLoaded(RsiLoadedEventArgs eventArgs)
{
OnRsiLoaded?.Invoke(eventArgs);
}

private sealed class TypeData
{
public readonly Dictionary<ResPath, BaseResource> Resources = new();

// List of resources which DON'T exist.
// Needed to avoid innocuous TryGet calls repeatedly trying to re-load non-existent resources from disk.
public readonly HashSet<ResPath> NonExistent = new();
}
}
9 changes: 9 additions & 0 deletions Robust.Client/UserInterface/Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,18 @@ public bool Visible
}
}

/// <summary>
/// Called when this control's visibility in the control tree changed.
/// </summary>
protected virtual void VisibilityChanged(bool newVisible)
{
}

private void _propagateVisibilityChanged(bool newVisible)
{
VisibilityChanged(newVisible);
OnVisibilityChanged?.Invoke(this);

if (!VisibleInTree)
{
UserInterfaceManagerInternal.ControlHidden(this);
Expand Down
7 changes: 7 additions & 0 deletions Robust.Client/UserInterface/Controls/ContainerButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class ContainerButton : BaseButton
public const string StylePseudoClassHover = "hover";
public const string StylePseudoClassDisabled = "disabled";

public StyleBox? StyleBoxOverride { get; set; }

public ContainerButton()
{
DrawModeChanged();
Expand All @@ -24,6 +26,11 @@ private StyleBox ActualStyleBox
{
get
{
if (StyleBoxOverride != null)
{
return StyleBoxOverride;
}

if (TryGetStyleProperty<StyleBox>(StylePropertyStyleBox, out var box))
{
return box;
Expand Down
36 changes: 27 additions & 9 deletions Robust.Client/UserInterface/Controls/OutputPanel.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.InteropServices;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.RichText;
using Robust.Shared.Collections;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
Expand All @@ -20,7 +19,7 @@ public class OutputPanel : Control

public const string StylePropertyStyleBox = "stylebox";

private readonly List<RichTextEntry> _entries = new();
private readonly RingBufferList<RichTextEntry> _entries = new();
private bool _isAtBottom = true;

private int _totalContentHeight;
Expand All @@ -30,6 +29,8 @@ public class OutputPanel : Control

public bool ScrollFollowing { get; set; } = true;

private bool _invalidOnVisible;

public OutputPanel()
{
IoCManager.InjectDependencies(this);
Expand All @@ -45,6 +46,8 @@ public OutputPanel()
_scrollBar.OnValueChanged += _ => _isAtBottom = _scrollBar.IsAtEnd;
}

public int EntryCount => _entries.Count;

public StyleBox? StyleBoxOverride
{
get => _styleBoxOverride;
Expand Down Expand Up @@ -91,7 +94,7 @@ public void AddMessage(FormattedMessage message)
{
var entry = new RichTextEntry(message, this, _tagManager, null);

entry.Update(_getFont(), _getContentBox().Width, UIScale);
entry.Update(_tagManager, _getFont(), _getContentBox().Width, UIScale);

_entries.Add(entry);
var font = _getFont();
Expand Down Expand Up @@ -134,7 +137,7 @@ protected internal override void Draw(DrawingHandleScreen handle)
// So when a new color tag gets hit this stack gets the previous color pushed on.
var context = new MarkupDrawingContext(2);

foreach (ref var entry in CollectionsMarshal.AsSpan(_entries))
foreach (ref var entry in _entries)
{
if (entryOffset + entry.Height < 0)
{
Expand All @@ -147,7 +150,7 @@ protected internal override void Draw(DrawingHandleScreen handle)
break;
}

entry.Draw(handle, font, contentBox, entryOffset, context, UIScale);
entry.Draw(_tagManager, handle, font, contentBox, entryOffset, context, UIScale);

entryOffset += entry.Height + font.GetLineSeparation(UIScale);
}
Expand Down Expand Up @@ -185,9 +188,9 @@ private void _invalidateEntries()
_totalContentHeight = 0;
var font = _getFont();
var sizeX = _getContentBox().Width;
foreach (ref var entry in CollectionsMarshal.AsSpan(_entries))
foreach (ref var entry in _entries)
{
entry.Update(font, sizeX, UIScale);
entry.Update(_tagManager, font, sizeX, UIScale);
_totalContentHeight += entry.Height + font.GetLineSeparation(UIScale);
}

Expand Down Expand Up @@ -239,7 +242,13 @@ private UIBox2 _getContentBox()

protected internal override void UIScaleChanged()
{
_invalidateEntries();
// If this control isn't visible, don't invalidate entries immediately.
// This saves invalidating the debug console if it's hidden,
// which is a huge boon as auto-scaling changes UI scale a lot in that scenario.
if (!VisibleInTree)
_invalidOnVisible = true;
else
_invalidateEntries();

base.UIScaleChanged();
}
Expand All @@ -257,5 +266,14 @@ protected override void EnteredTree()
// existing ones were valid when the UI scale was set.
_invalidateEntries();
}

protected override void VisibilityChanged(bool newVisible)
{
if (newVisible && _invalidOnVisible)
{
_invalidateEntries();
_invalidOnVisible = false;
}
}
}
}
4 changes: 2 additions & 2 deletions Robust.Client/UserInterface/Controls/RichTextLabel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ protected override Vector2 MeasureOverride(Vector2 availableSize)
}

var font = _getFont();
_entry.Update(font, availableSize.X * UIScale, UIScale, LineHeightScale);
_entry.Update(_tagManager, font, availableSize.X * UIScale, UIScale, LineHeightScale);

return new Vector2(_entry.Width / UIScale, _entry.Height / UIScale);
}
Expand All @@ -82,7 +82,7 @@ protected internal override void Draw(DrawingHandleScreen handle)
return;
}

_entry.Draw(handle, _getFont(), SizeBox, 0, new MarkupDrawingContext(), UIScale, LineHeightScale);
_entry.Draw(_tagManager, handle, _getFont(), SizeBox, 0, new MarkupDrawingContext(), UIScale, LineHeightScale);
}

[Pure]
Expand Down
Loading

0 comments on commit 7b2c03d

Please sign in to comment.