in reply to Re^5: Curses-based applications?
in thread Curses-based applications?

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");

Replies are listed 'Best First'.
Re^7: Curses-based applications?
by vkon (Curate) on Jan 03, 2025 at 18:32 UTC
    thanks for the code samples, I'll reuse those.

    Now after I've looked again into the "magic" part of your blog post, I've realised that this mechanic is implemented in addition to classical perl OO (or Moo or whatever else OO), and not a replacement to it, as I erroneously initially thought.

    This will provide more safety when interchanging pointers.

    Good idea. 99.9% that I will implement it.

      Yeah! Maybe I should have started with the description that what it's doing is just stuffing an extra C-struct into the back-end of a Perl object, and you can still do whatever you like with the Perl-facing side.
Re^7: Curses-based applications?
by vkon (Curate) on Jan 08, 2025 at 19:06 UTC
    currently simply casting to needed type just works, without any templates.
    I managed to go forward with typemaps, which indeed simplified things a lot

    Now some skeleton works, I'll implement more widgets and functions, and right after that I'll manage magic stuff.

    Thanks for the help!