ItsDeltin / Overwatch-Script-To-Workshop

Converts scripts to Overwatch workshops.
208 stars 26 forks source link

Support 'this' parameters #340

Open ItsDeltin opened 3 years ago

ItsDeltin commented 3 years ago

When the first parameter of a static method is tagged with the this keyword, it will be added to the type of the parameter. For example:

Vector Transpose(this Vector a, Vector b)
{
    // ...
}

Can be accessed by doing:

Vector myVector = eventPlayer.FacingDirection();
Vector transposed = myVector.Transpose(attacker.FacingDirection());

The this attribute could be paired with in and ref. in:

void ResetPlayerData(in this Player player)
{
    // ...
}

ref:

struct Dictionary<K, V>
{
    public K[] Keys;
    public V[] Values;

    public V Get(K key)
    {
        return Values[Keys.IndexOf(key)];
    }

    // Sets a value in the dictionary.
    public static void Set(ref this Dictionary<K, V> dictionary, in K key, in V value)
    {
        dictionary[dictionary.Keys.IndexOf(key)] = value;
    }

    // Adds a value to the dictionary.
    public static void Add(ref this Dictionary<K, V> dictionary, in K key, in V value)
    {
        dictionary.Keys += key;
        dictionary.Values += value;
    }

    // Sets a value in the dictionary. Will add the key if it doesn't exist.
    public static void SetOrAdd(ref this Dictionary<K, V> dictionary, in K key, in V value)
    {
        Number index = dictionary.Keys.IndexOf(key);
        if (index == -1) // Key not found; add it.
            dictionary.Add(key, value);
        else
            dictionary.Keys[index] = value;
    }
}

A big reason why 'ref this' is an important feature: the struct variables 'Keys' and 'Values' cannot be set from a typical method. This is because if you make a macro such as Dictionary<String, String> myDictionary: { Keys: ["primary", "secondary"], Values: ["First", "Second"] }, doing myDictionary.Set(key, value) won't work since the dictionary does not exist as a workshop variable. Classes don't have this issue due to it's referencing behavior. A static 'ref this' method would solve this issue while still maintaining a clean syntax for callers.