Files
2025-09-17 13:44:21 +03:00

203 lines
6.8 KiB
C#

#nullable enable
using System;
using System.Collections.Immutable;
namespace Barotrauma
{
public class RichString
{
protected bool loaded = false;
protected LanguageIdentifier language = LanguageIdentifier.None;
private int languageVersion = 0;
protected string cachedSanitizedValue = "";
public string SanitizedValue
{
get
{
if (MustRetrieveValue()) { RetrieveValue(); }
return cachedSanitizedValue;
}
}
public int Length => SanitizedValue.Length;
private readonly Func<string, string>? postProcess;
private readonly bool shouldParseRichTextData;
private readonly LocalizedString originalStr;
public LocalizedString NestedStr { get; private set; }
public readonly LocalizedString SanitizedString;
public bool Loaded => loaded;
#if CLIENT
private readonly GUIFont? font;
private readonly GUIComponentStyle? componentStyle;
private bool forceUpperCase = false;
private bool FontOrStyleForceUpperCase
=> font is { ForceUpperCase: true } || componentStyle is { ForceUpperCase: true };
#endif
public ImmutableArray<RichTextData>? RichTextData { get; private set; }
#if CLIENT
private RichString(
LocalizedString nestedStr, bool shouldParseRichTextData, Func<string, string>? postProcess = null,
GUIFont? font = null, GUIComponentStyle? componentStyle = null) : this(nestedStr, shouldParseRichTextData, postProcess)
{
this.font = font;
this.componentStyle = componentStyle;
}
#endif
private RichString(LocalizedString nestedStr, bool shouldParseRichTextData, Func<string,string>? postProcess = null)
{
originalStr = nestedStr;
NestedStr = originalStr;
this.shouldParseRichTextData = shouldParseRichTextData;
this.postProcess = postProcess;
SanitizedString = new StripRichTagsLString(this);
#if CLIENT
this.font = null;
this.componentStyle = null;
#endif
}
public static RichString Rich(LocalizedString str, Func<string, string>? postProcess = null)
{
return new RichString(str, true, postProcess);
}
public static RichString Plain(LocalizedString str)
{
return new RichString(str, false, postProcess: null);
}
public static implicit operator LocalizedString(RichString richStr) => richStr.NestedStr;
public static implicit operator RichString(LocalizedString lStr)
{
#if DEBUG
if (!lStr.IsNullOrEmpty() && lStr.Contains("‖"))
{
//if (Debugger.IsAttached) { Debugger.Break(); }
}
#endif
return Plain(lStr ?? string.Empty);
}
public static implicit operator RichString(string str) => (LocalizedString)str;
protected virtual bool MustRetrieveValue()
{
return NestedStr.Loaded != loaded
|| language != GameSettings.CurrentConfig.Language
|| languageVersion != TextManager.LanguageVersion
#if CLIENT
|| (FontOrStyleForceUpperCase != forceUpperCase)
#endif
;
}
public void RetrieveValue()
{
#if CLIENT
NestedStr = FontOrStyleForceUpperCase ? originalStr.ToUpper() : originalStr;
forceUpperCase = FontOrStyleForceUpperCase;
#endif
if (shouldParseRichTextData)
{
RichTextData = Barotrauma.RichTextData.GetRichTextData(NestedStr.Value, out cachedSanitizedValue);
}
else
{
cachedSanitizedValue = NestedStr.Value;
}
if (postProcess != null) { cachedSanitizedValue = postProcess(cachedSanitizedValue); }
language = GameSettings.CurrentConfig.Language;
languageVersion = TextManager.LanguageVersion;
loaded = NestedStr.Loaded;
}
#if CLIENT
public RichString CaseTiedToFontAndStyle(GUIFont? font, GUIComponentStyle? componentStyle)
{
return new RichString(originalStr, shouldParseRichTextData, postProcess, font, componentStyle);
}
#endif
public RichString ToUpper()
{
return new RichString(NestedStr.ToUpper(), shouldParseRichTextData, postProcess);
}
public RichString ToLower()
{
return new RichString(NestedStr.ToLower(), shouldParseRichTextData, postProcess);
}
public RichString Replace(string from, string to, StringComparison stringComparison = StringComparison.Ordinal)
{
return new RichString(NestedStr.Replace(from, to, stringComparison), shouldParseRichTextData, postProcess);
}
public override string ToString()
{
return SanitizedValue;
}
public bool Contains(string str, StringComparison stringComparison = StringComparison.Ordinal) =>
SanitizedValue.Contains(str, stringComparison);
public bool Contains(char chr, StringComparison stringComparison = StringComparison.Ordinal) =>
SanitizedValue.Contains(chr, stringComparison);
public static bool operator ==(RichString? a, RichString? b)
=> a?.SanitizedValue == b?.SanitizedValue
#if CLIENT
&& a?.font == b?.font
&& a?.componentStyle == b?.componentStyle
#endif
;
public static bool operator !=(RichString? a, RichString? b) => !(a == b);
public static bool operator ==(RichString? a, LocalizedString? b)
=> a?.SanitizedValue == b?.Value;
public static bool operator !=(RichString? a, LocalizedString? b) => !(a == b);
public static bool operator ==(LocalizedString? a, RichString? b)
=> a?.Value == b?.SanitizedValue;
public static bool operator !=(LocalizedString? a, RichString? b) => !(a == b);
public static bool operator ==(RichString? a, string? b)
=> a?.SanitizedValue == b;
public static bool operator !=(RichString? a, string? b) => !(a == b);
public static bool operator ==(string? a, RichString? b)
=> a == b?.SanitizedValue;
public static bool operator !=(string? a, RichString? b) => !(a == b);
}
class StripRichTagsLString : LocalizedString
{
public readonly RichString RichStr;
public StripRichTagsLString(RichString richStr)
{
RichStr = richStr;
}
public override bool Loaded => RichStr.NestedStr.Loaded;
public override void RetrieveValue()
{
cachedValue = RichStr.SanitizedValue;
}
}
}