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

refactor!: Kill TextRenderer, Long Live TextRenderer #2683

Merged
merged 4 commits into from Aug 27, 2023
Merged

Conversation

luanpotter
Copy link
Member

@luanpotter luanpotter commented Aug 26, 2023

Description

This will:

  • kill the TextRenderer inheritance chain
  • incorporate the functionality of the base TextRenderer in the base TextFormatter
  • rename TextFormatter to TextRenderer and appropriate references

That is because both essentially do the same job; encompass the style (or "how") information about how to render text, but using two slightly different interfaces. While that could allow for more flexibility, it is a faux choice that needlessly complicates the pipeline. By having a single interface to comply with, we still allow for custom renders while at the same time making all the code downstream simpler to use and understand.

image

In fact the main goal is to vastly simplify the rendering pipeline, while at the same time providing the minimum amount of breaking changes. In fact this should just work "as is" for the majority of use cases as long as you are importing the package:flame/text.dart module instead of individual source classes.

That is because people should probably be using the concrete classes TextPaint and SpriteFontRenderer, if at all (or the provided components under FCS). These are kept with the same name and have the same methods, even though the underlying inheritance chain has completely changed.

If you have custom renderers or formatters at all, your life has actually become much simpler, and migrating should be trivial and allow you to delete some connectors/helper code.

A full description of what the text rendering pipeline looks like after this PR can be seen on the updated docs (doc/flame/rendering/text_rendering.md).

Prior art

The first PR has a better breakdown of the ideals explained here, alongside an exploration of the current state of affairs before this series of smaller PRs:

Diagram Diff

Before:

classDiagram
    %% renderers
    class TextRenderer {
        Vector2 measureText(String text)
        void render(Canvas canvas, String text, ...)
    }
    class FormatterTextRenderer {
        TextFormatter formatter
        TextElement format(String text)
    }
    note for FormatterTextRenderer "This is just connecting the Formatter to comply with the TextRenderer interface.\nDoes not add anything new."
    class TextPaint
    class SpriteFontRenderer

    %% formatters
    class TextFormatter
    class SpriteFontTextFormatter
    class TextPainterTextFormatter
    class DebugTextFormatter

    %% elements
    class TextElement {
        LineMetrics metrics
        render(Canvas canvas)
    }
    class TextPainterTextElement

    TextRenderer --> FormatterTextRenderer
    FormatterTextRenderer --> TextPaint
    FormatterTextRenderer --> SpriteFontRenderer

    TextRenderer *-- TextFormatter
    TextPaint *-- TextPainterTextFormatter
    SpriteFontRenderer *-- SpriteFontTextFormatter

    note for TextFormatter "This includes the style (how to render), not the text."
    TextFormatter : TextElement format(String text)
    TextFormatter *-- TextElement
    TextFormatter --> SpriteFontTextFormatter
    TextFormatter --> TextPainterTextFormatter
    TextFormatter --> DebugTextFormatter

    TextFormatter *-- TextElement
    TextPainterTextFormatter *-- TextPainterTextElement
    SpriteFontTextFormatter *-- SpriteFontTextElement

    note for TextElement "This includes the text and the style, ready to render."
    TextElement --> TextPainterTextElement
    TextElement --> SpriteFontTextElement
    TextElement --> Others

After:

classDiagram
    %% renderers
    note for TextRenderer "This just the style (how).\nIt knows how to take a text string and create a TextElement.\n`render` is just a helper to `format(text).render(...)`. Same for `getLineMetrics`."
    class TextRenderer {
        TextElement format(String text)
        LineMetrics getLineMetrics(String text)
        void render(Canvas canvas, String text, ...)
    }
    class TextPaint
    class SpriteFontRenderer
    class DebugTextRenderer
    
    %% elements
    class TextElement {
        LineMetrics metrics
        render(Canvas canvas, ...)
    }
    class TextPainterTextElement
        
    TextRenderer --> TextPaint
    TextRenderer --> SpriteFontRenderer
    TextRenderer --> DebugTextRenderer

    TextRenderer *-- TextElement
    TextPaint *-- TextPainterTextElement
    SpriteFontRenderer *-- SpriteFontTextElement

    note for TextElement "This is the text (what) and the style (how);\nlaid out and ready to render."
    TextElement --> TextPainterTextElement
    TextElement --> SpriteFontTextElement
    TextElement --> Others

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Migration instructions

This is definitely a breaking change, but probably should not affect most users. These are the steps to migrate:

  • make sure you are importing the text module and not any implementation details (package:flame/text.dart)
  • if you are using TextPaint, SpriteFontRenderer, TextComponent or TextBoxComponent, no change should be necessary
  • if you are using DebugTextFormatter, it is now called DebugTextRenderer
  • if you have a custom formatter, just change it to inherit TextRenderer instead (and maybe change its name from Formatter to Renderer). they will still be doing the same job

@luanpotter luanpotter marked this pull request as ready for review August 26, 2023 21:19
@luanpotter luanpotter changed the title refactor!: Kill TextRenderer, Long Live TextRenderer [DRAFT] refactor!: Kill TextRenderer, Long Live TextRenderer Aug 26, 2023
Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

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

Awesome! Great improvement of the docs too!

@spydon spydon merged commit a1cb9a0 into main Aug 27, 2023
7 checks passed
@spydon spydon deleted the luan.text-4 branch August 27, 2023 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants