From f8e76834278bc87aa3b41f35c890adc287e2d13e Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Sat, 9 Jan 2010 01:42:46 +0000 Subject: [PATCH] MGR: Separate refresh of Event Log from refresh of tabs; Update Notices tab only when data changed; Clean up some async RPC logic svn path=/trunk/boinc/; revision=20110 --- checkin_notes | 15 +++++++- clientgui/AdvancedFrame.cpp | 9 +---- clientgui/AsyncRPC.cpp | 9 +++-- clientgui/AsyncRPC.h | 10 ++---- clientgui/DlgEventLog.cpp | 5 ++- clientgui/DlgEventLog.h | 4 +-- clientgui/MainDocument.cpp | 61 +++++++++++++++++---------------- clientgui/MainDocument.h | 1 - clientgui/ViewNotifications.cpp | 53 +++++++++++++++------------- clientgui/ViewNotifications.h | 1 + clientgui/sg_BoincSimpleGUI.cpp | 12 ++----- 11 files changed, 91 insertions(+), 89 deletions(-) diff --git a/checkin_notes b/checkin_notes index 38bbf45cd3..1c69f8249e 100644 --- a/checkin_notes +++ b/checkin_notes @@ -209,9 +209,22 @@ Rom 7 Jan 2010 clientgui/ ViewNotifications.cpp -Charlie 6 Jan 2010 +Charlie 8 Jan 2010 - client: Fix another crash bug due to calling memset(this, 0, sizeof(*this)) when the data contains a std::string. client/ cs_notice.cpp + +Charlie 8 Jan 2010 + - MGR: Separate refresh of Event Log from refresh of tabs. + - MGR: Update Notices tab only when data has changed. + - MGR: Clean up some async RPC logic. + + clientgui/ + AdvancedFrame.cpp + AsyncRPC.cpp, .h + DlgEventLog.cpp, .h + MainDocument.cpp, .h + sg_BoincSimpleGUI.cpp + ViewNotifications.cpp, .h diff --git a/clientgui/AdvancedFrame.cpp b/clientgui/AdvancedFrame.cpp index 6ea39abf2e..b89e5d9783 100644 --- a/clientgui/AdvancedFrame.cpp +++ b/clientgui/AdvancedFrame.cpp @@ -985,7 +985,6 @@ int CAdvancedFrame::_GetCurrentViewPage() { wxWindow* pwndNotebookPage = NULL; CBOINCBaseView* pView = NULL; - int vw_msg = wxGetApp().GetEventLog() ? VW_MSGS : 0; wxASSERT(m_pNotebook); @@ -995,7 +994,7 @@ int CAdvancedFrame::_GetCurrentViewPage() { pView = wxDynamicCast(pwndNotebookPage, CBOINCBaseView); wxASSERT(pView); - return pView->GetViewCurrentViewPage() | vw_msg; + return pView->GetViewCurrentViewPage(); } @@ -1634,7 +1633,6 @@ void CAdvancedFrame::OnRefreshView(CFrameEvent& WXUNUSED(event)) { wxWindow* pwndNotebookPage = NULL; CBOINCBaseView* pView = NULL; wxTimerEvent timerEvent; - CDlgEventLog* eventLog; wxASSERT(m_pNotebook); @@ -1645,11 +1643,6 @@ void CAdvancedFrame::OnRefreshView(CFrameEvent& WXUNUSED(event)) { wxASSERT(pView); pView->FireOnListRender(timerEvent); - - eventLog = wxGetApp().GetEventLog(); - if (eventLog) { - eventLog->OnRefresh(timerEvent); - } } wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::OnRefreshView - Function End")); diff --git a/clientgui/AsyncRPC.cpp b/clientgui/AsyncRPC.cpp index 4a4e9b0d4f..c348b6bfcc 100755 --- a/clientgui/AsyncRPC.cpp +++ b/clientgui/AsyncRPC.cpp @@ -32,6 +32,7 @@ #include "BOINCTaskBar.h" #include "error_numbers.h" #include "SkinManager.h" +#include "DlgEventLog.h" #include "util.h" extern bool s_bSkipExitConfirmation; @@ -1140,9 +1141,11 @@ void CMainDocument::HandleCompletedRPC() { } #endif - // CachedMessageUpdate() does not do any RPCs, so it is safe here - if (current_rpc_request.rpcType == RPC_TYPE_ASYNC_WITH_UPDATE_MESSAGE_LIST_AFTER) { - CachedMessageUpdate(); + if (current_rpc_request.rpcType == RPC_TYPE_ASYNC_WITH_REFRESH_EVENT_LOG_AFTER) { + CDlgEventLog* eventLog = wxGetApp().GetEventLog(); + if (eventLog) { + eventLog->OnRefresh(); + } } current_rpc_request.clear(); diff --git a/clientgui/AsyncRPC.h b/clientgui/AsyncRPC.h index e829259196..385302e5e5 100644 --- a/clientgui/AsyncRPC.h +++ b/clientgui/AsyncRPC.h @@ -148,17 +148,13 @@ enum ASYNC_RPC_TYPE { // Periodic RPC as above, but on completion also process a // wxEVT_FRAME_REFRESHVIEW event to refresh the display. RPC_TYPE_ASYNC_WITH_REFRESH_AFTER, - // Periodic RPC as above, but on completion also update message - // list by calling CMainDocument::CachedMessageUpdate(). - RPC_TYPE_ASYNC_WITH_UPDATE_MESSAGE_LIST_AFTER, - // Periodic RPC as above, but on completion also update notice - // list by calling CMainDocument::CachedNoticeUpdate(). - RPC_TYPE_ASYNC_WITH_UPDATE_NOTICES_LIST_AFTER, + // Periodic RPC as above, but on completion also process a + // wxEVT_FRAME_REFRESHVIEW event to refresh the display. + RPC_TYPE_ASYNC_WITH_REFRESH_EVENT_LOG_AFTER, // Periodic RPC as above, but on completion also process a // wxEVT_TASKBAR_REFRESH event to refresh the taskbar icon. RPC_TYPE_ASYNC_WITH_UPDATE_TASKBAR_ICON_AFTER, NUM_RPC_TYPES - }; // Pass the following structure to CMainDocument::RequestRPC() diff --git a/clientgui/DlgEventLog.cpp b/clientgui/DlgEventLog.cpp index 50f08349d8..a92c0f8fa6 100644 --- a/clientgui/DlgEventLog.cpp +++ b/clientgui/DlgEventLog.cpp @@ -295,10 +295,9 @@ void CDlgEventLog::OnClose(wxCloseEvent& WXUNUSED(event)) { /*! - * called from CAdvancedFrame::OnRefreshView() + * called from CMainDocument::HandleCompletedRPC() after wxEVT_RPC_FINISHED event */ - -void CDlgEventLog::OnRefresh( wxTimerEvent& WXUNUSED(event) ) { +void CDlgEventLog::OnRefresh() { bool isConnected; static bool was_connected = false; diff --git a/clientgui/DlgEventLog.h b/clientgui/DlgEventLog.h index 5eb9c60092..e20627f9bb 100644 --- a/clientgui/DlgEventLog.h +++ b/clientgui/DlgEventLog.h @@ -103,8 +103,8 @@ public: /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_SIMPLE_HELP void OnButtonHelp( wxCommandEvent& event ); - /// wxEVT_TIMER event handler for ID_DLGEVENTLOG - void OnRefresh( wxTimerEvent& event ); + /// called from CMainDocument::HandleCompletedRPC() after wxEVT_RPC_FINISHED event + void OnRefresh(); ////@end CDlgEventLog event handler declarations ////@begin CDlgEventLog member function declarations diff --git a/clientgui/MainDocument.cpp b/clientgui/MainDocument.cpp index f57ffdabca..728e3fc15d 100644 --- a/clientgui/MainDocument.cpp +++ b/clientgui/MainDocument.cpp @@ -878,39 +878,40 @@ void CMainDocument::RunPeriodicRPCs() { // *********** RPC_GET_NOTICES ************** - request.clear(); - request.which_rpc = RPC_GET_NOTICES; - // m_iMessageSequenceNumber could change between request and execution - // of RPC, so pass in a pointer rather than its value - request.arg1 = &m_iNoticeSequenceNumber; - request.arg2 = ¬ices; - request.rpcType = (currentTabView & VW_NOTIF) ? - RPC_TYPE_ASYNC_WITH_REFRESH_AFTER : RPC_TYPE_ASYNC_WITH_UPDATE_NOTICES_LIST_AFTER; - request.completionTime = NULL; - request.resultPtr = &m_iGet_notices_rpc_result; - - RequestRPC(request); - + if (currentTabView & VW_NOTIF) { + request.clear(); + request.which_rpc = RPC_GET_NOTICES; + // m_iNoticeSequenceNumber could change between request and execution + // of RPC, so pass in a pointer rather than its value + request.arg1 = &m_iNoticeSequenceNumber; + request.arg2 = ¬ices; + request.rpcType = RPC_TYPE_ASYNC_WITH_REFRESH_AFTER; + request.completionTime = NULL; + request.resultPtr = &m_iGet_notices_rpc_result; + + RequestRPC(request); + } + // *********** RPC_GET_MESSAGES ************** - request.clear(); - request.which_rpc = RPC_GET_MESSAGES; - // m_iMessageSequenceNumber could change between request and execution - // of RPC, so pass in a pointer rather than its value - request.arg1 = &m_iMessageSequenceNumber; - request.arg2 = &messages; -// request.arg2 = &async_messages_buf; -// request.exchangeBuf = &messages; - request.rpcType = (currentTabView & VW_MSGS) ? - RPC_TYPE_ASYNC_WITH_REFRESH_AFTER : RPC_TYPE_ASYNC_WITH_UPDATE_MESSAGE_LIST_AFTER; - request.completionTime = NULL; - request.resultPtr = &m_iGet_messages_rpc_result; - - RequestRPC(request); - - ts = dtNow - m_dtCachedStateTimestamp; - if (ts.GetSeconds() >= STATERPC_INTERVAL) { + if ((currentTabView & VW_SMSG) || wxGetApp().GetEventLog()) { + request.clear(); + request.which_rpc = RPC_GET_MESSAGES; + // m_iMessageSequenceNumber could change between request and execution + // of RPC, so pass in a pointer rather than its value + request.arg1 = &m_iMessageSequenceNumber; + request.arg2 = &messages; + // request.arg2 = &async_messages_buf; + // request.exchangeBuf = &messages; + request.rpcType = RPC_TYPE_ASYNC_WITH_REFRESH_EVENT_LOG_AFTER; + request.completionTime = NULL; + request.resultPtr = &m_iGet_messages_rpc_result; + + RequestRPC(request); + ts = dtNow - m_dtCachedStateTimestamp; + if (ts.GetSeconds() >= STATERPC_INTERVAL) { + } // *********** RPC_GET_STATE ************** request.clear(); diff --git a/clientgui/MainDocument.h b/clientgui/MainDocument.h index 49dbaf0297..05741e9db1 100644 --- a/clientgui/MainDocument.h +++ b/clientgui/MainDocument.h @@ -48,7 +48,6 @@ typedef struct { #define VW_XFER 4 #define VW_STAT 8 #define VW_DISK 16 -#define VW_MSGS 32 #define VW_NOTIF 128 #define VW_SGUI 256 #define VW_SMSG 2048 diff --git a/clientgui/ViewNotifications.cpp b/clientgui/ViewNotifications.cpp index 48fb9edc70..429caba22c 100644 --- a/clientgui/ViewNotifications.cpp +++ b/clientgui/ViewNotifications.cpp @@ -71,6 +71,8 @@ CViewNotifications::CViewNotifications(wxNotebook* pNotebook) : Layout(); + m_iOldNoticeCount = 0; + pGroup = new CTaskItemGroup( _("News Feeds") ); m_TaskGroups.push_back( pGroup ); @@ -153,37 +155,40 @@ void CViewNotifications::OnListRender( wxTimerEvent& WXUNUSED(event) ) { if (n == -1) { strItems += _("Retrieving notices..."); } else { + // Update display only if there is something new + if (n != m_iOldNoticeCount) { + m_iOldNoticeCount = n; + + // Pre-allocate buffer size so string concat is much faster + strItems.Alloc(4096*n); - // Pre-allocate buffer size so string concat is much faster - strItems.Alloc(4096*n); - - for (i = 0; i < (unsigned int)n; i++) { - NOTICE* np = pDoc->notice(i); - if (!np) continue; - char tbuf[512]; - if (strlen(np->title)) { - sprintf(tbuf, "%s
", np->title); - strItems += wxString(tbuf, wxConvUTF8); + for (i = 0; i < (unsigned int)n; i++) { + NOTICE* np = pDoc->notice(i); + if (!np) continue; + char tbuf[512]; + if (strlen(np->title)) { + sprintf(tbuf, "%s
", np->title); + strItems += wxString(tbuf, wxConvUTF8); + } + strItems += wxString(np->description.c_str(), wxConvUTF8); + strItems += wxT("
"); + dtBuffer.Set((time_t)np->arrival_time); + strItems += dtBuffer.Format(); + strItems += wxT("
\n"); } - strItems += wxString(np->description.c_str(), wxConvUTF8); - strItems += wxT("
"); - dtBuffer.Set((time_t)np->arrival_time); - strItems += dtBuffer.Format(); - strItems += wxT("
\n"); + + strHTML = wxT("\n\n"); + strHTML += strItems; + strHTML += wxT("
\n"); + strHTML += wxT("\n\n"); + m_pHtmlPane->SetFonts(wxT("Sans Serif"), wxT("Courier"), 0); + m_pHtmlPane->SetPage( strHTML ); } } - - strHTML = wxT("\n\n"); - strHTML += strItems; - //strHTML += wxT("
\n"); - strHTML += wxT("\n\n"); - m_pHtmlPane->SetFonts(wxT("Sans Serif"), wxT("Courier"), 0); - m_pHtmlPane->SetPage( strHTML ); - + s_bInProgress = false; } wxLogTrace(wxT("Function Start/End"), wxT("CViewNotifications::OnListRender - Function End")); } - diff --git a/clientgui/ViewNotifications.h b/clientgui/ViewNotifications.h index 2b60690989..a2026a2ae1 100644 --- a/clientgui/ViewNotifications.h +++ b/clientgui/ViewNotifications.h @@ -43,6 +43,7 @@ public: protected: wxHtmlWindow* m_pHtmlPane; + int m_iOldNoticeCount; virtual bool OnSaveState( wxConfigBase* pConfig ); virtual bool OnRestoreState( wxConfigBase* pConfig ); diff --git a/clientgui/sg_BoincSimpleGUI.cpp b/clientgui/sg_BoincSimpleGUI.cpp index ee7141d161..912537fbfa 100644 --- a/clientgui/sg_BoincSimpleGUI.cpp +++ b/clientgui/sg_BoincSimpleGUI.cpp @@ -251,12 +251,10 @@ bool CSimpleFrame::SaveState() { int CSimpleFrame::_GetCurrentViewPage() { - int vw_msg = wxGetApp().GetEventLog() ? VW_MSGS : 0; - if (isMessagesDlgOpen()) { - return VW_SGUI | VW_SMSG | vw_msg; + return VW_SGUI | VW_SMSG; } else { - return VW_SGUI | vw_msg; + return VW_SGUI; } return 0; // Should never happen. } @@ -324,7 +322,6 @@ void CSimpleFrame::OnRefreshView(CFrameEvent& WXUNUSED(event)) { wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnRefreshView - Function Start")); static bool bAlreadyRunning = false; - CDlgEventLog* eventLog; wxTimerEvent timerEvent; if (bAlreadyRunning) return; @@ -336,11 +333,6 @@ void CSimpleFrame::OnRefreshView(CFrameEvent& WXUNUSED(event)) { dlgMsgsPtr->OnRefresh(); } - eventLog = wxGetApp().GetEventLog(); - if (eventLog) { - eventLog->OnRefresh(timerEvent); - } - bAlreadyRunning = false; wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnRefreshView - Function End"));