mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-06 10:12:30 +00:00
Task Scheduler, log viewer pops up and disapperes. good good
git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@308 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -11,7 +11,7 @@ void
|
||||
Download::set_download(torrent::Download d) {
|
||||
m_download = d;
|
||||
|
||||
m_connTrackerSucceded = m_download.signal_tracker_succeded(sigc::bind(sigc::mem_fun(*this, &Download::receive_tracker_msg), "^_^"));
|
||||
m_connTrackerSucceded = m_download.signal_tracker_succeded(sigc::bind(sigc::mem_fun(*this, &Download::receive_tracker_msg), ""));
|
||||
m_connTrackerFailed = m_download.signal_tracker_failed(sigc::mem_fun(*this, &Download::receive_tracker_msg));
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@ Log::push_front(const std::string& msg) {
|
||||
|
||||
Log::iterator
|
||||
Log::find_older(utils::Timer t) {
|
||||
return std::find_if(begin(), end(), func::on(func::mem_ptr_ref(&Type::first),
|
||||
std::bind1st(std::less_equal<utils::Timer>(), t)));
|
||||
return std::find_if(begin(), end(),
|
||||
func::on(func::mem_ptr_ref(&Type::first), std::bind2nd(std::less_equal<utils::Timer>(), t)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-8
@@ -13,7 +13,7 @@
|
||||
namespace core {
|
||||
|
||||
void
|
||||
Poll::poll() {
|
||||
Poll::poll(utils::Timer timeout) {
|
||||
FD_ZERO(m_readSet);
|
||||
FD_ZERO(m_writeSet);
|
||||
FD_ZERO(m_exceptSet);
|
||||
@@ -29,15 +29,11 @@ Poll::poll() {
|
||||
m_maxFd = std::max(m_maxFd, n);
|
||||
}
|
||||
|
||||
uint64_t t = torrent::get(torrent::TIME_SELECT);
|
||||
|
||||
if (t > 1000000)
|
||||
t = 1000000;
|
||||
|
||||
timeval timeout = {t / 1000000, t % 1000000};
|
||||
timeout = std::min(timeout, utils::Timer(torrent::get(torrent::TIME_SELECT)));
|
||||
timeval t = timeout.tval();
|
||||
|
||||
errno = 0;
|
||||
m_maxFd = select(m_maxFd + 1, m_readSet, m_writeSet, m_exceptSet, &timeout);
|
||||
m_maxFd = select(m_maxFd + 1, m_readSet, m_writeSet, m_exceptSet, &t);
|
||||
|
||||
if (m_maxFd >= 0) {
|
||||
work();
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@
|
||||
#include <sys/select.h>
|
||||
#include <sigc++/slot.h>
|
||||
|
||||
#include "utils/timer.h"
|
||||
#include "curl_stack.h"
|
||||
|
||||
namespace core {
|
||||
@@ -19,7 +20,7 @@ public:
|
||||
Poll() : m_readSet(new fd_set), m_writeSet(new fd_set), m_exceptSet(new fd_set) {}
|
||||
~Poll() { delete m_readSet; delete m_writeSet; delete m_exceptSet; }
|
||||
|
||||
void poll();
|
||||
void poll(utils::Timer t);
|
||||
|
||||
SlotFactory get_http_factory();
|
||||
|
||||
|
||||
@@ -21,8 +21,11 @@ print_download_status(core::Download* d) {
|
||||
} else if (!d->get_download().is_active()) {
|
||||
str << "Inactive";
|
||||
|
||||
} else {
|
||||
} else if (!d->get_tracker_msg().empty()) {
|
||||
str << "Tracker: " << d->get_tracker_msg();
|
||||
|
||||
} else {
|
||||
str << "---";
|
||||
}
|
||||
|
||||
return str.str();
|
||||
|
||||
@@ -34,13 +34,13 @@ WindowDownloadList::redraw() {
|
||||
int i = 0;
|
||||
itr = last = *m_focus;
|
||||
|
||||
while (i < m_canvas->get_height() - y && !(itr == m_list->begin() && last == m_list->end())) {
|
||||
while (i < m_canvas->get_height() - y - 3 && !(itr == m_list->begin() && last == m_list->end())) {
|
||||
if (last != m_list->end()) {
|
||||
++last;
|
||||
i += 3;
|
||||
}
|
||||
|
||||
if (itr != m_list->begin() && i < m_canvas->get_height() - y) {
|
||||
if (itr != m_list->begin() && i < m_canvas->get_height() - y - 3) {
|
||||
--itr;
|
||||
i += 3;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "core/log.h"
|
||||
|
||||
#include "canvas.h"
|
||||
#include "window_log.h"
|
||||
|
||||
@@ -13,13 +11,19 @@ WindowLog::WindowLog(core::Log* l) :
|
||||
|
||||
set_active(false);
|
||||
|
||||
m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLog::receive_update));
|
||||
// We're trying out scheduled tasks instead.
|
||||
//m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLog::receive_update));
|
||||
}
|
||||
|
||||
WindowLog::~WindowLog() {
|
||||
m_connUpdate.disconnect();
|
||||
}
|
||||
|
||||
WindowLog::iterator
|
||||
WindowLog::find_older() {
|
||||
return m_log->find_older(utils::Timer::cache() - 10*1000000);
|
||||
}
|
||||
|
||||
void
|
||||
WindowLog::redraw() {
|
||||
if (!is_dirty())
|
||||
@@ -31,18 +35,22 @@ WindowLog::redraw() {
|
||||
|
||||
int pos = 0;
|
||||
|
||||
for (core::Log::iterator itr = m_log->begin(), end = m_log->end(); itr != end; ++itr)
|
||||
m_canvas->print(0, pos++, "Log: %s", itr->second.c_str());
|
||||
//m_canvas->print(std::max(0, (int)m_canvas->get_width() / 2 - 5), pos++, "*** Log ***");
|
||||
m_canvas->print(0, 0, "___");
|
||||
|
||||
for (core::Log::iterator itr = m_log->begin(), end = find_older(); itr != end && pos < m_minHeight; ++itr)
|
||||
m_canvas->print(0, pos++, "<date>: %s", itr->second.c_str());
|
||||
}
|
||||
|
||||
void
|
||||
WindowLog::receive_update() {
|
||||
int newHeight = std::min<size_t>(m_log->size(), 5);
|
||||
iterator itr = find_older();
|
||||
int h = std::distance(m_log->begin(), itr);
|
||||
|
||||
if (newHeight != m_minHeight) {
|
||||
m_minHeight = newHeight;
|
||||
if (h != m_minHeight) {
|
||||
set_active(h != 0);
|
||||
|
||||
set_active(m_minHeight != 0);
|
||||
m_minHeight = h;
|
||||
m_slotAdjust();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,24 +3,26 @@
|
||||
|
||||
#include <sigc++/connection.h>
|
||||
|
||||
#include "window.h"
|
||||
#include "core/log.h"
|
||||
|
||||
namespace core {
|
||||
class Log;
|
||||
}
|
||||
#include "window.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class WindowLog : public Window {
|
||||
public:
|
||||
typedef core::Log::iterator iterator;
|
||||
|
||||
WindowLog(core::Log* l);
|
||||
~WindowLog();
|
||||
|
||||
virtual void redraw();
|
||||
|
||||
private:
|
||||
void receive_update();
|
||||
|
||||
private:
|
||||
inline iterator find_older();
|
||||
|
||||
core::Log* m_log;
|
||||
sigc::connection m_connUpdate;
|
||||
};
|
||||
|
||||
+14
-20
@@ -72,20 +72,6 @@ do_shutdown(ui::Control* c) {
|
||||
start_shutdown = false;
|
||||
}
|
||||
|
||||
void
|
||||
test_dir(const std::string& s) {
|
||||
utils::Directory d(s);
|
||||
|
||||
d.update();
|
||||
|
||||
std::cout << "Listing dir \"" << s << '"' << std::endl;
|
||||
|
||||
for (utils::Directory::iterator itr = d.begin(); itr != d.end(); ++itr)
|
||||
std::cout << '"' << *itr << '"' << std::endl;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_options(ui::Control* c, int argc, char** argv) {
|
||||
OptionParser optionParser;
|
||||
@@ -126,11 +112,21 @@ register_main_keys(ui::Control* c, input::Bindings* b) {
|
||||
(*b)['\x11'] = sigc::ptr_fun(&set_shutdown);
|
||||
}
|
||||
|
||||
void
|
||||
initialize_core(ui::Control* c) {
|
||||
c->get_core().get_poll().slot_read_stdin(sigc::mem_fun(c->get_input(), &input::Manager::pressed));
|
||||
c->get_core().get_poll().slot_select_interrupted(sigc::ptr_fun(display::Canvas::do_update));
|
||||
|
||||
c->get_core().initialize();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv) {
|
||||
ui::Control uiControl;
|
||||
input::Bindings inputMain;
|
||||
|
||||
utils::Timer::update();
|
||||
|
||||
try {
|
||||
|
||||
register_signals(&uiControl);
|
||||
@@ -147,10 +143,7 @@ main(int argc, char** argv) {
|
||||
|
||||
register_main_keys(&uiControl, &inputMain);
|
||||
|
||||
uiControl.get_core().get_poll().slot_read_stdin(sigc::mem_fun(uiControl.get_input(), &input::Manager::pressed));
|
||||
uiControl.get_core().get_poll().slot_select_interrupted(sigc::ptr_fun(display::Canvas::do_update));
|
||||
|
||||
uiControl.get_core().initialize();
|
||||
initialize_core(&uiControl);
|
||||
|
||||
load_session_torrents(&uiControl);
|
||||
load_arg_torrents(&uiControl, argv + firstArg, argv + argc);
|
||||
@@ -162,10 +155,11 @@ main(int argc, char** argv) {
|
||||
do_shutdown(&uiControl);
|
||||
|
||||
utils::Timer::update();
|
||||
|
||||
utils::TaskSchedule::perform(utils::Timer::cache());
|
||||
|
||||
uiControl.get_display().do_update();
|
||||
|
||||
uiControl.get_core().get_poll().poll();
|
||||
uiControl.get_core().get_poll().poll(utils::TaskSchedule::get_timeout());
|
||||
}
|
||||
|
||||
display::Canvas::cleanup();
|
||||
|
||||
@@ -28,6 +28,7 @@ DownloadList::DownloadList(Control* c) :
|
||||
m_textInput(new WInput(new input::TextInput)),
|
||||
m_windowHttpQueue(new WHttp(&c->get_core().get_http_queue())),
|
||||
|
||||
m_taskUpdate(sigc::mem_fun(*this, &DownloadList::task_update)),
|
||||
m_download(NULL),
|
||||
m_focus(c->get_core().get_download_list().end()),
|
||||
m_control(c),
|
||||
@@ -55,6 +56,8 @@ DownloadList::~DownloadList() {
|
||||
|
||||
void
|
||||
DownloadList::activate() {
|
||||
m_taskUpdate.insert(utils::Timer::cache() + 1000000);
|
||||
|
||||
m_textInput->set_active(false);
|
||||
|
||||
m_control->get_input().push_front(m_bindings);
|
||||
@@ -69,6 +72,8 @@ DownloadList::activate() {
|
||||
|
||||
void
|
||||
DownloadList::disable() {
|
||||
m_taskUpdate.remove();
|
||||
|
||||
if (m_textInput->is_active()) {
|
||||
m_textInput->get_input()->clear();
|
||||
receive_exit_input();
|
||||
@@ -191,6 +196,13 @@ DownloadList::receive_exit_input() {
|
||||
m_bindings->erase(KEY_ENTER);
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::task_update() {
|
||||
m_windowLog->receive_update();
|
||||
|
||||
m_taskUpdate.insert(utils::Timer::cache() + 1000000);
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::bind_keys(input::Bindings* b) {
|
||||
(*b)['a'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_throttle), 1);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <sigc++/slot.h>
|
||||
|
||||
#include "utils/task.h"
|
||||
|
||||
namespace display {
|
||||
class WindowDownloadList;
|
||||
class WindowHttpQueue;
|
||||
@@ -60,6 +62,8 @@ private:
|
||||
void receive_view_input();
|
||||
void receive_exit_input();
|
||||
|
||||
void task_update();
|
||||
|
||||
void bind_keys(input::Bindings* b);
|
||||
|
||||
void mark_dirty();
|
||||
@@ -71,6 +75,8 @@ private:
|
||||
WInput* m_textInput;
|
||||
WHttp* m_windowHttpQueue;
|
||||
|
||||
utils::Task m_taskUpdate;
|
||||
|
||||
Download* m_download;
|
||||
|
||||
DList* m_list;
|
||||
|
||||
@@ -6,6 +6,9 @@ libsub_utils_a_SOURCES = \
|
||||
functional.h \
|
||||
parse.cc \
|
||||
parse.h \
|
||||
task.h \
|
||||
task_schedule.cc \
|
||||
task_schedule.h \
|
||||
timer.h
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifndef RTORRENT_UTILS_TASK_H
|
||||
#define RTORRENT_UTILS_TASK_H
|
||||
|
||||
#include <sigc++/slot.h>
|
||||
|
||||
#include "timer.h"
|
||||
#include "task_schedule.h"
|
||||
|
||||
namespace utils {
|
||||
|
||||
class Task {
|
||||
public:
|
||||
typedef sigc::slot<void> Slot;
|
||||
|
||||
Task(Slot s = Slot()) : m_slot(s) { clear_iterator(); }
|
||||
~Task() { remove(); }
|
||||
|
||||
bool is_scheduled() { return m_itr != TaskSchedule::end(); }
|
||||
|
||||
void set_slot(Slot s) { m_slot = s; }
|
||||
Slot& get_slot() { return m_slot; }
|
||||
|
||||
Timer get_time() { return m_time; }
|
||||
|
||||
void insert(Timer t) {
|
||||
remove();
|
||||
|
||||
m_time = t;
|
||||
m_itr = TaskSchedule::insert(this);
|
||||
}
|
||||
|
||||
void remove() {
|
||||
if (m_itr != TaskSchedule::end()) {
|
||||
TaskSchedule::erase(m_itr);
|
||||
clear_iterator();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class TaskSchedule;
|
||||
|
||||
TaskSchedule::iterator get_iterator() { return m_itr; }
|
||||
void clear_iterator() { m_itr = TaskSchedule::end(); }
|
||||
|
||||
private:
|
||||
Task(const Task&);
|
||||
void operator () (const Task&);
|
||||
|
||||
Timer m_time;
|
||||
TaskSchedule::iterator m_itr;
|
||||
Slot m_slot;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include "task.h"
|
||||
#include "task_schedule.h"
|
||||
|
||||
namespace utils {
|
||||
|
||||
TaskSchedule::Container TaskSchedule::m_container;
|
||||
|
||||
// Remove this, replace with stuff.
|
||||
struct task_comp {
|
||||
task_comp(Timer t) : m_time(t) {}
|
||||
|
||||
bool operator () (Task* t) {
|
||||
return m_time <= t->get_time();
|
||||
}
|
||||
|
||||
Timer m_time;
|
||||
};
|
||||
|
||||
inline void
|
||||
TaskSchedule::execute_task(Task* t) {
|
||||
t->clear_iterator();
|
||||
t->get_slot()();
|
||||
}
|
||||
|
||||
void
|
||||
TaskSchedule::perform(Timer t) {
|
||||
Container c;
|
||||
|
||||
c.splice(c.begin(), c, m_container.begin(), std::find_if(m_container.begin(), m_container.end(), task_comp(t)));
|
||||
|
||||
std::for_each(c.begin(), c.end(), std::ptr_fun(&TaskSchedule::execute_task));
|
||||
}
|
||||
|
||||
Timer
|
||||
TaskSchedule::get_timeout() {
|
||||
if (!m_container.empty())
|
||||
return std::max(m_container.front()->get_time() - Timer::current(), Timer());
|
||||
else
|
||||
return Timer((int64_t)(1 << 30) * 1000000);
|
||||
}
|
||||
|
||||
TaskSchedule::iterator
|
||||
TaskSchedule::insert(Task* t) {
|
||||
iterator itr = std::find_if(m_container.begin(), m_container.end(), task_comp(t->get_time()));
|
||||
|
||||
return m_container.insert(itr, t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef RTORRENT_UTILS_TASK_SCHEDULE_H
|
||||
#define RTORRENT_UTILS_TASK_SCHEDULE_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
namespace utils {
|
||||
|
||||
class Task;
|
||||
|
||||
class TaskSchedule {
|
||||
public:
|
||||
friend class Task;
|
||||
|
||||
typedef std::list<Task*> Container;
|
||||
typedef Container::iterator iterator;
|
||||
|
||||
static void perform(Timer t);
|
||||
|
||||
static Timer get_timeout();
|
||||
|
||||
protected:
|
||||
static iterator end() { return m_container.end(); }
|
||||
|
||||
static iterator insert(Task* t);
|
||||
static void erase(iterator itr) { m_container.erase(itr); }
|
||||
|
||||
private:
|
||||
static inline void execute_task(Task* t);
|
||||
|
||||
static Container m_container;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user