From 556998239ed5a099087765c276b10d429750196f Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Mon, 3 Feb 2020 04:37:14 +0100 Subject: [PATCH] Revert "formatting code redesign, part 1: Regex!" This reverts commit b480026b --- MLEM.Ui/Elements/Paragraph.cs | 12 +++--- MLEM/Animations/SpriteAnimation.cs | 6 ++- MLEM/Formatting/AnimationCode.cs | 40 ------------------- MLEM/Formatting/FormattingCode.cs | 29 ++++++-------- MLEM/Formatting/FormattingCodeCollection.cs | 18 --------- MLEM/Formatting/TextAnimation.cs | 26 +++++++++++++ MLEM/Formatting/TextFormatting.cs | 43 ++++++++++----------- 7 files changed, 69 insertions(+), 105 deletions(-) delete mode 100644 MLEM/Formatting/AnimationCode.cs delete mode 100644 MLEM/Formatting/FormattingCodeCollection.cs create mode 100644 MLEM/Formatting/TextAnimation.cs diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs index 7852acc..47236f0 100644 --- a/MLEM.Ui/Elements/Paragraph.cs +++ b/MLEM.Ui/Elements/Paragraph.cs @@ -16,7 +16,7 @@ namespace MLEM.Ui.Elements { private string text; private string splitText; - public FormattingCodeCollection FormattingCodes { get; private set; } + private Dictionary codeLocations; public StyleProp RegularFont; public StyleProp BoldFont; public StyleProp ItalicFont; @@ -36,6 +36,7 @@ namespace MLEM.Ui.Elements { } public bool AutoAdjustWidth; public TextCallback GetTextCallback; + public TimeSpan TimeIntoAnimation; public Paragraph(Anchor anchor, float width, TextCallback textCallback, bool centerText = false) : this(anchor, width, "", centerText) { @@ -59,7 +60,7 @@ namespace MLEM.Ui.Elements { var sc = this.TextScale * this.Scale; this.splitText = this.RegularFont.Value.SplitString(this.text.RemoveFormatting(this.RegularFont.Value), size.X - this.ScaledPadding.Width, sc); - this.FormattingCodes = this.text.GetFormattingCodes(this.RegularFont.Value); + this.codeLocations = this.text.GetFormattingCodes(this.RegularFont.Value); var textDims = this.RegularFont.Value.MeasureString(this.splitText) * sc; return new Vector2(this.AutoAdjustWidth ? textDims.X + this.ScaledPadding.Width : size.X, textDims.Y + this.ScaledPadding.Height); @@ -75,8 +76,7 @@ namespace MLEM.Ui.Elements { base.Update(time); if (this.GetTextCallback != null) this.Text = this.GetTextCallback(this); - if (this.FormattingCodes != null) - this.FormattingCodes.Update(time); + this.TimeIntoAnimation += time.ElapsedGameTime; } public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { @@ -85,11 +85,11 @@ namespace MLEM.Ui.Elements { var color = this.TextColor.OrDefault(Color.White) * alpha; // if we don't have any formatting codes, then we don't need to do complex drawing - if (this.FormattingCodes.Count <= 0) { + if (this.codeLocations.Count <= 0) { this.RegularFont.Value.DrawString(batch, this.splitText, pos, color, 0, Vector2.Zero, sc, SpriteEffects.None, 0); } else { // if we have formatting codes, we should do it - this.RegularFont.Value.DrawFormattedString(batch, pos, this.splitText, this.FormattingCodes, color, sc, this.BoldFont.Value, this.ItalicFont.Value, 0, this.FormatSettings); + this.RegularFont.Value.DrawFormattedString(batch, pos, this.splitText, this.codeLocations, color, sc, this.BoldFont.Value, this.ItalicFont.Value, 0, this.TimeIntoAnimation, this.FormatSettings); } base.Draw(time, batch, alpha, blendState, samplerState, matrix); } diff --git a/MLEM/Animations/SpriteAnimation.cs b/MLEM/Animations/SpriteAnimation.cs index b53d21b..615fadc 100644 --- a/MLEM/Animations/SpriteAnimation.cs +++ b/MLEM/Animations/SpriteAnimation.cs @@ -49,9 +49,13 @@ namespace MLEM.Animations { } public void Update(GameTime time) { + this.SetTime(this.TimeIntoAnimation + time.ElapsedGameTime.TotalSeconds * this.SpeedMultiplier); + } + + internal void SetTime(double totalTime) { if (this.IsFinished || this.IsPaused) return; - this.TimeIntoAnimation += time.ElapsedGameTime.TotalSeconds * this.SpeedMultiplier; + this.TimeIntoAnimation = totalTime; if (this.TimeIntoAnimation >= this.TotalTime) { if (!this.IsLooping) { this.IsFinished = true; diff --git a/MLEM/Formatting/AnimationCode.cs b/MLEM/Formatting/AnimationCode.cs deleted file mode 100644 index aaaec6d..0000000 --- a/MLEM/Formatting/AnimationCode.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using MLEM.Font; - -namespace MLEM.Formatting { - public class AnimationCode : FormattingCode { - - public static readonly DrawCharacter Default = (code, settings, font, batch, totalText, index, effectStartIndex, charSt, position, color, scale, layerDepth) => { - font.DrawString(batch, charSt, position, color, 0, Vector2.Zero, scale, SpriteEffects.None, layerDepth); - }; - public static readonly DrawCharacter Wobbly = (code, settings, font, batch, totalText, index, effectStartIndex, charSt, position, color, scale, layerDepth) => { - var offset = new Vector2(0, (float) Math.Sin(index + code.Time.TotalSeconds * settings.WobbleModifier) * font.LineHeight * settings.WobbleHeightModifier * scale); - font.DrawString(batch, charSt, position + offset, color, 0, Vector2.Zero, scale, SpriteEffects.None, layerDepth); - }; - public static readonly DrawCharacter Typing = (code, settings, font, batch, totalText, index, effectStartIndex, charSt, position, color, scale, layerDepth) => { - if (code.Time.TotalSeconds * settings.TypingSpeed > index - effectStartIndex + 1) - font.DrawString(batch, charSt, position, color, 0, Vector2.Zero, scale, SpriteEffects.None, layerDepth); - }; - public static readonly AnimationCode DefaultCode = new AnimationCode(Default); - - public readonly DrawCharacter Draw; - public TimeSpan Time; - - public AnimationCode(DrawCharacter draw) : base(Type.Animation) { - this.Draw = draw; - } - - public override void Update(GameTime time) { - this.Time += time.ElapsedGameTime; - } - - public override void Reset() { - this.Time = TimeSpan.Zero; - } - - public delegate void DrawCharacter(AnimationCode code, FormatSettings settings, IGenericFont font, SpriteBatch batch, string totalText, int index, int effectStartIndex, string charSt, Vector2 position, Color color, float scale, float layerDepth); - - } -} \ No newline at end of file diff --git a/MLEM/Formatting/FormattingCode.cs b/MLEM/Formatting/FormattingCode.cs index 832e0d8..46a4d05 100644 --- a/MLEM/Formatting/FormattingCode.cs +++ b/MLEM/Formatting/FormattingCode.cs @@ -10,41 +10,36 @@ namespace MLEM.Formatting { public readonly Color Color; public readonly TextStyle Style; public readonly SpriteAnimation Icon; + public readonly TextAnimation.DrawCharacter Animation; - protected FormattingCode(Type type) { - this.CodeType = type; - } - - public FormattingCode(Color color) : this(Type.Color) { + public FormattingCode(Color color) { this.Color = color; + this.CodeType = Type.Color; } - public FormattingCode(TextStyle style) : this(Type.Style) { + public FormattingCode(TextStyle style) { this.Style = style; + this.CodeType = Type.Style; } public FormattingCode(TextureRegion icon) : this(new SpriteAnimation(0, icon)) { } - public FormattingCode(SpriteAnimation icon) : this(Type.Icon) { + public FormattingCode(SpriteAnimation icon) { this.Icon = icon; + this.CodeType = Type.Icon; + } + + public FormattingCode(TextAnimation.DrawCharacter animation) { + this.Animation = animation; + this.CodeType = Type.Animation; } public virtual string GetReplacementString(IGenericFont font) { return this.CodeType == Type.Icon ? TextFormatting.GetOneEmString(font) : string.Empty; } - public virtual void Update(GameTime time) { - if (this.CodeType == Type.Icon) - this.Icon.Update(time); - } - - public virtual void Reset() { - if (this.CodeType == Type.Icon) - this.Icon.Restart(); - } - public enum Type { Color, diff --git a/MLEM/Formatting/FormattingCodeCollection.cs b/MLEM/Formatting/FormattingCodeCollection.cs deleted file mode 100644 index 7b20e61..0000000 --- a/MLEM/Formatting/FormattingCodeCollection.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using Microsoft.Xna.Framework; - -namespace MLEM.Formatting { - public class FormattingCodeCollection : Dictionary { - - public void Update(GameTime time) { - foreach (var code in this.Values) - code.Update(time); - } - - public void Reset() { - foreach (var code in this.Values) - code.Reset(); - } - - } -} \ No newline at end of file diff --git a/MLEM/Formatting/TextAnimation.cs b/MLEM/Formatting/TextAnimation.cs new file mode 100644 index 0000000..b1a7622 --- /dev/null +++ b/MLEM/Formatting/TextAnimation.cs @@ -0,0 +1,26 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using MLEM.Font; + +namespace MLEM.Formatting { + public static class TextAnimation { + + public static readonly DrawCharacter Default = (settings, font, batch, totalText, index, effectStartIndex, charSt, position, color, scale, layerDepth, timeIntoAnimation) => { + font.DrawString(batch, charSt, position, color, 0, Vector2.Zero, scale, SpriteEffects.None, layerDepth); + }; + + public static readonly DrawCharacter Wobbly = (settings, font, batch, totalText, index, effectStartIndex, charSt, position, color, scale, layerDepth, timeIntoAnimation) => { + var offset = new Vector2(0, (float) Math.Sin(index + timeIntoAnimation.TotalSeconds * settings.WobbleModifier) * font.LineHeight * settings.WobbleHeightModifier * scale); + font.DrawString(batch, charSt, position + offset, color, 0, Vector2.Zero, scale, SpriteEffects.None, layerDepth); + }; + + public static readonly DrawCharacter Typing = (settings, font, batch, totalText, index, effectStartIndex, charSt, position, color, scale, layerDepth, timeIntoAnimation) => { + if (timeIntoAnimation.TotalSeconds * settings.TypingSpeed > index - effectStartIndex + 1) + font.DrawString(batch, charSt, position, color, 0, Vector2.Zero, scale, SpriteEffects.None, layerDepth); + }; + + public delegate void DrawCharacter(FormatSettings settings, IGenericFont font, SpriteBatch batch, string totalText, int index, int effectStartIndex, string charSt, Vector2 position, Color color, float scale, float layerDepth, TimeSpan timeIntoAnimation); + + } +} \ No newline at end of file diff --git a/MLEM/Formatting/TextFormatting.cs b/MLEM/Formatting/TextFormatting.cs index 801ccdd..158ebce 100644 --- a/MLEM/Formatting/TextFormatting.cs +++ b/MLEM/Formatting/TextFormatting.cs @@ -11,7 +11,7 @@ using MLEM.Textures; namespace MLEM.Formatting { public static class TextFormatting { - public static readonly Dictionary> FormattingCodes = new Dictionary>(); + public static readonly Dictionary FormattingCodes = new Dictionary(); private static readonly Dictionary OneEmStrings = new Dictionary(); private static Regex formatRegex; @@ -19,22 +19,22 @@ namespace MLEM.Formatting { SetFormatIndicators('[', ']'); // style codes - FormattingCodes[new Regex("regular")] = m => new FormattingCode(TextStyle.Regular); - FormattingCodes[new Regex("italic")] = m => new FormattingCode(TextStyle.Italic); - FormattingCodes[new Regex("bold")] = m => new FormattingCode(TextStyle.Bold); - FormattingCodes[new Regex("shadow")] = m => new FormattingCode(TextStyle.Shadow); + FormattingCodes["regular"] = new FormattingCode(TextStyle.Regular); + FormattingCodes["italic"] = new FormattingCode(TextStyle.Italic); + FormattingCodes["bold"] = new FormattingCode(TextStyle.Bold); + FormattingCodes["shadow"] = new FormattingCode(TextStyle.Shadow); // color codes var colors = typeof(Color).GetProperties(); foreach (var color in colors) { if (color.GetGetMethod().IsStatic) - FormattingCodes[new Regex(color.Name.ToLowerInvariant())] = m => new FormattingCode((Color) color.GetValue(null)); + FormattingCodes[color.Name.ToLowerInvariant()] = new FormattingCode((Color) color.GetValue(null)); } // animations - FormattingCodes[new Regex("unanimated")] = m => new AnimationCode(AnimationCode.Default); - FormattingCodes[new Regex("wobbly")] = m => new AnimationCode(AnimationCode.Wobbly); - FormattingCodes[new Regex("typing")] = m => new AnimationCode(AnimationCode.Typing); + FormattingCodes["unanimated"] = new FormattingCode(TextAnimation.Default); + FormattingCodes["wobbly"] = new FormattingCode(TextAnimation.Wobbly); + FormattingCodes["typing"] = new FormattingCode(TextAnimation.Typing); } public static void SetFormatIndicators(char opener, char closer) { @@ -62,8 +62,8 @@ namespace MLEM.Formatting { }); } - public static FormattingCodeCollection GetFormattingCodes(this string s, IGenericFont font) { - var codes = new FormattingCodeCollection(); + public static Dictionary GetFormattingCodes(this string s, IGenericFont font) { + var codes = new Dictionary(); var codeLengths = 0; foreach (Match match in formatRegex.Matches(s)) { var code = FromMatch(match); @@ -75,18 +75,18 @@ namespace MLEM.Formatting { return codes; } - public static void DrawFormattedString(this IGenericFont regularFont, SpriteBatch batch, Vector2 pos, string text, FormattingCodeCollection codes, Color color, float scale, IGenericFont boldFont = null, IGenericFont italicFont = null, float depth = 0, FormatSettings formatSettings = null) { + public static void DrawFormattedString(this IGenericFont regularFont, SpriteBatch batch, Vector2 pos, string text, Dictionary codeLocations, Color color, float scale, IGenericFont boldFont = null, IGenericFont italicFont = null, float depth = 0, TimeSpan timeIntoAnimation = default, FormatSettings formatSettings = null) { var settings = formatSettings ?? FormatSettings.Default; var currColor = color; var currFont = regularFont; var currStyle = TextStyle.Regular; - var currAnim = AnimationCode.DefaultCode; + var currAnim = TextAnimation.Default; var animStart = 0; var innerOffset = new Vector2(); for (var i = 0; i < text.Length; i++) { // check if the current character's index has a formatting code - codes.TryGetValue(i, out var code); + codeLocations.TryGetValue(i, out var code); if (code != null) { // if so, apply it switch (code.CodeType) { @@ -108,10 +108,11 @@ namespace MLEM.Formatting { currStyle = code.Style; break; case FormattingCode.Type.Icon: + code.Icon.SetTime(timeIntoAnimation.TotalSeconds * code.Icon.SpeedMultiplier % code.Icon.TotalTime); batch.Draw(code.Icon.CurrentRegion, new RectangleF(pos + innerOffset, new Vector2(regularFont.LineHeight * scale)), color, 0, Vector2.Zero, SpriteEffects.None, depth); break; case FormattingCode.Type.Animation: - currAnim = (AnimationCode) code; + currAnim = code.Animation; animStart = i; break; } @@ -124,8 +125,8 @@ namespace MLEM.Formatting { innerOffset.Y += regularFont.LineHeight * scale; } else { if (currStyle == TextStyle.Shadow) - currAnim.Draw(currAnim, settings, currFont, batch, text, i, animStart, cSt, pos + innerOffset + settings.DropShadowOffset * scale, settings.DropShadowColor, scale, depth); - currAnim.Draw(currAnim, settings, currFont, batch, text, i, animStart, cSt, pos + innerOffset, currColor, scale, depth); + currAnim(settings, currFont, batch, text, i, animStart, cSt, pos + innerOffset + settings.DropShadowOffset * scale, settings.DropShadowColor, scale, depth, timeIntoAnimation); + currAnim(settings, currFont, batch, text, i, animStart, cSt, pos + innerOffset, currColor, scale, depth, timeIntoAnimation); innerOffset.X += regularFont.MeasureString(cSt).X * scale; } } @@ -133,12 +134,8 @@ namespace MLEM.Formatting { private static FormattingCode FromMatch(Capture match) { var rawCode = match.Value.Substring(1, match.Value.Length - 2).ToLowerInvariant(); - foreach (var code in FormattingCodes) { - var m = code.Key.Match(rawCode); - if (m.Success) - return code.Value(m); - } - return null; + FormattingCodes.TryGetValue(rawCode, out var val); + return val; } }