mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-20 21:11:43 +00:00
Thread git checks
Push the git checks from the main thread into child threads to prevent resource contention in some cases where Windows machines might have many files in git that are _also_ being managed by Google Drive Fixes https://gitlab.com/kicad/code/kicad/-/issues/20078
This commit is contained in:
parent
42e448dbf6
commit
2c54ab277b
@ -126,6 +126,8 @@ static const wxChar MaximumThreads[] = wxT( "MaximumThreads" );
|
||||
static const wxChar NetInspectorBulkUpdateOptimisationThreshold[] =
|
||||
wxT( "NetInspectorBulkUpdateOptimisationThreshold" );
|
||||
static const wxChar ExcludeFromSimulationLineWidth[] = wxT( "ExcludeFromSimulationLineWidth" );
|
||||
static const wxChar GitIconRefreshInterval[] = wxT( "GitIconRefreshInterval" );
|
||||
static const wxChar GitProjectStatusRefreshInterval[] = wxT( "GitProjectStatusRefreshInterval" );
|
||||
|
||||
} // namespace KEYS
|
||||
|
||||
@ -305,6 +307,9 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
|
||||
m_ExcludeFromSimulationLineWidth = 25;
|
||||
|
||||
m_GitIconRefreshInterval = 1000;
|
||||
m_GitProjectStatusRefreshInterval = 60000;
|
||||
|
||||
loadFromConfigFile();
|
||||
}
|
||||
|
||||
@ -586,6 +591,14 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
&m_ExcludeFromSimulationLineWidth,
|
||||
m_ExcludeFromSimulationLineWidth, 1, 100 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::GitIconRefreshInterval,
|
||||
&m_GitIconRefreshInterval,
|
||||
m_GitIconRefreshInterval, 0, 100000 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::GitProjectStatusRefreshInterval,
|
||||
&m_GitProjectStatusRefreshInterval,
|
||||
m_GitProjectStatusRefreshInterval, 0, 100000 ) );
|
||||
|
||||
// Special case for trace mask setting...we just grab them and set them immediately
|
||||
// Because we even use wxLogTrace inside of advanced config
|
||||
wxString traceMasks;
|
||||
|
@ -76,6 +76,7 @@ public:
|
||||
GIT_STATUS_BEHIND, // File changed in remote repository but not in local
|
||||
GIT_STATUS_AHEAD, // File changed in local repository but not in remote
|
||||
GIT_STATUS_CONFLICTED,
|
||||
GIT_STATUS_IGNORED,
|
||||
GIT_STATUS_LAST
|
||||
};
|
||||
|
||||
|
@ -740,6 +740,23 @@ public:
|
||||
*/
|
||||
int m_ExcludeFromSimulationLineWidth;
|
||||
|
||||
/**
|
||||
* The interval in milliseconds to refresh the git icons in the project tree.
|
||||
*
|
||||
* Setting name: "GitIconRefreshInterval"
|
||||
* Default value: 2000
|
||||
*/
|
||||
int m_GitIconRefreshInterval;
|
||||
|
||||
/**
|
||||
* The interval in milliseconds to refresh the project status by performing
|
||||
* a git fetch on the remote project. Set to 0 to disable.
|
||||
*
|
||||
* Setting name: "GitProjectStatusRefreshInterval"
|
||||
* Default value: 60000
|
||||
*/
|
||||
int m_GitProjectStatusRefreshInterval;
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
|
@ -114,6 +114,7 @@ void PROJECT_TREE::LoadIcons()
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_out_of_date ) ); // GIT_STATUS_BEHIND
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_changed_ahead ) ); // GIT_STATUS_AHEAD
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_conflict ) ); // GIT_STATUS_CONFLICTED
|
||||
stateImages.push_back( wxBitmapBundle( wxBitmap( 16, 16 ) ) ); // GIT_STATUS_IGNORED
|
||||
|
||||
SetStateImages( stateImages );
|
||||
#else
|
||||
@ -190,14 +191,15 @@ void PROJECT_TREE::LoadIcons()
|
||||
m_statusImageList = new wxImageList( size, size, true,
|
||||
static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_LAST ) );
|
||||
|
||||
m_statusImageList->Add( blank_bitmap ); // GIT_STATUS_UNTRACKED
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_good_check, size ) ); // GIT_STATUS_CURRENT
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_modified, size ) ); // GIT_STATUS_MODIFIED
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_add, size ) ); // GIT_STATUS_ADDED
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_delete, size ) ); // GIT_STATUS_DELETED
|
||||
m_statusImageList->Add( blank_bitmap ); // GIT_STATUS_UNTRACKED
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_good_check, size ) ); // GIT_STATUS_CURRENT
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_modified, size ) ); // GIT_STATUS_MODIFIED
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_add, size ) ); // GIT_STATUS_ADDED
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_delete, size ) ); // GIT_STATUS_DELETED
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_out_of_date, size ) ); // GIT_STATUS_BEHIND
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_changed_ahead, size ) ); // GIT_STATUS_AHEAD
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_conflict, size ) ); // GIT_STATUS_CONFLICTED
|
||||
m_statusImageList->Add( KiBitmap( BITMAPS::git_conflict, size ) ); // GIT_STATUS_CONFLICTED
|
||||
m_statusImageList->Add( blank_bitmap ); // GIT_STATUS_IGNORED
|
||||
|
||||
SetStateImageList( m_statusImageList );
|
||||
#endif
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include <stack>
|
||||
#include <thread>
|
||||
#include <git2.h>
|
||||
|
||||
#include <wx/regex.h>
|
||||
@ -31,6 +32,7 @@
|
||||
#include <wx/string.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/textdlg.h>
|
||||
#include <wx/timer.h>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <bitmaps.h>
|
||||
@ -48,6 +50,7 @@
|
||||
#include <project/project_local_settings.h>
|
||||
#include <scoped_set_reset.h>
|
||||
#include <string_utils.h>
|
||||
#include <thread_pool.h>
|
||||
#include <launch_ext.h>
|
||||
#include <wx/dcclient.h>
|
||||
#include <wx/settings.h>
|
||||
@ -187,16 +190,19 @@ PROJECT_TREE_PANE::PROJECT_TREE_PANE( KICAD_MANAGER_FRAME* parent ) :
|
||||
m_isRenaming = false;
|
||||
m_selectedItem = nullptr;
|
||||
m_watcherNeedReset = false;
|
||||
m_lastGitStatusUpdate = wxDateTime::Now();
|
||||
m_gitLastError = GIT_ERROR_NONE;
|
||||
|
||||
m_watcher = nullptr;
|
||||
Connect( wxEVT_FSWATCHER,
|
||||
wxFileSystemWatcherEventHandler( PROJECT_TREE_PANE::onFileSystemEvent ) );
|
||||
Bind( wxEVT_FSWATCHER,
|
||||
wxFileSystemWatcherEventHandler( PROJECT_TREE_PANE::onFileSystemEvent ), this );
|
||||
|
||||
Bind( wxEVT_SYS_COLOUR_CHANGED,
|
||||
wxSysColourChangedEventHandler( PROJECT_TREE_PANE::onThemeChanged ), this );
|
||||
|
||||
m_gitSyncTimer.SetOwner( this );
|
||||
m_gitStatusTimer.SetOwner( this );
|
||||
Bind( wxEVT_TIMER, wxTimerEventHandler( PROJECT_TREE_PANE::onGitSyncTimer ), this, m_gitSyncTimer.GetId() );
|
||||
Bind( wxEVT_TIMER, wxTimerEventHandler( PROJECT_TREE_PANE::onGitStatusTimer ), this, m_gitStatusTimer.GetId() );
|
||||
/*
|
||||
* Filtering is now inverted: the filters are actually used to _enable_ support
|
||||
* for a given file type.
|
||||
@ -208,15 +214,28 @@ PROJECT_TREE_PANE::PROJECT_TREE_PANE( KICAD_MANAGER_FRAME* parent ) :
|
||||
|
||||
ReCreateTreePrj();
|
||||
|
||||
// If we are asking for refresh, run one right at the beginning
|
||||
if( ADVANCED_CFG::GetCfg().m_GitProjectStatusRefreshInterval > 0 )
|
||||
m_gitSyncTimer.Start( 100, wxTIMER_ONE_SHOT );
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_GitIconRefreshInterval > 0 )
|
||||
m_gitStatusTimer.Start( 150, wxTIMER_ONE_SHOT );
|
||||
}
|
||||
|
||||
|
||||
PROJECT_TREE_PANE::~PROJECT_TREE_PANE()
|
||||
{
|
||||
Disconnect( wxEVT_FSWATCHER,
|
||||
wxFileSystemWatcherEventHandler( PROJECT_TREE_PANE::onFileSystemEvent ) );
|
||||
Unbind( wxEVT_FSWATCHER,
|
||||
wxFileSystemWatcherEventHandler( PROJECT_TREE_PANE::onFileSystemEvent ), this );
|
||||
Unbind( wxEVT_SYS_COLOUR_CHANGED,
|
||||
wxSysColourChangedEventHandler( PROJECT_TREE_PANE::onThemeChanged ), this );
|
||||
wxSysColourChangedEventHandler( PROJECT_TREE_PANE::onThemeChanged ), this );
|
||||
|
||||
m_gitSyncTimer.Stop();
|
||||
m_gitStatusTimer.Stop();
|
||||
Unbind( wxEVT_TIMER, wxTimerEventHandler( PROJECT_TREE_PANE::onGitSyncTimer ), this,
|
||||
m_gitSyncTimer.GetId() );
|
||||
Unbind( wxEVT_TIMER, wxTimerEventHandler( PROJECT_TREE_PANE::onGitStatusTimer ), this,
|
||||
m_gitStatusTimer.GetId() );
|
||||
shutdownFileWatcher();
|
||||
}
|
||||
|
||||
@ -605,6 +624,16 @@ wxTreeItemId PROJECT_TREE_PANE::addItemToProjectTree( const wxString& aName,
|
||||
|
||||
void PROJECT_TREE_PANE::ReCreateTreePrj()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock1( m_gitStatusMutex );
|
||||
std::lock_guard<std::mutex> lock2( m_gitTreeCacheMutex );
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.wait_for_tasks();
|
||||
m_gitStatusTimer.Stop();
|
||||
m_gitSyncTimer.Stop();
|
||||
m_gitTreeCache.clear();
|
||||
m_gitStatusIcons.clear();
|
||||
|
||||
wxString pro_dir = m_Parent->GetProjectFileName();
|
||||
|
||||
if( !m_TreeProject )
|
||||
@ -706,7 +735,13 @@ void PROJECT_TREE_PANE::ReCreateTreePrj()
|
||||
|
||||
// Sort filenames by alphabetic order
|
||||
m_TreeProject->SortChildren( m_root );
|
||||
updateGitStatusIcons();
|
||||
|
||||
CallAfter( [this] ()
|
||||
{
|
||||
updateTreeCache();
|
||||
m_gitSyncTimer.Start( 100, wxTIMER_ONE_SHOT );
|
||||
m_gitStatusTimer.Start( 150, wxTIMER_ONE_SHOT );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
@ -1123,7 +1158,6 @@ void PROJECT_TREE_PANE::onIdle( wxIdleEvent& aEvent )
|
||||
item->Activate( this );
|
||||
}
|
||||
|
||||
// Inside this routine, we rate limit to once per 2 seconds
|
||||
updateGitStatusIcons();
|
||||
}
|
||||
|
||||
@ -1299,22 +1333,6 @@ void PROJECT_TREE_PANE::onFileSystemEvent( wxFileSystemWatcherEvent& event )
|
||||
fn = fn.BeforeLast( '/' );
|
||||
}
|
||||
|
||||
switch( event.GetChangeType() )
|
||||
{
|
||||
case wxFSW_EVENT_DELETE:
|
||||
case wxFSW_EVENT_CREATE:
|
||||
case wxFSW_EVENT_RENAME:
|
||||
CallAfter( &PROJECT_TREE_PANE::updateGitStatusIcons );
|
||||
break;
|
||||
|
||||
case wxFSW_EVENT_MODIFY:
|
||||
CallAfter( &PROJECT_TREE_PANE::updateGitStatusIcons );
|
||||
KI_FALLTHROUGH;
|
||||
case wxFSW_EVENT_ACCESS:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
wxTreeItemId root_id = findSubdirTreeItem( subdir );
|
||||
|
||||
if( !root_id.IsOk() )
|
||||
@ -1944,31 +1962,25 @@ void PROJECT_TREE_PANE::onGitRemoveVCS( wxCommandEvent& aEvent )
|
||||
|
||||
void PROJECT_TREE_PANE::updateGitStatusIcons()
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_EnableGit == false )
|
||||
if( ADVANCED_CFG::GetCfg().m_EnableGit == false || !m_TreeProject )
|
||||
return;
|
||||
|
||||
if( !m_TreeProject )
|
||||
std::unique_lock<std::mutex> lock( m_gitStatusMutex, std::try_to_lock );
|
||||
|
||||
if( !lock.owns_lock() )
|
||||
return;
|
||||
|
||||
wxTimeSpan timeSinceLastUpdate = wxDateTime::Now() - m_lastGitStatusUpdate;
|
||||
|
||||
if( timeSinceLastUpdate.Abs() < wxTimeSpan::Seconds( 2 ) )
|
||||
return;
|
||||
|
||||
m_lastGitStatusUpdate = wxDateTime::Now();
|
||||
|
||||
wxTreeItemId kid = m_TreeProject->GetRootItem();
|
||||
|
||||
if( !kid.IsOk() )
|
||||
return;
|
||||
// Note that this function is called from the idle event, so we need to be careful about
|
||||
// accessing the tree control from a different thread.
|
||||
for( auto&[ item, status ] : m_gitStatusIcons )
|
||||
m_TreeProject->SetItemState( item, static_cast<int>( status ) );
|
||||
|
||||
wxTreeItemId kid = m_TreeProject->GetRootItem();
|
||||
git_repository* repo = m_TreeProject->GetGitRepo();
|
||||
|
||||
if( !repo )
|
||||
return;
|
||||
|
||||
// Get Current Branch
|
||||
|
||||
git_reference* currentBranchReference = nullptr;
|
||||
int rc = git_repository_head( ¤tBranchReference, repo );
|
||||
|
||||
@ -1993,40 +2005,81 @@ void PROJECT_TREE_PANE::updateGitStatusIcons()
|
||||
else
|
||||
{
|
||||
if( giterr_last()->klass != m_gitLastError )
|
||||
wxLogError( "Failed to lookup current branch: %s", giterr_last()->message );
|
||||
wxLogTrace( "git", "Failed to lookup current branch: %s", giterr_last()->message );
|
||||
|
||||
m_gitLastError = giterr_last()->klass;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PROJECT_TREE_PANE::updateTreeCache()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock( m_gitTreeCacheMutex, std::try_to_lock );
|
||||
|
||||
if( !lock.owns_lock() || !m_TreeProject )
|
||||
return;
|
||||
|
||||
wxTreeItemId kid = m_TreeProject->GetRootItem();
|
||||
|
||||
if( !kid.IsOk() )
|
||||
return;
|
||||
|
||||
// Collect a map to easily set the state of each item
|
||||
std::map<wxString, wxTreeItemId> branchMap;
|
||||
std::stack<wxTreeItemId> items;
|
||||
items.push( kid );
|
||||
|
||||
while( !items.empty() )
|
||||
{
|
||||
std::stack<wxTreeItemId> items;
|
||||
items.push( kid );
|
||||
kid = items.top();
|
||||
items.pop();
|
||||
|
||||
while( !items.empty() )
|
||||
{
|
||||
kid = items.top();
|
||||
items.pop();
|
||||
PROJECT_TREE_ITEM* nextItem = GetItemIdData( kid );
|
||||
|
||||
PROJECT_TREE_ITEM* nextItem = GetItemIdData( kid );
|
||||
|
||||
wxString gitAbsPath = nextItem->GetFileName();
|
||||
wxString gitAbsPath = nextItem->GetFileName();
|
||||
#ifdef _WIN32
|
||||
gitAbsPath.Replace( wxS( "\\" ), wxS( "/" ) );
|
||||
gitAbsPath.Replace( wxS( "\\" ), wxS( "/" ) );
|
||||
#endif
|
||||
branchMap[gitAbsPath] = kid;
|
||||
m_gitTreeCache[gitAbsPath] = kid;
|
||||
|
||||
wxTreeItemIdValue cookie;
|
||||
wxTreeItemId child = m_TreeProject->GetFirstChild( kid, cookie );
|
||||
wxTreeItemIdValue cookie;
|
||||
wxTreeItemId child = m_TreeProject->GetFirstChild( kid, cookie );
|
||||
|
||||
while( child.IsOk() )
|
||||
{
|
||||
items.push( child );
|
||||
child = m_TreeProject->GetNextChild( kid, cookie );
|
||||
}
|
||||
while( child.IsOk() )
|
||||
{
|
||||
items.push( child );
|
||||
child = m_TreeProject->GetNextChild( kid, cookie );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PROJECT_TREE_PANE::updateGitStatusIconMap()
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_EnableGit == false || !m_TreeProject )
|
||||
return;
|
||||
int refresh = ADVANCED_CFG::GetCfg().m_GitIconRefreshInterval;
|
||||
|
||||
if( refresh != 0 )
|
||||
{
|
||||
CallAfter(
|
||||
[this, refresh]()
|
||||
{
|
||||
m_gitStatusTimer.Start( refresh, wxTIMER_ONE_SHOT );
|
||||
} );
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock1( m_gitStatusMutex );
|
||||
std::unique_lock<std::mutex> lock2( m_gitTreeCacheMutex );
|
||||
|
||||
git_repository* repo = m_TreeProject->GetGitRepo();
|
||||
|
||||
if( !repo )
|
||||
return;
|
||||
|
||||
// Get Current Branch
|
||||
PROJECT_TREE_ITEM* rootItem = GetItemIdData( m_TreeProject->GetRootItem() );
|
||||
wxFileName rootFilename( rootItem->GetFileName() );
|
||||
wxString repoWorkDir( git_repository_workdir( repo ) );
|
||||
|
||||
wxFileName relative = rootFilename;
|
||||
relative.MakeRelativeTo( repoWorkDir );
|
||||
@ -2075,63 +2128,41 @@ void PROJECT_TREE_PANE::updateGitStatusIcons()
|
||||
wxString absPath = repoWorkDir;
|
||||
absPath << path;
|
||||
|
||||
auto iter = branchMap.find( absPath );
|
||||
auto iter = m_gitTreeCache.find( absPath );
|
||||
|
||||
if( iter == branchMap.end() )
|
||||
if( iter == m_gitTreeCache.end() )
|
||||
continue;
|
||||
|
||||
// If we are current, don't continue because we still need to check to see if the
|
||||
// current commit is ahead/behind the remote. If the file is modified/added/deleted,
|
||||
// that is the main status we want to show.
|
||||
if( entry->status == GIT_STATUS_CURRENT )
|
||||
if( entry->status & GIT_STATUS_IGNORED )
|
||||
{
|
||||
m_TreeProject->SetItemState(
|
||||
iter->second,
|
||||
static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_CURRENT ) );
|
||||
m_gitStatusIcons[iter->second] = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_IGNORED;
|
||||
}
|
||||
else if( entry->status & ( GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED ) )
|
||||
{
|
||||
m_TreeProject->SetItemState(
|
||||
iter->second,
|
||||
static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED ) );
|
||||
continue;
|
||||
m_gitStatusIcons[iter->second] = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED;
|
||||
}
|
||||
else if( entry->status & ( GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW ) )
|
||||
{
|
||||
m_TreeProject->SetItemState(
|
||||
iter->second,
|
||||
static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_ADDED ) );
|
||||
continue;
|
||||
m_gitStatusIcons[iter->second] = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_ADDED;
|
||||
}
|
||||
else if( entry->status & ( GIT_STATUS_INDEX_DELETED | GIT_STATUS_WT_DELETED ) )
|
||||
{
|
||||
m_TreeProject->SetItemState(
|
||||
iter->second,
|
||||
static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_DELETED ) );
|
||||
continue;
|
||||
m_gitStatusIcons[iter->second] = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_DELETED;
|
||||
}
|
||||
|
||||
// Check if file is up to date with the remote
|
||||
if( localChanges.count( path ) )
|
||||
else if( localChanges.count( path ) )
|
||||
{
|
||||
m_TreeProject->SetItemState(
|
||||
iter->second,
|
||||
static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_AHEAD ) );
|
||||
continue;
|
||||
m_gitStatusIcons[iter->second] = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_AHEAD;
|
||||
}
|
||||
else if( remoteChanges.count( path ) )
|
||||
{
|
||||
m_TreeProject->SetItemState(
|
||||
iter->second,
|
||||
static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_BEHIND ) );
|
||||
continue;
|
||||
m_gitStatusIcons[iter->second] = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_BEHIND;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TreeProject->SetItemState(
|
||||
iter->second,
|
||||
static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_CURRENT ) );
|
||||
continue;
|
||||
m_gitStatusIcons[iter->second] = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_CURRENT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2525,3 +2556,42 @@ void PROJECT_TREE_PANE::onRunSelectedJobsFile(wxCommandEvent& event)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PROJECT_TREE_PANE::onGitSyncTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_EnableGit == false || !m_TreeProject )
|
||||
return;
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.push_task( [this]()
|
||||
{
|
||||
KIGIT_COMMON* gitCommon = m_TreeProject->GitCommon();
|
||||
|
||||
if( !gitCommon )
|
||||
return;
|
||||
|
||||
GIT_PULL_HANDLER handler( gitCommon );
|
||||
handler.PerformFetch();
|
||||
} );
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_GitProjectStatusRefreshInterval > 0 )
|
||||
{
|
||||
m_gitSyncTimer.Start( ADVANCED_CFG::GetCfg().m_GitProjectStatusRefreshInterval,
|
||||
wxTIMER_ONE_SHOT );
|
||||
}
|
||||
}
|
||||
|
||||
void PROJECT_TREE_PANE::onGitStatusTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_EnableGit == false || !m_TreeProject )
|
||||
return;
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.push_task( [this]()
|
||||
{
|
||||
updateGitStatusIconMap();
|
||||
} );
|
||||
}
|
||||
|
@ -30,12 +30,17 @@
|
||||
#ifndef TREEPRJ_FRAME_H
|
||||
#define TREEPRJ_FRAME_H
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <wx/datetime.h>
|
||||
#include <wx/fswatcher.h>
|
||||
#include <wx/laywin.h>
|
||||
#include <wx/timer.h>
|
||||
#include <wx/treebase.h>
|
||||
|
||||
#include <git/kicad_git_common.h>
|
||||
#include "tree_file_type.h"
|
||||
|
||||
|
||||
@ -230,6 +235,17 @@ private:
|
||||
*/
|
||||
void updateGitStatusIcons();
|
||||
|
||||
/**
|
||||
* This is a threaded call that will change the map of git status icons for use in
|
||||
* the main thread
|
||||
*/
|
||||
void updateGitStatusIconMap();
|
||||
|
||||
/**
|
||||
* Updates the map of the wxtreeitemid to the name of each file for use in the thread
|
||||
*/
|
||||
void updateTreeCache();
|
||||
|
||||
/**
|
||||
* Returns true if the current project has any uncommitted changes
|
||||
*/
|
||||
@ -283,6 +299,10 @@ private:
|
||||
*/
|
||||
bool canFileBeAddedToVCS( const wxString& aFilePath );
|
||||
|
||||
void onGitSyncTimer( wxTimerEvent& event );
|
||||
|
||||
void onGitStatusTimer( wxTimerEvent& event );
|
||||
|
||||
public:
|
||||
KICAD_MANAGER_FRAME* m_Parent;
|
||||
PROJECT_TREE* m_TreeProject;
|
||||
@ -296,9 +316,16 @@ private:
|
||||
bool m_watcherNeedReset; // true if FileWatcherReset() must be called
|
||||
// (during an idle time for instance) after
|
||||
// the main loop event handler is started
|
||||
wxDateTime m_lastGitStatusUpdate;
|
||||
int m_gitLastError;
|
||||
|
||||
wxTimer m_gitSyncTimer;
|
||||
wxTimer m_gitStatusTimer;
|
||||
|
||||
std::mutex m_gitTreeCacheMutex;
|
||||
std::unordered_map<wxString, wxTreeItemId> m_gitTreeCache;
|
||||
std::mutex m_gitStatusMutex;
|
||||
std::map<wxTreeItemId, KIGIT_COMMON::GIT_STATUS> m_gitStatusIcons;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user