Hi,

Thought I'd rework and get it right I think.

New patch attached implements option 2 as intended.
Existing m_self used if available;

Also, implemented

wxPli_create_virtual_evthandler

which takes an extra param - bool forcevirtual

wxPli_create_evthandler is now just a wrapper for this and always passes 'false'.

Intended use is for long implemented virtual classes like wxScrolledWindow that don't have class names Wx::Pl....

Also implemented wxPli_get_selfref to avoid duplicating code, but I don't think it saved much

Builds and works OK for me on all my platforms. Creating virtual classes in a loop does not seem to leak memory - but I don't have the tools to prove. Going by my prior failed attempts at fixing this, if I've got the ref counts wrong somewhere I'd get problems in the tests.

Regards

Mark


On 18/03/2011 04:57, Mark Dootson wrote:
Hi,

On 15/03/2011 22:00, Mattia Barbon wrote:

2) change wxPli_create_evthandler to transparently use the existing
instance if present, and call wxPli_make_object otherwise

Attached patch implements this - but in reverse - always creates new
object, then sets m_self to this if virtual class. Seems to work OK.

Index: cpp/helpers.cpp
===================================================================
--- cpp/helpers.cpp     (revision 3036)
+++ cpp/helpers.cpp     (working copy)
@@ -486,28 +486,22 @@
         return var;
     }
 
-    wxClassInfo *ci = object->GetClassInfo();
-    const wxChar* classname = ci->GetClassName();
     wxEvtHandler* evtHandler = wxDynamicCast( object, wxEvtHandler );
 
     if( evtHandler && evtHandler->GetClientObject() )
         return wxPli_evthandler_2_sv( aTHX_ var, evtHandler );
 
-#if wxUSE_UNICODE
-    if( wcsncmp( classname, wxT("wxPl"), 4 ) == 0 ) 
-#else
-    if( strnEQ( classname, "wxPl", 4 ) ) 
-#endif
+       wxPliSelfRef* sr = wxPli_get_selfref( aTHX_ 
const_cast<wxObject*>(object), false );
+
+    if( sr && sr->m_self )
     {
-        wxPliClassInfo* cci = (wxPliClassInfo*)ci;
-        wxPliSelfRef* sr = cci->m_func( const_cast<wxObject*>(object) );
-
-        if( sr && sr->m_self )
-        {
-            SvSetSV_nosteal( var, sr->m_self );
-            return var;
-        }
+        SvSetSV_nosteal( var, sr->m_self );
+        return var;
     }
+    
+    /* duplicated :-( */
+       wxClassInfo *ci = object->GetClassInfo();
+       const wxChar* classname = ci->GetClassName();
 
     char buffer[WXPL_BUF_SIZE];
     const char* CLASS = wxPli_cpp_class_2_perl( classname, buffer );
@@ -521,6 +515,34 @@
     return var;
 }
 
