mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-12 05:02:31 +00:00
* Made the signal in View trigger using a task, thus avoiding bad
recursions and wrongly orderer commands. This should fix some problems with hash checking returning errno 0. * More changes to View usage. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1048 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -87,6 +87,7 @@ initialize_commands() {
|
||||
commandVariablesItr > commandVariables + COMMAND_VARIABLES_SIZE ||
|
||||
commandDownloadSlotsItr > commandDownloadSlots + COMMAND_DOWNLOAD_SLOTS_SIZE ||
|
||||
commandFileSlotsItr > commandFileSlots + COMMAND_FILE_SLOTS_SIZE ||
|
||||
commandFileItrSlotsItr > commandFileItrSlots + COMMAND_FILE_ITR_SLOTS_SIZE ||
|
||||
commandPeerSlotsItr > commandPeerSlots + COMMAND_PEER_SLOTS_SIZE ||
|
||||
commandTrackerSlotsItr > commandTrackerSlots + COMMAND_TRACKER_SLOTS_SIZE ||
|
||||
commandAnySlotsItr > commandAnySlots + COMMAND_ANY_SLOTS_SIZE)
|
||||
@@ -95,6 +96,7 @@ initialize_commands() {
|
||||
commandVariablesItr != commandVariables + COMMAND_VARIABLES_SIZE ||
|
||||
commandDownloadSlotsItr != commandDownloadSlots + COMMAND_DOWNLOAD_SLOTS_SIZE ||
|
||||
commandFileSlotsItr != commandFileSlots + COMMAND_FILE_SLOTS_SIZE ||
|
||||
commandFileItrSlotsItr != commandFileItrSlots + COMMAND_FILE_ITR_SLOTS_SIZE ||
|
||||
commandPeerSlotsItr != commandPeerSlots + COMMAND_PEER_SLOTS_SIZE ||
|
||||
commandTrackerSlotsItr != commandTrackerSlots + COMMAND_TRACKER_SLOTS_SIZE ||
|
||||
commandAnySlotsItr != commandAnySlots + COMMAND_ANY_SLOTS_SIZE)
|
||||
|
||||
@@ -46,14 +46,14 @@ namespace rpc {
|
||||
|
||||
// By using a static array we avoid allocating the variables on the
|
||||
// heap. This should reduce memory use and improve cache locality.
|
||||
#define COMMAND_SLOTS_SIZE 150
|
||||
#define COMMAND_SLOTS_SIZE 200
|
||||
#define COMMAND_VARIABLES_SIZE 100
|
||||
#define COMMAND_DOWNLOAD_SLOTS_SIZE 150
|
||||
#define COMMAND_FILE_SLOTS_SIZE 30
|
||||
#define COMMAND_FILE_ITR_SLOTS_SIZE 10
|
||||
#define COMMAND_PEER_SLOTS_SIZE 20
|
||||
#define COMMAND_TRACKER_SLOTS_SIZE 15
|
||||
#define COMMAND_ANY_SLOTS_SIZE 20
|
||||
#define COMMAND_ANY_SLOTS_SIZE 50
|
||||
|
||||
#define ADDING_COMMANDS
|
||||
|
||||
|
||||
+17
-1
@@ -392,6 +392,20 @@ cmd_view_filter_download(core::Download* download, const torrent::Object& rawArg
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
cmd_view_set_visible(core::Download* download, const torrent::Object& rawArgs) {
|
||||
(*control->view_manager()->find_throw(rawArgs.as_string()))->set_visible(download);
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
cmd_view_set_not_visible(core::Download* download, const torrent::Object& rawArgs) {
|
||||
(*control->view_manager()->find_throw(rawArgs.as_string()))->set_not_visible(download);
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
void
|
||||
initialize_command_ui() {
|
||||
ADD_VARIABLE_STRING("key_layout", "qwerty");
|
||||
@@ -412,7 +426,9 @@ initialize_command_ui() {
|
||||
|
||||
// Cleanup and add . to view.
|
||||
|
||||
CMD_D_STRING("view.filter_download", rak::ptr_fn(&cmd_view_filter_download));
|
||||
CMD_D_STRING("view.filter_download", rak::ptr_fn(&cmd_view_filter_download));
|
||||
CMD_D_STRING("view.set_visible", rak::ptr_fn(&cmd_view_set_visible));
|
||||
CMD_D_STRING("view.set_not_visible", rak::ptr_fn(&cmd_view_set_not_visible));
|
||||
|
||||
// Commands that affect the default rtorrent UI.
|
||||
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ Control::Control() :
|
||||
m_tick(0) {
|
||||
|
||||
m_core = new core::Manager();
|
||||
m_viewManager = new core::ViewManager(m_core->download_list());
|
||||
m_viewManager = new core::ViewManager();
|
||||
m_scheduler = new core::Scheduler(m_core->download_list());
|
||||
m_dhtManager = new core::DhtManager();
|
||||
|
||||
|
||||
@@ -156,6 +156,8 @@ Download::receive_chunk_failed(__UNUSED uint32_t idx) {
|
||||
|
||||
void
|
||||
Download::set_root_directory(const std::string& path) {
|
||||
control->core()->push_log_std("Pushed " + path);
|
||||
|
||||
torrent::FileList* fileList = m_download.file_list();
|
||||
|
||||
control->core()->download_list()->close_directly(this);
|
||||
|
||||
@@ -261,6 +261,23 @@ DownloadFactory::receive_success() {
|
||||
if (m_manager->download_list()->find(infohash) == m_manager->download_list()->end())
|
||||
throw torrent::input_error("The newly created download was removed.");
|
||||
|
||||
// When a download scheduler is implemented, this is handled by
|
||||
// the above insertion into download list.
|
||||
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 (rpc::call_command_value("d.get_hashing", rpc::make_target(download)) != Download::variable_hashing_stopped ||
|
||||
rpc::call_command_value("d.get_state", rpc::make_target(download)) != 0)
|
||||
m_manager->download_list()->resume(download);
|
||||
|
||||
} else {
|
||||
// Use the state thingie here, move below.
|
||||
if (m_start)
|
||||
m_manager->download_list()->start_normal(download);
|
||||
|
||||
m_manager->download_store()->save(download);
|
||||
}
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
std::string msg = "Command on torrent creation failed: " + std::string(e.what());
|
||||
|
||||
@@ -275,25 +292,6 @@ DownloadFactory::receive_success() {
|
||||
download->set_message(msg);
|
||||
// m_manager->download_list()->erase(m_manager->download_list()->find(infohash.data()));
|
||||
}
|
||||
|
||||
return m_slotFinished();
|
||||
}
|
||||
|
||||
// When a download scheduler is implemented, this is handled by the
|
||||
// above insertion into download list.
|
||||
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 (rpc::call_command_value("d.get_hashing", rpc::make_target(download)) != Download::variable_hashing_stopped ||
|
||||
rpc::call_command_value("d.get_state", rpc::make_target(download)) != 0)
|
||||
m_manager->download_list()->resume(download);
|
||||
|
||||
} else {
|
||||
// Use the state thingie here, move below.
|
||||
if (m_start)
|
||||
m_manager->download_list()->start_normal(download);
|
||||
|
||||
m_manager->download_store()->save(download);
|
||||
}
|
||||
|
||||
m_slotFinished();
|
||||
|
||||
@@ -329,6 +329,12 @@ DownloadList::start_normal(Download* download) {
|
||||
|
||||
(*control->view_manager()->find_throw("stopped"))->set_not_visible(download);
|
||||
(*control->view_manager()->find_throw("started"))->set_visible(download);
|
||||
|
||||
// try {
|
||||
// rpc::parse_command_multiple(rpc::make_target(download), "d.set_state=1 ;view.set_not_visible=stopped ;view.set_visible=started");
|
||||
// } catch (torrent::local_error& e) {
|
||||
// control->core()->push_log(e.what());
|
||||
// }
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -348,6 +354,8 @@ DownloadList::start_try(Download* download) {
|
||||
(*control->view_manager()->find_throw("stopped"))->set_not_visible(download);
|
||||
(*control->view_manager()->find_throw("started"))->set_visible(download);
|
||||
|
||||
// rpc::parse_command_multiple(rpc::make_target(download), "d.set_state=1 ;view.set_not_visible=stopped ;view.set_visible=started");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,6 @@ private:
|
||||
void initialize_bencode(Download* d);
|
||||
|
||||
void receive_http_failed(std::string msg);
|
||||
|
||||
void receive_hashing_changed();
|
||||
|
||||
DownloadList* m_downloadList;
|
||||
|
||||
+29
-27
@@ -39,14 +39,16 @@
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <rak/functional.h>
|
||||
#include <rak/functional_fun.h>
|
||||
#include <rpc/parse_commands.h>
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <torrent/download.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "control.h"
|
||||
#include "download.h"
|
||||
#include "download_list.h"
|
||||
|
||||
#include "manager.h"
|
||||
#include "view.h"
|
||||
|
||||
namespace core {
|
||||
@@ -63,7 +65,7 @@ struct view_downloads_compare : std::binary_function<Download*, Download*, bool>
|
||||
return rpc::parse_command_single(rpc::make_target_pair(d1, d2), m_command).as_value();
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
// control->core()->push_log(e.what());
|
||||
control->core()->push_log(e.what());
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -95,6 +97,8 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
|
||||
return true;
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
control->core()->push_log(e.what());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -102,15 +106,24 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
|
||||
const std::string& m_command;
|
||||
};
|
||||
|
||||
inline void
|
||||
View::emit_changed() {
|
||||
priority_queue_erase(&taskScheduler, &m_delayChanged);
|
||||
priority_queue_insert(&taskScheduler, &m_delayChanged, cachedTime);
|
||||
}
|
||||
|
||||
View::~View() {
|
||||
if (m_name.empty())
|
||||
return;
|
||||
|
||||
std::for_each(m_list->slot_map_begin(), m_list->slot_map_end(), rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
|
||||
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));
|
||||
|
||||
priority_queue_erase(&taskScheduler, &m_delayChanged);
|
||||
}
|
||||
|
||||
void
|
||||
View::initialize(const std::string& name, core::DownloadList* dlist) {
|
||||
View::initialize(const std::string& name) {
|
||||
if (!m_name.empty())
|
||||
throw torrent::internal_error("View::initialize(...) called on an already initialized view.");
|
||||
|
||||
@@ -118,35 +131,21 @@ View::initialize(const std::string& name, core::DownloadList* dlist) {
|
||||
throw torrent::internal_error("View::initialize(...) called with an empty 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))
|
||||
throw torrent::internal_error("View::initialize(...) duplicate key name found in DownloadList.");
|
||||
|
||||
m_name = name;
|
||||
m_list = dlist;
|
||||
|
||||
// Urgh, wrong. No filtering being done.
|
||||
std::for_each(m_list->begin(), m_list->end(), rak::bind1st(std::mem_fun(&View::push_back), this));
|
||||
std::for_each(dlist->begin(), dlist->end(), rak::bind1st(std::mem_fun(&View::push_back), this));
|
||||
|
||||
m_size = base_type::size();
|
||||
m_focus = 0;
|
||||
|
||||
set_last_changed(rak::timer());
|
||||
}
|
||||
|
||||
void
|
||||
View::insert(Download* download) {
|
||||
// if (view_downloads_filter(m_filter)(download)) {
|
||||
// insert_visible(download);
|
||||
// rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
|
||||
|
||||
// } else {
|
||||
// base_type::insert(end_filtered(), download);
|
||||
// }
|
||||
|
||||
// We can't make the download visible until after it has been added
|
||||
// to every single View, as it might trigger a command too early.
|
||||
base_type::insert(base_type::end(), download);
|
||||
m_delayChanged.set_slot(rak::mem_fn(&m_signalChanged, &signal_type::operator()));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -201,7 +200,7 @@ View::next_focus() {
|
||||
return;
|
||||
|
||||
m_focus = (m_focus + 1) % (size() + 1);
|
||||
m_signalChanged.emit();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -210,7 +209,7 @@ View::prev_focus() {
|
||||
return;
|
||||
|
||||
m_focus = (m_focus - 1 + size() + 1) % (size() + 1);
|
||||
m_signalChanged.emit();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -221,7 +220,7 @@ View::sort() {
|
||||
std::stable_sort(begin(), end_visible(), view_downloads_compare(m_sortCurrent));
|
||||
|
||||
m_focus = position(std::find(begin(), end_visible(), curFocus));
|
||||
m_signalChanged.emit();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -254,6 +253,8 @@ View::filter() {
|
||||
|
||||
if (!m_eventAdded.empty())
|
||||
std::for_each(splitChanged, changed.end(), rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_d_nothrow), m_eventAdded));
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -290,7 +291,7 @@ View::filter_download(core::Download* download) {
|
||||
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
|
||||
}
|
||||
|
||||
m_signalChanged.emit();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -298,14 +299,15 @@ View::set_filter_on(int event) {
|
||||
if (event == DownloadList::SLOTS_INSERT || event == DownloadList::SLOTS_ERASE || event >= DownloadList::SLOTS_MAX_SIZE)
|
||||
throw torrent::internal_error("View::filter_on(...) invalid event.");
|
||||
|
||||
m_list->slots(event)["0_view_" + m_name] = "view.filter_download=" + m_name;
|
||||
control->core()->download_list()->slots(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(m_list->slot_map_begin() + DownloadList::SLOTS_OPEN, m_list->slot_map_end(), rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
|
||||
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));
|
||||
}
|
||||
|
||||
inline void
|
||||
|
||||
+6
-5
@@ -60,7 +60,6 @@
|
||||
namespace core {
|
||||
|
||||
class Download;
|
||||
class DownloadList;
|
||||
|
||||
class View : private std::vector<Download*> {
|
||||
public:
|
||||
@@ -77,7 +76,7 @@ public:
|
||||
View() {}
|
||||
~View();
|
||||
|
||||
void initialize(const std::string& name, DownloadList* dlist);
|
||||
void initialize(const std::string& name);
|
||||
|
||||
const std::string& name() const { return m_name; }
|
||||
|
||||
@@ -102,7 +101,7 @@ public:
|
||||
const_iterator focus() const { return begin() + m_focus; }
|
||||
void set_focus(iterator itr) { m_focus = position(itr); m_signalChanged.emit(); }
|
||||
|
||||
void insert(Download* download);
|
||||
void insert(Download* download) { base_type::push_back(download); }
|
||||
void erase(Download* download);
|
||||
|
||||
void set_visible(Download* download);
|
||||
@@ -150,14 +149,14 @@ private:
|
||||
inline void insert_visible(Download* d);
|
||||
inline void erase_internal(iterator itr);
|
||||
|
||||
inline void emit_changed();
|
||||
|
||||
size_type position(const_iterator itr) const { return itr - begin(); }
|
||||
|
||||
// An received thing for changed status so we can sort and filter.
|
||||
|
||||
std::string m_name;
|
||||
|
||||
DownloadList* m_list;
|
||||
|
||||
size_type m_size;
|
||||
size_type m_focus;
|
||||
|
||||
@@ -171,7 +170,9 @@ private:
|
||||
std::string m_eventRemoved;
|
||||
|
||||
rak::timer m_lastChanged;
|
||||
|
||||
signal_type m_signalChanged;
|
||||
rak::priority_item m_delayChanged;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -53,12 +53,6 @@
|
||||
|
||||
namespace core {
|
||||
|
||||
// Really need to implement a factory and allow options in the sort
|
||||
// statements.
|
||||
ViewManager::ViewManager(DownloadList* dl) :
|
||||
m_list(dl) {
|
||||
}
|
||||
|
||||
void
|
||||
ViewManager::clear() {
|
||||
std::for_each(begin(), end(), rak::call_delete<View>());
|
||||
@@ -72,7 +66,7 @@ ViewManager::insert(const std::string& name) {
|
||||
throw torrent::internal_error("ViewManager::insert(...) name already inserted.");
|
||||
|
||||
View* view = new View();
|
||||
view->initialize(name, m_list);
|
||||
view->initialize(name);
|
||||
|
||||
return base_type::insert(end(), view);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
ViewManager(DownloadList* dl);
|
||||
ViewManager() {}
|
||||
~ViewManager() { clear(); }
|
||||
|
||||
// Ffff... Just throwing together an interface, need to think some
|
||||
|
||||
+2
-1
@@ -153,7 +153,8 @@ Download::create_info() {
|
||||
element->push_column("Created:", te_command("cat=$to_date=$d.get_creation_date=,\" \",$to_time=$d.get_creation_date="));
|
||||
|
||||
element->push_back("");
|
||||
element->push_column("Directory:", te_command("d.get_base_path="));
|
||||
element->push_column("Directory:", te_command("d.get_directory="));
|
||||
element->push_column("Base Path:", te_command("d.get_base_path="));
|
||||
element->push_column("Tied to file:", te_command("d.get_tied_to_file="));
|
||||
element->push_column("File stats:", te_command("cat=$if=$d.is_multi_file=\\,multi\\,single,\" \",$d.get_size_files=,\" files\""));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user