* Make VariableMap handle both global and core::Download

variables. Variable now has functions for both void and
core::Download*, where the core::Download* is discarded if necessary.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@847 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-01-17 15:18:33 +00:00
parent d030c5401e
commit e59b5bf7b6
19 changed files with 414 additions and 133 deletions
+13 -10
View File
@@ -36,11 +36,11 @@
#include "config.h"
#include <stdexcept>
#include <sigc++/bind.h>
#include <sigc++/hide.h>
#include <sigc++/signal.h>
#include <rak/path.h>
#include <rak/functional.h>
#include <torrent/exceptions.h>
#include <torrent/rate.h>
#include <torrent/torrent.h>
@@ -68,29 +68,32 @@ Download::Download(download_type d) :
m_download.signal_chunk_failed(sigc::mem_fun(*this, &Download::receive_chunk_failed));
m_variables.insert("connection_current", new utils::VariableStringSlot(rak::mem_fn(this, &Download::connection_current),
rak::mem_fn(this, &Download::set_connection_current)));
m_variables.insert("connection_current", new utils::VariableStringSlot(NULL, NULL,
rak::ftor_fn1(std::mem_fun(&Download::connection_current)),
rak::ftor_fn2(std::mem_fun(&Download::set_connection_current))));
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)));
// 0 - stopped
// 1 - started
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("state", new utils::VariableObject("rtorrent", "state", torrent::Object::TYPE_VALUE));
m_variables.insert("complete", new utils::VariableObject("rtorrent", "complete", torrent::Object::TYPE_VALUE));
// 0 - Not hashing
// 1 - Normal hashing
// 2 - Download finished, hashing
m_variables.insert("hashing", new utils::VariableObject(bencode(), "rtorrent", "hashing", torrent::Object::TYPE_VALUE));
m_variables.insert("tied_to_file", new utils::VariableObject(bencode(), "rtorrent", "tied_to_file", torrent::Object::TYPE_STRING));
m_variables.insert("hashing", new utils::VariableObject("rtorrent", "hashing", torrent::Object::TYPE_VALUE));
m_variables.insert("tied_to_file", new utils::VariableObject("rtorrent", "tied_to_file", torrent::Object::TYPE_STRING));
// The "state_changed" variable is required to be a valid unix time
// value, it indicates the last time the torrent changed its state,
// resume/pause.
m_variables.insert("state_changed", new utils::VariableObject(bencode(), "rtorrent", "state_changed", torrent::Object::TYPE_VALUE));
m_variables.insert("state_changed", new utils::VariableObject("rtorrent", "state_changed", torrent::Object::TYPE_VALUE));
m_variables.insert("directory", new utils::VariableStringSlot(rak::mem_fn(m_download.file_list(), &torrent::FileList::root_dir), rak::mem_fn(this, &Download::set_root_directory)));
m_variables.insert("directory", new utils::VariableStringSlot(NULL, NULL,
rak::ftor_fn1(rak::on(std::mem_fun(&Download::file_list), std::mem_fun(&torrent::FileList::root_dir))),
rak::ftor_fn2(std::mem_fun(&Download::set_root_directory))));
// m_variables.insert("info_hash", new utils::VariableStringSlot(rak::mem_fn(&m_download, &torrent::Download::info_hash), NULL));
@@ -113,7 +116,7 @@ Download::Download(download_type d) :
m_variables.insert("tracker_numwant", new utils::VariableValueSlot(rak::mem_fn(&m_trackerList, &tracker_list_type::numwant), rak::mem_fn(&m_trackerList, &tracker_list_type::set_numwant)));
m_variables.insert("ignore_commands", new utils::VariableObject(bencode(), "rtorrent", "ignore_commands", torrent::Object::TYPE_VALUE));
m_variables.insert("ignore_commands", new utils::VariableObject("rtorrent", "ignore_commands", torrent::Object::TYPE_VALUE));
}
Download::~Download() {
+11 -14
View File
@@ -82,14 +82,6 @@ public:
bool is_hash_failed() const { return m_hashFailed; }
void set_hash_failed(bool v) { m_hashFailed = v; }
variable_map_type* variable() { return &m_variables; }
int64_t variable_value(const std::string& key) const { return m_variables.get_value(key.c_str()); }
const std::string& variable_string(const std::string& key) const { return m_variables.get_string(key.c_str()); }
int64_t variable_value_c(const char* key) const { return m_variables.get_value(key); }
const std::string& variable_string_c(const char* key) const { return m_variables.get_string(key); }
download_type* download() { return &m_download; }
const download_type* c_download() const { return &m_download; }
@@ -109,13 +101,18 @@ public:
uint32_t priority();
void set_priority(uint32_t p);
// Helper functions for calling functions in download_type
// through sigc++.
template <typename Ret, Ret (download_type::*func)()>
void call() { (m_download.*func)(); }
// variable_map_type* variable() { return &m_variables; }
template <typename Ret, typename Arg1, Ret (download_type::*func)(Arg1)>
void call(Arg1 a1) { (m_download.*func)(a1); }
int64_t get_value(const char* key) { return m_variables.get_d_value(this, key); }
const std::string& get_string(const char* key) { return m_variables.get_d_string(this, key); }
int64_t get_std_value(const std::string& key) { return m_variables.get_d_value(this, key.c_str()); }
const std::string& get_std_string(const std::string& key) { return m_variables.get_d_string(this, key.c_str()); }
void set(const char* key, const torrent::Object& value) { return m_variables.set_d(this, key, value); }
void set_value(const char* key, int64_t value) { return m_variables.set_d_value(this, key, value); }
void set_string(const char* key, const std::string& value) { return m_variables.set_d_string(this, key, value); }
bool operator == (const std::string& str) const;
+17 -17
View File
@@ -172,27 +172,27 @@ DownloadFactory::receive_success() {
initialize_rtorrent(download, rtorrent);
// Move to 'rtorrent'.
download->variable()->set("connection_leech", m_variables.get("connection_leech"));
download->variable()->set("connection_seed", m_variables.get("connection_seed"));
download->set("connection_leech", m_variables.get("connection_leech"));
download->set("connection_seed", m_variables.get("connection_seed"));
download->variable()->set("max_uploads", control->variable()->get("max_uploads"));
download->variable()->set("min_peers", control->variable()->get("min_peers"));
download->variable()->set("max_peers", control->variable()->get("max_peers"));
download->variable()->set("tracker_numwant", control->variable()->get("tracker_numwant"));
download->set("max_uploads", control->variable()->get("max_uploads"));
download->set("min_peers", control->variable()->get("min_peers"));
download->set("max_peers", control->variable()->get("max_peers"));
download->set("tracker_numwant", control->variable()->get("tracker_numwant"));
if (download->variable()->get_value("complete") != 0) {
if (download->get_value("complete") != 0) {
if (control->variable()->get_value("min_peers_seed") >= 0)
download->variable()->set("min_peers", control->variable()->get("min_peers_seed"));
download->set("min_peers", control->variable()->get("min_peers_seed"));
if (control->variable()->get_value("max_peers_seed") >= 0)
download->variable()->set("max_peers", control->variable()->get("max_peers_seed"));
download->set("max_peers", control->variable()->get("max_peers_seed"));
}
if (!control->variable()->get_value("use_udp_trackers"))
download->enable_udp_trackers(false);
if (control->variable()->get_value("max_file_size") > 0)
download->variable()->set("max_file_size", control->variable()->get("max_file_size"));
download->set("max_file_size", control->variable()->get("max_file_size"));
// Check first if we already have these values set in the session
// torrent, so that it is safe to change the values.
@@ -204,12 +204,12 @@ DownloadFactory::receive_success() {
control->variable()->get_string("split_suffix"));
if (!rtorrent->has_key_string("directory"))
download->variable()->set("directory", m_variables.get("directory"));
download->set("directory", m_variables.get("directory"));
else
download->variable()->set("directory", rtorrent->get_key("directory"));
download->set("directory", rtorrent->get_key("directory"));
if (!m_session && m_variables.get("tied_to_file").as_value())
download->variable()->set("tied_to_file", m_uri);
download->set("tied_to_file", m_uri);
torrent::Object& resumeObject = root->has_key_map("libtorrent_resume")
? root->get_key("libtorrent_resume")
@@ -234,8 +234,8 @@ DownloadFactory::receive_success() {
if (m_session) {
// This torrent was queued for hashing or hashing when the session
// file was saved. Or it was in a started state.
if (download->variable()->get_value("hashing") != Download::variable_hashing_stopped ||
download->variable()->get_value("state") != 0)
if (download->get_value("hashing") != Download::variable_hashing_stopped ||
download->get_value("state") != 0)
m_manager->download_list()->resume(download);
} else {
@@ -284,9 +284,9 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre
rtorrent->insert_key("tied_to_file", std::string());
if (rtorrent->has_key_value("priority"))
download->variable()->set("priority", rtorrent->get_key_value("priority") % 4);
download->set("priority", rtorrent->get_key_value("priority") % 4);
else
download->variable()->set("priority", (int64_t)2);
download->set("priority", (int64_t)2);
if (rtorrent->has_key_value("key")) {
download->tracker_list()->set_key(rtorrent->get_key_value("key"));
+31 -31
View File
@@ -229,7 +229,7 @@ DownloadList::close_throw(Download* download) {
download->download()->close();
if (!download->is_hash_failed() && download->variable()->get_value("hashing") != Download::variable_hashing_stopped)
if (!download->is_hash_failed() && download->get_value("hashing") != 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));
@@ -243,7 +243,7 @@ DownloadList::start_normal(Download* download) {
// Clear hash failed as we're doing a manual start and want to try
// hashing again.
download->set_hash_failed(false);
download->variable()->set("state", (int64_t)1);
download->set("state", (int64_t)1);
resume(download);
}
@@ -255,12 +255,12 @@ DownloadList::start_try(Download* download) {
// Also don't start if the state is one of those that indicate we
// were manually stopped?
if (download->is_hash_failed() || download->variable()->get_value("ignore_commands") != 0)
if (download->is_hash_failed() || download->get_value("ignore_commands") != 0)
return false;
// Don't clear the hash failed as this function is used by scripts,
// etc.
download->variable()->set("state", (int64_t)1);
download->set("state", (int64_t)1);
resume(download);
return true;
@@ -270,7 +270,7 @@ void
DownloadList::stop_normal(Download* download) {
check_contains(download);
download->variable()->set("state", (int64_t)0);
download->set("state", (int64_t)0);
pause(download);
}
@@ -279,10 +279,10 @@ bool
DownloadList::stop_try(Download* download) {
check_contains(download);
if (download->variable()->get_value("ignore_commands") != 0)
if (download->get_value("ignore_commands") != 0)
return false;
download->variable()->set("state", (int64_t)0);
download->set("state", (int64_t)0);
pause(download);
return true;
@@ -308,8 +308,8 @@ DownloadList::resume(Download* download) {
if (download->is_hash_failed())
return;
if (download->variable()->get_value("hashing") == Download::variable_hashing_stopped)
download->variable()->set("hashing", Download::variable_hashing_initial);
if (download->get_value("hashing") == Download::variable_hashing_stopped)
download->set("hashing", Download::variable_hashing_initial);
std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download));
return;
@@ -318,12 +318,12 @@ DownloadList::resume(Download* download) {
// This will never actually do anything due to the above hash check.
// open_throw(download);
download->variable()->set("state_changed", cachedTime.seconds());
download->set("state_changed", cachedTime.seconds());
if (download->is_done()) {
download->set_connection_type(download->variable()->get_string("connection_seed"));
download->set_connection_type(download->get_string("connection_seed"));
} else {
download->set_connection_type(download->variable()->get_string("connection_leech"));
download->set_connection_type(download->get_string("connection_leech"));
// For the moment, clear the resume data so we force hash-check
// on non-complete downloads after a crash. This shouldn't be
@@ -352,9 +352,9 @@ DownloadList::pause(Download* download) {
// Always clear hashing on pause. When a hashing request is added,
// it should have cleared the hash resume data.
if (download->variable()->get_value("hashing") != Download::variable_hashing_stopped) {
if (download->get_value("hashing") != Download::variable_hashing_stopped) {
download->download()->hash_stop();
download->variable()->set_value("hashing", Download::variable_hashing_stopped);
download->set_value("hashing", Download::variable_hashing_stopped);
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
}
@@ -367,7 +367,7 @@ DownloadList::pause(Download* download) {
std::for_each(slot_map_stop().begin(), slot_map_stop().end(), download_list_call(download));
download->variable()->set("state_changed", cachedTime.seconds());
download->set("state_changed", cachedTime.seconds());
// Save the state after all the slots, etc have been called so we
// include the modifications they may make.
@@ -384,7 +384,7 @@ DownloadList::check_hash(Download* download) {
try {
if (download->variable()->get_value("hashing") != Download::variable_hashing_stopped)
if (download->get_value("hashing") != Download::variable_hashing_stopped)
return;
hash_queue(download, Download::variable_hashing_rehash);
@@ -417,8 +417,8 @@ DownloadList::hash_done(Download* download) {
// confirm all the data, avoiding large BW usage on f.ex. the
// ReiserFS bug with >4GB files.
int64_t hashing = download->variable()->get_value("hashing");
download->variable()->set_value("hashing", Download::variable_hashing_stopped);
int64_t hashing = download->get_value("hashing");
download->set_value("hashing", Download::variable_hashing_stopped);
switch (hashing) {
case Download::variable_hashing_initial:
@@ -427,17 +427,17 @@ DownloadList::hash_done(Download* download) {
// If the download was previously completed but the files were
// f.ex deleted, then we clear the state and complete.
if (download->variable()->get_value("complete") && !download->is_done()) {
download->variable()->set("state", (int64_t)0);
if (download->get_value("complete") && !download->is_done()) {
download->set("state", (int64_t)0);
download->set_message("Download registered as completed, but hash check returned unfinished chunks.");
}
// Save resume data so we update time-stamps and priorities if
// they were invalid/changed while loading/hashing.
download->variable()->set("complete", (int64_t)download->is_done());
download->set("complete", (int64_t)download->is_done());
torrent::resume_save_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume"));
if (download->variable()->get_value("state") == 1)
if (download->get_value("state") == 1)
resume(download);
break;
@@ -467,14 +467,14 @@ void
DownloadList::hash_queue(Download* download, int type) {
check_contains(download);
if (download->variable()->get_value("hashing") != Download::variable_hashing_stopped)
if (download->get_value("hashing") != Download::variable_hashing_stopped)
throw torrent::internal_error("DownloadList::hash_queue(...) hashing already queued.");
close_throw(download);
torrent::resume_clear_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume"));
download->set_hash_failed(false);
download->variable()->set_value("hashing", type);
download->set_value("hashing", type);
if (download->is_open())
throw torrent::internal_error("DownloadList::hash_clear(...) download still open.");
@@ -503,16 +503,16 @@ void
DownloadList::confirm_finished(Download* download) {
check_contains(download);
download->variable()->set("complete", (int64_t)1);
download->set("complete", (int64_t)1);
download->set_connection_type(download->variable()->get_string("connection_seed"));
download->set_connection_type(download->get_string("connection_seed"));
download->set_priority(download->priority());
if (download->variable_value("min_peers") == control->variable()->get_value("min_peers") && control->variable()->get_value("min_peers_seed") >= 0)
download->variable()->set("min_peers", control->variable()->get("min_peers_seed"));
if (download->get_value("min_peers") == control->variable()->get_value("min_peers") && control->variable()->get_value("min_peers_seed") >= 0)
download->set("min_peers", control->variable()->get("min_peers_seed"));
if (download->variable_value("max_peers") == control->variable()->get_value("max_peers") && control->variable()->get_value("max_peers_seed") >= 0)
download->variable()->set("max_peers", control->variable()->get("max_peers_seed"));
if (download->get_value("max_peers") == control->variable()->get_value("max_peers") && control->variable()->get_value("max_peers_seed") >= 0)
download->set("max_peers", control->variable()->get("max_peers_seed"));
// Do this before the slots are called in case one of them closes
// the download.
@@ -527,7 +527,7 @@ DownloadList::confirm_finished(Download* download) {
std::for_each(slot_map_finished().begin(), slot_map_finished().end(), download_list_call(download));
if (!download->is_active() && download->variable()->get_value("state") == 1)
if (!download->is_active() && download->get_value("state") == 1)
resume(download);
}
+7 -7
View File
@@ -166,8 +166,8 @@ Manager::handshake_log(const sockaddr* sa, int msg, int err, const torrent::Hash
// Hmm... find some better place for all this.
void
Manager::delete_tied(Download* d) {
const std::string& tie = d->variable()->get_string("tied_to_file");
Manager::delete_tied(Download* download) {
const std::string& tie = download->get_string("tied_to_file");
// This should be configurable, need to wait for the variable
// thingie to be implemented.
@@ -177,7 +177,7 @@ Manager::delete_tied(Download* d) {
if (::unlink(rak::path_expand(tie).c_str()) == -1)
push_log("Could not unlink tied file: " + std::string(rak::error_number::current().c_str()));
d->variable()->set("tied_to_file", std::string());
download->set("tied_to_file", std::string());
}
Manager::Manager() :
@@ -468,7 +468,7 @@ 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")))
if (std::find_if(m_downloadList->begin(), m_downloadList->end(), rak::equal(*itr, rak::bind2nd(std::mem_fun(&Download::get_string), "tied_to_file")))
!= m_downloadList->end())
itr = paths.erase(itr);
else
@@ -504,7 +504,7 @@ Manager::receive_hashing_changed() {
continue;
bool tryQuick =
(*itr)->variable()->get_value("hashing") == Download::variable_hashing_initial &&
(*itr)->get_value("hashing") == Download::variable_hashing_initial &&
(*itr)->download()->file_list()->bitfield()->empty();
if (!tryQuick && foundHashing)
@@ -526,7 +526,7 @@ Manager::receive_hashing_changed() {
(*itr)->download()->hash_stop();
// Make sure we don't repeat the quick hashing.
(*itr)->variable()->set_value("hashing", Download::variable_hashing_rehash);
(*itr)->set_value("hashing", Download::variable_hashing_rehash);
} else {
(*itr)->download()->hash_check(false);
@@ -535,7 +535,7 @@ Manager::receive_hashing_changed() {
} catch (torrent::local_error& e) {
if (tryQuick) {
// Make sure we don't repeat the quick hashing.
(*itr)->variable()->set_value("hashing", Download::variable_hashing_rehash);
(*itr)->set_value("hashing", Download::variable_hashing_rehash);
} else {
(*itr)->set_hash_failed(true);
+5 -5
View File
@@ -70,8 +70,8 @@ public:
virtual bool operator () (Download* d1, Download* d2) const {
return
d1->variable()->get_string(m_name) == m_value &&
d2->variable()->get_string(m_name) != m_value;
d1->get_string(m_name) == m_value &&
d2->get_string(m_name) != m_value;
}
private:
@@ -85,9 +85,9 @@ public:
virtual bool operator () (Download* d1, Download* d2) const {
if (m_reverse)
return d2->variable()->get_value(m_name) < d1->variable()->get_value(m_name);
return d2->get_value(m_name) < d1->get_value(m_name);
else
return d1->variable()->get_value(m_name) < d2->variable()->get_value(m_name);
return d1->get_value(m_name) < d2->get_value(m_name);
}
private:
@@ -114,7 +114,7 @@ public:
m_name(name), m_value(v), m_inverse(inverse) {}
virtual bool operator () (Download* d1) const {
return (d1->variable()->get_value(m_name) == m_value) != m_inverse;
return (d1->get_value(m_name) == m_value) != m_inverse;
}
private: