Zetrith / Prepatcher

Structured assembly rewriting library/mod for RW
MIT License
74 stars 7 forks source link

Adding method overrides #8

Open Zetrith opened 1 year ago

Zetrith commented 1 year ago

Example

class A {
    public int Method() {
        return 0;
    }

    public virtual int VirtualMethod() {
        return 0;
    }
}

class B : A {
}

// Static override template methods (first parameter specifies the target)
[PrepatcherOverride]
public static int Method(B b){
    return 1;
}

[PrepatcherOverride]
public static int VirtualMethod(B b){
    return 1;
}

A a = new B();
a.Method(); // returns 1
a.VirtualMethod(); // returns 1

class C : A {
    // Instance override template method
    [PrepatcherOverride]
    public new int Method() {
        return 1;
    }
}

A a = new C();
a.Method(); // returns 1

Implementation

A static override template method is copied into the the target class becoming a new instance method within it.

For an instance override template method, the process is the same but (*) results in an error because it doesn't make sense to use Prepatcher there - you can just override as usual using the C# keyword (unless the method was turned virtual by Prepatcher).

Compatibility

Poses some incompatibility risk with transpilers because call instructions to methods made virtual need to be turned into callvirt instructions.

Zetrith commented 1 year ago

A point I missed: there's potential for conflict in mods overwriting each other's overrides when multiple are requested on the same method.

Amendments:

SokyranTheDragon commented 1 year ago

I feel the example should (for extra clarity) show the methods for the class A being called along the classes B and C. For a moment, I got slightly confused by what PrepatcherOverride does - thinking it replaces the method in class A instead of adding the overrides in B and C.