From 850e9ab695ef7994d5a254bcbeaca7c870d30c2c Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:44:21 +1200 Subject: [PATCH] Try optimize `NetEntities` console completion helper (#5217) * Try optimize `NetEntities` completion options * Actually just remove it * a --- RELEASE-NOTES.md | 2 +- Resources/Locale/en-US/commands.ftl | 6 +-- .../Console/Commands/TeleportCommands.cs | 7 +-- Robust.Shared/Console/CompletionHelper.cs | 44 +++++++++++++------ Robust.Shared/GameObjects/NetEntity.cs | 2 +- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 6afc2154b..252a53723 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -35,7 +35,7 @@ END TEMPLATE--> ### Breaking changes -*None yet* +* `NetEntity.Parse` and `TryParse` will now fail to parse empty strings. ### New features diff --git a/Resources/Locale/en-US/commands.ftl b/Resources/Locale/en-US/commands.ftl index 2e4b31962..4d0c0cf84 100644 --- a/Resources/Locale/en-US/commands.ftl +++ b/Resources/Locale/en-US/commands.ftl @@ -382,9 +382,9 @@ cmd-tp-desc = Teleports a player to any location in the round. cmd-tp-help = tp [] cmd-tpto-desc = Teleports the current player or the specified players/entities to the location of the first player/entity. -cmd-tpto-help = tpto [username|uid]... -cmd-tpto-destination-hint = destination (uid or username) -cmd-tpto-victim-hint = entity to teleport (uid or username) +cmd-tpto-help = tpto [username|NetEntity]... +cmd-tpto-destination-hint = destination (NetEntity or username) +cmd-tpto-victim-hint = entity to teleport (NetEntity or username) cmd-tpto-parse-error = Cant resolve entity or player: {$str} cmd-listplayers-desc = Lists all players currently connected. diff --git a/Robust.Shared/Console/Commands/TeleportCommands.cs b/Robust.Shared/Console/Commands/TeleportCommands.cs index a98a37a11..35724df37 100644 --- a/Robust.Shared/Console/Commands/TeleportCommands.cs +++ b/Robust.Shared/Console/Commands/TeleportCommands.cs @@ -174,12 +174,7 @@ public sealed class TeleportToCommand : LocalizedCommands var hint = args.Length == 1 ? "cmd-tpto-destination-hint" : "cmd-tpto-victim-hint"; hint = Loc.GetString(hint); - - var opts = CompletionResult.FromHintOptions(users, hint); - if (last != string.Empty && !NetEntity.TryParse(last, out _)) - return opts; - - return CompletionResult.FromHintOptions(opts.Options.Concat(CompletionHelper.NetEntities(last, _entities)), hint); + return CompletionResult.FromHintOptions(users, hint); } } diff --git a/Robust.Shared/Console/CompletionHelper.cs b/Robust.Shared/Console/CompletionHelper.cs index ff0b48399..b804cd3ac 100644 --- a/Robust.Shared/Console/CompletionHelper.cs +++ b/Robust.Shared/Console/CompletionHelper.cs @@ -189,27 +189,45 @@ public static class CompletionHelper return Components(string.Empty, entManager); } - public static IEnumerable NetEntities(string text, IEntityManager? entManager = null) + /// + /// Return all existing entities as possible completions. You should generally avoid using this unless you need to. + /// + public static IEnumerable NetEntities(string text, IEntityManager? entManager = null, int limit = 20) { - return Components(text, entManager); - } + if (!NetEntity.TryParse(text, out _)) + yield break; - public static IEnumerable Components(string text, IEntityManager? entManager = null) where T : IComponent - { IoCManager.Resolve(ref entManager); + var query = entManager.AllEntityQueryEnumerator(); - var query = entManager.AllEntityQueryEnumerator(); - - while (query.MoveNext(out var uid, out _, out var metadata)) + var i = 0; + while (i < limit && query.MoveNext(out var metadata)) { - if (!entManager.TryGetNetEntity(uid, out var netEntity, metadata: metadata)) - continue; - - var netString = netEntity.Value.ToString(); - + var netString = metadata.NetEntity.ToString(); if (!netString.StartsWith(text)) continue; + i++; + yield return new CompletionOption(netString, metadata.EntityName); + } + } + + public static IEnumerable Components(string text, IEntityManager? entManager = null, int limit = 20) where T : IComponent + { + if (!NetEntity.TryParse(text, out _)) + yield break; + + IoCManager.Resolve(ref entManager); + var query = entManager.AllEntityQueryEnumerator(); + + var i = 0; + while (i < limit && query.MoveNext(out _, out var metadata)) + { + var netString = metadata.NetEntity.ToString(); + if (!netString.StartsWith(text)) + continue; + + i++; yield return new CompletionOption(netString, metadata.EntityName); } } diff --git a/Robust.Shared/GameObjects/NetEntity.cs b/Robust.Shared/GameObjects/NetEntity.cs index 857fd0878..ffe6ff522 100644 --- a/Robust.Shared/GameObjects/NetEntity.cs +++ b/Robust.Shared/GameObjects/NetEntity.cs @@ -49,7 +49,7 @@ public readonly struct NetEntity : IEquatable, IComparable public static NetEntity Parse(ReadOnlySpan uid) { if (uid.Length == 0) - return default; + throw new FormatException($"An empty string is not a valid NetEntity"); if (uid[0] != 'c') return new NetEntity(int.Parse(uid));