mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-15 14:42:30 +00:00
* Added view_event_{added,removed} commands that sets a command to be
triggered when a download is added/removed from the specified view. * Minor compiler errors fixed. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1045 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+50
-13
@@ -171,12 +171,34 @@ View::sort() {
|
||||
|
||||
void
|
||||
View::filter() {
|
||||
iterator split = std::stable_partition(base_type::begin(), base_type::end(), view_downloads_filter(m_filter));
|
||||
// Parition the list in two steps so we know which elements changed.
|
||||
iterator splitVisible = std::stable_partition(begin_visible(), end_visible(), view_downloads_filter(m_filter));
|
||||
iterator splitFiltered = std::stable_partition(begin_filtered(), end_filtered(), view_downloads_filter(m_filter));
|
||||
|
||||
m_size = position(split);
|
||||
base_type changed(splitVisible, splitFiltered);
|
||||
iterator splitChanged = changed.begin() + std::distance(splitVisible, end_visible());
|
||||
|
||||
m_size = std::distance(begin(), std::copy(splitChanged, changed.end(), splitVisible));
|
||||
std::copy(changed.begin(), splitChanged, begin_filtered());
|
||||
|
||||
// Fix focus
|
||||
// Fix this...
|
||||
m_focus = std::min(m_focus, m_size);
|
||||
|
||||
// The commands are allowed to remove itself from or change View
|
||||
// sorting since the commands are being called on the 'changed'
|
||||
// vector. But this will cause undefined behavior if elements are
|
||||
// removed.
|
||||
//
|
||||
// Consider if View should lock itself (and throw) if erase events
|
||||
// are triggered on a Download in the 'changed' list. This can be
|
||||
// done by using a base_type* member variable, and making sure we
|
||||
// set the elements to NULL as we trigger commands on them. Or
|
||||
// perhaps always clear them, thus not throwing anything.
|
||||
if (!m_eventRemoved.empty())
|
||||
std::for_each(changed.begin(), splitChanged, rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_d_nothrow), m_eventRemoved));
|
||||
|
||||
if (!m_eventAdded.empty())
|
||||
std::for_each(splitChanged, changed.end(), rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_d_nothrow), m_eventAdded));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -225,10 +247,13 @@ View::received(core::Download* download, int event) {
|
||||
if (itr != base_type::end())
|
||||
throw torrent::internal_error("View::received(..., SLOTS_INSERT) already inserted.");
|
||||
|
||||
if (view_downloads_filter(m_filter)(download))
|
||||
if (view_downloads_filter(m_filter)(download)) {
|
||||
insert_visible(download);
|
||||
else
|
||||
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
|
||||
|
||||
} else {
|
||||
base_type::insert(end_filtered(), download);
|
||||
}
|
||||
|
||||
if (m_focus > m_size)
|
||||
throw torrent::internal_error("View::received(...) m_focus > m_size.");
|
||||
@@ -237,6 +262,8 @@ View::received(core::Download* download, int event) {
|
||||
|
||||
case DownloadList::SLOTS_ERASE:
|
||||
erase(itr);
|
||||
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -245,20 +272,30 @@ View::received(core::Download* download, int event) {
|
||||
|
||||
if (view_downloads_filter(m_filter)(download)) {
|
||||
|
||||
// Erase even if it is in visible so that the download is
|
||||
// re-sorted.
|
||||
//
|
||||
// Do we really want to do this?
|
||||
erase(itr);
|
||||
insert_visible(download);
|
||||
if (itr >= end_visible()) {
|
||||
// Erase even if it is in visible so that the download is
|
||||
// re-sorted.
|
||||
//
|
||||
// This isn't the best solution...
|
||||
erase(itr);
|
||||
insert_visible(download);
|
||||
|
||||
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
|
||||
|
||||
} else {
|
||||
// Should we really sort it here, or just return?
|
||||
erase(itr);
|
||||
insert_visible(download);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (itr >= begin_filtered())
|
||||
if (itr >= end_visible())
|
||||
return;
|
||||
|
||||
erase(itr);
|
||||
base_type::push_back(download);
|
||||
|
||||
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user