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
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
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 :
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 :
Base* o = array[0];
o.GetSetting(); //This causes AbortGame because it calls Base::GetSetting instead of A::GetSetting
And if I do this :
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 :
A* AsA(this Base*)
{
return this; //AGS won't know how to cast from Base to A.
}
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.
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.