Provided by: libwx-perl_0.9922-2_amd64 bug

NAME

       NewClass - adding a new class to wxPerl

CHECKLIST

       •   Are there constants or events that need to be wrapped?

           see "CONSTANTS" and "EVENTS".

       •   Is the class is derived from wxObject, from wxEvtHandler or from another class?

           see "CHOOSING A TYPEMAP".

       •   Are class instances destroyed by wxWidgets or should they be garbage collected like
           normal Perl objects?

           see "DESTRUCTORS AND THREADS".

       •   Does the class have overloaded methods?

           see "OVERLOADING".

       •   Does the class have virtual methods that should be overridable from Perl?

           see "VIRTUAL METHODS".

SKELETON

       Add a new file XS/NewClass.xsp and update the MANIFEST.  Choose a relevant .xs file in the
       top level directory (eg. Controls.xs) and add this line:

           INCLUDE_COMMAND: $^X -MExtUtils::XSpp::Cmd -e xspp -- -t typemap.xsp XS/NewClass.xsp

       A skeleton for NewClass.xsp:

           %module{Wx};

           #include <wx/newclass.h> // use the relevant wxWidgets header(s)

           %name{Wx::NewClass} class wxNewClass : public wxSomeBaseClass
           {
               # constructors see the CONSTRUCTORS section
               wxNewClass( wxWindow* some_window, const wxString& str );

               # destructors
               ~wxNewClass();

               # methods
               wxString GetString() const;
               void SetString( const wxString& str );
           };

       Add the typemap definition to typemap.tmpl.  See "CHOOSING A TYPEMAP".

       If adding a class related to one of the wxPerl submodules ("Wx::RichText", "Wx::Html",
       ...) add the .xsp file to the relevant subdirectory and modify the .xs and typemap files
       in that subdirectory.

CHOOSING A TYPEMAP

       There are five typemaps that should work for most wxWidgets objects:

       •   "O_NON_WXOBJECT"

           for all classes that do not derive from "wxObject" AND do not need to be garbage
           collected.

       •   "O_NON_WXOBJECT_THR"

           for all classes that do not derive from "wxObject" AND need to be garbage collected
           (see "DESTRUCTORS AND THREADS").

       •   "O_WXOBJECT"

           for all classes that derive from "wxObject" AND do not need to be garbage collected.

       •   "O_WXOBJECT_THR"

           for all classes derived from "wxObject" AND need to be garbage collected (see
           "DESTRUCTORS AND THREADS").

       •   "O_WXEVTHANDLER"

           for all classes that derive from "wxEvtHandler".  See also "CONSTRUCTORS".

CONSTRUCTORS

       For "O_WXEVTHANDLER" typemaps, there is some additional code that needs to be added to the
       constructor:

           wxNewClass( wxWindow* some_window, const wxString& str )
               %code{% RETVAL = new wxNewClass( some_window, str );
                       wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
                       %};

DESTRUCTORS AND THREADS

       For many classes not derived from "wxEvtHandler" you need to add a destructor to free the
       C++ object when the Perl object is garbage collected.  At the XS++ level this means adding

           ~wxNewClass();

       to the class definition, but there is a catch: the Perl threading model.

       Without going into details, this is needed for Perl threads compatibility:

       •   Use the correct typemap

           choose either "O_NON_WXOBJECT_THR" or "O_WXOBJECT_THR".

       •   Implement a "CLONE" method

           add this code inside the class declaration:

               %{
               static void
               wxNewClass::CLONE()
                 CODE:
                   wxPli_thread_sv_clone( aTHX_ CLASS, (wxPliCloneSV)wxPli_detach_object );
               %}

       •   Fix the destructor.

           modify the destructor like this:

               ~wxNewClass()
                   %code%{  wxPli_thread_sv_unregister( aTHX_ "Wx::NewClass", THIS, ST(0) );
                            delete THIS;
                            %};

VIRTUAL METHODS

       The wrapping of virtual functions whose arguments are simple C++ types (integrals, bool,
       floating point) and common wxWidgets types (wxString) should be automatic: at the top of
       the file, load the plugin that handles virtual methods

           %loadplugin{build::Wx::XSP::Virtual};

       and decorate virtual/pure virtual methods using the %Virtual directive

           // pure virtual
           virtual wxString GetTitle() const = 0 %Virtual{pure};

           // virtual, not pure
           virtual int GetBestFittingWidth(unsigned int idx) const %Virtual;

       If the class contains pure virtual methods, it will be marked as abstract, and it will
       have no constructors.

       For abstract classes, XS++ will create an additional Perl-level class, called
       "Wx::Pl<classname>"; in order to override the virtual methods, you must derive from this
       class, and not from "Wx::<classname>".

       TODO allow changing the default behaviour for abstract/concrete classes

       TODO allow overriding the class name

       TODO allow specifying custom code

       TODO handle multiple return values

       TODO customized type mapping