Skip to content
This repository has been archived by the owner on May 28, 2024. It is now read-only.

Add bundle text format specification #9

Open
llucax opened this issue Feb 22, 2021 · 0 comments
Open

Add bundle text format specification #9

llucax opened this issue Feb 22, 2021 · 0 comments
Labels
epic This is a very large issue that is composed from smaller more actionable issues
Milestone

Comments

@llucax
Copy link
Member

llucax commented Feb 22, 2021

It should be possible to write bundle specification files in plain text, instead of dart code. A parser for some text format should be added. The easiest format would be something like YAML (which also support reusing snippets/templates).

Basic functionality

This could be an example bundle:

Bundle:                                                                                                                                                       
  rootMenu:
    GridMenu:
      rows: 1
      columns: 1
      buttons:
        - StyledButton:
          backgroundColor: red
          action:
            PlayContentAction:
              content:
                Image:
                  resource: button1.png
                  maxDuration: 5s

This would be a pretty 1-to-1 translation from dart types to YAML.

  • The file should be a dictionary with only one key. The key name is the bundle type to create.
  • Bundle is a dictionary with the attributes of the Bundle dart class.
  • There are primitive types: int, string, color, duration, etc.
  • Any non-primitive type that is represented by a class also use the class dart name
  • So rootMenu espects a Menu type, so it should be a dictionary of only one element where the key is the type name (as with Bundle, so GridMenu is the menu type, and the dictionary attributes are the class attributes.
  • When a list is expected, like with buttons, then each element is a dictionary with one key only and the key is the type of that particular element.
  • And so on...

So the parser should just read the YAML and delegate to type factories that will decide which type to created based on some string, and this should be propagated all the way down.

Advanced functionality

This approach allows us to then add aliases and default types, to make the syntax much more terse for the most common cases.

The most basic aliases would be just removing the last word for StyledButton and PlayContentAction for example, but it can be taken even further and make Play an alias for PlayContentAction. These aliases are context-sensitive, as we'll only search for types deriving from Action when parsing the action attribute contents, so it would be easy to avoid name clashes.

If a type is defined by a string or list instead of a dictionary, then it can be interpreted as a default attribute or several attributes parsed using a custom parser. For example:

Image:
  resource: image1.png`

Could be reduced to:

Image: image1.png`

Here the Image contents are expected to be a dictionary normally, but if a string is found instead, the resource attribute is set to that string.

If when a type is expected, a dictionary or a list if found instead, then a default type could be used. If a string is found but it doesn't match any type, then it could also fall back. For example this:

Bundle:
  rootMenu:
    GridMenu:
      rows: 1
      columns: 1
      buttons: ...

Could be written as:

Bundle:
  rootMenu:
    rows: 1
    columns: 1
    buttons: ...

Where the type is assumed to be GridMenu and then the attributes are interpreted as usual for GridMenu. But GridMenu could also implement a custom parser to set rows and columns in a more terse way, like size: 1x1.

A more complete demonstration:

# The default bundle type is Bundle
rootMenu:
  # The default Menu type is GridMenu
  size: 2x2 # alias for rows: 2, columns: 2
  buttons:
    # Default button type is StyledButton
    - backgroundColor: red
      action:
        PlayContent: # alias of PlayContent
          content:
            Image: button1.png # string is interpreted as the `resource`
    - backgroundColor: green
      action:
        play: # alias for PlayContentAction
          # A playable is expected, but `button2.png` doesn't match any type,
          # so the default `SingleMedium` type is used. SingleMedium delegates
          # the creation to sub-types Audio, Image and Video, which parse the
          # string and accepts it as valid if a matching extension is found.
          # Otherwise it fails and the next type is tried.
          # In this case Audio doesn't match png, but Image does, so it is an
          # Image, then the Image parser sees this is not a dictionary but
          # a string and, as the button above, it interprets the string as the
          # `resource`.
          content: button2.png
    - backgroundColor: yellow
      action:
        # PlayContentAction as string is interpreted as the `content`
        Play: button2.png
    - backgroundColor: blue
      # Default action type is PlayContentAction
      action: button2.png
@llucax llucax added the epic This is a very large issue that is composed from smaller more actionable issues label Feb 22, 2021
@llucax llucax added this to the v0.4.0 milestone Feb 22, 2021
@llucax llucax modified the milestones: v0.4.0, v0.5.0 Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
epic This is a very large issue that is composed from smaller more actionable issues
Projects
None yet
Development

No branches or pull requests

1 participant