goatcorp / Dalamud

FFXIV plugin framework and API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

rfc: New SeString classes

Soreepeong opened this issue · comments

SeString : IList<Payload>, IReadOnlyList<Payload>, IList

int SeString.Capacity { get; set; }
int SeString.Count { get; private set; }
Payload SeString.this[int index] { get; set; }

static SeString SeString.From(byte*);
static SeString SeString.From(ReadOnlySpan<byte>);
static SeString SeString.From(ReadOnlyMemory<byte>);
static SeString SeString.FromLumina(Lumina.Text.[ReadOnly]SeString[Span]);
static SeString SeString.FromPayload(Payload);
static SeString SeString.FromPayload(Payload, Payload[]...);
static SeString SeString.FromPayload(IEnumerable<Payload>);
static SeString SeString.FromText(ReadOnlySpan<char>, bool controlCharactersToPayload);
static SeString SeString.FromText(ReadOnlyMemory<char>, bool controlCharactersToPayload);
static SeString SeString.FromText(string?, bool controlCharactersToPayload);

void SeString.EnsureCapacity(int capacity);
void SeString.Add(Payload payload);
void SeString.AddRange(IEnumerable<Payload> payloads);
void SeString.Insert(int index, Payload payload);
void SeString.InsertRange(int index, IEnumerable<Payload> payloads);
void SeString.Remove(int index);
void SeString.RemoveRange(int startIndex, int count);

byte[] SeString.EvaluateToBytes(SeStringEvaluationContext);
string SeString.EvaluateToString(SeStringEvaluationContext);
void SeString.EvaluateToBuilder(StringBuilder, SeStringEvaluationContext);
void SeString.EvaluateToBuilder(SeStringBuilder, SeStringEvaluationContext);

int SeString.CalculateByteCount(bool allowOverestimation);
byte[] SeString.ToBytes();
string SeString.ToString();
void SeString.ToBuilder(StringBuilder);
void SeString.ToBuilder(SeStringBuilder);

Payload : IList<Expression>, IReadOnlyList<Expression>, IList

int Payload.Count { get; private init; }
Expression Payload.this[int index] { get; set; }

static implicit operator Payload(ReadOnlySpan<char> str);
static implicit operator Payload(ReadOnlyMemory<char> str);
static implicit operator Payload(string? str);

static Payload Payload.From(byte*);
static Payload Payload.From(ReadOnlySpan<byte>);
static Payload Payload.From(ReadOnlyMemory<byte>);
static Payload Payload.FromLumina(Lumina.Text.[ReadOnly]SePayload[Span]);
static Payload Payload.FromText(ReadOnlySpan<char>);
static Payload Payload.FromText(ReadOnlyMemory<char>);
static Payload Payload.FromText(string?);

byte[] Payload.EvaluateToBytes(SeStringEvaluationContext);
string Payload.EvaluateToString(SeStringEvaluationContext);
void Payload.EvaluateToBuilder(StringBuilder, SeStringEvaluationContext);
void Payload.EvaluateToBuilder(SeStringBuilder, SeStringEvaluationContext);

int Payload.CalculateByteCount(bool allowOverestimation);
byte[] Payload.ToBytes();
string Payload.ToString();
void Payload.ToBuilder(StringBuilder);
void Payload.ToBuilder(SeStringBuilder);

TextPayload : Payload

Payload.Count => 0;

string TextPayload.Text { get; set; }

NewlinePayload : Payload

HyphenPayload : Payload

SoftHyphenPayload : Payload

NonBreakingSpacePayload : Payload

Payload.Count => 0;

ItalicPayload : Payload

Payload.Count => 1;

Expression Enabled { get => this[0]; set => this[0] = value; }
void SetEnabled(bool value) => this.Enabled = new IntegerExpression(value ? 1 : 0);
bool EvaluateEnabled(SeStringEvaluationContext? context);
bool TryEvaluateEnabled(SeStringEvaluationContext? context, out bool value);

IconPayload : Payload

Icon2Payload : Payload

Payload.Count => 1;

