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