MainFrame: replace the timer with a file watcher.

This will lead to less UI flickering and faster response times.
This commit is contained in:
Guillaume Jacquemin 2020-01-10 00:01:24 +01:00
parent 6471a9dd93
commit 83008d3b01
5 changed files with 40 additions and 26 deletions

View file

@ -28,6 +28,7 @@
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
#include <Corrade/Utility/Directory.h> #include <Corrade/Utility/Directory.h>
#include <Corrade/Utility/FormatStl.h> #include <Corrade/Utility/FormatStl.h>
#include <Corrade/Utility/String.h>
#include <Corrade/Utility/Unicode.h> #include <Corrade/Utility/Unicode.h>
#include "EvtMainFrame.h" #include "EvtMainFrame.h"
@ -55,6 +56,10 @@ EvtMainFrame::EvtMainFrame(wxWindow* parent): MainFrame(parent) {
"Please avoid using this application while the game is running. Bad Things™ could happen to your data.\n\n" "Please avoid using this application while the game is running. Bad Things™ could happen to your data.\n\n"
"DISCLAIMER: The developer of this application cannot be held responsible for data loss or corruption. PLEASE USE AT YOUR OWN RISK!\n\n" "DISCLAIMER: The developer of this application cannot be held responsible for data loss or corruption. PLEASE USE AT YOUR OWN RISK!\n\n"
"Last but not least, this application is released under the terms of the GNU General Public Licence version 3. Please see the COPYING file for more details.")); "Last but not least, this application is released under the terms of the GNU General Public Licence version 3. Please see the COPYING file for more details."));
_watcher.Connect(wxEVT_FSWATCHER, wxFileSystemWatcherEventHandler(EvtMainFrame::fileUpdateEvent), nullptr, this);
_watcher.AddTree(wxFileName(Utility::Directory::toNativeSeparators(_saveDirectory), wxPATH_WIN),
wxFSW_EVENT_CREATE|wxFSW_EVENT_DELETE|wxFSW_EVENT_MODIFY|wxFSW_EVENT_RENAME, wxString::Format("Unit??%s.sav", _localSteamId));
} }
EvtMainFrame::~EvtMainFrame() { EvtMainFrame::~EvtMainFrame() {
@ -62,6 +67,7 @@ EvtMainFrame::~EvtMainFrame() {
_installedListView->Disconnect(wxEVT_LIST_ITEM_DESELECTED, wxListEventHandler(EvtMainFrame::installedSelectionEvent), nullptr, this); _installedListView->Disconnect(wxEVT_LIST_ITEM_DESELECTED, wxListEventHandler(EvtMainFrame::installedSelectionEvent), nullptr, this);
_installedListView->Disconnect(wxEVT_LIST_BEGIN_DRAG, wxListEventHandler(EvtMainFrame::listColumnDragEvent), nullptr, this); _installedListView->Disconnect(wxEVT_LIST_BEGIN_DRAG, wxListEventHandler(EvtMainFrame::listColumnDragEvent), nullptr, this);
_installedListView->Disconnect(wxEVT_LIST_COL_BEGIN_DRAG, wxListEventHandler(EvtMainFrame::listColumnDragEvent), nullptr, this); _installedListView->Disconnect(wxEVT_LIST_COL_BEGIN_DRAG, wxListEventHandler(EvtMainFrame::listColumnDragEvent), nullptr, this);
_watcher.Disconnect(wxEVT_FSWATCHER, wxFileSystemWatcherEventHandler(EvtMainFrame::fileUpdateEvent), nullptr, this);
} }
void EvtMainFrame::importEvent(wxCommandEvent&) { void EvtMainFrame::importEvent(wxCommandEvent&) {
@ -117,8 +123,6 @@ void EvtMainFrame::importEvent(wxCommandEvent&) {
*(iter + i) = _localSteamId[i]; *(iter + i) = _localSteamId[i];
} }
} }
refreshListView();
} }
void EvtMainFrame::moveEvent(wxCommandEvent&) { void EvtMainFrame::moveEvent(wxCommandEvent&) {
@ -147,8 +151,6 @@ void EvtMainFrame::moveEvent(wxCommandEvent&) {
if(dest_status != "<Empty>") { if(dest_status != "<Empty>") {
Utility::Directory::move(dest_file + ".tmp", orig_file); Utility::Directory::move(dest_file + ".tmp", orig_file);
} }
refreshListView();
} }
void EvtMainFrame::deleteEvent(wxCommandEvent&) { void EvtMainFrame::deleteEvent(wxCommandEvent&) {
@ -162,8 +164,6 @@ void EvtMainFrame::deleteEvent(wxCommandEvent&) {
if(Utility::Directory::exists(file)) { if(Utility::Directory::exists(file)) {
Utility::Directory::rm(file); Utility::Directory::rm(file);
} }
refreshListView();
} }
void EvtMainFrame::openSaveDirEvent(wxCommandEvent&) { void EvtMainFrame::openSaveDirEvent(wxCommandEvent&) {
@ -178,8 +178,34 @@ void EvtMainFrame::listColumnDragEvent(wxListEvent& event) {
event.Veto(); event.Veto();
} }
void EvtMainFrame::timerEvent(wxTimerEvent&) { void EvtMainFrame::fileUpdateEvent(wxFileSystemWatcherEvent& event) {
refreshListView(); int event_type = event.GetChangeType();
if(event_type == wxFSW_EVENT_MODIFY && _lastWatcherEventType == wxFSW_EVENT_RENAME) {
_lastWatcherEventType = event_type;
return;
}
_lastWatcherEventType = event_type;
std::string event_file =(Utility::Directory::fromNativeSeparators(event.GetNewPath().GetFullName().ToStdString()));
if(!Utility::String::endsWith(event_file, ".sav")) {
return;
}
long slot;
try {
slot = std::stol(std::string(event_file.data() + 4, 2));
}
catch(const std::invalid_argument&) {
return;
}
_installedListView->SetItem(slot, 1, getSlotMassName(slot));
updateCommandsState();
} }
void EvtMainFrame::getSaveDirectory() { void EvtMainFrame::getSaveDirectory() {
@ -228,8 +254,6 @@ void EvtMainFrame::initialiseListView() {
_installedListView->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER); _installedListView->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
refreshListView(); refreshListView();
_refreshTimer.Start(1000);
} }
void EvtMainFrame::refreshListView() { void EvtMainFrame::refreshListView() {

View file

@ -19,6 +19,8 @@
#include <string> #include <string>
#include <wx/fswatcher.h>
#include "MainFrame.h" #include "MainFrame.h"
class EvtMainFrame: public MainFrame { class EvtMainFrame: public MainFrame {
@ -33,7 +35,7 @@ class EvtMainFrame: public MainFrame {
void openSaveDirEvent(wxCommandEvent&); void openSaveDirEvent(wxCommandEvent&);
void installedSelectionEvent(wxListEvent&); void installedSelectionEvent(wxListEvent&);
void listColumnDragEvent(wxListEvent&); void listColumnDragEvent(wxListEvent&);
void timerEvent(wxTimerEvent&); void fileUpdateEvent(wxFileSystemWatcherEvent& event);
private: private:
void getSaveDirectory(); void getSaveDirectory();
@ -50,6 +52,9 @@ class EvtMainFrame: public MainFrame {
std::string _saveDirectory; std::string _saveDirectory;
std::string _localSteamId; std::string _localSteamId;
wxFileSystemWatcher _watcher;
int _lastWatcherEventType = 0;
}; };
#endif // __EvtMainFrame__ #endif // __EvtMainFrame__

View file

@ -79,7 +79,6 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
this->SetSizer( bSizerMain ); this->SetSizer( bSizerMain );
this->Layout(); this->Layout();
bSizerMain->Fit( this ); bSizerMain->Fit( this );
_refreshTimer.SetOwner( this, wxID_ANY );
this->Centre( wxBOTH ); this->Centre( wxBOTH );
@ -88,7 +87,6 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
_moveButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::moveEvent ), NULL, this ); _moveButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::moveEvent ), NULL, this );
_deleteButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::deleteEvent ), NULL, this ); _deleteButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::deleteEvent ), NULL, this );
_openSaveDirButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::openSaveDirEvent ), NULL, this ); _openSaveDirButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::openSaveDirEvent ), NULL, this );
this->Connect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( MainFrame::timerEvent ) );
} }
MainFrame::~MainFrame() MainFrame::~MainFrame()
@ -98,6 +96,5 @@ MainFrame::~MainFrame()
_moveButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::moveEvent ), NULL, this ); _moveButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::moveEvent ), NULL, this );
_deleteButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::deleteEvent ), NULL, this ); _deleteButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::deleteEvent ), NULL, this );
_openSaveDirButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::openSaveDirEvent ), NULL, this ); _openSaveDirButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::openSaveDirEvent ), NULL, this );
this->Disconnect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( MainFrame::timerEvent ) );
} }