+wxPliSelfRef* wxPli_get_selfref( pTHX_ wxObject* object, bool forcevirtual )
+{
+       wxPliSelfRef* sr = NULL;
+
+       wxClassInfo *ci = object->GetClassInfo();
+
+    if( forcevirtual )
+    {
+           wxPliClassInfo* cci = (wxPliClassInfo*)ci;
+           sr = cci->m_func( object );
+           return sr;
+    }
+
+    const wxChar* classname = ci->GetClassName();
+
+#if wxUSE_UNICODE
+       if( wcsncmp( classname, wxT("wxPl"), 4 ) == 0 )
+#else
+       if( strnEQ( classname, "wxPl", 4 ) )
+#endif
+       {
+           wxPliClassInfo* cci = (wxPliClassInfo*)ci;
+           sr = cci->m_func( object );
+    }
+
+       return sr;
+}
+
 void wxPli_attach_object( pTHX_ SV* object, void* ptr )
 {
     SV* ref = SvRV( object );
@@ -606,11 +628,33 @@
 SV* wxPli_create_evthandler( pTHX_ wxEvtHandler* object,
                              const char* classname )
 {
-    SV* sv = wxPli_make_object( object, classname );
-    wxPliUserDataCD* clientData = new wxPliUserDataCD( sv );
+    return wxPli_create_virtual_evthandler( aTHX_ object, classname, false );
+}
 
-    object->SetClientObject( clientData );
+SV* wxPli_create_virtual_evthandler( pTHX_ wxEvtHandler* object,
+                             const char* classname, bool forcevirtual )
+{
+    SV* sv = NULL;
+       wxPliUserDataCD* clientData = NULL;
 
+       wxPliSelfRef* sr = wxPli_get_selfref( aTHX_ (wxObject*)object, 
forcevirtual );
+
+       if( sr && sr->m_self )
+       {
+               sv = sv_2mortal( newRV_inc( SvRV( sr->m_self ) ) );
+               SvREFCNT_dec( sr->m_self );
+               clientData = new wxPliUserDataCD( sv );
+               sr->SetSelf(clientData->GetData(), true);
+       }
+
+       if( sv == NULL )
+       {
+               sv = wxPli_make_object( object, classname );
+               clientData = new wxPliUserDataCD( sv );
+       }
+
+       object->SetClientObject( clientData );
+       
     return sv;
 }
 
Index: cpp/helpers.h
===================================================================
--- cpp/helpers.h       (revision 3036)
+++ cpp/helpers.h       (working copy)
@@ -23,6 +23,7 @@
 
 class wxPliUserDataCD;
 class wxPliTreeItemData;
+class wxPliSelfRef;
 struct wxPliEventDescription;
 
 #ifndef WXDLLIMPEXP_FWD_CORE
@@ -250,6 +251,8 @@
 SV* FUNCPTR( wxPli_make_object )( void* object, const char* cname );
 SV* FUNCPTR( wxPli_create_evthandler )( pTHX_ wxEvtHandler* object,
                                         const char* classn );
+SV* FUNCPTR( wxPli_create_virtual_evthandler )( pTHX_ wxEvtHandler* object,
+                                        const char* classn, bool forcevirtual 
);                                        
 
 bool FUNCPTR( wxPli_object_is_deleteable )( pTHX_ SV* object );
 void FUNCPTR( wxPli_object_set_deleteable )( pTHX_ SV* object,
@@ -260,6 +263,7 @@
 void* FUNCPTR( wxPli_detach_object )( pTHX_ SV* object );
 
 const char* FUNCPTR( wxPli_get_class )( pTHX_ SV* ref );
+wxPliSelfRef* FUNCPTR( wxPli_get_selfref )( pTHX_ wxObject* object, bool 
forcevirtual );
 
 wxWindowID FUNCPTR( wxPli_get_wxwindowid )( pTHX_ SV* var );
 int FUNCPTR( wxPli_av_2_stringarray )( pTHX_ SV* avref, wxString** array );
@@ -489,6 +493,7 @@
     bool ( * m_wxPli_object_is_deleteable )( pTHX_ SV* );
     void ( * m_wxPli_object_set_deleteable )( pTHX_ SV*, bool );
     const char* ( * m_wxPli_get_class )( pTHX_ SV* );
+    wxPliSelfRef* ( * m_wxPli_get_selfref )( pTHX_ wxObject*, bool);
     wxWindowID ( * m_wxPli_get_wxwindowid )( pTHX_ SV* );
     int ( * m_wxPli_av_2_stringarray )( pTHX_ SV*, wxString** );
     wxPliInputStream* ( * m_wxPliInputStream_ctor )( SV* );
@@ -500,6 +505,8 @@
     void* ( * m_wxPli_detach_object )( pTHX_ SV* object );
     SV* ( * m_wxPli_create_evthandler )( pTHX_ wxEvtHandler* object,
                                          const char* cln );
+    SV* ( * m_wxPli_create_virtual_evthandler )( pTHX_ wxEvtHandler* object,
+                                         const char* cln, bool forcevirtual );
     bool (* m_wxPli_match_arguments_skipfirst )( pTHX_ const wxPliPrototype&,
                                                  int required,
                                                  bool allow_more );
@@ -562,9 +569,9 @@
  &wxPli_add_constant_function, &wxPli_remove_constant_function, \
  &wxPliVirtualCallback_FindCallback, &wxPliVirtualCallback_CallCallback, \
  &wxPli_object_is_deleteable, &wxPli_object_set_deleteable, &wxPli_get_class, \
- &wxPli_get_wxwindowid, &wxPli_av_2_stringarray, &wxPliInputStream_ctor, \
+ &wxPli_get_selfref, &wxPli_get_wxwindowid, &wxPli_av_2_stringarray, 
&wxPliInputStream_ctor, \
  &wxPli_cpp_class_2_perl, &wxPli_push_arguments, &wxPli_attach_object, \
- &wxPli_detach_object, &wxPli_create_evthandler, \
+ &wxPli_detach_object, &wxPli_create_evthandler, 
&wxPli_create_virtual_evthandler, \
  &wxPli_match_arguments_skipfirst, &wxPli_objlist_2_av, &wxPli_intarray_push, \
  &wxPli_clientdatacontainer_2_sv, \
  wxDEFINE_PLI_HELPER_THREADS() \
@@ -596,6 +603,7 @@
   wxPli_object_is_deleteable = name->m_wxPli_object_is_deleteable; \
   wxPli_object_set_deleteable = name->m_wxPli_object_set_deleteable; \
   wxPli_get_class = name->m_wxPli_get_class; \
+  wxPli_get_selfref = name->m_wxPli_get_selfref; \
   wxPli_get_wxwindowid = name->m_wxPli_get_wxwindowid; \
   wxPli_av_2_stringarray = name->m_wxPli_av_2_stringarray; \
   wxPliInputStream_ctor = name->m_wxPliInputStream_ctor; \
@@ -604,6 +612,7 @@
   wxPli_attach_object = name->m_wxPli_attach_object; \
   wxPli_detach_object = name->m_wxPli_detach_object; \
   wxPli_create_evthandler = name->m_wxPli_create_evthandler; \
+  wxPli_create_virtual_evthandler = name->m_wxPli_create_virtual_evthandler; \
   wxPli_match_arguments_skipfirst = name->m_wxPli_match_arguments_skipfirst; \
   wxPli_objlist_2_av = name->m_wxPli_objlist_2_av; \
   wxPli_intarray_push = name->m_wxPli_intarray_push; \
Index: typemap
===================================================================
--- typemap     (revision 3036)
+++ typemap     (working copy)
@@ -191,8 +191,8 @@
 wxPlVScrolledWindow *   O_WXEVTHANDLER
 wxPlHScrolledWindow *   O_WXEVTHANDLER
 wxPlHVScrolledWindow *  O_WXEVTHANDLER
-wxVListBox *            O_WXOBJECT
-wxPlVListBox *          O_WXOBJECT
+wxVListBox *            O_WXEVTHANDLER
+wxPlVListBox *          O_WXEVTHANDLER
 wxSplitterWindow *      O_WXEVTHANDLER
 wxSearchCtrl *          O_WXEVTHANDLER
 wxSashWindow *          O_WXEVTHANDLER
Index: typemap.tmpl
===================================================================
--- typemap.tmpl        (revision 3036)
+++ typemap.tmpl        (working copy)
@@ -191,8 +191,8 @@
 wxPlVScrolledWindow *   O_WXEVTHANDLER
 wxPlHScrolledWindow *   O_WXEVTHANDLER
 wxPlHVScrolledWindow *  O_WXEVTHANDLER
-wxVListBox *            O_WXOBJECT
-wxPlVListBox *          O_WXOBJECT
+wxVListBox *            O_WXEVTHANDLER
+wxPlVListBox *          O_WXEVTHANDLER
 wxSplitterWindow *      O_WXEVTHANDLER
 wxSearchCtrl *          O_WXEVTHANDLER
 wxSashWindow *          O_WXEVTHANDLER
Index: XS/VListBox.xsp
===================================================================
--- XS/VListBox.xsp     (revision 3036)
+++ XS/VListBox.xsp     (working copy)
@@ -185,7 +185,7 @@
 
     %name{newDefault} wxPlVListBox()
         %code{% RETVAL = new wxPlVListBox( CLASS ); 
-              // wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
+                wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
              %};
     %name{newFull} wxPlVListBox( wxWindow *parent,
                                  wxWindowID id = wxID_ANY,
@@ -195,7 +195,7 @@
                                  const wxString& name = wxVListBoxNameStr )
         %code{% RETVAL = new wxPlVListBox( CLASS, parent, id, pos, size,
                                            style, name );
-                // wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
+                wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
              %};
 };
 
Index: XS/VScrolledWindow.xsp
===================================================================
--- XS/VScrolledWindow.xsp      (revision 3036)
+++ XS/VScrolledWindow.xsp      (working copy)
@@ -272,7 +272,9 @@
 %}
 
     %name{newDefault} wxPlHScrolledWindow()
