mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Projucer: Use std::async instead of ThreadPool in module scanner
This commit is contained in:
parent
250870a868
commit
5a621e811f
1 changed files with 60 additions and 96 deletions
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include "jucer_ModuleDescription.h"
|
||||
|
||||
#include <future>
|
||||
|
||||
//==============================================================================
|
||||
class AvailableModulesList : private AsyncUpdater
|
||||
{
|
||||
|
|
@ -39,16 +41,36 @@ public:
|
|||
//==============================================================================
|
||||
void scanPaths (const Array<File>& paths)
|
||||
{
|
||||
auto job = createScannerJob (paths);
|
||||
auto& ref = *job;
|
||||
|
||||
removePendingAndAddJob (std::move (job));
|
||||
scanPool.waitForJobToFinish (&ref, -1);
|
||||
scanPathsAsync (paths);
|
||||
scanner = {};
|
||||
}
|
||||
|
||||
void scanPathsAsync (const Array<File>& paths)
|
||||
{
|
||||
removePendingAndAddJob (createScannerJob (paths));
|
||||
scanner = std::async (std::launch::async, [this, paths]
|
||||
{
|
||||
ModuleIDAndFolderList list;
|
||||
|
||||
for (auto& p : paths)
|
||||
addAllModulesInFolder (p, list);
|
||||
|
||||
std::sort (list.begin(), list.end(), [] (const ModuleIDAndFolder& m1,
|
||||
const ModuleIDAndFolder& m2)
|
||||
{
|
||||
return m1.first.compareIgnoreCase (m2.first) < 0;
|
||||
});
|
||||
|
||||
{
|
||||
const ScopedLock swapLock (lock);
|
||||
|
||||
if (list == modulesList)
|
||||
return;
|
||||
|
||||
modulesList.swap (list);
|
||||
}
|
||||
|
||||
triggerAsyncUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -95,85 +117,50 @@ public:
|
|||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct ModuleScannerJob : public ThreadPoolJob
|
||||
static bool tryToAddModuleFromFolder (const File& path, ModuleIDAndFolderList& list)
|
||||
{
|
||||
ModuleScannerJob (const Array<File>& paths,
|
||||
std::function<void (const ModuleIDAndFolderList&)>&& callback)
|
||||
: ThreadPoolJob ("ModuleScannerJob"),
|
||||
pathsToScan (paths),
|
||||
completionCallback (std::move (callback))
|
||||
ModuleDescription m (path);
|
||||
|
||||
if (m.isValid()
|
||||
&& std::none_of (list.begin(), list.end(),
|
||||
[&m] (const ModuleIDAndFolder& element) { return element.first == m.getID(); }))
|
||||
{
|
||||
list.push_back ({ m.getID(), path });
|
||||
return true;
|
||||
}
|
||||
|
||||
JobStatus runJob() override
|
||||
return false;
|
||||
}
|
||||
|
||||
static void addAllModulesInFolder (const File& topLevelPath, ModuleIDAndFolderList& list)
|
||||
{
|
||||
struct FileAndDepth
|
||||
{
|
||||
ModuleIDAndFolderList list;
|
||||
File file;
|
||||
int depth;
|
||||
};
|
||||
|
||||
for (auto& p : pathsToScan)
|
||||
addAllModulesInFolder (p, list);
|
||||
std::queue<FileAndDepth> pathsToCheck;
|
||||
pathsToCheck.push ({ topLevelPath, 0 });
|
||||
|
||||
if (! shouldExit())
|
||||
{
|
||||
std::sort (list.begin(), list.end(), [] (const ModuleIDAndFolder& m1,
|
||||
const ModuleIDAndFolder& m2)
|
||||
{
|
||||
return m1.first.compareIgnoreCase (m2.first) < 0;
|
||||
});
|
||||
|
||||
completionCallback (list);
|
||||
}
|
||||
|
||||
return jobHasFinished;
|
||||
}
|
||||
|
||||
static bool tryToAddModuleFromFolder (const File& path, ModuleIDAndFolderList& list)
|
||||
while (! pathsToCheck.empty())
|
||||
{
|
||||
ModuleDescription m (path);
|
||||
const auto path = pathsToCheck.front();
|
||||
pathsToCheck.pop();
|
||||
|
||||
if (m.isValid()
|
||||
&& std::none_of (list.begin(), list.end(),
|
||||
[&m] (const ModuleIDAndFolder& element) { return element.first == m.getID(); }))
|
||||
if (tryToAddModuleFromFolder (path.file, list) || path.depth == 3)
|
||||
continue;
|
||||
|
||||
for (const auto& iter : RangedDirectoryIterator (path.file, false, "*", File::findDirectories))
|
||||
{
|
||||
list.push_back ({ m.getID(), path });
|
||||
return true;
|
||||
}
|
||||
if (auto* job = ThreadPoolJob::getCurrentThreadPoolJob())
|
||||
if (job->shouldExit())
|
||||
return;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void addAllModulesInFolder (const File& topLevelPath, ModuleIDAndFolderList& list)
|
||||
{
|
||||
struct FileAndDepth
|
||||
{
|
||||
File file;
|
||||
int depth;
|
||||
};
|
||||
|
||||
std::queue<FileAndDepth> pathsToCheck;
|
||||
pathsToCheck.push ({ topLevelPath, 0 });
|
||||
|
||||
while (! pathsToCheck.empty())
|
||||
{
|
||||
const auto path = pathsToCheck.front();
|
||||
pathsToCheck.pop();
|
||||
|
||||
if (tryToAddModuleFromFolder (path.file, list) || path.depth == 3)
|
||||
continue;
|
||||
|
||||
for (const auto& iter : RangedDirectoryIterator (path.file, false, "*", File::findDirectories))
|
||||
{
|
||||
if (auto* job = ThreadPoolJob::getCurrentThreadPoolJob())
|
||||
if (job->shouldExit())
|
||||
return;
|
||||
|
||||
pathsToCheck.push({ iter.getFile(), path.depth + 1 });
|
||||
}
|
||||
pathsToCheck.push({ iter.getFile(), path.depth + 1 });
|
||||
}
|
||||
}
|
||||
|
||||
Array<File> pathsToScan;
|
||||
std::function<void (const ModuleIDAndFolderList&)> completionCallback;
|
||||
};
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void handleAsyncUpdate() override
|
||||
|
|
@ -181,31 +168,8 @@ private:
|
|||
listeners.call ([this] (Listener& l) { l.availableModulesChanged (this); });
|
||||
}
|
||||
|
||||
std::unique_ptr<ThreadPoolJob> createScannerJob (const Array<File>& paths)
|
||||
{
|
||||
return std::make_unique<ModuleScannerJob> (paths, [this] (ModuleIDAndFolderList scannedModulesList)
|
||||
{
|
||||
if (scannedModulesList == modulesList)
|
||||
return;
|
||||
|
||||
{
|
||||
const ScopedLock swapLock (lock);
|
||||
modulesList.swap (scannedModulesList);
|
||||
}
|
||||
|
||||
triggerAsyncUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
void removePendingAndAddJob (std::unique_ptr<ThreadPoolJob> jobToAdd)
|
||||
{
|
||||
scanPool.removeAllJobs (false, 100);
|
||||
scanPool.addJob (jobToAdd.release(), true);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ThreadPool scanPool { 1 };
|
||||
|
||||
std::future<void> scanner;
|
||||
ModuleIDAndFolderList modulesList;
|
||||
ListenerList<Listener> listeners;
|
||||
CriticalSection lock;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue