* Use user-modifiable commands instead of slots for the 'on_*' events.

git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1070 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2008-10-01 14:19:51 +00:00
parent d7c2960d1e
commit 07b9616ef6
13 changed files with 332 additions and 139 deletions
+27 -27
View File
@@ -72,19 +72,19 @@ DownloadList::check_contains(Download* d) {
#endif
}
struct download_list_call {
download_list_call(Download* d) : m_download(d) {}
// struct download_list_call {
// download_list_call(Download* d) : m_download(d) {}
void operator () (const DownloadList::slot_map::value_type& s) {
try {
rpc::parse_command_d_multiple_std(m_download, s.second);
} catch (torrent::input_error& e) {
control->core()->push_log((std::string("Download event action failed: ") + e.what()).c_str());
}
}
// void operator () (const DownloadList::slot_map::value_type& s) {
// try {
// rpc::parse_command_d_multiple_std(m_download, s.second);
// } catch (torrent::input_error& e) {
// control->core()->push_log((std::string("Download event action failed: ") + e.what()).c_str());
// }
// }
Download* m_download;
};
// Download* m_download;
// };
void
DownloadList::clear() {
@@ -171,7 +171,7 @@ DownloadList::insert(Download* download) {
std::for_each(control->view_manager()->begin(), control->view_manager()->end(), std::bind2nd(std::mem_fun(&View::insert), download));
std::for_each(control->view_manager()->begin(), control->view_manager()->end(), std::bind2nd(std::mem_fun(&View::filter_download), download));
std::for_each(slot_map_insert().begin(), slot_map_insert().end(), download_list_call(*itr));
rpc::commands.call_catch("event.download.inserted", rpc::make_target(*itr), torrent::Object(), "Download event action failed: ");
} catch (torrent::local_error& e) {
// Should perhaps relax this, just print an error and remove the
@@ -199,7 +199,7 @@ DownloadList::erase(iterator itr) {
control->core()->download_store()->remove(*itr);
std::for_each(slot_map_erase().begin(), slot_map_erase().end(), download_list_call(*itr));
rpc::commands.call_catch("event.download.erased", rpc::make_target(*itr), torrent::Object(), "Download event action failed: ");
std::for_each(control->view_manager()->begin(), control->view_manager()->end(), std::bind2nd(std::mem_fun(&View::erase), *itr));
torrent::download_remove(*(*itr)->download());
@@ -230,8 +230,7 @@ DownloadList::open_throw(Download* download) {
return;
download->download()->open(download->resume_flags());
std::for_each(slot_map_open().begin(), slot_map_open().end(), download_list_call(download));
rpc::commands.call_catch("event.download.opened", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
}
void
@@ -294,8 +293,8 @@ DownloadList::close_throw(Download* download) {
if (!download->is_hash_failed() && rpc::call_command_value("d.get_hashing", rpc::make_target(download)) != Download::variable_hashing_stopped)
throw torrent::internal_error("DownloadList::close_throw(...) called but we're going into a hashing loop.");
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
std::for_each(slot_map_close().begin(), slot_map_close().end(), download_list_call(download));
rpc::commands.call_catch("event.download.hash_removed", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
rpc::commands.call_catch("event.download.closed", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
}
void
@@ -328,7 +327,7 @@ DownloadList::resume(Download* download, int flags) {
if (rpc::call_command_value("d.get_hashing", rpc::make_target(download)) == Download::variable_hashing_stopped)
rpc::call_command("d.set_hashing", Download::variable_hashing_initial, rpc::make_target(download));
std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download));
rpc::commands.call_catch("event.download.hash_queued", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
return;
}
@@ -361,7 +360,7 @@ DownloadList::resume(Download* download, int flags) {
download->set_resume_flags(~uint32_t());
std::for_each(slot_map_start().begin(), slot_map_start().end(), download_list_call(download));
rpc::commands.call_catch("event.download.resumed", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
} catch (torrent::local_error& e) {
control->core()->push_log(e.what());
@@ -384,7 +383,7 @@ DownloadList::pause(Download* download, int flags) {
download->download()->hash_stop();
rpc::call_command_set_value("d.set_hashing", Download::variable_hashing_stopped, rpc::make_target(download));
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
rpc::commands.call_catch("event.download.hash_removed", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
}
if (!download->download()->is_active())
@@ -396,7 +395,7 @@ DownloadList::pause(Download* download, int flags) {
// TODO: This is actually for pause, not stop... And doesn't get
// called when the download isn't active, but was in the 'started'
// view.
std::for_each(slot_map_stop().begin(), slot_map_stop().end(), download_list_call(download));
rpc::commands.call_catch("event.download.paused", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
rpc::call_command("d.set_state_changed", cachedTime.seconds(), rpc::make_target(download));
rpc::call_command("d.set_state_counter", rpc::call_command_value("d.get_state_counter", rpc::make_target(download)), rpc::make_target(download));
@@ -441,7 +440,7 @@ DownloadList::hash_done(Download* download) {
if (!download->is_hash_checked()) {
download->set_hash_failed(true);
std::for_each(slot_map_hash_done().begin(), slot_map_hash_done().end(), download_list_call(download));
rpc::commands.call_catch("event.download.hash_done", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
return;
}
@@ -497,7 +496,7 @@ DownloadList::hash_done(Download* download) {
return;
}
std::for_each(slot_map_hash_done().begin(), slot_map_hash_done().end(), download_list_call(download));
rpc::commands.call_catch("event.download.hash_done", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
}
void
@@ -512,8 +511,9 @@ DownloadList::hash_queue(Download* download, int type) {
if (download->is_open()) {
pause(download, torrent::Download::stop_skip_tracker);
download->download()->close();
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
std::for_each(slot_map_close().begin(), slot_map_close().end(), download_list_call(download));
rpc::commands.call_catch("event.download.hash_removed", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
rpc::commands.call_catch("event.download.closed", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
}
torrent::resume_clear_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume"));
@@ -526,7 +526,7 @@ DownloadList::hash_queue(Download* download, int type) {
// If any more stuff is added here, make sure resume etc are still
// correct.
std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download));
rpc::commands.call_catch("event.download.hash_queued", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
}
void
@@ -570,7 +570,7 @@ DownloadList::confirm_finished(Download* download) {
// up/downloaded baseline.
download->download()->tracker_list()->send_completed();
std::for_each(slot_map_finished().begin(), slot_map_finished().end(), download_list_call(download));
rpc::commands.call_catch("event.download.finished", rpc::make_target(download), torrent::Object(), "Download event action failed: ");
if (download->resume_flags() != ~uint32_t())
throw torrent::internal_error("DownloadList::confirm_finished(...) download->resume_flags() != ~uint32_t().");
+25 -55
View File
@@ -60,7 +60,6 @@ class Download;
class DownloadList : private std::list<Download*> {
public:
typedef std::list<Download*> base_type;
typedef std::map<std::string, std::string> slot_map;
using base_type::iterator;
using base_type::const_iterator;
@@ -115,40 +114,35 @@ public:
void check_hash(Download* d);
enum {
SLOTS_INSERT,
SLOTS_ERASE,
SLOTS_OPEN,
SLOTS_CLOSE,
SLOTS_START,
SLOTS_STOP,
SLOTS_HASH_QUEUED,
SLOTS_HASH_REMOVED,
SLOTS_HASH_DONE,
SLOTS_FINISHED,
D_SLOTS_INSERT,
D_SLOTS_ERASE,
D_SLOTS_OPEN,
D_SLOTS_CLOSE,
D_SLOTS_START,
D_SLOTS_STOP,
D_SLOTS_HASH_QUEUED,
D_SLOTS_HASH_REMOVED,
D_SLOTS_HASH_DONE,
D_SLOTS_FINISHED,
SLOTS_MAX_SIZE
};
slot_map& slots(int m) { return m_slotMaps[m]; }
const slot_map& slots(int m) const { return m_slotMaps[m]; }
slot_map* slot_map_begin() { return m_slotMaps; }
const slot_map* slot_map_begin() const { return m_slotMaps; }
slot_map* slot_map_end() { return m_slotMaps + SLOTS_MAX_SIZE; }
const slot_map* slot_map_end() const { return m_slotMaps + SLOTS_MAX_SIZE; }
slot_map& slot_map_insert() { return m_slotMaps[SLOTS_INSERT]; }
const slot_map& slot_map_insert() const { return m_slotMaps[SLOTS_INSERT]; }
slot_map& slot_map_erase() { return m_slotMaps[SLOTS_ERASE]; }
const slot_map& slot_map_erase() const { return m_slotMaps[SLOTS_ERASE]; }
slot_map& slot_map_open() { return m_slotMaps[SLOTS_OPEN]; }
const slot_map& slot_map_open() const { return m_slotMaps[SLOTS_OPEN]; }
slot_map& slot_map_close() { return m_slotMaps[SLOTS_CLOSE]; }
const slot_map& slot_map_close() const { return m_slotMaps[SLOTS_CLOSE]; }
slot_map& slot_map_start() { return m_slotMaps[SLOTS_START]; }
const slot_map& slot_map_start() const { return m_slotMaps[SLOTS_START]; }
slot_map& slot_map_stop() { return m_slotMaps[SLOTS_STOP]; }
const slot_map& slot_map_stop() const { return m_slotMaps[SLOTS_STOP]; }
static const char* slot_name(int m) {
switch(m) {
case D_SLOTS_INSERT: return "event.download.inserted";
case D_SLOTS_ERASE: return "event.download.erased";
case D_SLOTS_OPEN: return "event.download.opened";
case D_SLOTS_CLOSE: return "event.download.closed";
case D_SLOTS_START: return "event.download.resumed";
case D_SLOTS_STOP: return "event.download.paused";
case D_SLOTS_HASH_QUEUED: return "event.download.hash_queued";
case D_SLOTS_HASH_REMOVED: return "event.download.hash_removed";
case D_SLOTS_HASH_DONE: return "event.download.hash_done";
case D_SLOTS_FINISHED: return "event.download.finished";
default: return "BORK";
}
}
// The finished slots will be called when an active download with
// "finished" == 0 performs a hash check which returns a done
@@ -158,28 +152,6 @@ public:
// Also we need to handle cases when a hashing torrent starts up
// after a shutdown.
slot_map& slot_map_hash_queued() { return m_slotMaps[SLOTS_HASH_QUEUED]; }
const slot_map& slot_map_hash_queued() const { return m_slotMaps[SLOTS_HASH_QUEUED]; }
slot_map& slot_map_hash_removed() { return m_slotMaps[SLOTS_HASH_REMOVED]; }
const slot_map& slot_map_hash_removed() const { return m_slotMaps[SLOTS_HASH_REMOVED]; }
slot_map& slot_map_hash_done() { return m_slotMaps[SLOTS_HASH_DONE]; }
const slot_map& slot_map_hash_done() const { return m_slotMaps[SLOTS_HASH_DONE]; }
slot_map& slot_map_finished() { return m_slotMaps[SLOTS_FINISHED]; }
const slot_map& slot_map_finished() const { return m_slotMaps[SLOTS_FINISHED]; }
bool has_slot_insert(const std::string& key) const { return slot_map_insert().find(key) != slot_map_insert().end(); }
bool has_slot_erase(const std::string& key) const { return slot_map_erase().find(key) != slot_map_erase().end(); }
bool has_slot_open(const std::string& key) const { return slot_map_open().find(key) != slot_map_open().end(); }
bool has_slot_close(const std::string& key) const { return slot_map_close().find(key) != slot_map_close().end(); }
bool has_slot_start(const std::string& key) const { return slot_map_start().find(key) != slot_map_start().end(); }
bool has_slot_stop(const std::string& key) const { return slot_map_stop().find(key) != slot_map_stop().end(); }
bool has_slot_hash_queued(const std::string& key) const{ return slot_map_hash_queued().find(key) != slot_map_hash_queued().end(); }
bool has_slot_hash_done(const std::string& key) const { return slot_map_hash_done().find(key) != slot_map_hash_done().end(); }
bool has_slot_finished(const std::string& key) const { return slot_map_finished().find(key) != slot_map_finished().end(); }
static void erase_key(slot_map& sm, const std::string& key) { sm.erase(key); }
private:
DownloadList(const DownloadList&);
void operator = (const DownloadList&);
@@ -191,8 +163,6 @@ private:
void received_finished(Download* d);
void confirm_finished(Download* d);
slot_map m_slotMaps[SLOTS_MAX_SIZE];
};
}
+2 -2
View File
@@ -213,8 +213,8 @@ Manager::initialize_second() {
// Register slots to be called when a download is inserted/erased,
// opened or closed.
m_downloadList->slot_map_insert()["1_connect_logs"] = "d.initialize_logs=";
m_downloadList->slot_map_erase()["9_delete_tied"] = "d.delete_tied=";
rpc::parse_command_single(rpc::make_target(), "system.method.set_key = event.download.inserted, 1_connect_logs, d.initialize_logs=");
rpc::parse_command_single(rpc::make_target(), "system.method.set_key = event.download.erased, 9_delete_tied, d.delete_tied=");
torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log));
}
+12 -8
View File
@@ -116,9 +116,10 @@ View::~View() {
if (m_name.empty())
return;
std::for_each(control->core()->download_list()->slot_map_begin(), control->core()->download_list()->slot_map_end(),
rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
for (int i = 0; i < DownloadList::SLOTS_MAX_SIZE; i++)
rpc::commands.call("system.method.set_key", rpc::make_target(),
rpc::create_object_list(control->core()->download_list()->slot_name(i), "0_view_" + m_name));
priority_queue_erase(&taskScheduler, &m_delayChanged);
}
@@ -133,7 +134,8 @@ View::initialize(const std::string& name) {
std::string key = "0_view_" + name;
core::DownloadList* dlist = control->core()->download_list();
if (dlist->has_slot_insert(key) || dlist->has_slot_erase(key))
if (rpc::commands.call("system.method.has_key", rpc::make_target(), rpc::create_object_list("event.download.inserted", key)).as_value() ||
rpc::commands.call("system.method.has_key", rpc::make_target(), rpc::create_object_list("event.download.erased", key)).as_value())
throw torrent::internal_error("View::initialize(...) duplicate key name found in DownloadList.");
m_name = name;
@@ -296,18 +298,20 @@ View::filter_download(core::Download* download) {
void
View::set_filter_on(int event) {
if (event == DownloadList::SLOTS_INSERT || event == DownloadList::SLOTS_ERASE || event >= DownloadList::SLOTS_MAX_SIZE)
if (event == DownloadList::D_SLOTS_INSERT || event == DownloadList::D_SLOTS_ERASE || event >= DownloadList::SLOTS_MAX_SIZE)
throw torrent::internal_error("View::filter_on(...) invalid event.");
control->core()->download_list()->slots(event)["0_view_" + m_name] = "view.filter_download=" + m_name;
rpc::commands.call("system.method.set_key", rpc::make_target(),
rpc::create_object_list(control->core()->download_list()->slot_name(event), "0_view_" + m_name, "view.filter_download=" + m_name));
}
void
View::clear_filter_on() {
// Don't clear insert and erase as these are required to keep the
// View up-to-date with the available downloads.
std::for_each(control->core()->download_list()->slot_map_begin() + DownloadList::SLOTS_OPEN, control->core()->download_list()->slot_map_end(),
rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
for (int i = DownloadList::D_SLOTS_OPEN; i < DownloadList::SLOTS_MAX_SIZE; i++)
rpc::commands.call("system.method.set_key", rpc::make_target(),
rpc::create_object_list(control->core()->download_list()->slot_name(i), "0_view_" + m_name));
}
inline void
+6 -6
View File
@@ -115,22 +115,22 @@ ViewManager::set_filter_on(const std::string& name, const filter_args& args) {
for (filter_args::const_iterator itr = args.begin(); itr != args.end(); ++itr) {
if (*itr == "start")
(*viewItr)->set_filter_on(DownloadList::SLOTS_START);
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_START);
else if (*itr == "stop")
(*viewItr)->set_filter_on(DownloadList::SLOTS_STOP);
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_STOP);
else if (*itr == "hash_queued")
(*viewItr)->set_filter_on(DownloadList::SLOTS_HASH_QUEUED);
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_HASH_QUEUED);
else if (*itr == "hash_removed")
(*viewItr)->set_filter_on(DownloadList::SLOTS_HASH_REMOVED);
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_HASH_REMOVED);
else if (*itr == "hash_done")
(*viewItr)->set_filter_on(DownloadList::SLOTS_HASH_DONE);
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_HASH_DONE);
else if (*itr == "finished")
(*viewItr)->set_filter_on(DownloadList::SLOTS_FINISHED);
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_FINISHED);
else
throw torrent::input_error("Invalid filter on identifier.");