How to make Option classes like GUILayoutOption?

I'm wondering how to make a class similar to GUILayoutOption class where it would take a whole bunch of GUILayout's static fields as parameters.

I couldn't find my answer in Unity Docs and I was wondering if somebody has made such a construct before.

I'm trying to make something like this:

public void SomeMethod( params MyClassOption[] options )

and call it for example like this: SomeMethod(MyClass.AnimationClip(aniClipRef), MyClass.AnimationDuration(duration), MyClass.StopAllOtherAnimations);

Seems like a great and clean way to wrap code with dozens of potentially optional parameters, but I'm not sure how to define it. Can somebody write a minimalistic example or explain how it works?

Upvotes: 1

Views: 911

Answers (1)

Programmer
Programmer

Reputation: 125435

You won't find stuff like these in the documentation or any tutorial. If you are curious on how something is implemented, use decompiler such as .NET Reflector and you will see how each class is implemented.

Below is a minimalist example of how to do this. Do not use this. This is only here to show exactly how this is done by Unity. It uses the param keyword and performs boxing, both which allocates memory.

Example:

MyClass.Button("Submit Button", MyClass.MinWidth(10), MyClass.MaxWidth(20),
             MyClass.MinHeight(10), MyClass.MaxHeight(10));

The MyClassOption class:

public class MyClassOption
{
    public Type type;
    public object value;

    public MyClassOption(Type type, object value)
    {
        this.type = type;
        this.value = value;
    }

    public enum Type
    {
        minWidth,
        maxWidth,
        minHeight,
        maxHeight,
    }
}

The MyClass class:

public class MyClass
{
    public static bool Button(string text, params MyClassOption[] options)
    {
        return showButton(text, options);
    }

    private static bool showButton(string text, MyClassOption[] options)
    {
        //Not IMPLEMENTED
        //DISPLAY BUTTON THEN CHECK IF IT IS CLICKED?
        return false;
    }

    public static MyClassOption MaxHeight(float maxHeight)
    {
        return new MyClassOption(MyClassOption.Type.maxHeight, maxHeight);
    }

    public static MyClassOption MaxWidth(float maxWidth)
    {
        return new MyClassOption(MyClassOption.Type.maxWidth, maxWidth);
    }

    public static MyClassOption MinHeight(float minHeight)
    {
        return new MyClassOption(MyClassOption.Type.minHeight, minHeight);
    }

    public static MyClassOption MinWidth(float minWidth)
    {
        return new MyClassOption(MyClassOption.Type.minWidth, minWidth);
    }
}

Basically, you add your custom options in the enum from the MyClassOption class then you add a function that will be used to access that enum in the MyClass. That function will return new MyClassOption object.

There's too much memory allocation going on each time an option is added to a function or executed to the extent that I think it is not worth it. It is fine in a normal C# application but not in a game app which can cause hiccups due to GC.

EDIT:

Things that can be done to improve this:

1.Change the MyClassOption class to struct.

2.On the MyClassOption class constructor object value parameter, change that to c# generics. T[] value.

Now, the only problem left is the param keyword which is the only thing that allocates memory. It should be fine for some applications but this is mostly useful for Editor plugins.

Upvotes: 1

Related Questions