mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-13 21:52:30 +00:00
* Moved various download related calls from core::Manager to
core::DownloadList, added a slot map for hash done. * Enabled the complete/incomplete views. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@677 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+2
-2
@@ -74,8 +74,8 @@ Control::Control() :
|
||||
m_tick(0) {
|
||||
|
||||
m_core = new core::Manager();
|
||||
m_viewManager = new core::ViewManager(&m_core->download_list());
|
||||
m_scheduler = new core::Scheduler(&m_core->download_list());
|
||||
m_viewManager = new core::ViewManager(m_core->download_list());
|
||||
m_scheduler = new core::Scheduler(m_core->download_list());
|
||||
|
||||
m_inputStdin->slot_pressed(sigc::mem_fun(m_input, &input::Manager::pressed));
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ libsub_core_a_SOURCES = \
|
||||
poll_manager_select.h \
|
||||
scheduler.cc \
|
||||
scheduler.h \
|
||||
view_downloads.cc \
|
||||
view_downloads.h \
|
||||
view.cc \
|
||||
view.h \
|
||||
view_manager.cc \
|
||||
view_manager.h
|
||||
|
||||
|
||||
+1
-26
@@ -71,6 +71,7 @@ Download::Download(download_type d) :
|
||||
m_variables.insert("connection_leech", new utils::VariableAny(connection_type_to_string(download_type::CONNECTION_LEECH)));
|
||||
m_variables.insert("connection_seed", new utils::VariableAny(connection_type_to_string(download_type::CONNECTION_SEED)));
|
||||
m_variables.insert("state", new utils::VariableObject(bencode(), "rtorrent", "state", torrent::Object::TYPE_VALUE));
|
||||
m_variables.insert("complete", new utils::VariableObject(bencode(), "rtorrent", "complete", torrent::Object::TYPE_VALUE));
|
||||
m_variables.insert("tied_to_file", new utils::VariableObject(bencode(), "rtorrent", "tied_to_file", torrent::Object::TYPE_STRING));
|
||||
|
||||
// The "state_changed" variable is required to be a valid unix time
|
||||
@@ -102,25 +103,6 @@ Download::~Download() {
|
||||
m_download = download_type();
|
||||
}
|
||||
|
||||
void
|
||||
Download::start() {
|
||||
if (is_done())
|
||||
m_download.set_connection_type(string_to_connection_type(m_variables.get("connection_seed").as_string()));
|
||||
else
|
||||
m_download.set_connection_type(string_to_connection_type(m_variables.get("connection_leech").as_string()));
|
||||
|
||||
// Update the priority to ensure it has the correct
|
||||
// seeding/unfinished modifiers.
|
||||
set_priority(priority());
|
||||
|
||||
m_download.start();
|
||||
}
|
||||
|
||||
void
|
||||
Download::stop() {
|
||||
m_download.stop();
|
||||
}
|
||||
|
||||
void
|
||||
Download::enable_udp_trackers(bool state) {
|
||||
torrent::TrackerList tl = m_download.tracker_list();
|
||||
@@ -152,13 +134,6 @@ Download::set_priority(uint32_t p) {
|
||||
bencode()->get_key("rtorrent").insert_key("priority", (int64_t)p);
|
||||
}
|
||||
|
||||
void
|
||||
Download::receive_finished() {
|
||||
m_download.set_connection_type(string_to_connection_type(m_variables.get("connection_seed").as_string()));
|
||||
// FIXME
|
||||
//torrent::download_set_priority(m_download, 2);
|
||||
}
|
||||
|
||||
void
|
||||
Download::receive_tracker_msg(std::string msg) {
|
||||
if (msg.empty())
|
||||
|
||||
+1
-6
@@ -62,11 +62,6 @@ public:
|
||||
bool is_active() const { return m_download.is_active(); }
|
||||
inline bool is_done() const { return m_download.chunks_done() == m_download.chunks_total(); }
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
// Add functions like pause/etc.
|
||||
|
||||
variable_map_type* variable() { return &m_variables; }
|
||||
std::string variable_string(const std::string& key) { return m_variables.get_string(key); }
|
||||
|
||||
@@ -97,7 +92,7 @@ public:
|
||||
|
||||
bool operator == (const std::string& str) { return str == m_download.info_hash(); }
|
||||
|
||||
void receive_finished();
|
||||
void set_connection_type(const std::string& t) { m_download.set_connection_type(string_to_connection_type(t)); }
|
||||
|
||||
static connection_type string_to_connection_type(const std::string& name);
|
||||
static const char* connection_type_to_string(connection_type t);
|
||||
|
||||
@@ -141,7 +141,7 @@ DownloadFactory::receive_success() {
|
||||
if (m_stream == NULL)
|
||||
throw torrent::client_error("DownloadFactory::receive_success() called on an object with m_stream == NULL");
|
||||
|
||||
Download* download = m_manager->download_list().create(m_stream, m_printLog);
|
||||
Download* download = m_manager->download_list()->create(m_stream, m_printLog);
|
||||
|
||||
if (download == NULL) {
|
||||
// core::Manager should already have added the error message to
|
||||
@@ -166,7 +166,7 @@ DownloadFactory::receive_success() {
|
||||
|
||||
initialize_rtorrent(download, rtorrent);
|
||||
|
||||
if (m_manager->download_list().insert(download) == m_manager->download_list().end()) {
|
||||
if (m_manager->download_list()->insert(download) == m_manager->download_list()->end()) {
|
||||
// ATM doesn't really ever get here.
|
||||
delete download;
|
||||
|
||||
@@ -191,7 +191,7 @@ DownloadFactory::receive_success() {
|
||||
download->variable()->set("directory", rtorrent->get_key("directory"));
|
||||
|
||||
if (download->variable()->get_value("state") == 1)
|
||||
m_manager->download_list().resume(download);
|
||||
m_manager->download_list()->resume(download);
|
||||
|
||||
} else {
|
||||
download->variable()->set("directory", m_variables.get("directory"));
|
||||
@@ -201,7 +201,7 @@ DownloadFactory::receive_success() {
|
||||
|
||||
// Use the state thingie here, move below.
|
||||
if (m_start)
|
||||
m_manager->download_list().start(download);
|
||||
m_manager->download_list()->start(download);
|
||||
|
||||
m_manager->download_store().save(download);
|
||||
}
|
||||
@@ -234,6 +234,9 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre
|
||||
rtorrent->insert_key("state_changed", cachedTime.seconds());
|
||||
}
|
||||
|
||||
if (!rtorrent->has_key_value("complete"))
|
||||
rtorrent->insert_key("complete", (int64_t)0);
|
||||
|
||||
if (!rtorrent->has_key_string("tied_to_file"))
|
||||
rtorrent->insert_key("tied_to_file", std::string());
|
||||
|
||||
|
||||
+102
-21
@@ -47,17 +47,19 @@
|
||||
#include "rak/functional.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "hash_queue.h"
|
||||
#include "manager.h"
|
||||
|
||||
#include "download.h"
|
||||
#include "download_list.h"
|
||||
#include "download_store.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
struct download_list_call {
|
||||
download_list_call(Download* d) : m_download(d) {}
|
||||
|
||||
void operator () (const DownloadList::SlotMap::value_type& s) {
|
||||
void operator () (const DownloadList::slot_map::value_type& s) {
|
||||
s.second(m_download);
|
||||
}
|
||||
|
||||
@@ -94,10 +96,10 @@ DownloadList::create(std::istream* str, bool printLog) {
|
||||
|
||||
DownloadList::iterator
|
||||
DownloadList::insert(Download* d) {
|
||||
iterator itr = Base::insert(end(), d);
|
||||
iterator itr = base_type::insert(end(), d);
|
||||
|
||||
try {
|
||||
(*itr)->download()->signal_download_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::finished), *itr));
|
||||
(*itr)->download()->signal_download_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::received_finished), d));
|
||||
std::for_each(m_slotMapInsert.begin(), m_slotMapInsert.end(), download_list_call(*itr));
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
@@ -128,7 +130,7 @@ DownloadList::erase(iterator itr) {
|
||||
torrent::download_remove(*(*itr)->download());
|
||||
delete *itr;
|
||||
|
||||
return Base::erase(itr);
|
||||
return base_type::erase(itr);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -173,18 +175,32 @@ DownloadList::stop(Download* d) {
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::resume(Download* d) {
|
||||
DownloadList::resume(Download* download) {
|
||||
try {
|
||||
if (!d->download()->is_open())
|
||||
std::for_each(m_slotMapOpen.begin(), m_slotMapOpen.end(), download_list_call(d));
|
||||
|
||||
if (d->download()->is_hash_checked())
|
||||
std::for_each(m_slotMapStart.begin(), m_slotMapStart.end(), download_list_call(d));
|
||||
else
|
||||
// TODO: This can cause infinit looping?
|
||||
control->core()->hash_queue().insert(d, sigc::bind(sigc::mem_fun(*this, &DownloadList::resume), d));
|
||||
|
||||
d->variable()->set("state_changed", cachedTime.seconds());
|
||||
if (!download->download()->is_open())
|
||||
std::for_each(m_slotMapOpen.begin(), m_slotMapOpen.end(), download_list_call(download));
|
||||
|
||||
if (download->download()->is_hash_checked()) {
|
||||
|
||||
if (download->is_done())
|
||||
download->set_connection_type(download->variable()->get_string("connection_seed"));
|
||||
else
|
||||
download->set_connection_type(download->variable()->get_string("connection_leech"));
|
||||
|
||||
// Update the priority to ensure it has the correct
|
||||
// seeding/unfinished modifiers.
|
||||
download->set_priority(download->priority());
|
||||
download->download()->start();
|
||||
|
||||
std::for_each(m_slotMapStart.begin(), m_slotMapStart.end(), download_list_call(download));
|
||||
|
||||
} else {
|
||||
// TODO: This can cause infinit looping?
|
||||
control->core()->hash_queue()->insert(download);
|
||||
}
|
||||
|
||||
download->variable()->set("state_changed", cachedTime.seconds());
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
control->core()->push_log(e.what());
|
||||
@@ -192,13 +208,20 @@ DownloadList::resume(Download* d) {
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::pause(Download* d) {
|
||||
DownloadList::pause(Download* download) {
|
||||
try {
|
||||
|
||||
if (d->download()->is_active())
|
||||
std::for_each(m_slotMapStop.begin(), m_slotMapStop.end(), download_list_call(d));
|
||||
download->download()->stop();
|
||||
download->download()->hash_resume_save();
|
||||
|
||||
if (download->download()->is_active())
|
||||
std::for_each(m_slotMapStop.begin(), m_slotMapStop.end(), download_list_call(download));
|
||||
|
||||
d->variable()->set("state_changed", cachedTime.seconds());
|
||||
download->variable()->set("state_changed", cachedTime.seconds());
|
||||
|
||||
// Save the state after all the slots, etc have been called so we
|
||||
// include the modifications they may make.
|
||||
control->core()->download_store().save(download);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
control->core()->push_log(e.what());
|
||||
@@ -209,12 +232,70 @@ void
|
||||
DownloadList::clear() {
|
||||
std::for_each(begin(), end(), rak::call_delete<Download>());
|
||||
|
||||
Base::clear();
|
||||
base_type::clear();
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::finished(Download* d) {
|
||||
std::for_each(m_slotMapFinished.begin(), m_slotMapFinished.end(), download_list_call(d));
|
||||
DownloadList::check_hash(Download* d) {
|
||||
close(d);
|
||||
d->download()->hash_resume_clear();
|
||||
open(d);
|
||||
|
||||
control->core()->hash_queue()->insert(d);
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::hash_done(Download* download) {
|
||||
if (!download->download()->is_hash_checked() || download->download()->is_hash_checking())
|
||||
throw torrent::internal_error("DownloadList::hash_done(...) download in invalid state.");
|
||||
|
||||
// Need to find some sane conditional here. Can we check the total
|
||||
// downloaded to ensure something was transferred, thus we didn't
|
||||
// just hash an already completed torrent with lacking session data?
|
||||
//
|
||||
// Perhaps we should use a seperate variable or state, and check
|
||||
// that. Thus we can bork the download if the hash check doesn't
|
||||
// confirm all the data, avoiding large BW usage on f.ex. the
|
||||
// ReiserFS bug with >4GB files.
|
||||
|
||||
// Use just is_done(), have another if statement inside.
|
||||
if (download->is_done() && download->variable()->get_value("complete") == 0) {
|
||||
|
||||
if (control->variable()->get_value("session_on_completion"))
|
||||
control->core()->download_store().save(download);
|
||||
|
||||
// Send a "truly finished message from here.
|
||||
confirm_finished(download);
|
||||
}
|
||||
|
||||
if (download->variable()->get_value("state") == 1)
|
||||
resume(download);
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::received_finished(Download* download) {
|
||||
if (control->variable()->get_value("check_hash")) {
|
||||
// Set some 'checking_finished_thingie' variable to make hash_done
|
||||
// trigger correctly, also so it can bork on missing data.
|
||||
|
||||
check_hash(download);
|
||||
|
||||
} else {
|
||||
confirm_finished(download);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::confirm_finished(Download* download) {
|
||||
// FIXME
|
||||
//torrent::download_set_priority(m_download, 2);
|
||||
|
||||
download->variable()->set("complete", (int64_t)1);
|
||||
download->set_connection_type(download->variable()->get_string("connection_seed"));
|
||||
|
||||
download->download()->tracker_list().send_completed();
|
||||
|
||||
std::for_each(m_slotMapFinished.begin(), m_slotMapFinished.end(), download_list_call(download));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+52
-36
@@ -53,23 +53,24 @@ class Download;
|
||||
|
||||
class DownloadList : private std::list<Download*> {
|
||||
public:
|
||||
typedef std::list<Download*> Base;
|
||||
typedef std::map<std::string, sigc::slot1<void, Download*> > SlotMap;
|
||||
typedef std::list<Download*> base_type;
|
||||
typedef sigc::slot1<void, Download*> slot_type;
|
||||
typedef std::map<std::string, slot_type> slot_map;
|
||||
|
||||
using Base::iterator;
|
||||
using Base::const_iterator;
|
||||
using Base::reverse_iterator;
|
||||
using Base::const_reverse_iterator;
|
||||
using Base::value_type;
|
||||
using Base::pointer;
|
||||
using base_type::iterator;
|
||||
using base_type::const_iterator;
|
||||
using base_type::reverse_iterator;
|
||||
using base_type::const_reverse_iterator;
|
||||
using base_type::value_type;
|
||||
using base_type::pointer;
|
||||
|
||||
using Base::begin;
|
||||
using Base::end;
|
||||
using Base::rbegin;
|
||||
using Base::rend;
|
||||
using base_type::begin;
|
||||
using base_type::end;
|
||||
using base_type::rbegin;
|
||||
using base_type::rend;
|
||||
|
||||
using Base::empty;
|
||||
using Base::size;
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
~DownloadList() { clear(); }
|
||||
|
||||
@@ -91,37 +92,52 @@ public:
|
||||
void resume(Download* d);
|
||||
void pause(Download* d);
|
||||
|
||||
SlotMap& slot_map_insert() { return m_slotMapInsert; }
|
||||
SlotMap& slot_map_erase() { return m_slotMapErase; }
|
||||
SlotMap& slot_map_open() { return m_slotMapOpen; }
|
||||
SlotMap& slot_map_close() { return m_slotMapClose; }
|
||||
SlotMap& slot_map_start() { return m_slotMapStart; }
|
||||
SlotMap& slot_map_stop() { return m_slotMapStop; }
|
||||
void check_hash(Download* d);
|
||||
void hash_done(Download* d);
|
||||
|
||||
SlotMap& slot_map_finished() { return m_slotMapFinished; }
|
||||
slot_map& slot_map_insert() { return m_slotMapInsert; }
|
||||
slot_map& slot_map_erase() { return m_slotMapErase; }
|
||||
slot_map& slot_map_open() { return m_slotMapOpen; }
|
||||
slot_map& slot_map_close() { return m_slotMapClose; }
|
||||
slot_map& slot_map_start() { return m_slotMapStart; }
|
||||
slot_map& slot_map_stop() { return m_slotMapStop; }
|
||||
|
||||
bool has_slot_insert(const std::string& key) const { return m_slotMapInsert.find(key) != m_slotMapInsert.end(); }
|
||||
bool has_slot_erase(const std::string& key) const { return m_slotMapErase.find(key) != m_slotMapErase.end(); }
|
||||
bool has_slot_open(const std::string& key) const { return m_slotMapOpen.find(key) != m_slotMapOpen.end(); }
|
||||
bool has_slot_close(const std::string& key) const { return m_slotMapClose.find(key) != m_slotMapClose.end(); }
|
||||
bool has_slot_start(const std::string& key) const { return m_slotMapStart.find(key) != m_slotMapStart.end(); }
|
||||
bool has_slot_stop(const std::string& key) const { return m_slotMapStop.find(key) != m_slotMapStop.end(); }
|
||||
// The finished slots will be called when an active download with
|
||||
// "finished" == 0 performs a hash check which returns a done
|
||||
// torrent.
|
||||
//
|
||||
// But how to avoid sending 'completed' messages to the tracker?
|
||||
// Also we need to handle cases when a hashing torrent starts up
|
||||
// after a shutdown.
|
||||
|
||||
bool has_slot_finished(const std::string& key) const { return m_slotMapFinished.find(key) != m_slotMapFinished.end(); }
|
||||
slot_map& slot_map_hash_done() { return m_slotMapHashDone; }
|
||||
slot_map& slot_map_finished() { return m_slotMapFinished; }
|
||||
|
||||
bool has_slot_insert(const std::string& key) const { return m_slotMapInsert.find(key) != m_slotMapInsert.end(); }
|
||||
bool has_slot_erase(const std::string& key) const { return m_slotMapErase.find(key) != m_slotMapErase.end(); }
|
||||
bool has_slot_open(const std::string& key) const { return m_slotMapOpen.find(key) != m_slotMapOpen.end(); }
|
||||
bool has_slot_close(const std::string& key) const { return m_slotMapClose.find(key) != m_slotMapClose.end(); }
|
||||
bool has_slot_start(const std::string& key) const { return m_slotMapStart.find(key) != m_slotMapStart.end(); }
|
||||
bool has_slot_stop(const std::string& key) const { return m_slotMapStop.find(key) != m_slotMapStop.end(); }
|
||||
|
||||
bool has_slot_hash_done(const std::string& key) const { return m_slotMapFinished.find(key) != m_slotMapFinished.end(); }
|
||||
bool has_slot_finished(const std::string& key) const { return m_slotMapFinished.find(key) != m_slotMapFinished.end(); }
|
||||
|
||||
private:
|
||||
void clear();
|
||||
|
||||
void finished(Download* d);
|
||||
void received_finished(Download* d);
|
||||
void confirm_finished(Download* d);
|
||||
|
||||
SlotMap m_slotMapInsert;
|
||||
SlotMap m_slotMapErase;
|
||||
SlotMap m_slotMapOpen;
|
||||
SlotMap m_slotMapClose;
|
||||
SlotMap m_slotMapStart;
|
||||
SlotMap m_slotMapStop;
|
||||
slot_map m_slotMapInsert;
|
||||
slot_map m_slotMapErase;
|
||||
slot_map m_slotMapOpen;
|
||||
slot_map m_slotMapClose;
|
||||
slot_map m_slotMapStart;
|
||||
slot_map m_slotMapStop;
|
||||
|
||||
SlotMap m_slotMapFinished;
|
||||
slot_map m_slotMapHashDone;
|
||||
slot_map m_slotMapFinished;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+12
-12
@@ -41,26 +41,29 @@
|
||||
#include <sigc++/bind.h>
|
||||
|
||||
#include "download.h"
|
||||
#include "download_list.h"
|
||||
#include "rak/functional.h"
|
||||
#include "hash_queue.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
void
|
||||
HashQueue::insert(Download* d, Slot s) {
|
||||
if (d->download()->is_hash_checking() ||
|
||||
find(d) != end())
|
||||
HashQueue::insert(Download* download) {
|
||||
if (download->download()->is_hash_checking() ||
|
||||
find(download) != end())
|
||||
return;
|
||||
|
||||
if (d->download()->is_hash_checked()) {
|
||||
s();
|
||||
if (download->download()->is_hash_checked()) {
|
||||
m_downloadList->hash_done(download);
|
||||
return;
|
||||
}
|
||||
|
||||
iterator itr = Base::insert(end(), new HashQueueNode(d, s));
|
||||
if (find(download) != end())
|
||||
throw torrent::internal_error("HashQueue::insert(...) download already in queue.");
|
||||
|
||||
(*itr)->set_connection(d->download()->signal_hash_done(sigc::bind(sigc::mem_fun(*this, &HashQueue::receive_hash_done),
|
||||
(*itr)->download())));
|
||||
iterator itr = Base::insert(end(), new HashQueueNode(download));
|
||||
|
||||
(*itr)->set_connection(download->download()->signal_hash_done(sigc::bind(sigc::mem_fun(*this, &HashQueue::receive_hash_done), download)));
|
||||
|
||||
fill_queue();
|
||||
}
|
||||
@@ -95,13 +98,10 @@ HashQueue::receive_hash_done(Download* d) {
|
||||
if (itr == end())
|
||||
return;
|
||||
|
||||
Slot s = (*itr)->get_slot();
|
||||
|
||||
delete *itr;
|
||||
Base::erase(itr);
|
||||
|
||||
// Can we call this before the delete?
|
||||
s();
|
||||
m_downloadList->hash_done(d);
|
||||
fill_queue();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
namespace core {
|
||||
|
||||
class Download;
|
||||
class DownloadList;
|
||||
|
||||
class HashQueueNode;
|
||||
|
||||
class HashQueue : private std::list<HashQueueNode*> {
|
||||
public:
|
||||
typedef std::list<HashQueueNode*> Base;
|
||||
typedef sigc::slot0<void> Slot;
|
||||
|
||||
using Base::iterator;
|
||||
using Base::const_iterator;
|
||||
@@ -68,7 +68,10 @@ public:
|
||||
using Base::empty;
|
||||
using Base::size;
|
||||
|
||||
void insert(Download* d, Slot s);
|
||||
// Replace 'dl' with a slot.
|
||||
HashQueue(DownloadList* dl) : m_downloadList(dl) {}
|
||||
|
||||
void insert(Download* d);
|
||||
|
||||
// It's safe to try to remove downloads not in the queue. The hash
|
||||
// checking is not stopped if it has already started.
|
||||
@@ -80,23 +83,22 @@ private:
|
||||
void receive_hash_done(Download* d);
|
||||
|
||||
void fill_queue();
|
||||
|
||||
DownloadList* m_downloadList;
|
||||
};
|
||||
|
||||
class HashQueueNode {
|
||||
public:
|
||||
HashQueueNode(Download* d, HashQueue::Slot s) : m_download(d), m_slot(s) {}
|
||||
HashQueueNode(Download* d) : m_download(d) {}
|
||||
~HashQueueNode() { disconnect(); }
|
||||
|
||||
void disconnect() { m_connection.disconnect(); }
|
||||
|
||||
Download* download() { return m_download; }
|
||||
HashQueue::Slot get_slot() { return m_slot; }
|
||||
|
||||
void set_connection(sigc::connection c) { m_connection = c; }
|
||||
|
||||
private:
|
||||
Download* m_download;
|
||||
HashQueue::Slot m_slot;
|
||||
sigc::connection m_connection;
|
||||
};
|
||||
|
||||
|
||||
+22
-81
@@ -59,6 +59,7 @@
|
||||
#include "curl_get.h"
|
||||
#include "download.h"
|
||||
#include "download_factory.h"
|
||||
#include "hash_queue.h"
|
||||
#include "manager.h"
|
||||
#include "poll_manager_epoll.h"
|
||||
#include "poll_manager_select.h"
|
||||
@@ -114,6 +115,14 @@ Manager::Manager() :
|
||||
m_pollManager(NULL),
|
||||
m_portFirst(6890),
|
||||
m_portLast(6999) {
|
||||
|
||||
m_downloadList = new DownloadList();
|
||||
m_hashQueue = new HashQueue(m_downloadList);
|
||||
}
|
||||
|
||||
Manager::~Manager() {
|
||||
delete m_hashQueue;
|
||||
delete m_downloadList;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -139,29 +148,20 @@ Manager::initialize_second() {
|
||||
|
||||
// Register slots to be called when a download is inserted/erased,
|
||||
// opened or closed.
|
||||
m_downloadList.slot_map_insert()["1_connect_network_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_network_log), sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
m_downloadList.slot_map_insert()["1_connect_storage_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_storage_log), sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
m_downloadList.slot_map_insert()["1_connect_tracker_dump"] = sigc::bind(sigc::ptr_fun(&connect_signal_tracker_dump), sigc::ptr_fun(&receive_tracker_dump));
|
||||
m_downloadList->slot_map_insert()["1_connect_network_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_network_log), sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
m_downloadList->slot_map_insert()["1_connect_storage_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_storage_log), sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
m_downloadList->slot_map_insert()["1_connect_tracker_dump"] = sigc::bind(sigc::ptr_fun(&connect_signal_tracker_dump), sigc::ptr_fun(&receive_tracker_dump));
|
||||
|
||||
m_downloadList.slot_map_erase()["1_hash_queue_remove"] = sigc::mem_fun(m_hashQueue, &HashQueue::remove);
|
||||
m_downloadList.slot_map_erase()["1_store_remove"] = sigc::mem_fun(m_downloadStore, &DownloadStore::remove);
|
||||
m_downloadList.slot_map_erase()["1_delete_tied"] = sigc::ptr_fun(&delete_tied);
|
||||
m_downloadList->slot_map_erase()["1_hash_queue_remove"] = sigc::mem_fun(m_hashQueue, &HashQueue::remove);
|
||||
m_downloadList->slot_map_erase()["1_store_remove"] = sigc::mem_fun(m_downloadStore, &DownloadStore::remove);
|
||||
m_downloadList->slot_map_erase()["1_delete_tied"] = sigc::ptr_fun(&delete_tied);
|
||||
|
||||
m_downloadList.slot_map_open()["1_download_open"] = sigc::mem_fun(&Download::call<void, &torrent::Download::open>);
|
||||
m_downloadList->slot_map_open()["1_download_open"] = sigc::mem_fun(&Download::call<void, &torrent::Download::open>);
|
||||
|
||||
// Currently does not call stop, might want to add a function that
|
||||
// checks if we're running, and if so stop?
|
||||
m_downloadList.slot_map_close()["1_hash_queue_remove"] = sigc::mem_fun(m_hashQueue, &HashQueue::remove);
|
||||
m_downloadList.slot_map_close()["2_download_close"] = sigc::mem_fun(&Download::call<void, &torrent::Download::close>);
|
||||
|
||||
m_downloadList.slot_map_start()["1_download_start"] = sigc::mem_fun(&Download::start);
|
||||
|
||||
m_downloadList.slot_map_stop()["1_download_stop"] = sigc::mem_fun(&Download::stop);
|
||||
m_downloadList.slot_map_stop()["2_hash_resume_save"] = sigc::mem_fun(&Download::call<void, &torrent::Download::hash_resume_save>);
|
||||
m_downloadList.slot_map_stop()["3_store_save"] = sigc::mem_fun(m_downloadStore, &DownloadStore::save);
|
||||
|
||||
m_downloadList.slot_map_finished()["1_download_done"] = sigc::mem_fun(*this, &Manager::receive_download_done);
|
||||
m_downloadList.slot_map_finished()["2_receive_finished"] = sigc::mem_fun(&Download::receive_finished);
|
||||
m_downloadList->slot_map_close()["1_hash_queue_remove"] = sigc::mem_fun(m_hashQueue, &HashQueue::remove);
|
||||
m_downloadList->slot_map_close()["2_download_close"] = sigc::mem_fun(&Download::call<void, &torrent::Download::close>);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -178,42 +178,9 @@ Manager::cleanup() {
|
||||
void
|
||||
Manager::shutdown(bool force) {
|
||||
if (!force)
|
||||
std::for_each(m_downloadList.begin(), m_downloadList.end(), std::bind1st(std::mem_fun(&DownloadList::pause), &m_downloadList));
|
||||
std::for_each(m_downloadList->begin(), m_downloadList->end(), std::bind1st(std::mem_fun(&DownloadList::pause), &m_downloadList));
|
||||
else
|
||||
std::for_each(m_downloadList.begin(), m_downloadList.end(), std::bind1st(std::mem_fun(&DownloadList::close), &m_downloadList));
|
||||
}
|
||||
|
||||
void
|
||||
Manager::check_hash(Download* d) {
|
||||
bool restart = d->download()->is_active();
|
||||
|
||||
try {
|
||||
prepare_hash_check(d);
|
||||
|
||||
if (restart)
|
||||
m_hashQueue.insert(d, sigc::bind(sigc::mem_fun(m_downloadList, &DownloadList::resume), d));
|
||||
else
|
||||
m_hashQueue.insert(d, sigc::slot0<void>());
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
m_logImportant.push_front(e.what());
|
||||
m_logComplete.push_front(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Manager::receive_download_done(Download* d) {
|
||||
if (control->variable()->get_value("check_hash")) {
|
||||
// Start the hash checking, send completed to tracker after
|
||||
// finishing.
|
||||
prepare_hash_check(d);
|
||||
|
||||
// TODO: Need to restart the torrent.
|
||||
m_hashQueue.insert(d, sigc::bind(sigc::mem_fun(*this, &Manager::receive_download_done_hash_checked), d));
|
||||
|
||||
} else {
|
||||
receive_download_done_hash_checked(d);
|
||||
}
|
||||
std::for_each(m_downloadList->begin(), m_downloadList->end(), std::bind1st(std::mem_fun(&DownloadList::close), &m_downloadList));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -297,38 +264,12 @@ Manager::set_local_address(const std::string& addr) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Manager::prepare_hash_check(Download* d) {
|
||||
m_downloadList.close(d);
|
||||
d->download()->hash_resume_clear();
|
||||
m_downloadList.open(d);
|
||||
|
||||
if (d->download()->is_hash_checking() ||
|
||||
d->download()->is_hash_checked())
|
||||
throw std::logic_error("Manager::check_hash(...) closed the torrent but is_hash_check{ing,ed}() == true");
|
||||
|
||||
if (m_hashQueue.find(d) != m_hashQueue.end())
|
||||
throw std::logic_error("Manager::check_hash(...) closed the torrent but it was found in m_hashQueue");
|
||||
}
|
||||
|
||||
void
|
||||
Manager::receive_http_failed(std::string msg) {
|
||||
m_logImportant.push_front("Http download error: \"" + msg + "\"");
|
||||
m_logComplete.push_front("Http download error: \"" + msg + "\"");
|
||||
}
|
||||
|
||||
void
|
||||
Manager::receive_download_done_hash_checked(Download* d) {
|
||||
m_downloadList.resume(d);
|
||||
|
||||
if (control->variable()->get_value("session_on_completion"))
|
||||
m_downloadStore.save(d);
|
||||
|
||||
// Don't send if we did a hash check and found incompelete chunks.
|
||||
if (d->is_done())
|
||||
d->download()->tracker_list().send_completed();
|
||||
}
|
||||
|
||||
void
|
||||
Manager::try_create_download(const std::string& uri, bool start, bool printLog, bool tied) {
|
||||
// Adding download.
|
||||
@@ -398,8 +339,8 @@ Manager::try_create_download_expand(const std::string& uri, bool start, bool pri
|
||||
|
||||
if (tied)
|
||||
for (std::vector<std::string>::iterator itr = paths.begin(); itr != paths.end(); )
|
||||
if (std::find_if(m_downloadList.begin(), m_downloadList.end(),
|
||||
rak::equal(*itr, rak::bind2nd(std::mem_fun(&Download::variable_string), "tied_to_file"))) != m_downloadList.end())
|
||||
if (std::find_if(m_downloadList->begin(), m_downloadList->end(),
|
||||
rak::equal(*itr, rak::bind2nd(std::mem_fun(&Download::variable_string), "tied_to_file"))) != m_downloadList->end())
|
||||
itr = paths.erase(itr);
|
||||
else
|
||||
itr++;
|
||||
|
||||
+8
-12
@@ -41,7 +41,6 @@
|
||||
|
||||
#include "download_list.h"
|
||||
#include "download_store.h"
|
||||
#include "hash_queue.h"
|
||||
#include "http_queue.h"
|
||||
#include "poll_manager.h"
|
||||
#include "log.h"
|
||||
@@ -52,6 +51,8 @@ namespace torrent {
|
||||
|
||||
namespace core {
|
||||
|
||||
class HashQueue;
|
||||
|
||||
class Manager {
|
||||
public:
|
||||
typedef DownloadList::iterator DListItr;
|
||||
@@ -59,12 +60,14 @@ public:
|
||||
typedef sigc::slot0<void> SlotFailed;
|
||||
|
||||
Manager();
|
||||
~Manager();
|
||||
|
||||
DownloadList& download_list() { return m_downloadList; }
|
||||
DownloadStore& download_store() { return m_downloadStore; }
|
||||
HashQueue& hash_queue() { return m_hashQueue; }
|
||||
HttpQueue& http_queue() { return m_httpQueue; }
|
||||
|
||||
DownloadList* download_list() { return m_downloadList; }
|
||||
HashQueue* hash_queue() { return m_hashQueue; }
|
||||
|
||||
PollManager* get_poll_manager() { return m_pollManager; }
|
||||
Log& get_log_important() { return m_logImportant; }
|
||||
Log& get_log_complete() { return m_logComplete; }
|
||||
@@ -86,8 +89,6 @@ public:
|
||||
|
||||
void shutdown(bool force);
|
||||
|
||||
void check_hash(Download* d);
|
||||
|
||||
void push_log(const std::string& msg) { m_logImportant.push_front(msg); m_logComplete.push_front(msg); }
|
||||
|
||||
// Temporary, find a better place for this.
|
||||
@@ -100,16 +101,11 @@ private:
|
||||
|
||||
void initialize_bencode(Download* d);
|
||||
|
||||
void prepare_hash_check(Download* d);
|
||||
|
||||
void receive_http_failed(std::string msg);
|
||||
void receive_download_done_hash_checked(Download* d);
|
||||
void receive_download_inserted(Download* d);
|
||||
void receive_download_done(Download* d);
|
||||
|
||||
DownloadList m_downloadList;
|
||||
DownloadList* m_downloadList;
|
||||
DownloadStore m_downloadStore;
|
||||
HashQueue m_hashQueue;
|
||||
HashQueue* m_hashQueue;
|
||||
HttpQueue m_httpQueue;
|
||||
|
||||
PollManager* m_pollManager;
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "download.h"
|
||||
#include "download_list.h"
|
||||
#include "scheduler.h"
|
||||
#include "view_downloads.h"
|
||||
#include "view.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -59,7 +59,7 @@ Scheduler::~Scheduler() {
|
||||
}
|
||||
|
||||
void
|
||||
Scheduler::set_view(ViewDownloads* view) {
|
||||
Scheduler::set_view(View* view) {
|
||||
m_view = view;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ Scheduler::update() {
|
||||
// inactive we can switch with.
|
||||
size_type target = m_maxActive - std::min(m_cycle, m_maxActive);
|
||||
|
||||
for (ViewDownloads::iterator itr = m_view->begin(), last = m_view->end(); curActive > target; ++itr) {
|
||||
for (View::iterator itr = m_view->begin(), last = m_view->end(); curActive > target; ++itr) {
|
||||
if (itr == last)
|
||||
throw torrent::internal_error("Scheduler::update() loop bork.");
|
||||
|
||||
@@ -92,7 +92,7 @@ Scheduler::update() {
|
||||
|
||||
m_view->sort();
|
||||
|
||||
for (ViewDownloads::iterator itr = m_view->begin(), last = m_view->end(); curActive < m_maxActive; ++itr) {
|
||||
for (View::iterator itr = m_view->begin(), last = m_view->end(); curActive < m_maxActive; ++itr) {
|
||||
if (itr == last)
|
||||
throw torrent::internal_error("Scheduler::update() loop bork.");
|
||||
|
||||
|
||||
@@ -41,12 +41,12 @@
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "view_downloads.h"
|
||||
#include "view.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class DownloadList;
|
||||
class ViewDownloads;
|
||||
class View;
|
||||
|
||||
class Scheduler {
|
||||
public:
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
Scheduler(DownloadList* dl);
|
||||
~Scheduler();
|
||||
|
||||
void set_view(ViewDownloads* view);
|
||||
void set_view(View* view);
|
||||
|
||||
size_type max_active() const { return m_maxActive; }
|
||||
void set_max_active(size_type v) { m_maxActive = v; }
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
void update();
|
||||
|
||||
private:
|
||||
ViewDownloads* m_view;
|
||||
View* m_view;
|
||||
DownloadList* m_downloadList;
|
||||
|
||||
size_type m_maxActive;
|
||||
|
||||
@@ -43,11 +43,11 @@
|
||||
#include "download.h"
|
||||
#include "download_list.h"
|
||||
|
||||
#include "view_downloads.h"
|
||||
#include "view.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
ViewDownloads::~ViewDownloads() {
|
||||
View::~View() {
|
||||
if (m_name.empty())
|
||||
return;
|
||||
|
||||
@@ -58,17 +58,17 @@ ViewDownloads::~ViewDownloads() {
|
||||
}
|
||||
|
||||
void
|
||||
ViewDownloads::initialize(const std::string& name, core::DownloadList* list) {
|
||||
View::initialize(const std::string& name, core::DownloadList* list) {
|
||||
if (!m_name.empty())
|
||||
throw torrent::internal_error("ViewDownloads::initialize(...) called on an already initialized view.");
|
||||
throw torrent::internal_error("View::initialize(...) called on an already initialized view.");
|
||||
|
||||
if (name.empty())
|
||||
throw torrent::internal_error("ViewDownloads::initialize(...) called with an empty name.");
|
||||
throw torrent::internal_error("View::initialize(...) called with an empty name.");
|
||||
|
||||
std::string key = "0_view_" + name;
|
||||
|
||||
if (list->has_slot_insert(key) || list->has_slot_erase(key))
|
||||
throw torrent::internal_error("ViewDownloads::initialize(...) duplicate key name found in DownloadList.");
|
||||
throw torrent::internal_error("View::initialize(...) duplicate key name found in DownloadList.");
|
||||
|
||||
m_name = name;
|
||||
|
||||
@@ -78,14 +78,14 @@ ViewDownloads::initialize(const std::string& name, core::DownloadList* list) {
|
||||
|
||||
set_last_changed(rak::timer());
|
||||
|
||||
std::for_each(m_list->begin(), m_list->end(), std::bind1st(std::mem_fun(&ViewDownloads::received_insert), this));
|
||||
std::for_each(m_list->begin(), m_list->end(), std::bind1st(std::mem_fun(&View::received_insert), this));
|
||||
|
||||
m_list->slot_map_insert()[key] = sigc::mem_fun(this, &ViewDownloads::received_insert);
|
||||
m_list->slot_map_erase()[key] = sigc::mem_fun(this, &ViewDownloads::received_erase);
|
||||
m_list->slot_map_insert()[key] = sigc::mem_fun(this, &View::received_insert);
|
||||
m_list->slot_map_erase()[key] = sigc::mem_fun(this, &View::received_erase);
|
||||
}
|
||||
|
||||
void
|
||||
ViewDownloads::next_focus() {
|
||||
View::next_focus() {
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
@@ -95,7 +95,7 @@ ViewDownloads::next_focus() {
|
||||
}
|
||||
|
||||
void
|
||||
ViewDownloads::prev_focus() {
|
||||
View::prev_focus() {
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
@@ -109,10 +109,10 @@ ViewDownloads::prev_focus() {
|
||||
|
||||
// Also add focus thingie here?
|
||||
struct view_downloads_compare : std::binary_function<Download*, Download*, bool> {
|
||||
view_downloads_compare(const ViewDownloads::sort_list& s) : m_sort(s) {}
|
||||
view_downloads_compare(const View::sort_list& s) : m_sort(s) {}
|
||||
|
||||
bool operator () (Download* d1, Download* d2) const {
|
||||
for (ViewDownloads::sort_list::const_iterator itr = m_sort.begin(), last = m_sort.end(); itr != last; ++itr)
|
||||
for (View::sort_list::const_iterator itr = m_sort.begin(), last = m_sort.end(); itr != last; ++itr)
|
||||
if ((**itr)(d1, d2))
|
||||
return true;
|
||||
else if ((**itr)(d2, d1))
|
||||
@@ -123,14 +123,14 @@ struct view_downloads_compare : std::binary_function<Download*, Download*, bool>
|
||||
return false;
|
||||
}
|
||||
|
||||
const ViewDownloads::sort_list& m_sort;
|
||||
const View::sort_list& m_sort;
|
||||
};
|
||||
|
||||
struct view_downloads_filter : std::unary_function<Download*, bool> {
|
||||
view_downloads_filter(const ViewDownloads::filter_list& s) : m_filter(s) {}
|
||||
view_downloads_filter(const View::filter_list& s) : m_filter(s) {}
|
||||
|
||||
bool operator () (Download* d1) const {
|
||||
for (ViewDownloads::filter_list::const_iterator itr = m_filter.begin(), last = m_filter.end(); itr != last; ++itr)
|
||||
for (View::filter_list::const_iterator itr = m_filter.begin(), last = m_filter.end(); itr != last; ++itr)
|
||||
if (!(**itr)(d1))
|
||||
return false;
|
||||
|
||||
@@ -139,11 +139,11 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ViewDownloads::filter_list& m_filter;
|
||||
const View::filter_list& m_filter;
|
||||
};
|
||||
|
||||
void
|
||||
ViewDownloads::sort() {
|
||||
View::sort() {
|
||||
Download* curFocus = focus() != end() ? *focus() : NULL;
|
||||
|
||||
// Don't go randomly switching around equivalent elements.
|
||||
@@ -154,7 +154,7 @@ ViewDownloads::sort() {
|
||||
}
|
||||
|
||||
void
|
||||
ViewDownloads::filter() {
|
||||
View::filter() {
|
||||
iterator split = std::stable_partition(base_type::begin(), base_type::end(), view_downloads_filter(m_filter));
|
||||
|
||||
m_size = position(split);
|
||||
@@ -164,7 +164,7 @@ ViewDownloads::filter() {
|
||||
}
|
||||
|
||||
void
|
||||
ViewDownloads::received_insert(core::Download* d) {
|
||||
View::received_insert(core::Download* d) {
|
||||
// Chagne according to filtered/not.
|
||||
iterator itr;
|
||||
|
||||
@@ -179,14 +179,14 @@ ViewDownloads::received_insert(core::Download* d) {
|
||||
}
|
||||
|
||||
if (m_focus > m_size)
|
||||
throw torrent::internal_error("ViewDownloads::received_insert(...) m_focus > m_size.");
|
||||
throw torrent::internal_error("View::received_insert(...) m_focus > m_size.");
|
||||
|
||||
base_type::insert(itr, d);
|
||||
m_signalChanged.emit();
|
||||
}
|
||||
|
||||
void
|
||||
ViewDownloads::received_erase(core::Download* d) {
|
||||
View::received_erase(core::Download* d) {
|
||||
iterator itr = std::find(begin(), end_filtered(), d);
|
||||
|
||||
if (itr == end_filtered())
|
||||
@@ -43,7 +43,7 @@
|
||||
#include "globals.h"
|
||||
|
||||
#include "download.h"
|
||||
#include "view_downloads.h"
|
||||
#include "view.h"
|
||||
#include "view_manager.h"
|
||||
|
||||
namespace core {
|
||||
@@ -123,17 +123,21 @@ ViewManager::ViewManager(DownloadList* dl) :
|
||||
|
||||
m_sort["stopped"] = new ViewSortVariableValue("state");
|
||||
m_sort["started"] = new ViewSortReverse(new ViewSortVariableValue("state"));
|
||||
m_sort["complete"] = new ViewSortVariableValue("complete");
|
||||
m_sort["incomplete"] = new ViewSortReverse(new ViewSortVariableValue("complete"));
|
||||
|
||||
m_sort["state_changed"] = new ViewSortVariableValue("state_changed");
|
||||
m_sort["state_changed_reverse"] = new ViewSortReverse(new ViewSortVariableValue("state_changed"));
|
||||
|
||||
m_filter["started"] = new ViewFilterVariableValue("state", 1);
|
||||
m_filter["stopped"] = new ViewFilterVariableValue("state", 0);
|
||||
m_filter["complete"] = new ViewFilterVariableValue("complete", 1);
|
||||
m_filter["incomplete"] = new ViewFilterVariableValue("complete", 0);
|
||||
}
|
||||
|
||||
void
|
||||
ViewManager::clear() {
|
||||
std::for_each(begin(), end(), rak::call_delete<ViewDownloads>());
|
||||
std::for_each(begin(), end(), rak::call_delete<View>());
|
||||
std::for_each(m_sort.begin(), m_sort.end(), rak::on(rak::mem_ptr_ref(&sort_map::value_type::second), rak::call_delete<ViewSort>()));
|
||||
|
||||
base_type::clear();
|
||||
@@ -144,7 +148,7 @@ ViewManager::insert(const std::string& name) {
|
||||
if (find(name) != end())
|
||||
throw torrent::internal_error("ViewManager::insert(...) name already inserted.");
|
||||
|
||||
ViewDownloads* view = new ViewDownloads();
|
||||
View* view = new View();
|
||||
view->initialize(name, m_list);
|
||||
|
||||
return base_type::insert(end(), view);
|
||||
@@ -152,12 +156,12 @@ ViewManager::insert(const std::string& name) {
|
||||
|
||||
ViewManager::iterator
|
||||
ViewManager::find(const std::string& name) {
|
||||
return std::find_if(begin(), end(), rak::equal(name, std::mem_fun(&ViewDownloads::name)));
|
||||
return std::find_if(begin(), end(), rak::equal(name, std::mem_fun(&View::name)));
|
||||
}
|
||||
|
||||
ViewManager::iterator
|
||||
ViewManager::find_throw(const std::string& name) {
|
||||
iterator itr = std::find_if(begin(), end(), rak::equal(name, std::mem_fun(&ViewDownloads::name)));
|
||||
iterator itr = std::find_if(begin(), end(), rak::equal(name, std::mem_fun(&View::name)));
|
||||
|
||||
if (itr == end())
|
||||
throw torrent::input_error("Could not find view: " + name);
|
||||
@@ -167,7 +171,7 @@ ViewManager::find_throw(const std::string& name) {
|
||||
|
||||
inline ViewManager::sort_list
|
||||
ViewManager::build_sort_list(const sort_args& args) {
|
||||
ViewDownloads::sort_list sortList;
|
||||
View::sort_list sortList;
|
||||
sortList.reserve(args.size());
|
||||
|
||||
for (sort_args::const_iterator itr = args.begin(), last = args.end(); itr != last; ++itr) {
|
||||
@@ -211,7 +215,7 @@ ViewManager::set_sort_current(const std::string& name, const sort_args& sort) {
|
||||
|
||||
inline ViewManager::filter_list
|
||||
ViewManager::build_filter_list(const filter_args& args) {
|
||||
ViewDownloads::filter_list filterList;
|
||||
View::filter_list filterList;
|
||||
filterList.reserve(args.size());
|
||||
|
||||
for (filter_args::const_iterator itr = args.begin(), last = args.end(); itr != last; ++itr) {
|
||||
|
||||
@@ -41,23 +41,23 @@
|
||||
#include <string>
|
||||
#include <rak/unordered_vector.h>
|
||||
|
||||
#include "view_downloads.h"
|
||||
#include "view.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class ViewDownloads;
|
||||
class View;
|
||||
class ViewSort;
|
||||
|
||||
class ViewManager : public rak::unordered_vector<ViewDownloads*> {
|
||||
class ViewManager : public rak::unordered_vector<View*> {
|
||||
public:
|
||||
typedef rak::unordered_vector<ViewDownloads*> base_type;
|
||||
typedef rak::unordered_vector<View*> base_type;
|
||||
|
||||
typedef std::map<std::string, ViewSort*> sort_map;
|
||||
typedef ViewDownloads::sort_list sort_list;
|
||||
typedef View::sort_list sort_list;
|
||||
typedef std::list<std::string> sort_args;
|
||||
|
||||
typedef std::map<std::string, ViewFilter*> filter_map;
|
||||
typedef ViewDownloads::filter_list filter_list;
|
||||
typedef View::filter_list filter_list;
|
||||
typedef std::list<std::string> filter_args;
|
||||
|
||||
using base_type::iterator;
|
||||
@@ -92,8 +92,8 @@ public:
|
||||
iterator find(const std::string& name);
|
||||
iterator find_throw(const std::string& name);
|
||||
|
||||
// If ViewDownloads::last_changed() is less than 'timeout' seconds
|
||||
// ago, don't sort.
|
||||
// If View::last_changed() is less than 'timeout' seconds ago, don't
|
||||
// sort.
|
||||
//
|
||||
// Find a better name for 'timeout'.
|
||||
void sort(const std::string& name, uint32_t timeout = 0);
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <rak/algorithm.h>
|
||||
|
||||
#include "core/download.h"
|
||||
#include "core/view_downloads.h"
|
||||
#include "core/view.h"
|
||||
|
||||
#include "canvas.h"
|
||||
#include "globals.h"
|
||||
@@ -53,7 +53,7 @@ WindowDownloadList::~WindowDownloadList() {
|
||||
}
|
||||
|
||||
void
|
||||
WindowDownloadList::set_view(core::ViewDownloads* l) {
|
||||
WindowDownloadList::set_view(core::View* l) {
|
||||
m_view = l;
|
||||
|
||||
m_connChanged.disconnect();
|
||||
@@ -76,7 +76,7 @@ WindowDownloadList::redraw() {
|
||||
if (m_view->empty() || m_canvas->get_width() < 5 || m_canvas->get_height() < 2)
|
||||
return;
|
||||
|
||||
typedef std::pair<core::ViewDownloads::iterator, core::ViewDownloads::iterator> Range;
|
||||
typedef std::pair<core::View::iterator, core::View::iterator> Range;
|
||||
|
||||
Range range = rak::advance_bidirectional(m_view->begin(),
|
||||
m_view->focus() != m_view->end() ? m_view->focus() : m_view->begin(),
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include "core/download_list.h"
|
||||
|
||||
namespace core {
|
||||
class ViewDownloads;
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace display {
|
||||
@@ -56,12 +56,12 @@ public:
|
||||
|
||||
virtual void redraw();
|
||||
|
||||
void set_view(core::ViewDownloads* l);
|
||||
void set_view(core::View* l);
|
||||
|
||||
private:
|
||||
core::ViewDownloads* m_view;
|
||||
core::View* m_view;
|
||||
|
||||
sigc::connection m_connChanged;
|
||||
sigc::connection m_connChanged;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+22
-10
@@ -162,9 +162,14 @@ main(int argc, char** argv) {
|
||||
// torrent::ConnectionManager* is valid etc.
|
||||
initialize_option_handler(control);
|
||||
|
||||
// Currently not doing any sorting on main.
|
||||
control->variable()->process_command("view_add = main");
|
||||
control->variable()->process_command("view_sort_new = main,name");
|
||||
control->variable()->process_command("view_sort_current = main,name");
|
||||
control->variable()->process_command("view_sort_new = main");
|
||||
control->variable()->process_command("view_sort_current = main");
|
||||
|
||||
control->variable()->process_command("view_add = name");
|
||||
control->variable()->process_command("view_sort_new = name,name");
|
||||
control->variable()->process_command("view_sort_current = name,name");
|
||||
|
||||
control->variable()->process_command("view_add = started");
|
||||
control->variable()->process_command("view_filter = started,started");
|
||||
@@ -176,15 +181,22 @@ main(int argc, char** argv) {
|
||||
control->variable()->process_command("view_sort_new = stopped,name");
|
||||
control->variable()->process_command("view_sort_current = stopped,name");
|
||||
|
||||
control->variable()->process_command("view_add = finished");
|
||||
//control->variable()->process_command("view_filter = finished,stopped");
|
||||
control->variable()->process_command("view_sort_new = finished,state_changed");
|
||||
control->variable()->process_command("view_sort_current = finished,state_changed_reverse");
|
||||
control->variable()->process_command("view_add = complete");
|
||||
control->variable()->process_command("view_filter = complete,complete");
|
||||
control->variable()->process_command("view_sort_new = complete,state_changed");
|
||||
control->variable()->process_command("view_sort_current = complete,state_changed_reverse");
|
||||
|
||||
control->variable()->process_command("schedule = view_main,10,10,view_sort=main,30");
|
||||
control->variable()->process_command("schedule = view_started,10,10,view_sort=started");
|
||||
control->variable()->process_command("schedule = view_stopped,10,10,view_sort=stopped");
|
||||
control->variable()->process_command("schedule = view_finished,10,10,view_sort=finished,30");
|
||||
control->variable()->process_command("view_add = incomplete");
|
||||
control->variable()->process_command("view_filter = incomplete,incomplete");
|
||||
control->variable()->process_command("view_sort_new = incomplete,state_changed");
|
||||
control->variable()->process_command("view_sort_current = incomplete,state_changed_reverse");
|
||||
|
||||
control->variable()->process_command("schedule = view_main,10,10,view_sort=main,20");
|
||||
control->variable()->process_command("schedule = view_name,10,10,view_sort=main,20");
|
||||
control->variable()->process_command("schedule = view_started,10,10,view_sort=started,20");
|
||||
control->variable()->process_command("schedule = view_stopped,10,10,view_sort=stopped,20");
|
||||
control->variable()->process_command("schedule = view_complete,10,10,view_sort=complete,20");
|
||||
control->variable()->process_command("schedule = view_incomplete,10,10,view_sort=incomplete,20");
|
||||
|
||||
//control->variable()->process_command("schedule = scheduler,10,10,download_scheduler=");
|
||||
|
||||
|
||||
+10
-10
@@ -98,17 +98,17 @@ apply_load_start(Control* m, const std::string& arg) {
|
||||
|
||||
void
|
||||
apply_stop_untied(Control* m, __UNUSED const std::string& arg) {
|
||||
core::Manager::DListItr itr = m->core()->download_list().begin();
|
||||
core::Manager::DListItr itr = m->core()->download_list()->begin();
|
||||
|
||||
while ((itr = std::find_if(itr, m->core()->download_list().end(),
|
||||
while ((itr = std::find_if(itr, m->core()->download_list()->end(),
|
||||
rak::on(rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"),
|
||||
std::not1(std::mem_fun_ref(&std::string::empty)))))
|
||||
!= m->core()->download_list().end()) {
|
||||
!= m->core()->download_list()->end()) {
|
||||
rak::file_stat fs;
|
||||
|
||||
if (!fs.update(rak::path_expand((*itr)->variable_string("tied_to_file")))) {
|
||||
(*itr)->variable()->set("tied_to_file", std::string());
|
||||
m->core()->download_list().stop(*itr);
|
||||
m->core()->download_list()->stop(*itr);
|
||||
}
|
||||
|
||||
++itr;
|
||||
@@ -117,18 +117,18 @@ apply_stop_untied(Control* m, __UNUSED const std::string& arg) {
|
||||
|
||||
void
|
||||
apply_remove_untied(Control* m, __UNUSED const std::string& arg) {
|
||||
core::Manager::DListItr itr = m->core()->download_list().begin();
|
||||
core::Manager::DListItr itr = m->core()->download_list()->begin();
|
||||
|
||||
while ((itr = std::find_if(itr, m->core()->download_list().end(),
|
||||
while ((itr = std::find_if(itr, m->core()->download_list()->end(),
|
||||
rak::on(rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"),
|
||||
std::not1(std::mem_fun_ref(&std::string::empty)))))
|
||||
!= m->core()->download_list().end()) {
|
||||
!= m->core()->download_list()->end()) {
|
||||
rak::file_stat fs;
|
||||
|
||||
if (!fs.update(rak::path_expand((*itr)->variable_string("tied_to_file")))) {
|
||||
(*itr)->variable()->set("tied_to_file", std::string());
|
||||
m->core()->download_list().stop(*itr);
|
||||
itr = m->core()->download_list().erase(itr);
|
||||
m->core()->download_list()->stop(*itr);
|
||||
itr = m->core()->download_list()->erase(itr);
|
||||
|
||||
} else {
|
||||
++itr;
|
||||
@@ -145,7 +145,7 @@ void
|
||||
apply_enable_trackers(Control* m, __UNUSED const std::string& arg) {
|
||||
bool state = (arg != "no");
|
||||
|
||||
for (core::Manager::DListItr itr = m->core()->download_list().begin(), last = m->core()->download_list().end(); itr != last; ++itr) {
|
||||
for (core::Manager::DListItr itr = m->core()->download_list()->begin(), last = m->core()->download_list()->end(); itr != last; ++itr) {
|
||||
|
||||
torrent::TrackerList tl = (*itr)->download()->tracker_list();
|
||||
|
||||
|
||||
+18
-11
@@ -47,7 +47,7 @@
|
||||
#include "core/download.h"
|
||||
#include "core/download_list.h"
|
||||
#include "core/manager.h"
|
||||
#include "core/view_downloads.h"
|
||||
#include "core/view.h"
|
||||
#include "core/view_manager.h"
|
||||
|
||||
#include "input/bindings.h"
|
||||
@@ -130,7 +130,7 @@ DownloadList::activate() {
|
||||
|
||||
m_control->input()->push_front(m_bindings);
|
||||
|
||||
m_control->core()->download_list().slot_map_erase()["0_download_list"] = sigc::mem_fun(this, &DownloadList::receive_download_erased);
|
||||
m_control->core()->download_list()->slot_map_erase()["0_download_list"] = sigc::mem_fun(this, &DownloadList::receive_download_erased);
|
||||
|
||||
activate_display(DISPLAY_DOWNLOAD_LIST);
|
||||
}
|
||||
@@ -200,7 +200,8 @@ DownloadList::receive_start_download() {
|
||||
if (m_view->focus() == m_view->end())
|
||||
return;
|
||||
|
||||
m_control->core()->download_list().start(*m_view->focus());
|
||||
m_control->core()->download_list()->start(*m_view->focus());
|
||||
m_view->set_last_changed();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -209,9 +210,11 @@ DownloadList::receive_stop_download() {
|
||||
return;
|
||||
|
||||
if ((*m_view->focus())->download()->is_active())
|
||||
m_control->core()->download_list().stop(*m_view->focus());
|
||||
m_control->core()->download_list()->stop(*m_view->focus());
|
||||
else
|
||||
m_control->core()->download_list().erase(*m_view->focus());
|
||||
m_control->core()->download_list()->erase(*m_view->focus());
|
||||
|
||||
m_view->set_last_changed();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -219,7 +222,8 @@ DownloadList::receive_close_download() {
|
||||
if (m_view->focus() == m_view->end())
|
||||
return;
|
||||
|
||||
m_control->core()->download_list().close(*m_view->focus());
|
||||
m_control->core()->download_list()->close(*m_view->focus());
|
||||
m_view->set_last_changed();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -247,6 +251,7 @@ DownloadList::receive_exit_download() {
|
||||
delete m_uiDownload;
|
||||
m_uiDownload = NULL;
|
||||
|
||||
m_view->set_last_changed();
|
||||
activate();
|
||||
|
||||
m_control->display()->adjust_layout();
|
||||
@@ -273,7 +278,8 @@ DownloadList::receive_check_hash() {
|
||||
if (m_view->focus() == m_view->end())
|
||||
return;
|
||||
|
||||
m_control->core()->check_hash(*m_view->focus());
|
||||
// Catch here?
|
||||
m_control->core()->download_list()->check_hash(*m_view->focus());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -419,10 +425,11 @@ DownloadList::setup_keys() {
|
||||
(*m_bindings)['l'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change), DISPLAY_LOG);
|
||||
|
||||
(*m_bindings)['1'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "main");
|
||||
(*m_bindings)['2'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "started");
|
||||
(*m_bindings)['3'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "stopped");
|
||||
(*m_bindings)['4'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "finished");
|
||||
(*m_bindings)['5'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "incomplete");
|
||||
(*m_bindings)['2'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "name");
|
||||
(*m_bindings)['3'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "started");
|
||||
(*m_bindings)['4'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "stopped");
|
||||
(*m_bindings)['5'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "complete");
|
||||
(*m_bindings)['6'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "incomplete");
|
||||
|
||||
m_uiArray[DISPLAY_LOG]->get_bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change), DISPLAY_DOWNLOAD_LIST);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class Control;
|
||||
|
||||
namespace core {
|
||||
class Download;
|
||||
class ViewDownloads;
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace input {
|
||||
@@ -159,7 +159,7 @@ private:
|
||||
|
||||
Download* m_uiDownload;
|
||||
|
||||
core::ViewDownloads* m_view;
|
||||
core::View* m_view;
|
||||
|
||||
Control* m_control;
|
||||
input::Bindings* m_bindings;
|
||||
|
||||
@@ -70,7 +70,7 @@ ElementDownloadList::disable(Control* c) {
|
||||
}
|
||||
|
||||
void
|
||||
ElementDownloadList::set_view(core::ViewDownloads* l) {
|
||||
ElementDownloadList::set_view(core::View* l) {
|
||||
m_view = l;
|
||||
|
||||
if (m_window == NULL)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class Control;
|
||||
|
||||
namespace core {
|
||||
class ViewDownloads;
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
@@ -59,11 +59,11 @@ public:
|
||||
void activate(Control* c, MItr mItr);
|
||||
void disable(Control* c);
|
||||
|
||||
void set_view(core::ViewDownloads* l);
|
||||
void set_view(core::View* l);
|
||||
|
||||
private:
|
||||
WDownloadList* m_window;
|
||||
core::ViewDownloads* m_view;
|
||||
core::View* m_view;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user