Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LocalizedPrototype Type #747

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions Content.Shared/Prototypes/LocalizedPrototype.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Linq;
using Robust.Shared.Prototypes;

namespace Content.Shared.Prototypes;

public abstract class LocalizedPrototype : IPrototype
{
[IdDataField]
public string ID { get; } = default!;

public const string LocFormat = "{0}-{1}-{2}";

/// <summary>The localization string for the name of this prototype</summary>
public string NameLoc => ToLocalizationString("name");
/// <summary>The localized string for the name of prototype</summary>
public string Name => Loc.GetString(NameLoc);
VMSolidus marked this conversation as resolved.
Show resolved Hide resolved
Comment on lines +14 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This recalculates NameLoc every time either of those properties is accessed, which is bad. It should be cached and only calculated once (perhaps as a deserialization hook, or a lazily evaluated/cached property?)


/// <summary>
/// Returns an Loc string using the <see cref="field"/> as the 'property'.
/// Given `desc` it will return `this-prototype-PrototypeId-desc`.
/// </summary>
public string ToLocalizationString(string field)
DEATHB4DEFEAT marked this conversation as resolved.
Show resolved Hide resolved
{
// Get the ID of the proto Type
var type =
((PrototypeAttribute?) Attribute.GetCustomAttribute(GetType(), typeof(PrototypeAttribute)))?.Type
?? GetType().Name.Remove(GetType().Name.Length - 9);
// Lowercase the first letter
type = char.ToLowerInvariant(type[0]) + type[1..];
// Replace every uppercase letter with a dash and the lowercase letter
type = type.Aggregate("", (current, c) => current + (char.IsUpper(c) ? "-" + char.ToLowerInvariant(c) : c.ToString()));
DEATHB4DEFEAT marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This performs n string concatenations, each concatenation having a cost of n itself, resulting in an O(n²) operation. This should use a StringBuilder instead. Considering that this function will be called hundreds or thousands of times, performance matters here.


return string.Format(LocFormat, type, ID, field);
}
}
Loading