status: optimize filtering when chars are being taken from input queue

This commit is contained in:
Andrzej Rybczak
2012-09-05 22:20:50 +02:00
parent 39c5087d18
commit 21947d3655
5 changed files with 35 additions and 11 deletions

View File

@@ -1879,15 +1879,16 @@ void ApplyFilter::Run()
using Global::wFooter;
Filterable *f = dynamic_cast<Filterable *>(myScreen);
std::string filter = f->currentFilter();
LockStatusbar();
Statusbar() << NC::fmtBold << "Apply filter: " << NC::fmtBoldEnd;
wFooter->setGetStringHelper(std::bind(StatusbarApplyFilterImmediately, f, _1));
wFooter->getString(f->currentFilter());
wFooter->setGetStringHelper(StatusbarApplyFilterImmediately(f, ToWString(filter)));
wFooter->getString(filter);
wFooter->setGetStringHelper(StatusbargetStringHelper);
UnlockStatusbar();
std::string filter = f->currentFilter();
filter = f->currentFilter();
if (filter.empty())
{
myPlaylist->Items->clearFilterResults();

View File

@@ -78,16 +78,23 @@ void StatusbargetStringHelper(const std::wstring &)
TraceMpdStatus();
}
void StatusbarApplyFilterImmediately(Filterable *f, const std::wstring &ws)
void StatusbarApplyFilterImmediately::operator()(const std::wstring &ws)
{
static std::wstring cmp;
if (cmp != ws)
// if input queue is not empty, we don't want to update filter since next
// character will be taken from queue immediately, trigering this function
// again and thus making it inefficient, so let's apply filter only if
// "real" user input arrived. however, we want to apply filter if ENTER
// is next in queue, so its effects will be seen.
if (wFooter->inputQueue().empty() || wFooter->inputQueue().front() == KEY_ENTER)
{
cmp = ws;
f->applyFilter(ToString(cmp));
myScreen->RefreshWindow();
if (m_ws != ws)
{
m_ws = ws;
m_f->applyFilter(ToString(m_ws));
myScreen->RefreshWindow();
}
TraceMpdStatus();
}
TraceMpdStatus();
}
void LockProgressbar()

View File

@@ -46,7 +46,18 @@ void ShowMessage(const char *, ...) GNUC_PRINTF(1, 2);
void StatusbarMPDCallback();
void StatusbargetStringHelper(const std::wstring &);
void StatusbarApplyFilterImmediately(Filterable *f, const std::wstring &ws);
struct StatusbarApplyFilterImmediately
{
StatusbarApplyFilterImmediately(Filterable *f, const std::wstring &filter)
: m_f(f), m_ws(filter) { }
void operator()(const std::wstring &ws);
private:
Filterable *m_f;
std::wstring m_ws;
};
#endif

View File

@@ -174,6 +174,8 @@ std::string getEnclosedString(const std::string &s, char a, char b, size_t *pos)
// we want to set pos to char after b if possible
if (i < s.length())
++i;
else // we reached end of string and didn't encounter closing char
result.clear();
}
if (pos != 0)
*pos = i;

View File

@@ -340,6 +340,9 @@ struct Window
/// Push single character into input queue, so it can get consumed by ReadKey
void pushChar(int ch);
/// @return const reference to internal input queue
const std::queue<int> &inputQueue() { return m_input_queue; }
/// Scrolls the window by amount of lines given in its parameter
/// @param where indicates how many lines it has to scroll
virtual void scroll(Where where);