Expression Icon { get => this[0]; set => this[0] = value; }
void SetIcon(BitmapFontIcon value) => this.Icon = new IntegerExpression((int)value);
BitmapFontIcon EvaluateIcon(SeStringEvaluationContext? context);
bool TryEvaluateIcon(SeStringEvaluationContext? context, out BitmapFontIcon value);

ColorTypePayload : Payload

EdgeColorTypePayload : Payload

Payload.Count => 1;

Expression ColorType { get => this[0]; set => this[0] = value; }
void SetColorType(uint value) => this.Icon = new IntegerExpression(value);
uint EvaluateColorType(SeStringEvaluationContext? context);
bool TryEvaluateColorType(SeStringEvaluationContext? context, out uint value);

ColorPayload : Payload

EdgeColorPayload : Payload

ShadowColorPayload : Payload

Payload.Count => 1;

Expression Color { get => this[0]; set => this[0] = value; }
void SetColor(uint rgba32) => this.Icon = new IntegerExpression(rgba32);
void SetRevert() => this.Icon = new NullaryExpression(StackColor);
uint? EvaluateColor(SeStringEvaluationContext? context);
bool TryEvaluateColor(SeStringEvaluationContext? context, out uint value, out bool revert);

abstract LinkPayload : Payload

PlayerNameLinkPayload : LinkPayload

TerminatorLinkPayload : LinkPayload

yeag

UnknownPayload : Payload

Used for payloads without specialized Dalamud classes.

Expression

ExpressionType Expression.Type { get; }
bool Expression.RequiresEvaluation { get; }

static Expression Expression.From(byte*);
static Expression Expression.From(ReadOnlySpan<byte>);
static Expression Expression.From(ReadOnlyMemory<byte>);
static Expression Expression.FromLumina(Lumina.Text.[ReadOnly]SeExpression[Span]);

bool Expression.EvaluateToBool(SeStringEvaluationContext);
int Expression.EvaluateToInt(SeStringEvaluationContext);
uint Expression.EvaluateToUInt(SeStringEvaluationContext);
byte[] Expression.EvaluateToBytes(SeStringEvaluationContext);
string Expression.EvaluateToString(SeStringEvaluationContext);
void Expression.EvaluateToBuilder(StringBuilder, SeStringEvaluationContext);
void Expression.EvaluateToBuilder(SeStringBuilder, SeStringEvaluationContext);

int Expression.CalculateByteCount(bool allowOverestimation);
byte[] Expression.ToBytes();
string Expression.ToString();
void Expression.ToBuilder(StringBuilder);
void Expression.ToBuilder(SeStringBuilder);

IntegerExpression : Expression

Expression.Type => default;
Expression.RequiresEvaluation => false;

bool IntegerExpression.BoolValue { get; set; }
int IntegerExpression.IntValue { get; set; }
uint IntegerExpression.UIntValue { get; set; }

StringExpression : Expression

Expression.Type => 0xFF;
Expression.RequiresEvaluation => true;

SeString? Expression.StringValue { get; set; } // defaults to new SeString()

NullaryExpression : Expression

This class should be private-only-constructible, and use singletons per expression type.

Expression.Type => (nullary expression type);
Expression.RequiresEvaluation => true;

UnaryExpression : Expression

Expression.Type => (unary expression type);
Expression.RequiresEvaluation => true;

Expression UnaryExpression.Operand { get; set; } // defaults to new IntegerExpression()

BinaryExpression : Expression

Expression.Type => (binary expression type);
Expression.RequiresEvaluation => true;

Expression BinaryExpression.Operand1 { get; set; } // defaults to new IntegerExpression()
Expression BinaryExpression.Operand2 { get; set; } // defaults to new IntegerExpression()

For event delegates:

ref struct LazySeString {
    public readonly ReadOnlySpan<byte> Data;
    
    private ref SeString? instance;

    public LazySeString(ref SeString? buf) => this.instance = ref buf;
    
    public SeString SeString { get => this.instance ??= SeString.From(this.Data); }
}

So that SeStrings do not get parsed unnecessarily when no callee needs it.

Reminder to use MacroCode and LinkMacroPayloadType names for payload names. 🙂