Skip to content

Commit

Permalink
Redesign file browser searching (LMMS#7130)
Browse files Browse the repository at this point in the history
  • Loading branch information
sakertooth authored and Rossmaxx committed Jun 15, 2024
1 parent 0f2866a commit fe7efa9
Show file tree
Hide file tree
Showing 10 changed files with 403 additions and 326 deletions.
20 changes: 11 additions & 9 deletions include/FileBrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@
#include <QCheckBox>
#include <QDir>
#include <QMutex>
#include "embed.h"

#include "FileBrowserSearcher.h"
#include <QProgressBar>
#include <memory>

#include "FileSearch.h"
#include "embed.h"

#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
#include <QRecursiveMutex>
Expand Down Expand Up @@ -76,9 +77,9 @@ class FileBrowser : public SideBarWidget

~FileBrowser() override = default;

static QStringList directoryBlacklist()
static QStringList excludedPaths()
{
static auto s_blacklist = QStringList{
static auto s_excludedPaths = QStringList{
#ifdef LMMS_BUILD_LINUX
"/bin", "/boot", "/dev", "/etc", "/proc", "/run", "/sbin",
"/sys"
Expand All @@ -87,7 +88,7 @@ class FileBrowser : public SideBarWidget
"C:\\Windows"
#endif
};
return s_blacklist;
return s_excludedPaths;
}
static QDir::Filters dirFilters() { return QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot; }
static QDir::SortFlags sortFlags() { return QDir::LocaleAware | QDir::DirsFirst | QDir::Name | QDir::IgnoreCase; }
Expand All @@ -105,16 +106,17 @@ private slots:
void saveDirectoriesStates();
void restoreDirectoriesStates();

void buildSearchTree();
void foundSearchMatch(FileSearch* search, const QString& match);
void searchCompleted(FileSearch* search);
void onSearch(const QString& filter);
void toggleSearch(bool on);
void displaySearch(bool on);

FileBrowserTreeWidget * m_fileBrowserTreeWidget;
FileBrowserTreeWidget * m_searchTreeWidget;

QLineEdit * m_filterEdit;

std::shared_ptr<FileBrowserSearcher::SearchFuture> m_currentSearch;
std::shared_ptr<FileSearch> m_currentSearch;
QProgressBar* m_searchIndicator = nullptr;

QString m_directories; //!< Directories to search, split with '*'
Expand Down
148 changes: 0 additions & 148 deletions include/FileBrowserSearcher.h

This file was deleted.

73 changes: 73 additions & 0 deletions include/FileSearch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* FileSearch.h - File system search task
*
* Copyright (c) 2024 saker
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#ifndef LMMS_FILE_SEARCH_H
#define LMMS_FILE_SEARCH_H

#include <QDir>
#include <QObject>
#include <atomic>

namespace lmms {
//! A Qt object that encapsulates the operation of searching the file system.
class FileSearch : public QObject
{
Q_OBJECT
public:
//! Number of milliseconds the search waits before signaling a matching result.
static constexpr int MillisecondsBetweenResults = 1;

//! Create a `FileSearch` object that uses the specified string filter `filter` and extension filters in
//! `extensions` to search within the given `paths`.
//! `excludedPaths`, `dirFilters`, and `sortFlags` can optionally be specified to exclude certain directories, filter
//! out certain types of entries, and sort the matches.
FileSearch(const QString& filter, const QStringList& paths, const QStringList& extensions,
const QStringList& excludedPaths = {}, QDir::Filters dirFilters = QDir::Filters{},
QDir::SortFlags sortFlags = QDir::SortFlags{});

//! Execute the search, emitting the `foundResult` signal when matches are found.
void operator()();

//! Cancel the search.
void cancel();

signals:
//! Emitted when a result is found when searching the file system.
void foundMatch(FileSearch* search, const QString& match);

//! Emitted when the search completes.
void searchCompleted(FileSearch* search);

private:
static auto isPathExcluded(const QString& path) -> bool;
QString m_filter;
QStringList m_paths;
QStringList m_extensions;
QStringList m_excludedPaths;
QDir::Filters m_dirFilters;
QDir::SortFlags m_sortFlags;
std::atomic<bool> m_cancel = false;
};
} // namespace lmms
#endif // LMMS_FILE_SEARCH_H
100 changes: 100 additions & 0 deletions include/ThreadPool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* ThreadPool.h
*
* Copyright (c) 2024 saker
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#ifndef LMMS_THREAD_POOL_H
#define LMMS_THREAD_POOL_H

#include <atomic>
#include <queue>
#include <tuple>
#include <type_traits>
#include <vector>

#ifdef __MINGW32__
#include <mingw.condition_variable.h>
#include <mingw.future.h>
#include <mingw.mutex.h>
#include <mingw.thread.h>
#else
#include <condition_variable>
#include <future>
#include <mutex>
#include <thread>
#endif

namespace lmms {
//! A thread pool that can be used for asynchronous processing.
class ThreadPool
{
public:
//! Destroys the `ThreadPool` object.
//! This blocks until all workers have finished executing.
~ThreadPool();

//! Enqueue function `fn` with arguments `args` to be ran asynchronously.
template <typename Fn, typename... Args>
auto enqueue(Fn&& fn, Args&&... args) -> std::future<std::invoke_result_t<Fn, Args...>>
{
using ReturnType = std::invoke_result_t<Fn, Args...>;

auto promise = std::make_shared<std::promise<ReturnType>>();
auto task = [promise, fn = std::forward<Fn>(fn), args = std::make_tuple(std::forward<Args>(args)...)]
{
if constexpr (!std::is_same_v<ReturnType, void>)
{
promise->set_value(std::apply(fn, args));
return;
}
std::apply(fn, args);
promise->set_value();
};

{
const auto lock = std::unique_lock{m_runMutex};
m_queue.push(std::move(task));
}

m_runCond.notify_one();
return promise->get_future();
}

//! Return the number of worker threads used.
auto numWorkers() const -> size_t;

//! Return the global `ThreadPool` instance.
static auto instance() -> ThreadPool&;

private:
ThreadPool(size_t numWorkers);
void run();
std::vector<std::thread> m_workers;
std::queue<std::function<void()>> m_queue;
std::atomic<bool> m_done = false;
std::condition_variable m_runCond;
std::mutex m_runMutex;
inline static size_t s_numWorkers = std::thread::hardware_concurrency();
};
} // namespace lmms

#endif // LMMS_THREAD_POOL_H
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set(LMMS_SRCS
core/Engine.cpp
core/EnvelopeAndLfoParameters.cpp
core/fft_helpers.cpp
core/FileSearch.cpp
core/Mixer.cpp
core/ImportFilter.cpp
core/InlineAutomation.cpp
Expand Down Expand Up @@ -76,6 +77,7 @@ set(LMMS_SRCS
core/SerializingObject.cpp
core/Song.cpp
core/TempoSyncKnobModel.cpp
core/ThreadPool.cpp
core/Timeline.cpp
core/TimePos.cpp
core/ToolPlugin.cpp
Expand Down
Loading

0 comments on commit fe7efa9

Please sign in to comment.