-        %code{% RETVAL = new wxPlHScrolledWindow( CLASS ); %};
+        %code{% RETVAL = new wxPlHScrolledWindow( CLASS ); 
+                wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
+             %};
     %name{newFull} wxPlHScrolledWindow( wxWindow *parent,
                                         wxWindowID id = wxID_ANY,
                                         const wxPoint& pos = wxDefaultPosition,
@@ -281,6 +283,7 @@
                                         const wxString& name = wxPanelNameStr )
         %code{% RETVAL = new wxPlHScrolledWindow( CLASS, parent, id, pos, size,
                                                   style, name );
+                wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
                 %};
 };
 
@@ -299,7 +302,9 @@
 %}
 
     %name{newDefault} wxPlVScrolledWindow()
-        %code{% RETVAL = new wxPlVScrolledWindow( CLASS ); %};
+        %code{% RETVAL = new wxPlVScrolledWindow( CLASS ); 
+                wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
+              %};
     %name{newFull} wxPlVScrolledWindow( wxWindow *parent,
                                         wxWindowID id = wxID_ANY,
                                         const wxPoint& pos = wxDefaultPosition,
@@ -308,6 +313,7 @@
                                         const wxString& name = wxPanelNameStr )
         %code{% RETVAL = new wxPlVScrolledWindow( CLASS, parent, id, pos, size,
                                                   style, name );
+                 wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
                 %};
 };
 
@@ -326,7 +332,9 @@
 %}
 
     %name{newDefault} wxPlHVScrolledWindow()
-        %code{% RETVAL = new wxPlHVScrolledWindow( CLASS ); %};
+        %code{% RETVAL = new wxPlHVScrolledWindow( CLASS ); 
+                wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
+              %};
     %name{newFull} wxPlHVScrolledWindow( wxWindow *parent,
                                          wxWindowID id = wxID_ANY,
                                          const wxPoint& pos = 
wxDefaultPosition,
@@ -335,6 +343,7 @@
                                          const wxString& name = wxPanelNameStr 
)
         %code{% RETVAL = new wxPlHVScrolledWindow( CLASS, parent, id, pos,
                                                    size, style, name );
+                wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
                 %};
 };
 

Reply via email to