Now "TButton" is descendant of "TView" so it could use both TButton and TView methods because of @ISA - is the same possible in "magic" approach?
Multiple inheritance is an interesting situation! I think it should work... Your magic would be for type 'TObject*' (or a record with a TObject* field, since extra fields are almost always needed) and then you could use dynamic_cast to find out whether the method was being called on the correct type.
TVision.xs
struct tvision_info {
TObject *tobj;
};
struct tvision_info*
tvision_info_from_magic(SV *objref, int flags) {
...
}
typemap
TYPEMAP
TObject* O_TObject
TView* O_TView
TButton* O_TButton
INPUT
O_TObject
$var= tvision_info_from_magic($arg, OR_DIE)->tobj;
O_TView
$var= dynamic_cast<TView*>(tvision_info_from_magic($arg, OR_DIE)->to
+bj);
if (!$var) croak("Not an instance of TView");
O_TButton
$var= dynamic_cast<TButton*>(tvision_info_from_magic($arg, OR_DIE)->
+tobj);
if (!$var) croak("Not an instance of TButton");
later in TVision.xs
bool
focus(view)
TView* view
CODE:
RETVAL= view->focus();
OUTPUT:
RETVAL
You might even be able to use a C++ template function to fetch the magic, but I've never tried that. (my C++ is rusty, don't expect this to work as-is)
template <T> void tvision_obj_from_magic(T *dest, SV *objref, int flag
+s) {
struct tvision_info* tinfo= tvision_info_from_magic(objref, flags);
T typed= tinfo->tobj? dynamic_cast<T>(tinfo->tobj) : NULL;
if ((flags & OR_DIE) && !typed) croak("Wrong type of object");
*dest= typed;
}
O_TButton
tvision_obj_from_magic(&$var, $arg, OR_DIE);
Update
There's no need for a C++ template here because Perl XS provides you a variable '$type'.
TYPEMAP
TObject* O_TObject
TView* O_TObject
TButton* O_TObject
INPUT
O_TObject
$var= dynamic_cast<$type>(tvision_info_from_magic($arg, OR_DIE)->tob
+j);
if (!$var) croak("Object is not a $type");
|