Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Monsieur OUXX on Mon 06/09/2021 16:47:28

Title: Polymorphism
Post by: Monsieur OUXX on Mon 06/09/2021 16:47:28
I'm experimenting with the old discovery of monkey0506 that polymorphism is somewhat possible. He explained it here : https://www.adventuregamestudio.co.uk/wiki/Extender_Methods_mean_Polymorphism!

What I've done :

HEADER
Code (ags) Select

managed struct Base {
};
import int GetSetting(this Base*);


managed struct A extends Base {
};
import int GetSetting(this A*);


managed struct B extends Base {
};
import int GetSetting(this B*);



BODY
Code (ags) Select


int GetSetting(this Base*)
{
   AbortGame("You need to overwrite this function");
}

int GetSetting(this A*)
{
   return 666;
}

int GetSetting(this B*)
{
   return 777;
}


Then I do this :
Code (ags) Select

Base* array[10];
array[0] = new A;
array[1] = new B;

So far so good. I've managed to store instances of both A and B into the same array of Base.

My issue is that I don't know how to cast back.

If I do this :
Code (ags) Select

Base* o = array[0];
o.GetSetting(); //This causes AbortGame because it calls Base::GetSetting instead of A::GetSetting



And if I do this :
Code (ags) Select

A* o = array[0]; //The compiler forbids this. It doesn't know how to cast back from Base* to A*


Do you have an idea to make polymorphism work? Something like GUIControl::AsLabel or GUIControl::AsButton.
If I try to write this I'll encounter the same issue as before :
Code (ags) Select

A* AsA(this Base*)
{
    return this; //AGS won't know how to cast from Base to A.
}
Title: Re: Polymorphism
Post by: Crimson Wizard on Mon 06/09/2021 22:00:50
Don't have time for a good reply right now, but some time ago I commented on this very article (https://github.com/adventuregamestudio/ags-manual/issues/85#issuecomment-815714477) when it was suggested to be added to the new manual (I thought it's not structured well enough and may be confusing to users).

Something I'd like to copy here is this paragraph:

If we look into theory, there's static or compile-time polymorphism and dynamic or run-time polymorphism. Now, AGS script formally does not support either by itself. This text explains how to achieve kind of static polymorphism (I think?) for a very specific case using extenders. Dynamic polymorphism and things like calling child-type implementation from a reference to parent type is not possible in AGS without scripting that yourself, and it's more complicated than, say, in C, where you do not have "classes" but may have pointers to functions allowing you to create virtual tables by hand...


I may expand on this if find time later.


PS. Oh, and one of the potential consequences of adding RTTI feature (https://github.com/adventuregamestudio/ags/issues/1259) would be dynamic pointer type casting from parent to child.
Title: Re: Polymorphism
Post by: Monsieur OUXX on Tue 07/09/2021 07:58:51
Ok then, thank you. I understand the ins and outs of AGS inner workings, but I'm really interested in a practical solution.

What I understand by "casting to child type is not possible unless you do it yourself" is "you must do it through something similar to monkey's example: create a new instance of the child type and manually 'recreate' it by starting off the parent's data and passing child-specific data". I understand.