mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-18 07:06:18 +00:00
Cleaned up ui::Root, fixed updating and hiding status bar.
Using displayScheduler for updating windows, much more efficient. Added saving of some parts of the state of torrents. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@482 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -416,6 +416,23 @@
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>hash_interval = <replaceable>ms</replaceable></term>
|
||||||
|
<listitem><para>
|
||||||
|
Interval between attempts to check the hash when the chunk
|
||||||
|
is not in memory, in milliseconds.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>hash_max_tries = <replaceable>tries</replaceable></term>
|
||||||
|
<listitem><para>
|
||||||
|
Number of attempts to check the hash while using the mincore
|
||||||
|
status, before forcing. Overworked systems might need lower
|
||||||
|
values to get a decent hash checking rate.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>max_open_files = <replaceable>value</replaceable></term>
|
<term>max_open_files = <replaceable>value</replaceable></term>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
|
|||||||
@@ -53,6 +53,14 @@
|
|||||||
# pages in memory thus end up trashing.
|
# pages in memory thus end up trashing.
|
||||||
#hash_read_ahead = 10
|
#hash_read_ahead = 10
|
||||||
|
|
||||||
|
# Interval between attempts to check the hash, in milliseconds.
|
||||||
|
#hash_interval = 100
|
||||||
|
|
||||||
|
# Number of attempts to check the hash while using the mincore status,
|
||||||
|
# before forcing. Overworked systems might need lower values to get a
|
||||||
|
# decent hash checking rate.
|
||||||
|
#hash_max_tries = 10
|
||||||
|
|
||||||
# Max number of files to keep open simultaniously.
|
# Max number of files to keep open simultaniously.
|
||||||
#max_open_files = 100
|
#max_open_files = 100
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <sigc++/connection.h>
|
#include <sigc++/connection.h>
|
||||||
#include <torrent/download.h>
|
#include <torrent/download.h>
|
||||||
|
#include <torrent/torrent.h>
|
||||||
|
|
||||||
namespace core {
|
namespace core {
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ public:
|
|||||||
|
|
||||||
torrent::Download& get_download() { return m_download; }
|
torrent::Download& get_download() { return m_download; }
|
||||||
std::string get_hash() { return m_download.get_hash(); }
|
std::string get_hash() { return m_download.get_hash(); }
|
||||||
|
torrent::Bencode& get_bencode() { return torrent::download_bencode(m_download.get_hash()); }
|
||||||
|
|
||||||
const std::string& get_message() { return m_message; }
|
const std::string& get_message() { return m_message; }
|
||||||
|
|
||||||
|
|||||||
+41
-2
@@ -31,7 +31,6 @@
|
|||||||
#include <sigc++/hide.h>
|
#include <sigc++/hide.h>
|
||||||
#include <torrent/bencode.h>
|
#include <torrent/bencode.h>
|
||||||
#include <torrent/exceptions.h>
|
#include <torrent/exceptions.h>
|
||||||
#include <torrent/torrent.h>
|
|
||||||
|
|
||||||
#include "download.h"
|
#include "download.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
@@ -54,8 +53,9 @@ Manager::initialize() {
|
|||||||
|
|
||||||
// Register slots to be called when a download is inserted/erased,
|
// Register slots to be called when a download is inserted/erased,
|
||||||
// opened or closed.
|
// opened or closed.
|
||||||
|
m_downloadList.slot_map_insert().insert("0_initialize_bencode", sigc::mem_fun(*this, &Manager::initialize_bencode));
|
||||||
m_downloadList.slot_map_insert().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().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().insert("3_manager_start", sigc::mem_fun(*this, &Manager::start));
|
m_downloadList.slot_map_insert().insert("3_manager_inserted", sigc::mem_fun(*this, &Manager::receive_download_inserted));
|
||||||
m_downloadList.slot_map_insert().insert("4_store_save", sigc::mem_fun(m_downloadStore, &DownloadStore::save));
|
m_downloadList.slot_map_insert().insert("4_store_save", sigc::mem_fun(m_downloadStore, &DownloadStore::save));
|
||||||
|
|
||||||
m_downloadList.slot_map_erase().insert("1_hash_queue_remove", sigc::mem_fun(m_hashQueue, &HashQueue::remove));
|
m_downloadList.slot_map_erase().insert("1_hash_queue_remove", sigc::mem_fun(m_hashQueue, &HashQueue::remove));
|
||||||
@@ -87,6 +87,16 @@ Manager::cleanup() {
|
|||||||
core::CurlStack::cleanup();
|
core::CurlStack::cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Manager::shutdown(bool force) {
|
||||||
|
if (!force)
|
||||||
|
std::for_each(m_downloadList.begin(), m_downloadList.end(),
|
||||||
|
std::bind1st(std::mem_fun(&DownloadList::stop), &m_downloadList));
|
||||||
|
else
|
||||||
|
std::for_each(m_downloadList.begin(), m_downloadList.end(),
|
||||||
|
std::bind1st(std::mem_fun(&DownloadList::close), &m_downloadList));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Manager::insert(std::string uri) {
|
Manager::insert(std::string uri) {
|
||||||
if (std::strncmp(uri.c_str(), "http://", 7) == 0) {
|
if (std::strncmp(uri.c_str(), "http://", 7) == 0) {
|
||||||
@@ -111,6 +121,8 @@ Manager::erase(DListItr itr) {
|
|||||||
void
|
void
|
||||||
Manager::start(Download* d) {
|
Manager::start(Download* d) {
|
||||||
try {
|
try {
|
||||||
|
d->get_bencode()["rtorrent"]["state"] = "started";
|
||||||
|
|
||||||
if (d->get_download().is_active())
|
if (d->get_download().is_active())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -132,6 +144,8 @@ Manager::start(Download* d) {
|
|||||||
void
|
void
|
||||||
Manager::stop(Download* d) {
|
Manager::stop(Download* d) {
|
||||||
try {
|
try {
|
||||||
|
d->get_bencode()["rtorrent"]["state"] = "stopped";
|
||||||
|
|
||||||
m_downloadList.stop(d);
|
m_downloadList.stop(d);
|
||||||
|
|
||||||
} catch (torrent::local_error& e) {
|
} catch (torrent::local_error& e) {
|
||||||
@@ -212,6 +226,21 @@ Manager::create_final(std::istream* s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Manager::initialize_bencode(Download* d) {
|
||||||
|
torrent::Bencode& bencode = d->get_bencode();
|
||||||
|
|
||||||
|
// TODO: Check that stuff are the right type, like state etc.
|
||||||
|
if (bencode.has_key("rtorrent") &&
|
||||||
|
bencode["rtorrent"].is_map() &&
|
||||||
|
bencode["rtorrent"].has_key("state") &&
|
||||||
|
bencode["rtorrent"]["state"].is_string())
|
||||||
|
return;
|
||||||
|
|
||||||
|
bencode.insert_key("rtorrent", torrent::Bencode(torrent::Bencode::TYPE_MAP));
|
||||||
|
bencode["rtorrent"].insert_key("state", "started");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Manager::prepare_hash_check(Download* d) {
|
Manager::prepare_hash_check(Download* d) {
|
||||||
m_downloadList.close(d);
|
m_downloadList.close(d);
|
||||||
@@ -242,4 +271,14 @@ Manager::receive_download_done_hash_checked(Download* d) {
|
|||||||
d->get_download().tracker_send_completed();
|
d->get_download().tracker_send_completed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Manager::receive_download_inserted(Download* d) {
|
||||||
|
// Check if there is an "rtorrent" section in the bencoded data.
|
||||||
|
|
||||||
|
torrent::Bencode& bencode = d->get_bencode();
|
||||||
|
|
||||||
|
if (bencode["rtorrent"]["state"].as_string() == "started")
|
||||||
|
start(d);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public:
|
|||||||
void initialize();
|
void initialize();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
void shutdown(bool force);
|
||||||
|
|
||||||
void insert(std::string uri);
|
void insert(std::string uri);
|
||||||
DListItr erase(DListItr itr);
|
DListItr erase(DListItr itr);
|
||||||
|
|
||||||
@@ -77,10 +79,13 @@ private:
|
|||||||
void create_http(const std::string& uri);
|
void create_http(const std::string& uri);
|
||||||
void create_final(std::istream* s);
|
void create_final(std::istream* s);
|
||||||
|
|
||||||
|
void initialize_bencode(Download* d);
|
||||||
|
|
||||||
void prepare_hash_check(Download* d);
|
void prepare_hash_check(Download* d);
|
||||||
|
|
||||||
void receive_http_failed(std::string msg);
|
void receive_http_failed(std::string msg);
|
||||||
void receive_download_done_hash_checked(Download* d);
|
void receive_download_done_hash_checked(Download* d);
|
||||||
|
void receive_download_inserted(Download* d);
|
||||||
|
|
||||||
DownloadList m_downloadList;
|
DownloadList m_downloadList;
|
||||||
DownloadStore m_downloadStore;
|
DownloadStore m_downloadStore;
|
||||||
|
|||||||
@@ -83,8 +83,7 @@ void
|
|||||||
Manager::do_update() {
|
Manager::do_update() {
|
||||||
Canvas::refresh_std();
|
Canvas::refresh_std();
|
||||||
|
|
||||||
std::for_each(begin(), end(), rak::if_then(std::mem_fun(&Window::is_active), rak::if_then(std::mem_fun(&Window::is_dirty),
|
utils::displayScheduler.execute(utils::Timer::cache());
|
||||||
std::mem_fun(&Window::redraw))));
|
|
||||||
std::for_each(begin(), end(), rak::if_then(std::mem_fun(&Window::is_active), std::mem_fun(&Window::refresh)));
|
std::for_each(begin(), end(), rak::if_then(std::mem_fun(&Window::is_active), std::mem_fun(&Window::refresh)));
|
||||||
|
|
||||||
Canvas::do_update();
|
Canvas::do_update();
|
||||||
|
|||||||
@@ -30,10 +30,31 @@ namespace display {
|
|||||||
|
|
||||||
Window::Slot Window::m_slotAdjust;
|
Window::Slot Window::m_slotAdjust;
|
||||||
|
|
||||||
|
Window::Window(Canvas* c, bool d, int h) :
|
||||||
|
m_canvas(c),
|
||||||
|
m_active(true),
|
||||||
|
m_dynamic(d),
|
||||||
|
m_minHeight(h) {
|
||||||
|
|
||||||
|
m_taskUpdate.set_iterator(utils::displayScheduler.end());
|
||||||
|
m_taskUpdate.set_slot(sigc::mem_fun(*this, &Window::redraw));
|
||||||
|
}
|
||||||
|
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
|
utils::displayScheduler.erase(&m_taskUpdate);
|
||||||
delete m_canvas;
|
delete m_canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Window::set_active(bool a) {
|
||||||
|
if (a)
|
||||||
|
mark_dirty();
|
||||||
|
else
|
||||||
|
utils::displayScheduler.erase(&m_taskUpdate);
|
||||||
|
|
||||||
|
m_active = a;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Window::resize(int x, int y, int w, int h) {
|
Window::resize(int x, int y, int w, int h) {
|
||||||
if (x < 0 || y < 0)
|
if (x < 0 || y < 0)
|
||||||
|
|||||||
+26
-20
@@ -26,6 +26,7 @@
|
|||||||
#include <sigc++/slot.h>
|
#include <sigc++/slot.h>
|
||||||
|
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
|
#include "utils/task.h"
|
||||||
#include "utils/timer.h"
|
#include "utils/timer.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
@@ -36,46 +37,51 @@ class Window {
|
|||||||
public:
|
public:
|
||||||
typedef sigc::slot0<void> Slot;
|
typedef sigc::slot0<void> Slot;
|
||||||
|
|
||||||
Window(Canvas* c = NULL, bool d = false, int h = 1) :
|
Window(Canvas* c = NULL, bool d = false, int h = 1);
|
||||||
m_canvas(c), m_active(true), m_dynamic(d), m_minHeight(h) {}
|
|
||||||
|
|
||||||
virtual ~Window();
|
virtual ~Window();
|
||||||
|
|
||||||
bool is_active() { return m_active; }
|
bool is_active() { return m_active; }
|
||||||
bool is_dynamic() { return m_dynamic; }
|
bool is_dynamic() { return m_dynamic; }
|
||||||
bool is_dirty() { return m_nextDraw <= utils::Timer::cache(); }
|
bool is_dirty() { return utils::displayScheduler.is_scheduled(&m_taskUpdate); }
|
||||||
|
|
||||||
utils::Timer get_next_draw() { return m_nextDraw; }
|
//utils::Timer get_next_draw() { return m_nextDraw; }
|
||||||
|
|
||||||
int get_min_height() { return m_minHeight; }
|
int get_min_height() { return m_minHeight; }
|
||||||
|
|
||||||
bool get_active() { return m_active; }
|
bool get_active() { return m_active; }
|
||||||
void set_active(bool a) { m_active = a; }
|
void set_active(bool a);
|
||||||
|
|
||||||
void refresh() { m_canvas->refresh(); }
|
void refresh() { m_canvas->refresh(); }
|
||||||
void resize(int x, int y, int w, int h);
|
void resize(int x, int y, int w, int h);
|
||||||
|
|
||||||
void mark_dirty() { m_nextDraw = utils::Timer::min(); }
|
void mark_dirty();
|
||||||
|
|
||||||
virtual void redraw() = 0;
|
virtual void redraw() = 0;
|
||||||
|
|
||||||
static void slot_adjust(Slot s) { m_slotAdjust = s; }
|
static void slot_adjust(Slot s) { m_slotAdjust = s; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Window(const Window&);
|
Window(const Window&);
|
||||||
void operator = (const Window&);
|
void operator = (const Window&);
|
||||||
|
|
||||||
static Slot m_slotAdjust;
|
static Slot m_slotAdjust;
|
||||||
|
|
||||||
Canvas* m_canvas;
|
Canvas* m_canvas;
|
||||||
|
|
||||||
bool m_active;
|
bool m_active;
|
||||||
bool m_dynamic;
|
bool m_dynamic;
|
||||||
int m_minHeight;
|
int m_minHeight;
|
||||||
|
|
||||||
utils::Timer m_nextDraw;
|
utils::TaskItem m_taskUpdate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Window::mark_dirty() {
|
||||||
|
utils::displayScheduler.erase(&m_taskUpdate);
|
||||||
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ WindowDownloadList::~WindowDownloadList() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowDownloadList::redraw() {
|
WindowDownloadList::redraw() {
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 1000000);
|
||||||
|
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ WindowDownloadStatusbar::WindowDownloadStatusbar(core::Download* d) :
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowDownloadStatusbar::redraw() {
|
WindowDownloadStatusbar::redraw() {
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 1000000);
|
||||||
|
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ WindowFileList::WindowFileList(core::Download* d, unsigned int* focus) :
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowFileList::redraw() {
|
WindowFileList::redraw() {
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 10 * 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 10 * 1000000);
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
if (m_download->get_download().get_entry_size() == 0 ||
|
if (m_download->get_download().get_entry_size() == 0 ||
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ WindowHttpQueue::WindowHttpQueue(core::HttpQueue* q) :
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowHttpQueue::redraw() {
|
WindowHttpQueue::redraw() {
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 1000000);
|
||||||
|
|
||||||
cleanup_list();
|
cleanup_list();
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,7 @@ WindowInput::WindowInput(input::TextInput* input) :
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowInput::redraw() {
|
WindowInput::redraw() {
|
||||||
m_nextDraw = utils::Timer::max();
|
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
m_canvas->print(0, 0, "> %s", m_input->c_str());
|
m_canvas->print(0, 0, "> %s", m_input->c_str());
|
||||||
|
|
||||||
if (m_focus)
|
if (m_focus)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ WindowLog::WindowLog(core::Log* l) :
|
|||||||
Window(new Canvas, false, 0),
|
Window(new Canvas, false, 0),
|
||||||
m_log(l) {
|
m_log(l) {
|
||||||
|
|
||||||
set_active(false);
|
m_active = false;
|
||||||
|
|
||||||
// We're trying out scheduled tasks instead.
|
// We're trying out scheduled tasks instead.
|
||||||
m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLog::receive_update));
|
m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLog::receive_update));
|
||||||
@@ -51,8 +51,6 @@ WindowLog::find_older() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowLog::redraw() {
|
WindowLog::redraw() {
|
||||||
m_nextDraw = utils::Timer::max();
|
|
||||||
|
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ WindowLogComplete::find_older() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowLogComplete::redraw() {
|
WindowLogComplete::redraw() {
|
||||||
m_nextDraw = utils::Timer::max();
|
|
||||||
|
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ WindowPeerInfo::WindowPeerInfo(core::Download* d, PList* l, PList::iterator* f)
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowPeerInfo::redraw() {
|
WindowPeerInfo::redraw() {
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 1000000);
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ WindowPeerList::WindowPeerList(core::Download* d, PList* l, PList::iterator* f)
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowPeerList::redraw() {
|
WindowPeerList::redraw() {
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 1000000);
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
int x = 2;
|
int x = 2;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ WindowStatusbar::WindowStatusbar(core::Manager* c) :
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowStatusbar::redraw() {
|
WindowStatusbar::redraw() {
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 1000000);
|
||||||
|
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,6 @@ WindowStringList::~WindowStringList() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowStringList::redraw() {
|
WindowStringList::redraw() {
|
||||||
m_nextDraw = utils::Timer::max();
|
|
||||||
|
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
size_t ypos = 0;
|
size_t ypos = 0;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ WindowTitle::WindowTitle(const std::string& s) :
|
|||||||
|
|
||||||
void
|
void
|
||||||
WindowTitle::redraw() {
|
WindowTitle::redraw() {
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 1000000);
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
m_canvas->print(std::max(0, (m_canvas->get_width() - (int)m_title.size()) / 2 - 4), 0,
|
m_canvas->print(std::max(0, (m_canvas->get_width() - (int)m_title.size()) / 2 - 4), 0,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ WindowTrackerList::WindowTrackerList(core::Download* d, unsigned int* focus) :
|
|||||||
void
|
void
|
||||||
WindowTrackerList::redraw() {
|
WindowTrackerList::redraw() {
|
||||||
// TODO: Make this depend on tracker signal.
|
// TODO: Make this depend on tracker signal.
|
||||||
m_nextDraw = utils::Timer::cache().round_seconds() + 10 * 1000000;
|
utils::displayScheduler.insert(&m_taskUpdate, utils::Timer::cache().round_seconds() + 10 * 1000000);
|
||||||
m_canvas->erase();
|
m_canvas->erase();
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|||||||
+16
-16
@@ -42,7 +42,6 @@
|
|||||||
#include "display/canvas.h"
|
#include "display/canvas.h"
|
||||||
#include "display/window.h"
|
#include "display/window.h"
|
||||||
#include "ui/control.h"
|
#include "ui/control.h"
|
||||||
#include "ui/root.h"
|
|
||||||
#include "input/bindings.h"
|
#include "input/bindings.h"
|
||||||
|
|
||||||
#include "utils/task.h"
|
#include "utils/task.h"
|
||||||
@@ -64,6 +63,7 @@ void print_help();
|
|||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
TaskScheduler taskScheduler;
|
TaskScheduler taskScheduler;
|
||||||
|
TaskScheduler displayScheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -85,15 +85,12 @@ do_shutdown(ui::Control* c) {
|
|||||||
is_shutting_down = true;
|
is_shutting_down = true;
|
||||||
|
|
||||||
torrent::listen_close();
|
torrent::listen_close();
|
||||||
|
c->get_core().shutdown(false);
|
||||||
std::for_each(c->get_core().get_download_list().begin(), c->get_core().get_download_list().end(),
|
|
||||||
std::bind1st(std::mem_fun(&core::Manager::stop), &c->get_core()));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Close all torrents, this will stop all tracker connections and cause
|
// Close all torrents, this will stop all tracker connections and cause
|
||||||
// a quick shutdown.
|
// a quick shutdown.
|
||||||
std::for_each(c->get_core().get_download_list().begin(), c->get_core().get_download_list().end(),
|
c->get_core().shutdown(true);
|
||||||
std::mem_fun(&core::Download::call<void, &torrent::Download::close>));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +129,9 @@ initialize_option_handler(ui::Control* c, OptionHandler* optionHandler) {
|
|||||||
optionHandler->insert("check_hash", new OptionHandlerString(c, &apply_check_hash, &validate_yes_no));
|
optionHandler->insert("check_hash", new OptionHandlerString(c, &apply_check_hash, &validate_yes_no));
|
||||||
optionHandler->insert("directory", new OptionHandlerString(c, &apply_download_directory, &validate_directory));
|
optionHandler->insert("directory", new OptionHandlerString(c, &apply_download_directory, &validate_directory));
|
||||||
|
|
||||||
optionHandler->insert("hash_read_ahead", new OptionHandlerInt(c, &apply_hash_read_ahead, &validate_read_ahead));
|
optionHandler->insert("hash_read_ahead", new OptionHandlerInt(c, &apply_hash_read_ahead, &validate_hash_read_ahead));
|
||||||
|
optionHandler->insert("hash_interval", new OptionHandlerInt(c, &apply_hash_interval, &validate_hash_interval));
|
||||||
|
optionHandler->insert("hash_max_tries", new OptionHandlerInt(c, &apply_hash_max_tries, &validate_hash_max_tries));
|
||||||
optionHandler->insert("max_open_files", new OptionHandlerInt(c, &apply_max_open_files, &validate_fd));
|
optionHandler->insert("max_open_files", new OptionHandlerInt(c, &apply_max_open_files, &validate_fd));
|
||||||
optionHandler->insert("throttle_interval", new OptionHandlerInt(c, &apply_throttle_interval, &validate_throttle_interval));
|
optionHandler->insert("throttle_interval", new OptionHandlerInt(c, &apply_throttle_interval, &validate_throttle_interval));
|
||||||
|
|
||||||
@@ -186,7 +185,6 @@ int
|
|||||||
main(int argc, char** argv) {
|
main(int argc, char** argv) {
|
||||||
OptionHandler optionHandler;
|
OptionHandler optionHandler;
|
||||||
ui::Control uiControl;
|
ui::Control uiControl;
|
||||||
ui::Root uiRoot(&uiControl);
|
|
||||||
|
|
||||||
utils::Timer::update();
|
utils::Timer::update();
|
||||||
|
|
||||||
@@ -198,10 +196,10 @@ main(int argc, char** argv) {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
SignalHandler::set_ignore(SIGPIPE);
|
SignalHandler::set_ignore(SIGPIPE);
|
||||||
SignalHandler::set_handler(SIGINT, sigc::bind(sigc::mem_fun(uiRoot, &ui::Root::set_shutdown_received), true));
|
SignalHandler::set_handler(SIGINT, sigc::bind(sigc::mem_fun(uiControl, &ui::Control::set_shutdown_received), true));
|
||||||
SignalHandler::set_handler(SIGSEGV, sigc::bind(sigc::ptr_fun(&do_panic), SIGSEGV));
|
SignalHandler::set_handler(SIGSEGV, sigc::bind(sigc::ptr_fun(&do_panic), SIGSEGV));
|
||||||
SignalHandler::set_handler(SIGBUS, sigc::bind(sigc::ptr_fun(&do_panic), SIGBUS));
|
SignalHandler::set_handler(SIGBUS, sigc::bind(sigc::ptr_fun(&do_panic), SIGBUS));
|
||||||
SignalHandler::set_handler(SIGFPE, sigc::bind(sigc::ptr_fun(&do_panic), SIGFPE));
|
SignalHandler::set_handler(SIGFPE, sigc::bind(sigc::ptr_fun(&do_panic), SIGFPE));
|
||||||
|
|
||||||
// Need to initialize this before parseing options.
|
// Need to initialize this before parseing options.
|
||||||
torrent::initialize();
|
torrent::initialize();
|
||||||
@@ -214,7 +212,7 @@ main(int argc, char** argv) {
|
|||||||
initialize_display(&uiControl);
|
initialize_display(&uiControl);
|
||||||
initialize_core(&uiControl);
|
initialize_core(&uiControl);
|
||||||
|
|
||||||
uiRoot.init();
|
uiControl.get_ui().init(&uiControl);
|
||||||
|
|
||||||
load_session_torrents(&uiControl);
|
load_session_torrents(&uiControl);
|
||||||
load_arg_torrents(&uiControl, argv + firstArg, argv + argc);
|
load_arg_torrents(&uiControl, argv + firstArg, argv + argc);
|
||||||
@@ -223,9 +221,9 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
while (!is_shutting_down || !torrent::is_inactive()) {
|
while (!is_shutting_down || !torrent::is_inactive()) {
|
||||||
|
|
||||||
if (uiRoot.get_shutdown_received()) {
|
if (uiControl.get_shutdown_received()) {
|
||||||
do_shutdown(&uiControl);
|
do_shutdown(&uiControl);
|
||||||
uiRoot.set_shutdown_received(false);
|
uiControl.set_shutdown_received(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::Timer::update();
|
utils::Timer::update();
|
||||||
@@ -233,14 +231,16 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
// This needs to be called every second or so. Currently done by
|
// This needs to be called every second or so. Currently done by
|
||||||
// the throttle task in libtorrent.
|
// the throttle task in libtorrent.
|
||||||
uiControl.get_display().do_update();
|
if (!utils::displayScheduler.empty() &&
|
||||||
|
utils::displayScheduler.get_next_timeout() <= utils::Timer::cache())
|
||||||
|
uiControl.get_display().do_update();
|
||||||
|
|
||||||
uiControl.get_core().get_poll().poll(!utils::taskScheduler.empty() ?
|
uiControl.get_core().get_poll().poll(!utils::taskScheduler.empty() ?
|
||||||
utils::taskScheduler.get_next_timeout() - utils::Timer::cache() :
|
utils::taskScheduler.get_next_timeout() - utils::Timer::cache() :
|
||||||
60 * 1000000);
|
60 * 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
uiRoot.cleanup();
|
uiControl.get_ui().cleanup();
|
||||||
uiControl.get_core().cleanup();
|
uiControl.get_core().cleanup();
|
||||||
|
|
||||||
display::Canvas::erase_std();
|
display::Canvas::erase_std();
|
||||||
|
|||||||
@@ -71,10 +71,20 @@ validate_rate(int arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
validate_read_ahead(int arg) {
|
validate_hash_read_ahead(int arg) {
|
||||||
return arg >= 1 && arg < 64;
|
return arg >= 1 && arg < 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
validate_hash_interval(int arg) {
|
||||||
|
return arg >= 1 && arg < 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
validate_hash_max_tries(int arg) {
|
||||||
|
return arg >= 1 && arg < 20;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
validate_fd(int arg) {
|
validate_fd(int arg) {
|
||||||
return arg >= 10 && arg < (1 << 16);
|
return arg >= 10 && arg < (1 << 16);
|
||||||
@@ -123,6 +133,16 @@ apply_hash_read_ahead(ui::Control* m, int arg) {
|
|||||||
torrent::set_hash_read_ahead(arg << 20);
|
torrent::set_hash_read_ahead(arg << 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apply_hash_interval(ui::Control* m, int arg) {
|
||||||
|
torrent::set_hash_interval(arg * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apply_hash_max_tries(ui::Control* m, int arg) {
|
||||||
|
torrent::set_hash_max_tries(arg);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
apply_max_open_files(ui::Control* m, int arg) {
|
apply_max_open_files(ui::Control* m, int arg) {
|
||||||
torrent::set_max_open_files(arg);
|
torrent::set_max_open_files(arg);
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ bool validate_yes_no(const std::string& arg);
|
|||||||
|
|
||||||
bool validate_download_peers(int arg);
|
bool validate_download_peers(int arg);
|
||||||
bool validate_rate(int arg);
|
bool validate_rate(int arg);
|
||||||
bool validate_read_ahead(int arg);
|
bool validate_hash_read_ahead(int arg);
|
||||||
|
bool validate_hash_interval(int arg);
|
||||||
|
bool validate_hash_max_tries(int arg);
|
||||||
bool validate_fd(int arg);
|
bool validate_fd(int arg);
|
||||||
|
|
||||||
bool validate_throttle_interval(int arg);
|
bool validate_throttle_interval(int arg);
|
||||||
@@ -56,6 +58,8 @@ void apply_global_download_rate(ui::Control* m, int arg);
|
|||||||
void apply_global_upload_rate(ui::Control* m, int arg);
|
void apply_global_upload_rate(ui::Control* m, int arg);
|
||||||
|
|
||||||
void apply_hash_read_ahead(ui::Control* m, int arg);
|
void apply_hash_read_ahead(ui::Control* m, int arg);
|
||||||
|
void apply_hash_interval(ui::Control* m, int arg);
|
||||||
|
void apply_hash_max_tries(ui::Control* m, int arg);
|
||||||
void apply_max_open_files(ui::Control* m, int arg);
|
void apply_max_open_files(ui::Control* m, int arg);
|
||||||
void apply_throttle_interval(ui::Control* m, int arg);
|
void apply_throttle_interval(ui::Control* m, int arg);
|
||||||
|
|
||||||
|
|||||||
+16
-7
@@ -27,23 +27,32 @@
|
|||||||
#include "display/manager.h"
|
#include "display/manager.h"
|
||||||
#include "input/manager.h"
|
#include "input/manager.h"
|
||||||
|
|
||||||
|
#include "root.h"
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
class Control {
|
class Control {
|
||||||
public:
|
public:
|
||||||
Control() {}
|
Control() : m_shutdownReceived(false) {}
|
||||||
|
|
||||||
core::Manager& get_core() { return m_core; }
|
bool get_shutdown_received() { return m_shutdownReceived; }
|
||||||
display::Manager& get_display() { return m_display; }
|
void set_shutdown_received(bool v) { m_shutdownReceived = v; }
|
||||||
input::Manager& get_input() { return m_input; }
|
|
||||||
|
Root& get_ui() { return m_ui; }
|
||||||
|
core::Manager& get_core() { return m_core; }
|
||||||
|
display::Manager& get_display() { return m_display; }
|
||||||
|
input::Manager& get_input() { return m_input; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Control(const Control&);
|
Control(const Control&);
|
||||||
void operator = (const Control&);
|
void operator = (const Control&);
|
||||||
|
|
||||||
core::Manager m_core;
|
bool m_shutdownReceived;
|
||||||
display::Manager m_display;
|
|
||||||
input::Manager m_input;
|
Root m_ui;
|
||||||
|
core::Manager m_core;
|
||||||
|
display::Manager m_display;
|
||||||
|
input::Manager m_input;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "display/window_input.h"
|
#include "display/window_input.h"
|
||||||
#include "display/window_log.h"
|
#include "display/window_log.h"
|
||||||
#include "display/window_title.h"
|
#include "display/window_title.h"
|
||||||
|
#include "display/window_statusbar.h"
|
||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "download.h"
|
#include "download.h"
|
||||||
@@ -113,15 +114,15 @@ DownloadList::disable() {
|
|||||||
if (!is_active())
|
if (!is_active())
|
||||||
throw std::logic_error("ui::Download::disable() called on an already disabled object");
|
throw std::logic_error("ui::Download::disable() called on an already disabled object");
|
||||||
|
|
||||||
disable_display();
|
|
||||||
|
|
||||||
utils::taskScheduler.erase(&m_taskUpdate);
|
|
||||||
|
|
||||||
if (m_windowTextInput->is_active()) {
|
if (m_windowTextInput->is_active()) {
|
||||||
m_windowTextInput->get_input()->clear();
|
m_windowTextInput->get_input()->clear();
|
||||||
receive_exit_input();
|
receive_exit_input();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disable_display();
|
||||||
|
|
||||||
|
utils::taskScheduler.erase(&m_taskUpdate);
|
||||||
|
|
||||||
m_control->get_display().erase(m_window);
|
m_control->get_display().erase(m_window);
|
||||||
m_control->get_display().erase(m_windowTitle);
|
m_control->get_display().erase(m_windowTitle);
|
||||||
m_control->get_display().erase(m_windowTextInput);
|
m_control->get_display().erase(m_windowTextInput);
|
||||||
@@ -225,7 +226,7 @@ DownloadList::receive_check_hash() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
DownloadList::receive_view_input() {
|
DownloadList::receive_view_input() {
|
||||||
//m_windowStatus->set_active(false);
|
m_control->get_ui().window_statusbar()->set_active(false);
|
||||||
m_windowTextInput->set_active(true);
|
m_windowTextInput->set_active(true);
|
||||||
m_control->get_display().adjust_layout();
|
m_control->get_display().adjust_layout();
|
||||||
|
|
||||||
@@ -239,7 +240,7 @@ DownloadList::receive_view_input() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
DownloadList::receive_exit_input() {
|
DownloadList::receive_exit_input() {
|
||||||
//m_windowStatus->set_active(true);
|
m_control->get_ui().window_statusbar()->set_active(true);
|
||||||
m_windowTextInput->set_active(false);
|
m_windowTextInput->set_active(false);
|
||||||
|
|
||||||
m_control->get_input().set_text_input();
|
m_control->get_input().set_text_input();
|
||||||
|
|||||||
+18
-14
@@ -34,24 +34,24 @@
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
Root::Root(Control* c) :
|
Root::Root() :
|
||||||
m_shutdownReceived(false),
|
m_control(NULL),
|
||||||
m_control(c),
|
|
||||||
m_downloadList(NULL),
|
m_downloadList(NULL),
|
||||||
m_windowStatus(NULL) {
|
m_windowStatusbar(NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Root::init() {
|
Root::init(Control* c) {
|
||||||
if (m_downloadList != NULL)
|
if (m_control != NULL)
|
||||||
throw std::logic_error("Root::init() called twice on the same object");
|
throw std::logic_error("Root::init() called twice on the same object");
|
||||||
|
|
||||||
|
m_control = c;
|
||||||
setup_keys();
|
setup_keys();
|
||||||
|
|
||||||
m_windowStatus = new WStatus(&m_control->get_core());
|
m_windowStatusbar = new WStatusbar(&m_control->get_core());
|
||||||
m_downloadList = new DownloadList(m_control);
|
m_downloadList = new DownloadList(m_control);
|
||||||
|
|
||||||
m_control->get_display().push_back(m_windowStatus);
|
m_control->get_display().push_back(m_windowStatusbar);
|
||||||
|
|
||||||
m_downloadList->activate();
|
m_downloadList->activate();
|
||||||
m_downloadList->slot_open_uri(sigc::mem_fun(m_control->get_core(), &core::Manager::insert));
|
m_downloadList->slot_open_uri(sigc::mem_fun(m_control->get_core(), &core::Manager::insert));
|
||||||
@@ -59,15 +59,19 @@ Root::init() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
Root::cleanup() {
|
Root::cleanup() {
|
||||||
|
if (m_control == NULL)
|
||||||
|
throw std::logic_error("Root::cleanup() called twice on the same object");
|
||||||
|
|
||||||
if (m_downloadList->is_active())
|
if (m_downloadList->is_active())
|
||||||
m_downloadList->disable();
|
m_downloadList->disable();
|
||||||
|
|
||||||
m_control->get_display().erase(m_windowStatus);
|
m_control->get_display().erase(m_windowStatusbar);
|
||||||
|
|
||||||
delete m_downloadList;
|
delete m_downloadList;
|
||||||
delete m_windowStatus;
|
delete m_windowStatusbar;
|
||||||
|
|
||||||
m_control->get_input().erase(&m_bindings);
|
m_control->get_input().erase(&m_bindings);
|
||||||
|
m_control = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -89,19 +93,19 @@ Root::setup_keys() {
|
|||||||
m_bindings['C'] = sigc::bind(sigc::mem_fun(*this, &Root::receive_read_throttle), -50);
|
m_bindings['C'] = sigc::bind(sigc::mem_fun(*this, &Root::receive_read_throttle), -50);
|
||||||
|
|
||||||
m_bindings[KEY_RESIZE] = sigc::mem_fun(m_control->get_display(), &display::Manager::adjust_layout);
|
m_bindings[KEY_RESIZE] = sigc::mem_fun(m_control->get_display(), &display::Manager::adjust_layout);
|
||||||
m_bindings['\x11'] = sigc::bind(sigc::mem_fun(*this, &Root::set_shutdown_received), true);
|
m_bindings['\x11'] = sigc::bind(sigc::mem_fun(*m_control, &Control::set_shutdown_received), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Root::receive_read_throttle(int t) {
|
Root::receive_read_throttle(int t) {
|
||||||
//m_downloadList->mark_dirty();
|
m_windowStatusbar->mark_dirty();
|
||||||
|
|
||||||
torrent::set_read_throttle(torrent::get_read_throttle() + t * 1024);
|
torrent::set_read_throttle(torrent::get_read_throttle() + t * 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Root::receive_write_throttle(int t) {
|
Root::receive_write_throttle(int t) {
|
||||||
//m_downloadList->mark_dirty();
|
m_windowStatusbar->mark_dirty();
|
||||||
|
|
||||||
torrent::set_write_throttle(torrent::get_write_throttle() + t * 1024);
|
torrent::set_write_throttle(torrent::get_write_throttle() + t * 1024);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-8
@@ -32,18 +32,18 @@ namespace display {
|
|||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
class DownloadList;
|
class DownloadList;
|
||||||
|
class Control;
|
||||||
|
|
||||||
class Root {
|
class Root {
|
||||||
public:
|
public:
|
||||||
typedef display::WindowStatusbar WStatus;
|
typedef display::WindowStatusbar WStatusbar;
|
||||||
|
|
||||||
Root(Control* c);
|
Root();
|
||||||
|
|
||||||
void init();
|
void init(Control* c);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
bool get_shutdown_received() { return m_shutdownReceived; }
|
WStatusbar* window_statusbar() { return m_windowStatusbar; }
|
||||||
void set_shutdown_received(bool v) { m_shutdownReceived = v; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup_keys();
|
void setup_keys();
|
||||||
@@ -51,12 +51,10 @@ private:
|
|||||||
void receive_read_throttle(int t);
|
void receive_read_throttle(int t);
|
||||||
void receive_write_throttle(int t);
|
void receive_write_throttle(int t);
|
||||||
|
|
||||||
bool m_shutdownReceived;
|
|
||||||
|
|
||||||
Control* m_control;
|
Control* m_control;
|
||||||
DownloadList* m_downloadList;
|
DownloadList* m_downloadList;
|
||||||
|
|
||||||
WStatus* m_windowStatus;
|
WStatusbar* m_windowStatusbar;
|
||||||
|
|
||||||
input::Bindings m_bindings;
|
input::Bindings m_bindings;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
extern TaskScheduler taskScheduler;
|
extern TaskScheduler taskScheduler;
|
||||||
|
extern TaskScheduler displayScheduler;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user