Kiway: Improve performance by using IDs and clearing closed frame entries

This commit is contained in:
david-beinder 2021-07-02 21:07:26 +02:00 committed by Jon Evans
parent a5308e5f5c
commit f33ea6f997
2 changed files with 27 additions and 17 deletions

View File

@ -52,15 +52,14 @@ KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ):
{
SetTop( aTop ); // hook player_destroy_handler() into aTop.
// Prepare the room to store the frame names, once they will be created
// with FRAME_T type as index in this table.
// (note this is a list of frame names, but a non empty entry
// does not mean the frame still exists. It means only the frame was created
// at least once. It can be destroyed after. These entries are not cleared.
// the purpose is just to allow a call to wxWindow::FindWindowByName(), from
// a FRAME_T frame type
m_playerFrameName.Add( wxEmptyString, KIWAY_PLAYER_COUNT );
// Set the array of all known frame window IDs to empty = wxID_NONE,
// once they are be created, they are added with FRAME_T as index to this array.
// Note: A non empty entry does not mean the frame still exists.
// It means only the frame was created at least once. It can be destroyed after.
// These entries are not cleared automatically on window closing. The purpose is just
// to allow a call to wxWindow::FindWindowById() using a FRAME_T frame type
for( int n = 0; n < KIWAY_PLAYER_COUNT; n++ )
m_playerFrameId[n] = wxID_NONE;
}
@ -361,10 +360,19 @@ KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType )
KIWAY_PLAYER* KIWAY::GetPlayerFrame( FRAME_T aFrameType )
{
if( m_playerFrameName[aFrameType].IsEmpty() )
wxWindowID storedId = m_playerFrameId[aFrameType];
if( storedId == wxID_NONE )
return NULL;
return static_cast<KIWAY_PLAYER*>( wxWindow::FindWindowByName( m_playerFrameName[aFrameType] ) );
wxWindow* frame = wxWindow::FindWindowById( storedId );
// Since wxWindow::FindWindow*() is not cheap (especially if the window does not exist),
// clear invalid entries to save CPU on repeated calls that do not lead to frame creation
if( !frame )
m_playerFrameId[aFrameType].compare_exchange_strong( storedId, wxID_NONE );
return static_cast<KIWAY_PLAYER*>( frame );
}
@ -403,7 +411,7 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow
// were passed to KIFACE::OnKifaceStart()
);
m_playerFrameName[aFrameType] = frame->GetName();
m_playerFrameId[aFrameType].store( frame->GetId() );
return frame;
}
catch( const IO_ERROR& ioe )

View File

@ -95,6 +95,8 @@
*/
#include <atomic>
#include <wx/defs.h>
#include <wx/event.h>
#include <import_export.h>
#include <search_stack.h>
@ -424,13 +426,13 @@ private:
wxFrame* m_top; // Usually m_top is the Project manager
// a string array ( size KIWAY_PLAYER_COUNT ) to Store the frame name
// of PLAYER frames which were run.
// An array to store the window ID of PLAYER frames which were run.
// A non empty name means only a PLAYER was run at least one time.
// It can be closed. Call :
// wxWindow::FindWindowByName( m_playerFrameName[aFrameType] )
// Empty entries are represented by wxID_NONE.
// They can be closed, and the stored window ID may be invalid.
// Call: wxWindow::FindWindowById( m_playerFrameId[aFrameType] )
// to know if still exists (or GetPlayerFrame( FRAME_T aFrameType )
wxArrayString m_playerFrameName;
std::atomic<wxWindowID> m_playerFrameId[KIWAY_PLAYER_COUNT];
};