From b9787c6754be1f130d454651f2d8fbcd73d7702d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 24 Apr 2023 22:34:14 +0100 Subject: [PATCH 1/6] Use std::vector<> instead of wxArray in thread sample No real changes, just use the standard container instead of macro-based array. --- samples/thread/thread.cpp | 69 +++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/samples/thread/thread.cpp b/samples/thread/thread.cpp index aa235126bf..4d22fbed0b 100644 --- a/samples/thread/thread.cpp +++ b/samples/thread/thread.cpp @@ -29,7 +29,6 @@ #endif // wxUSE_THREADS #include "wx/thread.h" -#include "wx/dynarray.h" #include "wx/numdlg.h" #include "wx/progdlg.h" @@ -53,7 +52,7 @@ #endif class MyThread; -WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread); +using MyThreads = std::vector; // ---------------------------------------------------------------------------- // the application object @@ -72,7 +71,7 @@ public: // all the threads currently alive - as soon as the thread terminates, it's // removed from the array - wxArrayThread m_threads; + MyThreads m_threads; // semaphore used to wait for the threads to exit, see MyFrame::OnQuit() wxSemaphore m_semAllDone; @@ -431,10 +430,7 @@ MyFrame::~MyFrame() wxCriticalSectionLocker locker(wxGetApp().m_critsect); // check if we have any threads running first - const wxArrayThread& threads = wxGetApp().m_threads; - size_t count = threads.GetCount(); - - if ( !count ) + if ( wxGetApp().m_threads.empty() ) return; // set the flag indicating that all threads should exit @@ -489,7 +485,7 @@ MyThread *MyFrame::CreateThread() } wxCriticalSectionLocker enter(wxGetApp().m_critsect); - wxGetApp().m_threads.Add(thread); + wxGetApp().m_threads.push_back(thread); return thread; } @@ -500,10 +496,10 @@ void MyFrame::UpdateThreadStatus() // update the counts of running/total threads size_t nRunning = 0, - nCount = wxGetApp().m_threads.Count(); - for ( size_t n = 0; n < nCount; n++ ) + nCount = wxGetApp().m_threads.size(); + for ( wxThread* thr : wxGetApp().m_threads ) { - if ( wxGetApp().m_threads[n]->IsRunning() ) + if ( thr->IsRunning() ) nRunning++; } @@ -543,7 +539,7 @@ void MyFrame::OnStartThreads(wxCommandEvent& WXUNUSED(event) ) unsigned count = unsigned(s_num), n; - wxArrayThread threads; + MyThreads threads; // first create them all... for ( n = 0; n < count; n++ ) @@ -560,7 +556,7 @@ void MyFrame::OnStartThreads(wxCommandEvent& WXUNUSED(event) ) else thr->SetPriority(wxPRIORITY_DEFAULT); - threads.Add(thr); + threads.push_back(thr); } #if wxUSE_STATUSBAR @@ -597,13 +593,13 @@ void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) ) wxCriticalSectionLocker enter(wxGetApp().m_critsect); // stop the last thread - if ( wxGetApp().m_threads.IsEmpty() ) + if ( wxGetApp().m_threads.empty() ) { wxLogError("No thread to stop!"); } else { - toDelete = wxGetApp().m_threads.Last(); + toDelete = wxGetApp().m_threads.back(); } } @@ -624,17 +620,23 @@ void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) ) wxCriticalSectionLocker enter(wxGetApp().m_critsect); // resume first suspended thread - size_t n = 0, count = wxGetApp().m_threads.Count(); - while ( n < count && !wxGetApp().m_threads[n]->IsPaused() ) - n++; + wxThread* thrToResume = nullptr; + for ( wxThread* thr : wxGetApp().m_threads ) + { + if ( thr->IsPaused() ) + { + thrToResume = thr; + break; + } + } - if ( n == count ) + if ( !thrToResume ) { wxLogError("No thread to resume!"); } else { - wxGetApp().m_threads[n]->Resume(); + thrToResume->Resume(); #if wxUSE_STATUSBAR SetStatusText("Thread resumed.", 1); @@ -647,17 +649,25 @@ void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) ) wxCriticalSectionLocker enter(wxGetApp().m_critsect); // pause last running thread - int n = wxGetApp().m_threads.Count() - 1; - while ( n >= 0 && !wxGetApp().m_threads[n]->IsRunning() ) - n--; + wxThread* thrToPause = nullptr; + for ( wxThread* thr : wxGetApp().m_threads ) + { + if ( thr->IsRunning() ) + { + thrToPause = thr; + // Don't break, we want the last running thread, not the first one + // (and yes, it would be more efficient to iterate using reverse + // iterators, but keep the code simple and not efficient here). + } + } - if ( n < 0 ) + if ( !thrToPause ) { wxLogError("No thread to pause!"); } else { - wxGetApp().m_threads[n]->Pause(); + thrToPause->Pause(); #if wxUSE_STATUSBAR SetStatusText("Thread paused.", 1); @@ -901,10 +911,13 @@ MyThread::~MyThread() { wxCriticalSectionLocker locker(wxGetApp().m_critsect); - wxArrayThread& threads = wxGetApp().m_threads; - threads.Remove(this); + auto& threads = wxGetApp().m_threads; + const auto it = std::find(threads.begin(), threads.end(), this); + wxASSERT_MSG( it != threads.end(), "unknown thread?" ); - if ( threads.IsEmpty() ) + threads.erase(it); + + if ( threads.empty() ) { // signal the main thread that there are no more threads left if it is // waiting for us From d1619058569ea1448db3d38c8611386e74b2515d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 24 Apr 2023 22:34:38 +0100 Subject: [PATCH 2/6] Remove unnecessary includes of wx/dynarray.h from the samples No changes at all, just prune the unnecessary header. --- samples/validate/validate.h | 1 - samples/widgets/notebook.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/samples/validate/validate.h b/samples/validate/validate.h index ac17bfde54..679289e996 100644 --- a/samples/validate/validate.h +++ b/samples/validate/validate.h @@ -11,7 +11,6 @@ #include "wx/app.h" #include "wx/combobox.h" #include "wx/dialog.h" -#include "wx/dynarray.h" #include "wx/frame.h" #include "wx/listbox.h" #include "wx/string.h" diff --git a/samples/widgets/notebook.cpp b/samples/widgets/notebook.cpp index 9118ef0939..ea3df7e8d7 100644 --- a/samples/widgets/notebook.cpp +++ b/samples/widgets/notebook.cpp @@ -33,8 +33,6 @@ #include "wx/radiobox.h" #include "wx/statbox.h" #include "wx/textctrl.h" - - #include "wx/dynarray.h" #endif #include "wx/sizer.h" From 20e521348b0a054a489412d2981a75184b0453a0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 24 Apr 2023 22:34:14 +0100 Subject: [PATCH 3/6] Use std::vector<> instead of wxArray in exec sample No real changes, just use the standard containers instead of macro-based arrays. --- samples/exec/exec.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/samples/exec/exec.cpp b/samples/exec/exec.cpp index a3437a5a79..a882df7b8c 100644 --- a/samples/exec/exec.cpp +++ b/samples/exec/exec.cpp @@ -63,6 +63,7 @@ #endif // __WINDOWS__ #include +#include #ifndef wxHAS_IMAGES_IN_RESOURCES #include "../sample.xpm" @@ -87,10 +88,10 @@ public: // Define an array of process pointers used by MyFrame class MyPipedProcess; -WX_DEFINE_ARRAY_PTR(MyPipedProcess *, MyPipedProcessesArray); +using MyPipedProcessesArray = std::vector; class MyProcess; -WX_DEFINE_ARRAY_PTR(MyProcess *, MyProcessesArray); +using MyProcessesArray = std::vector; // Define a new frame type: this is going to be our main frame class MyFrame : public wxFrame @@ -541,9 +542,9 @@ MyFrame::~MyFrame() // any processes left until now must be deleted manually: normally this is // done when the associated process terminates but it must be still running // if this didn't happen until now - for ( size_t n = 0; n < m_allAsync.size(); n++ ) + for ( auto process : m_allAsync ) { - delete m_allAsync[n]; + delete process; } } @@ -1266,10 +1267,9 @@ void MyFrame::OnDDERequest(wxCommandEvent& WXUNUSED(event)) // input polling void MyFrame::OnIdle(wxIdleEvent& event) { - size_t count = m_running.GetCount(); - for ( size_t n = 0; n < count; n++ ) + for ( auto process : m_running ) { - if ( m_running[n]->HasInput() ) + if ( process->HasInput() ) { event.RequestMore(); } @@ -1294,14 +1294,14 @@ void MyFrame::OnProcessTerminated(MyPipedProcess *process) void MyFrame::OnAsyncTermination(MyProcess *process) { - m_allAsync.Remove(process); + m_allAsync.erase(std::find(m_allAsync.begin(), m_allAsync.end(), process)); delete process; } void MyFrame::AddPipedProcess(MyPipedProcess *process) { - if ( m_running.IsEmpty() ) + if ( m_running.empty() ) { // we want to start getting the timer events to ensure that a // steady stream of idle events comes in -- otherwise we @@ -1310,15 +1310,15 @@ void MyFrame::AddPipedProcess(MyPipedProcess *process) } //else: the timer is already running - m_running.Add(process); - m_allAsync.Add(process); + m_running.push_back(process); + m_allAsync.push_back(process); } void MyFrame::RemovePipedProcess(MyPipedProcess *process) { - m_running.Remove(process); + m_running.erase(std::find(m_running.begin(), m_running.end(), process)); - if ( m_running.IsEmpty() ) + if ( m_running.empty() ) { // we don't need to get idle events all the time any more m_timerIdleWakeUp.Stop(); From 58168736a04f32e9d94d09c2dfd266b7bf203365 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 24 Apr 2023 22:34:14 +0100 Subject: [PATCH 4/6] Use std::vector<> instead of wxArray in regtest sample No real changes, just use the standard container instead of macro-based array. --- samples/regtest/regtest.cpp | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/samples/regtest/regtest.cpp b/samples/regtest/regtest.cpp index 32965b02f3..a7a3ee1d0c 100644 --- a/samples/regtest/regtest.cpp +++ b/samples/regtest/regtest.cpp @@ -106,7 +106,7 @@ private: // structure describing a registry key/value class TreeNode : public wxTreeItemData { - WX_DEFINE_ARRAY_PTR(TreeNode *, TreeChildren); + using TreeChildren = std::vector; public: RegTreeCtrl *m_pTree; // must be non-null TreeNode *m_pParent; // nullptr only for the root node @@ -601,7 +601,7 @@ RegTreeCtrl::TreeNode *RegTreeCtrl::InsertNewTreeNode( // add it to the list of parent's children if ( pParent != nullptr ) { - pParent->m_aChildren.Add(pNewNode); + pParent->m_aChildren.push_back(pNewNode); } if ( pNewNode->IsKey() ) @@ -979,7 +979,7 @@ void RegTreeCtrl::OnEndDrag(wxTreeEvent& event) bool RegTreeCtrl::TreeNode::OnExpand() { // we add children only once - if ( !m_aChildren.IsEmpty() ) + if ( !m_aChildren.empty() ) { // we've been already expanded return true; @@ -1124,11 +1124,11 @@ void RegTreeCtrl::TreeNode::Refresh() bool RegTreeCtrl::TreeNode::DeleteChild(TreeNode *child) { - int index = m_aChildren.Index(child); - wxCHECK_MSG( index != wxNOT_FOUND, false, + const auto iter = std::find(m_aChildren.begin(), m_aChildren.end(), child); + wxCHECK_MSG( iter != m_aChildren.end(), false, "our child in tree should be in m_aChildren" ); - m_aChildren.RemoveAt((size_t)index); + m_aChildren.erase(iter); bool ok; if ( child->IsKey() ) @@ -1157,14 +1157,12 @@ bool RegTreeCtrl::TreeNode::DeleteChild(TreeNode *child) void RegTreeCtrl::TreeNode::DestroyChildren() { // destroy all children - size_t nCount = m_aChildren.GetCount(); - for ( size_t n = 0; n < nCount; n++ ) + for ( auto child : m_aChildren ) { - wxTreeItemId lId = m_aChildren[n]->Id(); - m_pTree->Delete(lId); + m_pTree->Delete(child->Id()); } - m_aChildren.Empty(); + m_aChildren.clear(); } RegTreeCtrl::TreeNode::~TreeNode() @@ -1196,9 +1194,8 @@ void RegTreeCtrl::TreeNode::SetRegistryView(wxRegKey::WOW64ViewMode viewMode) m_viewMode = viewMode; // Update children with new view. - size_t nCount = m_aChildren.GetCount(); - for (size_t n = 0; n < nCount; n++) - m_aChildren[n]->SetRegistryView(viewMode); + for ( auto child : m_aChildren ) + child->SetRegistryView(viewMode); } // ---------------------------------------------------------------------------- From ac854d371847b69421fe94778c81c63ef82a12fb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 24 Apr 2023 22:34:14 +0100 Subject: [PATCH 5/6] Use std::vector<> instead of wxArray in widgets sample No real changes, just use the standard container instead of macro-based array. --- samples/widgets/widgets.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/samples/widgets/widgets.cpp b/samples/widgets/widgets.cpp index 0b848a40bd..6928bf853e 100644 --- a/samples/widgets/widgets.cpp +++ b/samples/widgets/widgets.cpp @@ -293,9 +293,6 @@ private: }; #endif // USE_LOG -// array of pages -WX_DEFINE_ARRAY_PTR(WidgetsPage *, ArrayWidgetsPage); - // ---------------------------------------------------------------------------- // misc macros // ---------------------------------------------------------------------------- @@ -572,6 +569,7 @@ void WidgetsFrame::InitBook() WidgetsBookCtrl *books[MAX_PAGES]; #endif + using ArrayWidgetsPage = std::vector; ArrayWidgetsPage pages[MAX_PAGES]; wxArrayString labels[MAX_PAGES]; @@ -609,7 +607,7 @@ void WidgetsFrame::InitBook() books[cat] #endif , imageList); - pages[cat].Add(page); + pages[cat].push_back(page); labels[cat].Add(info->GetLabel()); if ( cat == ALL_PAGE ) @@ -645,7 +643,7 @@ void WidgetsFrame::InitBook() #endif // now do add them - size_t count = pages[cat].GetCount(); + size_t count = pages[cat].size(); for ( size_t n = 0; n < count; n++ ) { #if USE_TREEBOOK From 8f4c9f41a46795ac7cd521cbd36786adddbcbc9c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 24 Apr 2023 22:46:13 +0100 Subject: [PATCH 6/6] Use std::map<> instead of wxHashMap in webview sample No real changes, just use the standard class. --- samples/webview/webview.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/samples/webview/webview.cpp b/samples/webview/webview.cpp index 1156fa3542..8b84ea34a7 100644 --- a/samples/webview/webview.cpp +++ b/samples/webview/webview.cpp @@ -54,10 +54,10 @@ #include "wxlogo.xpm" +#include //We map menu items to their history items -WX_DECLARE_HASH_MAP(int, wxSharedPtr, - wxIntegerHash, wxIntegerEqual, wxMenuHistoryMap); +using wxMenuHistoryMap = std::map>; class WebApp : public wxApp { @@ -1108,10 +1108,9 @@ void WebFrame::OnToolsClicked(wxCommandEvent& WXUNUSED(evt)) m_browser_accelerator_keys->Check(m_browser->AreBrowserAcceleratorKeysEnabled()); //Firstly we clear the existing menu items, then we add the current ones - wxMenuHistoryMap::const_iterator it; - for( it = m_histMenuItems.begin(); it != m_histMenuItems.end(); ++it ) + for ( auto& item : m_histMenuItems ) { - m_tools_history_menu->Destroy(it->first); + m_tools_history_menu->Destroy(item.first); } m_histMenuItems.clear();