Implemented a method to disables update signals from the FileList model. This will significantly speed-up adding a lot files, but comes with the drawback that updates won't be visible immediately.
This commit is contained in:
parent
160b997c76
commit
a7a776ed82
@ -20,6 +20,7 @@ a:visited { color: #0000EE; }
|
|||||||
<li>Added Swedish translation, thanks to Åke Engelbrektson <eson57@gmail.com>
|
<li>Added Swedish translation, thanks to Åke Engelbrektson <eson57@gmail.com>
|
||||||
<li>Implemented multi-threading in initialization code for faster application startup
|
<li>Implemented multi-threading in initialization code for faster application startup
|
||||||
<li>Implemented multi-threading in file analyzer for faster file import
|
<li>Implemented multi-threading in file analyzer for faster file import
|
||||||
|
<li>Fixed a potential crash (stack overflow) when adding a huge number of files
|
||||||
</ul><br>
|
</ul><br>
|
||||||
|
|
||||||
<a name="4.04"></a>Changes between v4.03 and v4.04 [2012-04-26]:<br><ul>
|
<a name="4.04"></a>Changes between v4.03 and v4.04 [2012-04-26]:<br><ul>
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#define VER_LAMEXP_MINOR_LO 5
|
#define VER_LAMEXP_MINOR_LO 5
|
||||||
#define VER_LAMEXP_TYPE Alpha
|
#define VER_LAMEXP_TYPE Alpha
|
||||||
#define VER_LAMEXP_PATCH 1
|
#define VER_LAMEXP_PATCH 1
|
||||||
#define VER_LAMEXP_BUILD 1005
|
#define VER_LAMEXP_BUILD 1008
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Tool versions (minimum expected versions!)
|
// Tool versions (minimum expected versions!)
|
||||||
|
@ -519,7 +519,22 @@ void MainWindow::addFiles(const QStringList &files)
|
|||||||
connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
|
connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
|
||||||
connect(m_banner, SIGNAL(userAbort()), analyzer, SLOT(abortProcess()), Qt::DirectConnection);
|
connect(m_banner, SIGNAL(userAbort()), analyzer, SLOT(abortProcess()), Qt::DirectConnection);
|
||||||
|
|
||||||
m_banner->show(tr("Adding file(s), please wait..."), analyzer);
|
try
|
||||||
|
{
|
||||||
|
m_fileListModel->setBlockUpdates(true);
|
||||||
|
m_banner->show(tr("Adding file(s), please wait..."), analyzer);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
/* ignore any exceptions that may occur */
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fileListModel->setBlockUpdates(false);
|
||||||
|
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
|
sourceFileView->update();
|
||||||
|
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
|
sourceFileView->scrollToBottom();
|
||||||
|
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
|
|
||||||
if(analyzer->filesDenied())
|
if(analyzer->filesDenied())
|
||||||
{
|
{
|
||||||
@ -539,7 +554,6 @@ void MainWindow::addFiles(const QStringList &files)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LAMEXP_DELETE(analyzer);
|
LAMEXP_DELETE(analyzer);
|
||||||
sourceFileView->scrollToBottom();
|
|
||||||
m_banner->close();
|
m_banner->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ WorkingBanner::WorkingBanner(QWidget *parent)
|
|||||||
|
|
||||||
//Start animation
|
//Start animation
|
||||||
m_working = new QMovie(":/images/Busy.gif");
|
m_working = new QMovie(":/images/Busy.gif");
|
||||||
m_working->setSpeed(25);
|
m_working->setSpeed(50);
|
||||||
labelWorking->setMovie(m_working);
|
labelWorking->setMovie(m_working);
|
||||||
m_working->start();
|
m_working->start();
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
FileListModel::FileListModel(void)
|
FileListModel::FileListModel(void)
|
||||||
:
|
:
|
||||||
|
m_blockUpdates(false),
|
||||||
m_fileIcon(":/icons/page_white_cd.png")
|
m_fileIcon(":/icons/page_white_cd.png")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -138,26 +139,28 @@ void FileListModel::addFile(const QString &filePath)
|
|||||||
{
|
{
|
||||||
QFileInfo fileInfo(filePath);
|
QFileInfo fileInfo(filePath);
|
||||||
const QString key = MAKE_KEY(fileInfo.canonicalFilePath());
|
const QString key = MAKE_KEY(fileInfo.canonicalFilePath());
|
||||||
|
const bool flag = (!m_blockUpdates);
|
||||||
|
|
||||||
if(!m_fileStore.contains(key))
|
if(!m_fileStore.contains(key))
|
||||||
{
|
{
|
||||||
beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
|
if(flag) beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
|
||||||
m_fileStore.insert(key, AudioFileModel(fileInfo.canonicalFilePath(), fileInfo.baseName()));
|
m_fileStore.insert(key, AudioFileModel(fileInfo.canonicalFilePath(), fileInfo.baseName()));
|
||||||
m_fileList.append(key);
|
m_fileList.append(key);
|
||||||
endInsertRows();
|
if(flag) endInsertRows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileListModel::addFile(const AudioFileModel &file)
|
void FileListModel::addFile(const AudioFileModel &file)
|
||||||
{
|
{
|
||||||
const QString key = MAKE_KEY(file.filePath());
|
const QString key = MAKE_KEY(file.filePath());
|
||||||
|
const bool flag = (!m_blockUpdates);
|
||||||
|
|
||||||
if(!m_fileStore.contains(key))
|
if(!m_fileStore.contains(key))
|
||||||
{
|
{
|
||||||
beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
|
if(flag) beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
|
||||||
m_fileStore.insert(key, file);
|
m_fileStore.insert(key, file);
|
||||||
m_fileList.append(key);
|
m_fileList.append(key);
|
||||||
endInsertRows();
|
if(flag) endInsertRows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,11 +65,19 @@ public:
|
|||||||
}
|
}
|
||||||
CsvError;
|
CsvError;
|
||||||
|
|
||||||
|
//Speed hacks
|
||||||
|
void setBlockUpdates(bool flag)
|
||||||
|
{
|
||||||
|
m_blockUpdates = flag;
|
||||||
|
if(!flag) reset();
|
||||||
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addFile(const QString &filePath);
|
void addFile(const QString &filePath);
|
||||||
void addFile(const AudioFileModel &file);
|
void addFile(const AudioFileModel &file);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_blockUpdates;
|
||||||
QList<QString> m_fileList;
|
QList<QString> m_fileList;
|
||||||
QHash<QString, AudioFileModel> m_fileStore;
|
QHash<QString, AudioFileModel> m_fileStore;
|
||||||
const QIcon m_fileIcon;
|
const QIcon m_fileIcon;
|
||||||
|
@ -143,13 +143,18 @@ void FileAnalyzer::run()
|
|||||||
|
|
||||||
while(!pool->tryStart(task))
|
while(!pool->tryStart(task))
|
||||||
{
|
{
|
||||||
AnalyzeTask::waitForOneThread(1250);
|
if(!AnalyzeTask::waitForOneThread(1250))
|
||||||
|
{
|
||||||
|
qWarning("FileAnalyzer::run() -> Timeout !!!");
|
||||||
|
}
|
||||||
|
|
||||||
if(m_abortFlag)
|
if(m_abortFlag)
|
||||||
{
|
{
|
||||||
LAMEXP_DELETE(task);
|
LAMEXP_DELETE(task);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QThread::yieldCurrentThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_abortFlag)
|
if(m_abortFlag)
|
||||||
|
@ -80,7 +80,7 @@ AnalyzeTask::AnalyzeTask(const QString &inputFile, const QString &templateFile,
|
|||||||
AnalyzeTask::~AnalyzeTask(void)
|
AnalyzeTask::~AnalyzeTask(void)
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&s_lock);
|
QWriteLocker lock(&s_lock);
|
||||||
s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1);
|
s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1ui64);
|
||||||
s_waitCond.wakeAll();
|
s_waitCond.wakeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,23 @@ AnalyzeTask::~AnalyzeTask(void)
|
|||||||
// Thread Main
|
// Thread Main
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void AnalyzeTask::run(void)
|
void AnalyzeTask::run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
run_ex();
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
qWarning("WARNING: Caught an in exception AnalyzeTask thread!");
|
||||||
|
}
|
||||||
|
|
||||||
|
QWriteLocker lock(&s_lock);
|
||||||
|
s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1ui64);
|
||||||
|
s_waitCond.wakeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzeTask::run_ex(void)
|
||||||
{
|
{
|
||||||
int fileType = fileTypeNormal;
|
int fileType = fileTypeNormal;
|
||||||
QString currentFile = QDir::fromNativeSeparators(m_inputFile);
|
QString currentFile = QDir::fromNativeSeparators(m_inputFile);
|
||||||
@ -707,7 +723,10 @@ void AnalyzeTask::waitForPreviousThreads(void)
|
|||||||
}
|
}
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
waitForOneThread(1250);
|
if(!AnalyzeTask::waitForOneThread(1250))
|
||||||
|
{
|
||||||
|
qWarning("AnalyzeTask::waitForPreviousThreads -> Timeout !!!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,20 +54,22 @@ public:
|
|||||||
static unsigned int filesCueSheet(void);
|
static unsigned int filesCueSheet(void);
|
||||||
|
|
||||||
//Wait till the next running thread terminates
|
//Wait till the next running thread terminates
|
||||||
static void waitForOneThread(unsigned long timeout)
|
static __forceinline bool waitForOneThread(unsigned long timeout)
|
||||||
{
|
{
|
||||||
|
bool ret = false;
|
||||||
s_waitMutex.lock();
|
s_waitMutex.lock();
|
||||||
s_waitCond.wait(&s_waitMutex, timeout);
|
ret = s_waitCond.wait(&s_waitMutex, timeout);
|
||||||
s_waitMutex.unlock();
|
s_waitMutex.unlock();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(void);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void fileSelected(const QString &fileName);
|
void fileSelected(const QString &fileName);
|
||||||
void fileAnalyzed(const AudioFileModel &file);
|
void fileAnalyzed(const AudioFileModel &file);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void run(void);
|
||||||
|
void run_ex(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum cover_t
|
enum cover_t
|
||||||
|
Loading…
Reference in New Issue
Block a user