View file

@ -603,15 +603,6 @@
</object> </object>
</object> </object>
</object> </object>
<object class="wxTimer" expanded="1">
<property name="enabled">0</property>
<property name="id">wxID_ANY</property>
<property name="name">_refreshTimer</property>
<property name="oneshot">0</property>
<property name="period">1000</property>
<property name="permission">protected</property>
<event name="OnTimer">timerEvent</event>
</object>
</object> </object>
</object> </object>
</wxFormBuilder_Project> </wxFormBuilder_Project>

View file

@ -22,7 +22,6 @@
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/statbox.h> #include <wx/statbox.h>
#include <wx/stattext.h> #include <wx/stattext.h>
#include <wx/timer.h>
#include <wx/frame.h> #include <wx/frame.h>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -43,14 +42,12 @@ class MainFrame : public wxFrame
wxButton* _openSaveDirButton; wxButton* _openSaveDirButton;
wxStaticText* _riskLabel; wxStaticText* _riskLabel;
wxStaticText* _aboutText; wxStaticText* _aboutText;
wxTimer _refreshTimer;
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void importEvent( wxCommandEvent& event ) { event.Skip(); } virtual void importEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void moveEvent( wxCommandEvent& event ) { event.Skip(); } virtual void moveEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void deleteEvent( wxCommandEvent& event ) { event.Skip(); } virtual void deleteEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void openSaveDirEvent( wxCommandEvent& event ) { event.Skip(); } virtual void openSaveDirEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void timerEvent( wxTimerEvent& event ) { event.Skip(); }
public: public: