From: Václav Slavík Date: Tue, 28 Jun 2011 17:24:37 +0000 (+0000) Subject: Move wxThreadEvent into wxBase. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/c1b293bb8df110ae772cd99fde09e5724730653a?ds=inline Move wxThreadEvent into wxBase. For this, it cannot derive from wxCommandEvent. Extracted the bits from wxCommandEvent useful for passing data between threads into wxEventBasicPayloadMixin helper class shared by both. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68076 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 57982bbed8..fd1fb817e8 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -455,6 +455,7 @@ All: - Added wxThread::Wait() and Delete() "wait mode" parameter (Catalin Raceanu). - Allow showing milliseconds in wxLog time stamps (tan). - Added support for processing instructions in wxXmlDocument (Nick Matthews). +- Added wxThreadEvent for communicating between threads to wxBase. Unix: diff --git a/include/wx/event.h b/include/wx/event.h index 8fc2dcb6af..338ce78a09 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -615,8 +615,9 @@ extern WXDLLIMPEXP_BASE const wxEventType wxEVT_FIRST; extern WXDLLIMPEXP_BASE const wxEventType wxEVT_USER_FIRST; // Need events declared to do this +class WXDLLIMPEXP_FWD_BASE wxIdleEvent; +class WXDLLIMPEXP_FWD_BASE wxThreadEvent; class WXDLLIMPEXP_FWD_CORE wxCommandEvent; -class WXDLLIMPEXP_FWD_CORE wxThreadEvent; class WXDLLIMPEXP_FWD_CORE wxMouseEvent; class WXDLLIMPEXP_FWD_CORE wxFocusEvent; class WXDLLIMPEXP_FWD_CORE wxChildFocusEvent; @@ -649,7 +650,6 @@ class WXDLLIMPEXP_FWD_CORE wxPaletteChangedEvent; class WXDLLIMPEXP_FWD_CORE wxJoystickEvent; class WXDLLIMPEXP_FWD_CORE wxDropFilesEvent; class WXDLLIMPEXP_FWD_CORE wxInitDialogEvent; -class WXDLLIMPEXP_FWD_CORE wxIdleEvent; class WXDLLIMPEXP_FWD_CORE wxUpdateUIEvent; class WXDLLIMPEXP_FWD_CORE wxClipboardTextEvent; class WXDLLIMPEXP_FWD_CORE wxHelpEvent; @@ -678,7 +678,7 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCo wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEvent); // Thread events -wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_THREAD, wxThreadEvent); +wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_BASE, wxEVT_THREAD, wxThreadEvent); // Mouse event types wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_LEFT_DOWN, wxMouseEvent); @@ -1116,6 +1116,148 @@ private: wxDECLARE_NO_COPY_CLASS(wxEventProcessInHandlerOnly); }; + +class WXDLLIMPEXP_BASE wxEventBasicPayloadMixin +{ +public: + wxEventBasicPayloadMixin() + : m_commandInt(0), + m_extraLong(0) + { + } + + void SetString(const wxString& s) { m_cmdString = s; } + const wxString& GetString() const { return m_cmdString; } + + void SetInt(int i) { m_commandInt = i; } + int GetInt() const { return m_commandInt; } + + void SetExtraLong(long extraLong) { m_extraLong = extraLong; } + long GetExtraLong() const { return m_extraLong; } + +protected: + // Note: these variables have "cmd" or "command" in their name for backward compatibility: + // they used to be part of wxCommandEvent, not this mixin. + wxString m_cmdString; // String event argument + int m_commandInt; + long m_extraLong; // Additional information (e.g. select/deselect) + + wxDECLARE_NO_ASSIGN_CLASS(wxEventBasicPayloadMixin); +}; + +class WXDLLIMPEXP_BASE wxEventAnyPayloadMixin : public wxEventBasicPayloadMixin +{ +public: + wxEventAnyPayloadMixin() : wxEventBasicPayloadMixin() {} + +#if wxUSE_ANY && (!defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)) + template + void SetPayload(const T& payload) + { + m_payload = payload; + } + + template + T GetPayload() const + { + return m_payload.As(); + } + +protected: + wxAny m_payload; +#endif // wxUSE_ANY && (!defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)) + + wxDECLARE_NO_ASSIGN_CLASS(wxEventBasicPayloadMixin); +}; + + +// Idle event +/* + wxEVT_IDLE + */ + +// Whether to always send idle events to windows, or +// to only send update events to those with the +// wxWS_EX_PROCESS_IDLE style. + +enum wxIdleMode +{ + // Send idle events to all windows + wxIDLE_PROCESS_ALL, + + // Send idle events to windows that have + // the wxWS_EX_PROCESS_IDLE flag specified + wxIDLE_PROCESS_SPECIFIED +}; + +class WXDLLIMPEXP_BASE wxIdleEvent : public wxEvent +{ +public: + wxIdleEvent() + : wxEvent(0, wxEVT_IDLE), + m_requestMore(false) + { } + wxIdleEvent(const wxIdleEvent& event) + : wxEvent(event), + m_requestMore(event.m_requestMore) + { } + + void RequestMore(bool needMore = true) { m_requestMore = needMore; } + bool MoreRequested() const { return m_requestMore; } + + virtual wxEvent *Clone() const { return new wxIdleEvent(*this); } + + // Specify how wxWidgets will send idle events: to + // all windows, or only to those which specify that they + // will process the events. + static void SetMode(wxIdleMode mode) { sm_idleMode = mode; } + + // Returns the idle event mode + static wxIdleMode GetMode() { return sm_idleMode; } + +protected: + bool m_requestMore; + static wxIdleMode sm_idleMode; + +private: + DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxIdleEvent) +}; + + +// Thread event + +class WXDLLIMPEXP_BASE wxThreadEvent : public wxEvent, + public wxEventAnyPayloadMixin +{ +public: + wxThreadEvent(wxEventType eventType = wxEVT_THREAD, int id = wxID_ANY) + : wxEvent(id, eventType) + { } + + wxThreadEvent(const wxThreadEvent& event) + : wxEvent(event), + wxEventAnyPayloadMixin(event) + { + // make sure our string member (which uses COW, aka refcounting) is not + // shared by other wxString instances: + SetString(GetString().c_str()); + } + + virtual wxEvent *Clone() const + { + return new wxThreadEvent(*this); + } + + // this is important to avoid that calling wxEventLoopBase::YieldFor thread events + // gets processed when this is unwanted: + virtual wxEventCategory GetEventCategory() const + { return wxEVT_CATEGORY_THREAD; } + +private: + DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxThreadEvent) +}; + + #if wxUSE_GUI @@ -1138,16 +1280,15 @@ private: wxEVT_COMMAND_TOGGLEBUTTON_CLICKED */ -class WXDLLIMPEXP_CORE wxCommandEvent : public wxEvent +class WXDLLIMPEXP_CORE wxCommandEvent : public wxEvent, + public wxEventBasicPayloadMixin { public: wxCommandEvent(wxEventType commandType = wxEVT_NULL, int winid = 0); wxCommandEvent(const wxCommandEvent& event) : wxEvent(event), - m_cmdString(event.m_cmdString), - m_commandInt(event.m_commandInt), - m_extraLong(event.m_extraLong), + wxEventBasicPayloadMixin(event), m_clientData(event.m_clientData), m_clientObject(event.m_clientObject) { } @@ -1160,32 +1301,23 @@ public: void SetClientObject(wxClientData* clientObject) { m_clientObject = clientObject; } wxClientData *GetClientObject() const { return m_clientObject; } + // Note: this shadows wxEventBasicPayloadMixin::GetString(), because it does some + // GUI-specific hacks + wxString GetString() const; + // Get listbox selection if single-choice int GetSelection() const { return m_commandInt; } - // Set/Get listbox/choice selection string - void SetString(const wxString& s) { m_cmdString = s; } - wxString GetString() const; - // Get checkbox value bool IsChecked() const { return m_commandInt != 0; } // true if the listbox event was a selection. bool IsSelection() const { return (m_extraLong != 0); } - void SetExtraLong(long extraLong) { m_extraLong = extraLong; } - long GetExtraLong() const { return m_extraLong; } - - void SetInt(int i) { m_commandInt = i; } - int GetInt() const { return m_commandInt; } - virtual wxEvent *Clone() const { return new wxCommandEvent(*this); } virtual wxEventCategory GetEventCategory() const { return wxEVT_CATEGORY_USER_INPUT; } protected: - wxString m_cmdString; // String event argument - int m_commandInt; - long m_extraLong; // Additional information (e.g. select/deselect) void* m_clientData; // Arbitrary client data wxClientData* m_clientObject; // Arbitrary client object @@ -1225,60 +1357,6 @@ private: }; -// Thread event - -class WXDLLIMPEXP_CORE wxThreadEvent : public wxCommandEvent -{ -public: - wxThreadEvent(wxEventType eventType = wxEVT_COMMAND_THREAD, int id = wxID_ANY) - : wxCommandEvent(eventType, id) - { } - - wxThreadEvent(const wxThreadEvent& event) - : wxCommandEvent(event) - { - // make sure our string member (which uses COW, aka refcounting) is not - // shared by other wxString instances: - SetString(GetString().c_str()); - -#if wxUSE_ANY && (!defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)) - m_payload = event.m_payload; -#endif - } - - virtual wxEvent *Clone() const - { - return new wxThreadEvent(*this); - } - - // this is important to avoid that calling wxEventLoopBase::YieldFor thread events - // gets processed when this is unwanted: - virtual wxEventCategory GetEventCategory() const - { return wxEVT_CATEGORY_THREAD; } - -#if wxUSE_ANY && (!defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)) - template - void SetPayload(const T& payload) - { - m_payload = payload; - } - - template - T GetPayload() const - { - return m_payload.As(); - } - -protected: - wxAny m_payload; -#endif // wxUSE_ANY && (!defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)) - -private: - DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxThreadEvent) -}; - - - // Scroll event class, derived form wxCommandEvent. wxScrollEvents are // sent by wxSlider and wxScrollBar. /* @@ -2726,59 +2804,6 @@ private: DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxContextMenuEvent) }; -#endif // wxUSE_GUI - -// Idle event -/* - wxEVT_IDLE - */ - -// Whether to always send idle events to windows, or -// to only send update events to those with the -// wxWS_EX_PROCESS_IDLE style. - -enum wxIdleMode -{ - // Send idle events to all windows - wxIDLE_PROCESS_ALL, - - // Send idle events to windows that have - // the wxWS_EX_PROCESS_IDLE flag specified - wxIDLE_PROCESS_SPECIFIED -}; - -class WXDLLIMPEXP_BASE wxIdleEvent : public wxEvent -{ -public: - wxIdleEvent() - : wxEvent(0, wxEVT_IDLE), - m_requestMore(false) - { } - wxIdleEvent(const wxIdleEvent& event) - : wxEvent(event), - m_requestMore(event.m_requestMore) - { } - - void RequestMore(bool needMore = true) { m_requestMore = needMore; } - bool MoreRequested() const { return m_requestMore; } - - virtual wxEvent *Clone() const { return new wxIdleEvent(*this); } - - // Specify how wxWidgets will send idle events: to - // all windows, or only to those which specify that they - // will process the events. - static void SetMode(wxIdleMode mode) { sm_idleMode = mode; } - - // Returns the idle event mode - static wxIdleMode GetMode() { return sm_idleMode; } - -protected: - bool m_requestMore; - static wxIdleMode sm_idleMode; - -private: - DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxIdleEvent) -}; /* TODO wxEVT_MOUSE_CAPTURE_CHANGED, @@ -2790,6 +2815,7 @@ private: wxEVT_COMPARE_ITEM */ +#endif // wxUSE_GUI // ============================================================================ @@ -3422,11 +3448,14 @@ inline void wxQueueEvent(wxEvtHandler *dest, wxEvent *event) typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); typedef void (wxEvtHandler::*wxIdleEventFunction)(wxIdleEvent&); +typedef void (wxEvtHandler::*wxThreadEventFunction)(wxThreadEvent&); #define wxEventHandler(func) \ wxEVENT_HANDLER_CAST(wxEventFunction, func) #define wxIdleEventHandler(func) \ wxEVENT_HANDLER_CAST(wxIdleEventFunction, func) +#define wxThreadEventHandler(func) \ + wxEVENT_HANDLER_CAST(wxThreadEventFunction, func) #if wxUSE_GUI @@ -3455,7 +3484,6 @@ protected: }; typedef void (wxEvtHandler::*wxCommandEventFunction)(wxCommandEvent&); -typedef void (wxEvtHandler::*wxThreadEventFunction)(wxThreadEvent&); typedef void (wxEvtHandler::*wxScrollEventFunction)(wxScrollEvent&); typedef void (wxEvtHandler::*wxScrollWinEventFunction)(wxScrollWinEvent&); typedef void (wxEvtHandler::*wxSizeEventFunction)(wxSizeEvent&); @@ -3495,8 +3523,6 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& #define wxCommandEventHandler(func) \ wxEVENT_HANDLER_CAST(wxCommandEventFunction, func) -#define wxThreadEventHandler(func) \ - wxEVENT_HANDLER_CAST(wxThreadEventFunction, func) #define wxScrollEventHandler(func) \ wxEVENT_HANDLER_CAST(wxScrollEventFunction, func) #define wxScrollWinEventHandler(func) \ @@ -3980,7 +4006,9 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& #define EVT_TEXT_PASTE(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_TEXT_PASTE, winid, wxClipboardTextEventHandler(func)) // Thread events -#define EVT_THREAD(id, func) wx__DECLARE_EVT1(wxEVT_COMMAND_THREAD, id, wxThreadEventHandler(func)) +#define EVT_THREAD(id, func) wx__DECLARE_EVT1(wxEVT_THREAD, id, wxThreadEventHandler(func)) +// alias for backward compatibility with 2.9.0: +#define wxEVT_COMMAND_THREAD wxEVT_THREAD // ---------------------------------------------------------------------------- // Helper functions diff --git a/interface/wx/event.h b/interface/wx/event.h index 6d7b85754d..d3ad26b231 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -3036,14 +3036,16 @@ public: @category{events,threading} @see @ref overview_thread, wxEventLoopBase::YieldFor + + @since 2.9.0 */ -class wxThreadEvent : public wxCommandEvent +class wxThreadEvent : public wxEvent { public: /** Constructor. */ - wxThreadEvent(wxEventType eventType = wxEVT_COMMAND_THREAD, int id = wxID_ANY); + wxThreadEvent(wxEventType eventType = wxEVT_THREAD, int id = wxID_ANY); /** Clones this event making sure that all internal members which use @@ -3090,6 +3092,37 @@ public: */ template T GetPayload() const; + + /** + Returns extra information integer value. + */ + long GetExtraLong() const; + + /** + Returns stored integer value. + */ + int GetInt() const; + + /** + Returns stored string value. + */ + wxString GetString() const; + + + /** + Sets the extra information value. + */ + void SetExtraLong(long extraLong); + + /** + Sets the integer value. + */ + void SetInt(int intCommand); + + /** + Sets the string value. + */ + void SetString(const wxString& string); }; @@ -4244,7 +4277,7 @@ wxEventType wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED; wxEventType wxEVT_COMMAND_TOOL_ENTER; wxEventType wxEVT_COMMAND_COMBOBOX_DROPDOWN; wxEventType wxEVT_COMMAND_COMBOBOX_CLOSEUP; -wxEventType wxEVT_COMMAND_THREAD; +wxEventType wxEVT_THREAD; wxEventType wxEVT_LEFT_DOWN; wxEventType wxEVT_LEFT_UP; wxEventType wxEVT_MIDDLE_DOWN; diff --git a/samples/dll/my_dll.cpp b/samples/dll/my_dll.cpp index 4b67d6d04e..bfd6ed508f 100644 --- a/samples/dll/my_dll.cpp +++ b/samples/dll/my_dll.cpp @@ -150,10 +150,10 @@ MyDllApp::MyDllApp() Connect(wxEVT_IDLE, wxIdleEventHandler(MyDllApp::OnIdle)); Connect(CMD_SHOW_WINDOW, - wxEVT_COMMAND_THREAD, + wxEVT_THREAD, wxThreadEventHandler(MyDllApp::OnShowWindow)); Connect(CMD_TERMINATE, - wxEVT_COMMAND_THREAD, + wxEVT_THREAD, wxThreadEventHandler(MyDllApp::OnTerminate)); } @@ -288,7 +288,7 @@ void run_wx_gui_from_dll(const char *title) // Send a message to wx thread to show a new frame: wxThreadEvent *event = - new wxThreadEvent(wxEVT_COMMAND_THREAD, CMD_SHOW_WINDOW); + new wxThreadEvent(wxEVT_THREAD, CMD_SHOW_WINDOW); event->SetString(title); wxQueueEvent(wxApp::GetInstance(), event); } @@ -303,7 +303,7 @@ void wx_dll_cleanup() // If wx main thread is running, we need to stop it. To accomplish this, // send a message telling it to terminate the app. wxThreadEvent *event = - new wxThreadEvent(wxEVT_COMMAND_THREAD, CMD_TERMINATE); + new wxThreadEvent(wxEVT_THREAD, CMD_TERMINATE); wxQueueEvent(wxApp::GetInstance(), event); // We must then wait for the thread to actually terminate. diff --git a/samples/thread/thread.cpp b/samples/thread/thread.cpp index cb3f8aef59..6b0903cb82 100644 --- a/samples/thread/thread.cpp +++ b/samples/thread/thread.cpp @@ -969,7 +969,7 @@ wxThread::ExitCode MyWorkerThread::Entry() if ( TestDestroy() ) return NULL; - wxThreadEvent event( wxEVT_COMMAND_THREAD, WORKER_EVENT ); + wxThreadEvent event( wxEVT_THREAD, WORKER_EVENT ); event.SetInt( 50 ); wxQueueEvent( m_frame, event.Clone() ); @@ -984,7 +984,7 @@ wxThread::ExitCode MyWorkerThread::Entry() break; // create any type of command event here - wxThreadEvent event( wxEVT_COMMAND_THREAD, WORKER_EVENT ); + wxThreadEvent event( wxEVT_THREAD, WORKER_EVENT ); event.SetInt( m_count ); // send in a thread-safe way @@ -993,7 +993,7 @@ wxThread::ExitCode MyWorkerThread::Entry() wxMilliSleep(200); } - wxThreadEvent event( wxEVT_COMMAND_THREAD, WORKER_EVENT ); + wxThreadEvent event( wxEVT_THREAD, WORKER_EVENT ); event.SetInt(-1); // that's all wxQueueEvent( m_frame, event.Clone() ); #endif @@ -1043,7 +1043,7 @@ wxThread::ExitCode MyGUIThread::Entry() wxMutexGuiLeave(); // notify the dialog that another piece of our masterpiece is complete: - wxThreadEvent event( wxEVT_COMMAND_THREAD, GUITHREAD_EVENT ); + wxThreadEvent event( wxEVT_THREAD, GUITHREAD_EVENT ); event.SetInt(i+1); wxQueueEvent( m_dlg, event.Clone() ); diff --git a/src/common/event.cpp b/src/common/event.cpp index fcb917dae8..31e6e6adef 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -62,11 +62,11 @@ IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject) IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject) IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent) + IMPLEMENT_DYNAMIC_CLASS(wxThreadEvent, wxEvent) #endif // wxUSE_BASE #if wxUSE_GUI IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent, wxEvent) - IMPLEMENT_DYNAMIC_CLASS(wxThreadEvent, wxCommandEvent) IMPLEMENT_DYNAMIC_CLASS(wxNotifyEvent, wxCommandEvent) IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent, wxCommandEvent) IMPLEMENT_DYNAMIC_CLASS(wxScrollWinEvent, wxEvent) @@ -155,6 +155,9 @@ const wxEventType wxEVT_NULL = wxNewEventType(); wxDEFINE_EVENT( wxEVT_IDLE, wxIdleEvent ); +// Thread event +wxDEFINE_EVENT( wxEVT_THREAD, wxThreadEvent ); + #endif // wxUSE_BASE #if wxUSE_GUI @@ -312,9 +315,6 @@ wxDEFINE_EVENT( wxEVT_COMMAND_ENTER, wxCommandEvent ); wxDEFINE_EVENT( wxEVT_HELP, wxHelpEvent ); wxDEFINE_EVENT( wxEVT_DETAILED_HELP, wxHelpEvent ); -// Thread event -wxDEFINE_EVENT( wxEVT_COMMAND_THREAD, wxThreadEvent ); - #endif // wxUSE_GUI #if wxUSE_BASE @@ -422,8 +422,6 @@ wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId) { m_clientData = NULL; m_clientObject = NULL; - m_extraLong = 0; - m_commandInt = 0; m_isCommandEvent = true; // the command events are propagated upwards by default