Remove use of va_list in favor of template fwd args.

Several bug fixes.
Git plugin more WIP.
This commit is contained in:
Martín Lucas Golini
2024-01-16 20:14:38 -03:00
parent c159620c56
commit aaa70460d8
18 changed files with 198 additions and 305 deletions
-1
View File
@@ -1,4 +1,3 @@
#include <cassert>
#include <cstdarg>
#include <eepp/core/debug.hpp>
#include <eepp/system/log.hpp>
+9 -9
View File
@@ -9,17 +9,17 @@
namespace EE { namespace Graphics {
const char* EEGL3CP_STATES_NAME[] = {"dgl_Vertex", "dgl_Normal", "dgl_FrontColor"};
const char* EEGL3CP_STATES_NAME[] = { "dgl_Vertex", "dgl_Normal", "dgl_FrontColor" };
const char* EEGL3CP_TEXTUREUNIT_NAMES[] = {"dgl_MultiTexCoord0", "dgl_MultiTexCoord1",
"dgl_MultiTexCoord2", "dgl_MultiTexCoord3"};
const char* EEGL3CP_TEXTUREUNIT_NAMES[] = { "dgl_MultiTexCoord0", "dgl_MultiTexCoord1",
"dgl_MultiTexCoord2", "dgl_MultiTexCoord3" };
const char* EEGL3CP_PLANES_ENABLED_NAME[] = {"dgl_ClipEnabled[0]", "dgl_ClipEnabled[1]",
"dgl_ClipEnabled[2]", "dgl_ClipEnabled[3]",
"dgl_ClipEnabled[4]", "dgl_ClipEnabled[5]"};
const char* EEGL3CP_PLANES_ENABLED_NAME[] = { "dgl_ClipEnabled[0]", "dgl_ClipEnabled[1]",
"dgl_ClipEnabled[2]", "dgl_ClipEnabled[3]",
"dgl_ClipEnabled[4]", "dgl_ClipEnabled[5]" };
const char* EEGL3CP_PLANES_NAME[] = {"dgl_ClipPlane[0]", "dgl_ClipPlane[1]", "dgl_ClipPlane[2]",
"dgl_ClipPlane[3]", "dgl_ClipPlane[4]", "dgl_ClipPlane[5]"};
const char* EEGL3CP_PLANES_NAME[] = { "dgl_ClipPlane[0]", "dgl_ClipPlane[1]", "dgl_ClipPlane[2]",
"dgl_ClipPlane[3]", "dgl_ClipPlane[4]", "dgl_ClipPlane[5]" };
#ifdef EE_GLES2
const GLchar* GL3CP_SHADER_HEAD = "precision mediump float;\nprecision lowp int;\n";
@@ -116,7 +116,7 @@ void RendererGL3CP::init() {
mShaders[EEGL3CP_SHADER_BASE] =
ShaderProgram::New( vs.c_str(), vs.size(), fs.c_str(), fs.size() );
mShaders[EEGL3CP_SHADER_BASE]->setReloadCb(
cb::Make1( this, &RendererGL3CP::reloadShader ) );
[this]( ShaderProgram* shader ) { RendererGL3CP::reloadShader( shader ); } );
Shader::ensure( true );
} else {
+8 -8
View File
@@ -95,34 +95,34 @@ void RendererGLES2::init() {
Shader::ensure( false );
auto reloadShader = [this]( ShaderProgram* shader ) {
RendererGLES2::reloadShader( shader );
};
mShaders[EEGLES2_SHADER_BASE] =
ShaderProgram::New( vs.c_str(), vs.size(), fs.c_str(), fs.size() );
mShaders[EEGLES2_SHADER_BASE]->setReloadCb(
cb::Make1( this, &RendererGLES2::reloadShader ) );
mShaders[EEGLES2_SHADER_BASE]->setReloadCb( reloadShader );
vs = hs + EEGLES2_SHADER_CLIPPED_VS;
fs = hs + EEGLES2_SHADER_CLIPPED_FS;
mShaders[EEGLES2_SHADER_CLIPPED] =
ShaderProgram::New( vs.c_str(), vs.size(), fs.c_str(), fs.size() );
mShaders[EEGLES2_SHADER_CLIPPED]->setReloadCb(
cb::Make1( this, &RendererGLES2::reloadShader ) );
mShaders[EEGLES2_SHADER_CLIPPED]->setReloadCb( reloadShader );
vs = hs + EEGLES2_SHADER_POINTSPRITE_VS;
fs = hs + EEGLES2_SHADER_POINTSPRITE_FS;
mShaders[EEGLES2_SHADER_POINTSPRITE] =
ShaderProgram::New( vs.c_str(), vs.size(), fs.c_str(), fs.size() );
mShaders[EEGLES2_SHADER_POINTSPRITE]->setReloadCb(
cb::Make1( this, &RendererGLES2::reloadShader ) );
mShaders[EEGLES2_SHADER_POINTSPRITE]->setReloadCb( reloadShader );
vs = hs + EEGLES2_SHADER_PRIMITIVE_VS;
fs = hs + EEGLES2_SHADER_PRIMITIVE_FS;
mShaders[EEGLES2_SHADER_PRIMITIVE] =
ShaderProgram::New( vs.c_str(), vs.size(), fs.c_str(), fs.size() );
mShaders[EEGLES2_SHADER_PRIMITIVE]->setReloadCb(
cb::Make1( this, &RendererGLES2::reloadShader ) );
mShaders[EEGLES2_SHADER_PRIMITIVE]->setReloadCb( reloadShader );
Shader::ensure( true );
+1 -1
View File
@@ -25,7 +25,7 @@ EventDispatcher::EventDispatcher( SceneNode* sceneNode ) :
mFirstPress( false ),
mNodeWasDragging( NULL ),
mNodeDragging( NULL ) {
mCbId = mInput->pushCallback( cb::Make1( this, &EventDispatcher::inputCallback ) );
mCbId = mInput->pushCallback( [this]( InputEvent* event ) { inputCallback( event ); } );
mIMECbId = mWindow->getIME().addTextEditingCb(
[this]( const String& text, Int32 start, Int32 length ) {
sendTextEditing( text, start, length );
+1 -1
View File
@@ -43,7 +43,7 @@ SceneNode::SceneNode( EE::Window::Window* window ) :
mWindow = Engine::instance()->getCurrentWindow();
}
mResizeCb = mWindow->pushResizeCallback( cb::Make1( this, &SceneNode::resizeNode ) );
mResizeCb = mWindow->pushResizeCallback( [this]( auto win ) { resizeNode( win ); } );
DisplayManager* displayManager = Engine::instance()->getDisplayManager();
int currentDisplayIndex = getWindow()->getCurrentDisplayIndex();
+2 -123
View File
@@ -166,8 +166,8 @@ static std::string logLevelToString( const LogLevel& level ) {
}
}
static std::string logLevelWithTimestamp( const LogLevel& level, const std::string_view& text,
bool appendNewLine ) {
std::string Log::logLevelWithTimestamp( const LogLevel& level, const std::string_view& text,
bool appendNewLine ) {
return String::format( appendNewLine ? "%s - %s: %s\n" : "%s - %s: %s",
Sys::getDateTimeStr().c_str(), logLevelToString( level ).c_str(),
text.data() );
@@ -236,127 +236,6 @@ void Log::closeFS() {
unlock();
}
void Log::writef( const char* format, ... ) {
int n, size = 256;
std::string tstr( size, '\0' );
va_list args;
va_start( args, format );
while ( 1 ) {
n = vsnprintf( &tstr[0], size, format, args );
if ( n > -1 && n < size ) {
tstr.resize( n );
tstr += '\n';
if ( mKeepLog ) {
lock();
mData += tstr;
unlock();
}
writeToReaders( tstr );
if ( mConsoleOutput ) {
#if EE_PLATFORM == EE_PLATFORM_ANDROID
__android_log_print( ANDROID_LOG_INFO, "eepp", "%s", tstr.c_str() );
#elif defined( EE_COMPILER_MSVC )
#ifdef UNICODE
OutputDebugString( String::fromUtf8( tstr ).toWideString().c_str() );
#else
OutputDebugString( tstr.c_str() );
#endif
#else
std::cout << tstr;
#endif
}
if ( mLiveWrite ) {
openFS();
mFS->write( tstr.c_str(), tstr.size() );
mFS->flush();
}
va_end( args );
return;
}
if ( n > -1 ) // glibc 2.1
size = n + 1; // precisely what is needed
else // glibc 2.0
size *= 2; // twice the old size
tstr.resize( size, '\0' );
}
}
void Log::writef( const LogLevel& level, const char* format, ... ) {
if ( mLogLevelThreshold > level )
return;
int n, size = 256;
std::string tstr( size, '\0' );
va_list args;
va_start( args, format );
while ( 1 ) {
n = vsnprintf( &tstr[0], size, format, args );
if ( n > -1 && n < size ) {
tstr.resize( n );
tstr += '\n';
tstr = logLevelWithTimestamp( level, tstr, false );
if ( mKeepLog ) {
lock();
mData += tstr;
unlock();
}
writeToReaders( tstr );
if ( mConsoleOutput ) {
#if EE_PLATFORM == EE_PLATFORM_ANDROID
__android_log_print( ANDROID_LOG_INFO, "eepp", "%s", tstr.c_str() );
#elif defined( EE_COMPILER_MSVC )
#ifdef UNICODE
OutputDebugString( String::fromUtf8( tstr ).toWideString().c_str() );
#else
OutputDebugString( tstr.c_str() );
#endif
#else
std::cout << tstr;
#endif
}
if ( mLiveWrite ) {
openFS();
mFS->write( tstr.c_str(), tstr.size() );
mFS->flush();
}
va_end( args );
return;
}
if ( n > -1 ) // glibc 2.1
size = n + 1; // precisely what is needed
else // glibc 2.0
size *= 2; // twice the old size
tstr.resize( size, '\0' );
}
}
const std::string& Log::getBuffer() const {
return mData;
}
-37
View File
@@ -184,43 +184,6 @@ String Translator::getString( const std::string& key, const String& defaultValue
return defaultValue;
}
String Translator::getStringf( const char* key, ... ) {
std::string str( getString( key ).toUtf8() );
if ( str.empty() )
return String();
const char* format = str.c_str();
int size = 256;
std::string tstr( size, '\0' );
va_list args;
while ( 1 ) {
va_start( args, key );
int n = vsnprintf( &tstr[0], size, format, args );
if ( n > -1 && n < size ) {
tstr.resize( n );
va_end( args );
return tstr;
}
if ( n > -1 ) // glibc 2.1
size = n + 1; // precisely what is needed
else // glibc 2.0
size *= 2; // twice the old size
tstr.resize( size );
}
return String( tstr );
}
void Translator::setLanguageFromLocale( std::locale locale ) {
std::string name = locale.name();
-30
View File
@@ -1423,36 +1423,6 @@ void UIConsole::pushText( const String& str ) {
}
}
void UIConsole::pushText( const char* format, ... ) {
int n, size = 256;
std::string tstr( size, '\0' );
va_list args;
va_start( args, format );
while ( 1 ) {
n = vsnprintf( &tstr[0], size, format, args );
if ( n > -1 && n < size ) {
tstr.resize( n );
pushText( tstr );
va_end( args );
return;
}
if ( n > -1 ) // glibc 2.1
size = n + 1; // precisely what is needed
else // glibc 2.0
size *= 2; // twice the old size
tstr.resize( size );
}
}
Float UIConsole::getLineHeight() const {
return mFontStyleConfig.Font->getFontHeight( mFontStyleConfig.CharacterSize );
}
+1 -1
View File
@@ -915,7 +915,7 @@ void UITabWidget::tryCloseTab( UITab* tab, FocusTabBehavior focusTabBehavior ) {
}
void UITabWidget::swapTabs( UITab* left, UITab* right ) {
if ( !left || !right )
if ( !left || !right || left->getTabWidget() != this || right->getTabWidget() != this )
return;
Uint32 leftIndex = getTabIndex( left );
Uint32 rightIndex = getTabIndex( right );
+58 -42
View File
@@ -173,32 +173,31 @@ std::vector<Git::Branch> Git::getAllBranches( const std::string& projectDir ) {
static Git::Branch parseLocalBranch( const std::string_view& raw ) {
static constexpr size_t len = std::string_view{ "refs/heads/"sv }.size();
return Git::Branch{ std::string{ raw.substr( len ) }, std::string{}, Git::RefType::Head,
std::string{} };
if ( len < raw.size() )
return Git::Branch{ std::string{ raw.substr( len ) }, std::string{}, Git::RefType::Head,
std::string{} };
return {};
}
static Git::Branch parseRemoteBranch( const std::string_view& raw ) {
static constexpr size_t len = std::string_view( "refs/remotes/"sv ).size();
size_t indexOfRemote = raw.find_first_of( '/', len );
if ( indexOfRemote != std::string::npos )
if ( indexOfRemote != std::string::npos && len < raw.size() ) {
return Git::Branch{ std::string{ raw.substr( len ) },
std::string{ raw.substr( len, indexOfRemote - len ) },
Git::RefType::Remote, std::string{} };
}
return {};
}
std::vector<Git::Branch> Git::getAllBranchesAndTags( RefType ref, const std::string& projectDir ) {
std::string args( "for-each-ref --format '%(refname)' --sort=-committerdate" );
if ( ref & RefType::Head ) {
std::string args( "for-each-ref --format '%(refname)' --sort=v:refname" );
if ( ref & RefType::Head )
args.append( " refs/heads" );
}
if ( ref & RefType::Remote ) {
if ( ref & RefType::Remote )
args.append( " refs/remotes" );
}
if ( ref & RefType::Tag ) {
if ( ref & RefType::Tag )
args.append( " refs/tags" );
args.append( " --sort=-taggerdate" );
}
std::vector<Branch> branches;
std::string buf;
@@ -206,24 +205,23 @@ std::vector<Git::Branch> Git::getAllBranchesAndTags( RefType ref, const std::str
if ( EXIT_SUCCESS != git( args, projectDir, buf ) )
return branches;
branches.reserve( countLines( buf ) );
readAllLines( buf, [&branches, ref]( const std::string_view& line ) {
auto branch = String::trim( line, '\n' );
branch = String::trim( line, '\'' );
auto branch = String::trim( String::trim( line, '\n' ), '\'' );
if ( ( ref & Head ) && String::startsWith( branch, "refs/heads/" ) ) {
branches.emplace_back( parseLocalBranch( branch ) );
} else if ( ( ref & Remote ) && String::startsWith( branch, "refs/remotes/" ) ) {
branches.emplace_back( parseRemoteBranch( branch ) );
} else if ( ( ref & Tag ) && String::startsWith( branch, "refs/tags/" ) ) {
static constexpr size_t len = std::string_view{ "refs/tags/"sv }.size();
branches.push_back( { std::string{ branch.substr( len ) }, std::string{}, RefType::Tag,
std::string{} } );
Branch newBranch;
newBranch.name = branch.substr( len );
newBranch.type = RefType::Tag;
branches.emplace_back( std::move( newBranch ) );
}
} );
std::sort( branches.begin(), branches.end(), []( const Branch& left, const Branch& right ) {
return left.type < right.type || left.name < right.name;
} );
return branches;
}
@@ -257,7 +255,7 @@ bool Git::hasSubmodules( const std::string& projectDir ) {
std::string Git::inSubModule( const std::string& file, const std::string& projectDir ) {
for ( const auto& subRepo : mSubModules ) {
if ( String::startsWith( file, subRepo ) )
if ( String::startsWith( file, subRepo ) && file.size() != subRepo.size() )
return subRepo;
}
return FileSystem::fileNameFromPath( !projectDir.empty() ? projectDir : mProjectPath );
@@ -270,26 +268,37 @@ Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir )
std::string buf;
if ( EXIT_SUCCESS != git( DIFF_CMD, projectDir, buf ) )
return s;
auto parseNumStat = [&s, &buf, &projectDir, this]() {
getSubModules( projectDir );
LuaPattern subModulePattern( "^Entering '(.*)'" );
auto parseNumStat = [&s, &buf, &projectDir, this, &subModulePattern]() {
auto lastNL = 0;
auto nextNL = buf.find_first_of( '\n' );
LuaPattern pattern( "(%d+)%s+(%d+)%s+(.+)" );
std::string subModulePath = "";
while ( nextNL != std::string_view::npos ) {
LuaPattern::Range matches[4];
if ( pattern.matches( buf.c_str(), lastNL, matches, nextNL ) ) {
if ( subModulePattern.matches( buf.c_str(), lastNL, matches, nextNL ) ) {
subModulePath = String::trim(
buf.substr( matches[1].start, matches[1].end - matches[1].start ) );
FileSystem::dirAddSlashAtEnd( subModulePath );
} else if ( pattern.matches( buf.c_str(), lastNL, matches, nextNL ) ) {
auto inserted = buf.substr( matches[1].start, matches[1].end - matches[1].start );
auto deleted = buf.substr( matches[2].start, matches[2].end - matches[2].start );
auto file = buf.substr( matches[3].start, matches[3].end - matches[3].start );
int inserts;
int deletes;
if ( String::fromString( inserts, inserted ) &&
String::fromString( deletes, deleted ) ) {
auto repo = inSubModule( file, projectDir );
String::fromString( deletes, deleted ) && ( inserts || deletes ) ) {
auto filePath = subModulePath + file;
auto repo = inSubModule( filePath, projectDir );
auto repoIt = s.files.find( repo );
if ( repoIt != s.files.end() ) {
bool found = false;
for ( auto& fileIt : repoIt->second ) {
if ( fileIt.file == file ) {
if ( fileIt.file == filePath ) {
fileIt.inserts = inserts;
fileIt.deletes = deletes;
found = true;
@@ -297,15 +306,15 @@ Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir )
}
}
if ( !found )
s.files[repo].push_back( { std::move( file ), inserts, deletes } );
s.files[repo].push_back( { std::move( filePath ), inserts, deletes } );
} else {
s.files.insert( { repo, { { std::move( file ), inserts, deletes } } } );
s.files.insert( { repo, { { std::move( filePath ), inserts, deletes } } } );
}
s.totalInserts += inserts;
s.totalDeletions += deletes;
}
}
lastNL = nextNL;
lastNL = nextNL + 1;
nextNL = buf.find_first_of( '\n', nextNL + 1 );
}
};
@@ -319,19 +328,23 @@ Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir )
parseNumStat();
}
getSubModules( projectDir );
bool modifiedSubmodule = false;
auto parseStatus = [&s, &buf, &modifiedSubmodule, &projectDir, this]() {
auto parseStatus = [&s, &buf, &modifiedSubmodule, &projectDir, this, &subModulePattern]() {
auto lastNL = 0;
auto nextNL = buf.find_first_of( '\n' );
LuaPattern pattern( "\n([%sA?][MARTUD?%s])%s(.*)" );
LuaPattern pattern( "([mMARTUD?%s][mMARTUD?%s])%s(.*)" );
std::string subModulePath = "";
while ( nextNL != std::string_view::npos ) {
std::string_view line = std::string_view{ buf }.substr( lastNL, nextNL - lastNL );
LuaPattern::Range matches[3];
if ( pattern.matches( buf.c_str(), lastNL, matches, nextNL ) ) {
auto status = buf.substr( matches[1].start, matches[1].end - matches[1].start );
String::trimInPlace( status );
auto file = buf.substr( matches[2].start, matches[2].end - matches[2].start );
if ( subModulePattern.matches( line.data(), 0, matches, line.size() ) ) {
subModulePath = String::trim(
line.substr( matches[1].start, matches[1].end - matches[1].start ) );
FileSystem::dirAddSlashAtEnd( subModulePath );
} else if ( pattern.matches( line.data(), 0, matches, line.size() ) ) {
auto status = String::trim(
line.substr( matches[1].start, matches[1].end - matches[1].start ) );
auto file = line.substr( matches[2].start, matches[2].end - matches[2].start );
FileStatus rstatus = FileStatus::Unknown;
if ( "??" == status )
rstatus = FileStatus::Untracked;
@@ -354,26 +367,28 @@ Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir )
if ( rstatus == FileStatus::ModifiedSubmodule )
modifiedSubmodule = true;
else {
auto repo = inSubModule( file, projectDir );
auto filePath = subModulePath + file;
auto repo = inSubModule( filePath, projectDir );
auto repoIt = s.files.find( repo );
if ( repoIt != s.files.end() ) {
bool found = false;
for ( auto& fileIt : repoIt->second ) {
if ( fileIt.file == file ) {
if ( fileIt.file == filePath ) {
fileIt.status = rstatus;
found = true;
break;
}
}
if ( !found )
s.files[repo].push_back( { std::move( file ), 0, 0, rstatus } );
s.files[repo].push_back( { std::move( filePath ), 0, 0, rstatus } );
} else {
s.files.insert( { file, { { file, 0, 0, rstatus } } } );
s.files.insert(
{ repo, { { std::move( filePath ), 0, 0, rstatus } } } );
}
}
}
}
lastNL = nextNL;
lastNL = nextNL + 1;
nextNL = buf.find_first_of( '\n', nextNL + 1 );
}
};
@@ -381,7 +396,7 @@ Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir )
git( STATUS_CMD, projectDir, buf );
parseStatus();
if ( modifiedSubmodule && submodules ) {
if ( modifiedSubmodule && recurseSubmodules && submodules ) {
gitSubmodules( STATUS_CMD, projectDir, buf );
parseStatus();
}
@@ -393,6 +408,7 @@ Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir )
FileSystem::fileGet( ( projectDir.empty() ? mProjectPath : projectDir ) + val.file,
fileText );
val.inserts = countLines( fileText );
s.totalInserts += val.inserts;
}
}
}
+1
View File
@@ -32,6 +32,7 @@ class Git {
UpdatedUnmerged = 'U',
Deleted = 'D',
Untracked = '?',
Ignored = 'I',
ModifiedSubmodule = 'm',
};
+71 -38
View File
@@ -33,7 +33,7 @@ static const std::string GIT_REPO = "repo";
static size_t hashBranches( const std::vector<Git::Branch>& branches ) {
size_t hash = 0;
for ( const auto& branch : branches )
hash = hashCombine( hash, String::hash( branch.name ), String::hash( branch.lastCommit ) );
hash = hashCombine( hash, String::hash( branch.name ) );
return hash;
}
@@ -231,11 +231,11 @@ class GitStatusModel : public Model {
case Column::File:
return Variant( FileSystem::fileNameFromPath( s.file ) );
case Column::Inserted:
return Variant( String::format( " +%d ", s.inserts ) );
return Variant( String::format( "+%d ", s.inserts ) );
case Column::Removed:
return Variant( String::format( " -%d ", s.deletes ) );
return Variant( String::format( "-%d ", s.deletes ) );
case Column::State:
return Variant( String::format( " %c ", s.status ) );
return Variant( String::format( "%c", s.status ) );
case Column::RelativeDirectory:
return Variant( FileSystem::fileRemoveFileName( s.file ) );
}
@@ -423,6 +423,7 @@ void GitPlugin::updateStatusBarSync() {
->setEnabled( !mGitContentView->isEnabled() );
if ( !mGit->getGitFolder().empty() ) {
Lock l( mGitStatusMutex );
mStatusTree->setModel( GitStatusModel::asModel( mGitStatus.files, this ) );
mStatusTree->expandAll();
}
@@ -459,12 +460,15 @@ void GitPlugin::updateStatusBarSync() {
if ( mGit->getGitFolder().empty() )
return;
std::string text( mStatusBarDisplayModifications &&
( mGitStatus.totalInserts || mGitStatus.totalDeletions )
? String::format( "%s (+%d / -%d)", mGitBranch.c_str(),
mGitStatus.totalInserts, mGitStatus.totalDeletions )
: mGitBranch );
std::string text;
{
Lock l( mGitStatusMutex );
text = mStatusBarDisplayModifications &&
( mGitStatus.totalInserts || mGitStatus.totalDeletions )
? String::format( "%s (+%d / -%d)", gitBranch().c_str(), mGitStatus.totalInserts,
mGitStatus.totalDeletions )
: gitBranch();
}
mStatusButton->setText( text );
if ( !mStatusBarDisplayModifications )
@@ -493,25 +497,39 @@ void GitPlugin::updateStatusBarSync() {
}
void GitPlugin::updateStatus( bool force ) {
if ( !mGit || !mGitFound || !mStatusBarDisplayBranch )
if ( !mGit || !mGitFound || !mStatusBarDisplayBranch || mRunningUpdateStatus )
return;
mThreadPool->run( [this, force] {
if ( !mGit )
return;
if ( !mGit->getGitFolder().empty() ) {
auto prevBranch = mGitBranch;
mGitBranch = mGit->branch();
auto prevGitStatus = mGitStatus;
mGitStatus = mGit->status( mStatusRecurseSubmodules );
if ( !force && mGitBranch == prevBranch && mGitStatus == prevGitStatus )
mRunningUpdateStatus = true;
mThreadPool->run(
[this, force] {
if ( !mGit )
return;
} else if ( !mStatusButton ) {
return;
}
getUISceneNode()->runOnMainThread( [this] { updateStatusBarSync(); } );
} );
if ( !mGit->getGitFolder().empty() ) {
auto prevBranch = mGitBranch;
{
Lock l( mGitBranchMutex );
mGitBranch = mGit->branch();
}
Git::Status prevGitStatus;
{
Lock l( mGitStatusMutex );
prevGitStatus = mGitStatus;
}
Git::Status newGitStatus = mGit->status( mStatusRecurseSubmodules );
{
Lock l( mGitStatusMutex );
mGitStatus = std::move( newGitStatus );
if ( !force && mGitBranch == prevBranch && mGitStatus == prevGitStatus )
return;
}
} else if ( !mStatusButton ) {
return;
}
getUISceneNode()->runOnMainThread( [this] { updateStatusBarSync(); } );
},
[this]( auto ) { mRunningUpdateStatus = false; } );
}
PluginRequestHandle GitPlugin::processMessage( const PluginMessage& msg ) {
@@ -520,11 +538,13 @@ PluginRequestHandle GitPlugin::processMessage( const PluginMessage& msg ) {
if ( mGit ) {
mGit->setProjectPath( msg.asJSON()["folder"] );
updateUINow( true );
mInitialized = true;
}
break;
}
case ecode::PluginMessageType::UIReady: {
updateUINow();
if ( !mInitialized )
updateUINow();
break;
}
case ecode::PluginMessageType::UIThemeReloaded: {
@@ -638,7 +658,8 @@ bool GitPlugin::onMouseLeave( UICodeEditor* editor, const Vector2i&, const Uint3
return false;
}
std::string GitPlugin::gitBranch() const {
std::string GitPlugin::gitBranch() {
Lock l( mGitBranchMutex );
return mGitBranch;
}
@@ -751,25 +772,32 @@ bool GitPlugin::onKeyDown( UICodeEditor* editor, const KeyEvent& event ) {
}
void GitPlugin::updateBranches() {
if ( !mGit || !mGitFound )
if ( !mGit || !mGitFound || mRunningUpdateBranches )
return;
mThreadPool->run( [this] {
if ( !mGit )
return;
mRunningUpdateBranches = true;
mThreadPool->run(
[this] {
if ( !mGit || mGit->getGitFolder().empty() )
return;
{
Lock l( mGitBranchMutex );
if ( mGitBranch.empty() )
mGitBranch = mGit->branch();
}
if ( !mGit->getGitFolder().empty() ) {
if ( mGitBranch.empty() )
mGitBranch = mGit->branch();
auto branches = mGit->getAllBranchesAndTags();
auto hash = hashBranches( branches );
auto model = GitBranchModel::asModel( std::move( branches ), hash, this );
if ( mBranchesTree &&
static_cast<GitBranchModel*>( mBranchesTree->getModel() )->getHash() == hash )
return;
getUISceneNode()->runOnMainThread( [this, model] { updateBranchesUI( model ); } );
}
} );
},
[this]( auto ) { mRunningUpdateBranches = false; } );
}
void GitPlugin::updateBranchesUI( std::shared_ptr<GitBranchModel> model ) {
@@ -825,6 +853,7 @@ void GitPlugin::buildSidePanelTab() {
mBranchesTree->setAutoExpandOnSingleColumn( true );
mBranchesTree->setHeadersVisible( false );
mBranchesTree->setIndentWidth( 0 );
mBranchesTree->on( Event::OnModelEvent, [this]( const Event* event ) {
const ModelEvent* modelEvent = static_cast<const ModelEvent*>( event );
if ( !modelEvent->getModelIndex().hasParent() )
@@ -837,7 +866,10 @@ void GitPlugin::buildSidePanelTab() {
case EE::UI::Abstract::ModelEventType::Open: {
auto result = mGit->checkout( branch->name );
if ( result.returnCode == EXIT_SUCCESS ) {
mGitBranch = branch->name;
{
Lock l( mGitBranchMutex );
mGitBranch = branch->name;
}
if ( mBranchesTree->getModel() )
mBranchesTree->getModel()->invalidate( Model::DontInvalidateIndexes );
} else {
@@ -865,6 +897,7 @@ void GitPlugin::buildSidePanelTab() {
mStatusTree->setAutoColumnsWidth( true );
mStatusTree->setHeadersVisible( false );
mStatusTree->setIndentWidth( 0 );
}
} // namespace ecode
+7 -2
View File
@@ -16,7 +16,7 @@ class UITreeView;
class UIDropDownList;
class UIStackWidget;
class UIListBoxItem;
}
} // namespace EE::UI
namespace ecode {
@@ -54,7 +54,7 @@ class GitPlugin : public PluginBase {
bool onMouseLeave( UICodeEditor*, const Vector2i&, const Uint32& ) override;
std::string gitBranch() const;
std::string gitBranch();
protected:
std::unique_ptr<Git> mGit;
@@ -87,6 +87,7 @@ class GitPlugin : public PluginBase {
bool mStatusRecurseSubmodules{ true };
bool mOldDontAutoHideOnMouseMove{ false };
bool mOldUsingCustomStyling{ false };
bool mInitialized{ false };
Uint32 mOldTextStyle{ 0 };
Uint32 mOldTextAlign{ 0 };
Color mOldBackgroundColor;
@@ -100,6 +101,10 @@ class GitPlugin : public PluginBase {
std::vector<UIWidget*> mStackMap;
UIWidget* mGitContentView{ nullptr };
UIWidget* mGitNoContentView{ nullptr };
std::atomic<bool> mRunningUpdateBranches{ false };
std::atomic<bool> mRunningUpdateStatus{ false };
Mutex mGitBranchMutex;
Mutex mGitStatusMutex;
struct CustomTokenizer {
SyntaxDefinition def;
@@ -244,6 +244,8 @@ class LSPClientServer {
LSPDocumentClient* getLSPDocumentClient( TextDocument* doc );
bool isSilent() const;
protected:
LSPClientServerManager* mManager{ nullptr };
String::HashType mId;
@@ -314,8 +316,6 @@ class LSPClientServer {
void refreshCodeLens();
bool isSilent() const;
bool trimLogs() const;
};
@@ -299,7 +299,7 @@ void LSPDocumentClient::highlight() {
const auto& caps = mServer->getCapabilities().semanticTokenProvider;
Uint32 currentLine = 0;
Uint32 start = 0;
UnorderedMap<size_t, TokenizedLine> tokenizerLines;
std::unordered_map<size_t, TokenizedLine> tokenizerLines;
Int64 lastLine = 0;
TokenizedLine* lastLinePtr = nullptr;
Time diff;
@@ -350,10 +350,12 @@ void LSPDocumentClient::highlight() {
mDoc->getHighlighter()->mergeLine( tline.first, tline.second );
}
Log::debug( "LSPDocumentClient::highlight took: %.2f ms. Diff analysis took: %.2f ms. Updated "
"%lld elements",
clock.getElapsedTime().asMilliseconds(), diff.asMilliseconds(),
tokenizerLines.size() );
if ( !mServer->isSilent() ) {
Log::debug(
"LSPDocumentClient::highlight took: %.2f ms. Diff analysis took: %.2f ms. Updated "
"%lld elements",
clock.getElapsedTime().asMilliseconds(), diff.asMilliseconds(), tokenizerLines.size() );
}
}
void LSPDocumentClient::notifyOpen() {