mirror of https://github.com/PCSX2/pcsx2.git
wxgui: Optimizations and improvements to the console logger's threading model.
git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1535 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
539a35fe80
commit
ccdb5d84b9
|
@ -29,6 +29,9 @@ namespace Threading
|
|||
///////////////////////////////////////////////////////////////
|
||||
// Define some useful object handles - wait events, mutexes.
|
||||
|
||||
// pthread Cond is an evil api that is not suited for Pcsx2 needs.
|
||||
// Let's not use it. Use mutexes and semaphores instead to create waits. (Air)
|
||||
#if 0
|
||||
struct WaitEvent
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
|
@ -40,6 +43,7 @@ namespace Threading
|
|||
void Set();
|
||||
void Wait();
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Semaphore
|
||||
{
|
||||
|
|
|
@ -49,37 +49,19 @@ namespace Console
|
|||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall WriteLn( const char* fmt )
|
||||
{
|
||||
Write( fmt );
|
||||
Newline();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall WriteLn( Colors color, const char* fmt )
|
||||
{
|
||||
SetColor( color );
|
||||
Write( fmt );
|
||||
Newline();
|
||||
WriteLn( fmt );
|
||||
ClearColor();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall WriteLn( const wxString& fmt )
|
||||
{
|
||||
Write( fmt );
|
||||
Newline();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall WriteLn( Colors color, const wxString& fmt )
|
||||
{
|
||||
SetColor( color );
|
||||
Write( fmt );
|
||||
Newline();
|
||||
WriteLn( fmt );
|
||||
ClearColor();
|
||||
return false;
|
||||
}
|
||||
|
@ -94,8 +76,10 @@ namespace Console
|
|||
|
||||
__forceinline void __fastcall _WriteLn( const char* fmt, va_list args )
|
||||
{
|
||||
_Write( fmt, args );
|
||||
Newline();
|
||||
ScopedLock locker( m_writelock );
|
||||
vssprintf( m_format_buffer, fmt, args );
|
||||
m_format_buffer += "\n";
|
||||
Write( m_format_buffer.c_str() );
|
||||
}
|
||||
|
||||
__forceinline void __fastcall _WriteLn( Colors color, const char* fmt, va_list args )
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include "System.h"
|
||||
|
||||
using namespace Threading;
|
||||
|
||||
class MainEmuFrame;
|
||||
class IniInterface;
|
||||
|
||||
|
@ -32,7 +34,7 @@ extern wxFileHistory* g_RecentIsoList;
|
|||
|
||||
class LogWriteEvent;
|
||||
|
||||
DECLARE_EVENT_TYPE(wxEVT_DockConsole, -1)
|
||||
DECLARE_EVENT_TYPE(wxEVT_DockConsole, -1);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -66,7 +68,15 @@ public:
|
|||
ConsoleLogFrame(MainEmuFrame *pParent, const wxString& szTitle);
|
||||
virtual ~ConsoleLogFrame();
|
||||
|
||||
virtual void OnCloseWindow(wxCloseEvent& event);
|
||||
virtual void Write( const wxString& text );
|
||||
virtual void SetColor( Console::Colors color );
|
||||
virtual void ClearColor();
|
||||
virtual void DockedMove();
|
||||
|
||||
void Write( Console::Colors color, const wxString& text );
|
||||
void Newline();
|
||||
void CountMessage();
|
||||
void DoMessage();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -75,6 +85,7 @@ protected:
|
|||
virtual void OnClose(wxMenuEvent& event);
|
||||
virtual void OnSave (wxMenuEvent& event);
|
||||
virtual void OnClear(wxMenuEvent& event);
|
||||
virtual void OnCloseWindow(wxCloseEvent& event);
|
||||
|
||||
void OnWrite( wxCommandEvent& event );
|
||||
void OnNewline( wxCommandEvent& event );
|
||||
|
@ -86,10 +97,6 @@ protected:
|
|||
|
||||
void OnMoveAround( wxMoveEvent& evt );
|
||||
void OnResize( wxSizeEvent& evt );
|
||||
|
||||
virtual void Write( const wxString& text );
|
||||
void SetColor( Console::Colors color );
|
||||
void ClearColor();
|
||||
};
|
||||
|
||||
|
||||
|
@ -173,6 +180,22 @@ public:
|
|||
return *m_MainFrame;
|
||||
}
|
||||
|
||||
ConsoleLogFrame* GetProgramLog()
|
||||
{
|
||||
return m_ProgramLogBox;
|
||||
}
|
||||
|
||||
ConsoleLogFrame* GetConsoleLog()
|
||||
{
|
||||
return m_Ps2ConLogBox;
|
||||
}
|
||||
|
||||
void ProgramLog_CountMsg()
|
||||
{
|
||||
if( m_ProgramLogBox == NULL ) return;
|
||||
m_ProgramLogBox->CountMessage();
|
||||
}
|
||||
|
||||
void ProgramLog_PostEvent( wxEvent& evt )
|
||||
{
|
||||
if( m_ProgramLogBox == NULL ) return;
|
||||
|
|
|
@ -90,16 +90,20 @@ ConsoleLogFrame::ColorArray::ColorArray() :
|
|||
m_table( 8 )
|
||||
{
|
||||
// Standard R, G, B format:
|
||||
new (&m_table[Color_Black]) wxTextAttr( wxColor( 0, 0, 0 ) );
|
||||
new (&m_table[Color_Red]) wxTextAttr( wxColor( 128, 0, 0 ) );
|
||||
new (&m_table[Color_Green]) wxTextAttr( wxColor( 0, 128, 0 ) );
|
||||
new (&m_table[Color_Blue]) wxTextAttr( wxColor( 0, 0, 128 ) );
|
||||
new (&m_table[Color_Yellow])wxTextAttr( wxColor( 180, 180, 0 ) );
|
||||
new (&m_table[Color_Cyan]) wxTextAttr( wxColor( 0, 160, 160 ) );
|
||||
new (&m_table[Color_Magenta])wxTextAttr( wxColor( 160, 0, 160 ) );
|
||||
new (&m_table[Color_White]) wxTextAttr( wxColor( 160, 160, 160 ) );
|
||||
new (&m_table[Color_Black]) wxTextAttr( wxColor( 0, 0, 0 ) );
|
||||
new (&m_table[Color_Red]) wxTextAttr( wxColor( 128, 0, 0 ) );
|
||||
new (&m_table[Color_Green]) wxTextAttr( wxColor( 0, 128, 0 ) );
|
||||
new (&m_table[Color_Blue]) wxTextAttr( wxColor( 0, 0, 128 ) );
|
||||
new (&m_table[Color_Yellow]) wxTextAttr( wxColor( 180, 180, 0 ) );
|
||||
new (&m_table[Color_Cyan]) wxTextAttr( wxColor( 0, 160, 160 ) );
|
||||
new (&m_table[Color_Magenta]) wxTextAttr( wxColor( 160, 0, 160 ) );
|
||||
new (&m_table[Color_White]) wxTextAttr( wxColor( 160, 160, 160 ) );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Threading: this function may employ the use of GDI objects in Win32, which means it's
|
||||
// not safe to be clled from anything but the main gUI thread.
|
||||
//
|
||||
void ConsoleLogFrame::ColorArray::SetFont( const wxFont& font )
|
||||
{
|
||||
for( int i=0; i<8; ++i )
|
||||
|
@ -170,7 +174,7 @@ void ConsoleLogFrame::OnMoveAround( wxMoveEvent& evt )
|
|||
wxRect snapzone( topright - wxSize( 8,8 ), wxSize( 16,16 ) );
|
||||
|
||||
g_Conf->ConLogBox.AutoDock = snapzone.Contains( GetPosition() );
|
||||
Console::WriteLn( "DockCheck: %d", params g_Conf->ConLogBox.AutoDock );
|
||||
//Console::WriteLn( "DockCheck: %d", params g_Conf->ConLogBox.AutoDock );
|
||||
if( g_Conf->ConLogBox.AutoDock )
|
||||
{
|
||||
SetPosition( topright + wxSize( 1,0 ) );
|
||||
|
@ -246,27 +250,26 @@ void ConsoleLogFrame::OnClear(wxMenuEvent& WXUNUSED(event))
|
|||
|
||||
void ConsoleLogFrame::SetColor( Colors color )
|
||||
{
|
||||
m_TextCtrl.SetDefaultStyle( m_ColorTable[color] );
|
||||
if( color != m_curcolor )
|
||||
m_TextCtrl.SetDefaultStyle( m_ColorTable[m_curcolor=color] );
|
||||
}
|
||||
|
||||
void ConsoleLogFrame::ClearColor()
|
||||
{
|
||||
m_curcolor = Color_Black;
|
||||
m_TextCtrl.SetDefaultStyle( m_ColorTable.Default() );
|
||||
}
|
||||
|
||||
void ConsoleLogFrame::OnWrite( wxCommandEvent& event )
|
||||
{
|
||||
Colors color = (Colors)event.GetExtraLong();
|
||||
|
||||
if( color != m_curcolor )
|
||||
m_TextCtrl.SetDefaultStyle( m_ColorTable[m_curcolor=color] );
|
||||
|
||||
Write( event.GetString() );
|
||||
Write( (Colors)event.GetExtraLong(), event.GetString() );
|
||||
DoMessage();
|
||||
}
|
||||
|
||||
void ConsoleLogFrame::OnNewline( wxCommandEvent& event )
|
||||
{
|
||||
Write( L"\n" );
|
||||
Newline();
|
||||
DoMessage();
|
||||
}
|
||||
|
||||
void ConsoleLogFrame::OnSetTitle( wxCommandEvent& event )
|
||||
|
@ -276,7 +279,11 @@ void ConsoleLogFrame::OnSetTitle( wxCommandEvent& event )
|
|||
|
||||
void ConsoleLogFrame::OnDockedMove( wxCommandEvent& event )
|
||||
{
|
||||
Console::Error( "Dock Message: %d, %d", params g_Conf->ConLogBox.DisplayPosition.x, g_Conf->ConLogBox.DisplayPosition.y );
|
||||
DockedMove();
|
||||
}
|
||||
|
||||
void ConsoleLogFrame::DockedMove()
|
||||
{
|
||||
if( g_Conf != NULL )
|
||||
SetPosition( g_Conf->ConLogBox.DisplayPosition );
|
||||
}
|
||||
|
@ -284,21 +291,85 @@ void ConsoleLogFrame::OnDockedMove( wxCommandEvent& event )
|
|||
void ConsoleLogFrame::Write( const wxString& text )
|
||||
{
|
||||
// remove selection (WriteText is in fact ReplaceSelection)
|
||||
|
||||
#ifdef __WXMSW__
|
||||
wxTextPos nLen = m_TextCtrl.GetLastPosition();
|
||||
m_TextCtrl.SetSelection(nLen, nLen);
|
||||
#endif
|
||||
|
||||
m_TextCtrl.AppendText( text );
|
||||
|
||||
// cap at 256k for now:
|
||||
if( m_TextCtrl.GetLastPosition() > 0x40000 )
|
||||
{
|
||||
m_TextCtrl.AppendText( L"************************ REMOVING BUFFER CRAP *****************\n" );
|
||||
m_TextCtrl.Remove( 0, 0x8000 );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation note: Calls SetColor and Write( text ). Override those virtuals
|
||||
// and this one will magically follow suite. :)
|
||||
void ConsoleLogFrame::Write( Colors color, const wxString& text )
|
||||
{
|
||||
SetColor( color );
|
||||
Write( text );
|
||||
}
|
||||
|
||||
void ConsoleLogFrame::Newline()
|
||||
{
|
||||
Write( L"\n" );
|
||||
}
|
||||
|
||||
static volatile long counter = 0;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Deadlock protection: High volume logs will over-tax our message pump and cause the
|
||||
// GUI to become inaccessible. The cool solution would be a threaded log window, but wx
|
||||
// is entirely un-safe for that kind of threading. So instead I use a message counter
|
||||
// that stalls non-GUI threads when they attempt to over-tax an already burdened log.
|
||||
// If too many messages get queued up, non-gui threads are stalled to allow the gui to
|
||||
// catch up.
|
||||
void ConsoleLogFrame::CountMessage()
|
||||
{
|
||||
_InterlockedIncrement( &counter );
|
||||
|
||||
if( counter > 0x10 ) // 0x10 -- arbitrary value that seems to work well on my C2Q 3.2ghz
|
||||
{
|
||||
if( !wxThread::IsMain() )
|
||||
{
|
||||
// fixme : It'd be swell if this could be replaced with something that uses
|
||||
// pthreads semaphores instead of Sleep, but I haven't been able to conjure up
|
||||
// such an alternative yet.
|
||||
|
||||
while( counter > 1 ) { Sleep(1); }
|
||||
Sleep(1); // give the main thread more time to catch up. :|
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ConsoleLogFrame::DoMessage()
|
||||
{
|
||||
int cur = _InterlockedDecrement( &counter );
|
||||
if( m_TextCtrl.IsFrozen() )
|
||||
{
|
||||
if( cur <= 1 && wxThread::IsMain() )
|
||||
m_TextCtrl.Thaw();
|
||||
}
|
||||
else if( cur >= 4 && wxThread::IsMain() )
|
||||
{
|
||||
m_TextCtrl.Freeze();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
namespace Console
|
||||
{
|
||||
// thread-local console color storage.
|
||||
__threadlocal Colors th_CurrentColor = Color_Black;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void __fastcall SetTitle( const wxString& title )
|
||||
{
|
||||
wxCommandEvent evt( wxEVT_SetTitleText );
|
||||
|
@ -306,36 +377,35 @@ namespace Console
|
|||
wxGetApp().ProgramLog_PostEvent( evt );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void __fastcall SetColor( Colors color )
|
||||
{
|
||||
th_CurrentColor = color;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ClearColor()
|
||||
{
|
||||
th_CurrentColor = Color_Black;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Newline()
|
||||
{
|
||||
if( emuLog != NULL )
|
||||
fputs( "\n", emuLog );
|
||||
|
||||
wxGetApp().ProgramLog_CountMsg();
|
||||
wxCommandEvent evt( wxEVT_LOG_Newline );
|
||||
wxGetApp().ProgramLog_PostEvent( evt );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall Write( const char* fmt )
|
||||
{
|
||||
if( emuLog != NULL )
|
||||
fputs( fmt, emuLog );
|
||||
|
||||
wxGetApp().ProgramLog_CountMsg();
|
||||
|
||||
wxCommandEvent evt( wxEVT_LOG_Write );
|
||||
evt.SetString( wxString::FromAscii( fmt ) );
|
||||
evt.SetExtraLong( th_CurrentColor );
|
||||
|
@ -344,12 +414,13 @@ namespace Console
|
|||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall Write( const wxString& fmt )
|
||||
{
|
||||
if( emuLog != NULL )
|
||||
fputs( fmt.ToAscii().data(), emuLog );
|
||||
|
||||
wxGetApp().ProgramLog_CountMsg();
|
||||
|
||||
wxCommandEvent evt( wxEVT_LOG_Write );
|
||||
evt.SetString( fmt );
|
||||
evt.SetExtraLong( th_CurrentColor );
|
||||
|
@ -357,6 +428,48 @@ namespace Console
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall WriteLn( const char* fmt )
|
||||
{
|
||||
// Implementation note: I've duplicated Write+Newline behavior here to avoid polluting
|
||||
// the message pump with lots of erroneous messages (Newlines can be bound into Write message).
|
||||
|
||||
if( emuLog != NULL )
|
||||
{
|
||||
fputs( fmt, emuLog );
|
||||
fputs( "\n", emuLog );
|
||||
}
|
||||
|
||||
wxGetApp().ProgramLog_CountMsg();
|
||||
|
||||
wxCommandEvent evt( wxEVT_LOG_Write );
|
||||
evt.SetString( wxString::FromAscii( fmt ) + L"\n" );
|
||||
evt.SetExtraLong( th_CurrentColor );
|
||||
wxGetApp().ProgramLog_PostEvent( evt );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall WriteLn( const wxString& fmt )
|
||||
{
|
||||
// Implementation note: I've duplicated Write+Newline behavior here to avoid polluting
|
||||
// the message pump with lots of erroneous messages (Newlines can be bound into Write message).
|
||||
|
||||
if( emuLog != NULL )
|
||||
{
|
||||
fputs( fmt.ToAscii().data(), emuLog );
|
||||
fputs( "\n", emuLog );
|
||||
}
|
||||
|
||||
wxGetApp().ProgramLog_CountMsg();
|
||||
|
||||
wxCommandEvent evt( wxEVT_LOG_Write );
|
||||
evt.SetString( fmt + L"\n" );
|
||||
evt.SetExtraLong( th_CurrentColor );
|
||||
wxGetApp().ProgramLog_PostEvent( evt );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Msgbox
|
||||
|
|
|
@ -78,44 +78,6 @@ wxMenu* MainEmuFrame::MakeIsoMenu()
|
|||
wxMenu* mnuIso = new wxMenu();
|
||||
|
||||
mnuIso->Append( Menu_IsoBrowse, _("Browse..."), _("Select an Iso image from your hard drive.") );
|
||||
//mnuIso->AppendSeparator();
|
||||
|
||||
// Add in the recent files!
|
||||
|
||||
/*const StringListNode* cruise = g_Conf->RecentIsos;
|
||||
|
||||
int i = 0;
|
||||
int threshold = 15;
|
||||
while( cruise != NULL && (--threshold >= 0) )
|
||||
{
|
||||
wxString ellipsized;
|
||||
|
||||
if( cruise->item->Length() > 64 )
|
||||
{
|
||||
// Ellipsize it!
|
||||
wxFileName src( *cruise->item );
|
||||
ellipsized = src.GetVolume() + wxFileName::GetVolumeSeparator() + wxFileName::GetPathSeparator() + L"...";
|
||||
|
||||
const wxArrayString& dirs( src.GetDirs() );
|
||||
int totalLen = ellipsized.Length();
|
||||
int i=dirs.Count()-1;
|
||||
|
||||
for( ; i; --i )
|
||||
{
|
||||
if( totalLen + dirs[i].Length() < 56 )
|
||||
totalLen += dirs[i];
|
||||
}
|
||||
|
||||
for( ; i<dirs.Count(); ++i )
|
||||
ellipsized += wxFileName::GetPathSeparator() + dirs[i];
|
||||
|
||||
ellipsized += wxFileName::GetPathSeparator() + src.GetFullName();
|
||||
}
|
||||
else
|
||||
ellipsized = *cruise->item;
|
||||
|
||||
mnuIso->Append( Menu_Iso_Recent+i, Path::GetFilename( ellipsized ), *cruise->item );
|
||||
}*/
|
||||
|
||||
if( g_RecentIsoList != NULL )
|
||||
{
|
||||
|
@ -180,16 +142,21 @@ void MainEmuFrame::OnMoveAround( wxMoveEvent& evt )
|
|||
|
||||
static wxPoint lastpos( wxDefaultCoord, wxDefaultCoord );
|
||||
|
||||
Console::Status( "Mess o' crashiness? It can't be!" );
|
||||
|
||||
if( lastpos == evt.GetPosition() ) return;
|
||||
lastpos = evt.GetPosition();
|
||||
if( g_Conf->ConLogBox.AutoDock )
|
||||
{
|
||||
g_Conf->ConLogBox.DisplayPosition = GetRect().GetTopRight();
|
||||
//if( ConsoleLogFrame* frame = wxGetApp().GetProgramLog() )
|
||||
// frame->DockedMove();
|
||||
|
||||
wxCommandEvent conevt( wxEVT_DockConsole );
|
||||
wxGetApp().ProgramLog_PostEvent( conevt );
|
||||
}
|
||||
|
||||
Console::Error( "XWindows Messages Suck: %d, %d", params GetPosition().x, GetPosition().y );
|
||||
//Console::Error( "XWindows Messages Suck: %d, %d", params GetPosition().x, GetPosition().y );
|
||||
g_Conf->MainGuiPosition = evt.GetPosition();
|
||||
|
||||
//evt.Skip();
|
||||
|
|
|
@ -126,6 +126,26 @@ bool Pcsx2App::OnCmdLineParsed(wxCmdLineParser& parser)
|
|||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ConsoleThreadTest -- useful class for unit testing the thread safety and general performance
|
||||
// of the console logger.
|
||||
#if 0
|
||||
class ConsoleTestThread : public Thread
|
||||
{
|
||||
int Callback()
|
||||
{
|
||||
static int numtrack = 0;
|
||||
|
||||
while( true )
|
||||
{
|
||||
Console::WriteLn( wxsFormat( L"This is a threaded logging test. Something bad could happen... %d", ++numtrack ) );
|
||||
Sleep( 0 );
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Pcsx2App::OnInit()
|
||||
{
|
||||
wxInitAllImageHandlers();
|
||||
|
@ -170,6 +190,8 @@ bool Pcsx2App::OnInit()
|
|||
SetExitOnFrameDelete( true );
|
||||
m_MainFrame->Show();
|
||||
|
||||
//ConsoleTestThread* woo = new ConsoleTestThread();
|
||||
//woo->Start();
|
||||
|
||||
// Check to see if the user needs to perform initial setup:
|
||||
|
||||
|
|
|
@ -618,6 +618,6 @@ Global
|
|||
{4639972E-424E-4E13-8B07-CA403C481346} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
AMDCaProjectFile = C:\pcsx2dev\pcsx2\CodeAnalyst\pcsx2_suite_2008.caw
|
||||
AMDCaProjectFile = E:\devpcsx2\fail\wx\CodeAnalyst\pcsx2_suite_2008.caw
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
Loading…
Reference in New Issue