Skip to content

Complex Type Shortcuts

Jimmy Cushnie edited this page Apr 17, 2020 · 10 revisions

Complex Type Shortcuts allow you to write data more concisely in your configuration files. SUCC will never save shortcuts, it will only read them.

Usually, Complex Types are serialized in a file as a parent node with no value, and all their data is contained in child nodes. Shortcuts are written by removing all the children and giving that node a value.

Shortcuts have two use cases:

  • Shortcuts are easier to write that manually defining each property of a complex type
  • Shortcuts can be used to set properties that SUCC can otherwise not access, like readonly fields or get-only properties

Property Shortcuts

If your type has a static, read-only property that returns a value of that type, you can use it as a shortcut when writing configuration files. For example, SUCC will parse the following two lists of Vector3 exactly the same:

Vector List One:
    -
        x: 0
        y: 0
        z: 0
    -
        x: 0
        y: 1
        z: 0
    -
        x: 1
        y: 1
        z: 1

Vector List Two:
    - zero              # see https://docs.unity3d.com/ScriptReference/Vector3-zero.html
    - up                # see https://docs.unity3d.com/ScriptReference/Vector3-up.html
    - one               # see https://docs.unity3d.com/ScriptReference/Vector3-one.html

Constructor Shortcuts

You can use the constructor of a type as a shortcut when writing it. To do this, separate the values you want to pass to the constructor with commas, and encase the value with parenthesis. The following list of Vector3s is parsed exactly the same as the two above:

# see https://docs.unity3d.com/ScriptReference/Vector3-ctor.html
Vector List Three:
    - (0, 0, 0)
    - (0, 1, 0)
    - (1, 1, 1)

Note that the parameters of constructors used in shortcuts must be of base types.

Constructor shortcuts are a little finicky, because a type can have multiple constructors. SUCC uses the following rules to determine which constructor to use with a constructor shortcut:

  • if the type has only one constructor, that constructor is used
  • if the type has more than one constructor, the first constructor with the same number of parameters as those used in the shortcut is used.

Method Shortcuts

If your type has a static method which returns a value of that type, you can use it as a shortcut and pass it parameters in the same way as constructor shortcuts. Consider the following class:

public class Example
{
    public List<int> Numbers = new List<int>();
    public List<string> Words = new List<string>();

    public static Example Sequence(int count)
    {
        var example = new Example();
        for (int i = 0; i < count; i++)
        {
            example.Numbers.Add(i);
            example.Words.Add(i.ToString());
        }
        return example;
    }
}

The following two values will parse the exact same value when interpreted as Example:

Item1:
    Numbers:
        - 0
        - 1
        - 2
        - 3
        - 4
    Words:
        - "0"
        - "1"
        - "2"
        - "3"
        - "4"

Item2: Sequence(5)

Custom Shortcuts

If SUCC detects a shortcut, but the given shortcut does not match any of the other shortcut types, it will attempt to treat it as a custom shortcut. Custom shortcuts can have any rules you want, which you specify in your code.

Give your type a static method called "Shortcut" which

  • Accepts a single string as its parameters
  • Returns the same type it is a part of

This method will be used by SUCC to parse the data.

public class Cat
{
    public string Name;
    public float Fuzziness;

    static Cat Shortcut(string catName)
    {
        switch (catName)
        {
            case "Wiggles":
                return new Cat() { Name = "Wiggles", Fuzziness = 3.5f };
            case "Mittens":
                return new Cat() { Name = "Mittens", Fuzziness = 5f };
            case "Agrat bat Mahlat":
                return new Cat() { Name = "אגרת בת מחלת", Fuzziness = float.NegativeInfinity };
        }

        throw new Exception($"{catName} is not a valid cat name");
    }
}

The following two lists of cats will parse exactly the same:

cat list 1:
    -
        Name        : "Wiggles"
        Fuzziness   : 3.5
    -
        Name        : "Mittens"
        Fuzziness   : 5

cat list 2:
    - Wiggles
    - Mittens