Destroy the wxDialog::ShowWindowModalThenDo() functor a.s.a.p.

Previously, the functor was kept in a helper event handler that was bound to
wxEVT_WINDOW_MODAL_DIALOG_CLOSED and only marked as already called, but never
unbound. Consequently, the functor object remained allocated for as long as the
event table existed and was only freed with the dialog instance.

Change the logic to destroy the functor object as soon as it was called and is
no longer needed for anything.

This is particularly important when used with C++11 lambdas that capture the
dialog in a wxWindowPtr pointer, because the pointer would be retained forever
otherwise.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74890 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2013-10-01 12:19:56 +00:00
parent 38ececd4c3
commit 5ca59eb82e

View File

@@ -13,6 +13,7 @@
#include "wx/toplevel.h"
#include "wx/containr.h"
#include "wx/sharedptr.h"
class WXDLLIMPEXP_FWD_CORE wxSizer;
class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
@@ -402,24 +403,29 @@ class wxWindowModalDialogEventFunctor
{
public:
wxWindowModalDialogEventFunctor(const Functor& f)
: m_f(f), m_wasCalled(false)
: m_f(new Functor(f))
{}
void operator()(wxWindowModalDialogEvent& event)
{
if ( m_wasCalled )
if ( m_f )
{
// We only want to call this handler once. Also, by deleting
// the functor here, its data (such as wxWindowPtr pointing to
// the dialog) are freed immediately after exiting this operator().
wxSharedPtr<Functor> functor(m_f);
m_f.reset();
(*functor)(event.GetReturnCode());
}
else // was already called once
{
event.Skip();
return;
}
m_wasCalled = true;
m_f(event.GetReturnCode());
}
private:
Functor m_f;
bool m_wasCalled;
wxSharedPtr<Functor> m_f;
};
template<typename Functor>