diff --git a/src/display/Makefile.am b/src/display/Makefile.am index 2fe1d621..8c881367 100644 --- a/src/display/Makefile.am +++ b/src/display/Makefile.am @@ -7,7 +7,7 @@ libsub_display_a_SOURCES = \ manager.h \ window.cc \ window.h \ - window_downloads.cc \ - window_downloads.h + window_download_list.cc \ + window_download_list.h INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) diff --git a/src/display/canvas.h b/src/display/canvas.h index 627dfafd..331876f8 100644 --- a/src/display/canvas.h +++ b/src/display/canvas.h @@ -35,6 +35,14 @@ public: template void print(int x, int y, const char* str, A1 a1, A2 a2) { mvwprintw(m_window, y, x, str, a1, a2); } + template + void print(int x, int y, const char* str, + A1 a1, A2 a2, A3 a3) { mvwprintw(m_window, y, x, str, a1, a2, a3); } + + template + void print(int x, int y, const char* str, + A1 a1, A2 a2, A3 a3, A4 a4) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4); } + void print_border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc new file mode 100644 index 00000000..6e6a081b --- /dev/null +++ b/src/display/window_download_list.cc @@ -0,0 +1,30 @@ +#include "config.h" + +#include "canvas.h" +#include "window_download_list.h" + +#include "engine/download_list.h" + +namespace display { + +WindowDownloadList::WindowDownloadList(engine::DownloadList* d) : + Window(new Canvas, true), + m_downloads(d) { +} + +void +WindowDownloadList::redraw() { + m_canvas->erase(); + m_canvas->print_border(' ', ' ', '-', '-', ' ', ' ', ' ', ' '); + + int pos = 1; + + for (engine::DownloadList::iterator itr = m_downloads->begin(); itr != m_downloads->end(); ++itr, ++pos) + m_canvas->print(1, pos, "Download: %s Open: %c Tracker: %c Active: %c", + itr->get_download().get_name().c_str(), + itr->get_download().is_open() ? 'Y' : 'N', + itr->get_download().is_tracker_busy() ? 'Y' : 'N', + itr->get_download().is_active() ? 'Y' : 'N'); +} + +} diff --git a/src/display/window_download_list.h b/src/display/window_download_list.h new file mode 100644 index 00000000..e879246d --- /dev/null +++ b/src/display/window_download_list.h @@ -0,0 +1,24 @@ +#ifndef RTORRENT_DISPLAY_WINDOW_DOWNLOAD_LIST_H +#define RTORRENT_DISPLAY_WINDOW_DOWNLOAD_LIST_H + +#include "window.h" + +namespace engine { + class DownloadList; +} + +namespace display { + +class WindowDownloadList : public Window { +public: + WindowDownloadList(engine::DownloadList* d); + + virtual void redraw(); + +private: + engine::DownloadList* m_downloads; +}; + +} + +#endif diff --git a/src/display/window_downloads.cc b/src/display/window_downloads.cc deleted file mode 100644 index 93b64da6..00000000 --- a/src/display/window_downloads.cc +++ /dev/null @@ -1,24 +0,0 @@ -#include "config.h" - -#include "canvas.h" -#include "window_downloads.h" - -namespace display { - -WindowDownloads::WindowDownloads(engine::Downloads* d) : - Window(new Canvas, true), - m_downloads(d) { -} - -void -WindowDownloads::redraw() { - m_canvas->erase(); - m_canvas->print_border(' ', ' ', '-', '-', ' ', ' ', ' ', ' '); - - int pos = 1; - - for (engine::Downloads::iterator itr = m_downloads->begin(); itr != m_downloads->end(); ++itr, ++pos) - m_canvas->print(1, pos, "Download: %s", itr->get_name().c_str()); -} - -} diff --git a/src/display/window_downloads.h b/src/display/window_downloads.h deleted file mode 100644 index 28d61864..00000000 --- a/src/display/window_downloads.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef RTORRENT_DISPLAY_WINDOW_DOWNLOADS_H -#define RTORRENT_DISPLAY_WINDOW_DOWNLOADS_H - -#include "window.h" -#include "engine/downloads.h" - -namespace display { - -class WindowDownloads : public Window { -public: - WindowDownloads(engine::Downloads* d); - - virtual void redraw(); - -private: - engine::Downloads* m_downloads; -}; - -} - -#endif diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index c3ea3d63..686bb44f 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -5,8 +5,9 @@ libsub_engine_a_SOURCES = \ curl_get.h \ curl_stack.cc \ curl_stack.h \ - downloads.cc \ - downloads.h \ + download.h \ + download_list.cc \ + download_list.h \ poll.cc \ poll.h diff --git a/src/engine/download.h b/src/engine/download.h new file mode 100644 index 00000000..9c88ac6f --- /dev/null +++ b/src/engine/download.h @@ -0,0 +1,29 @@ +#ifndef RTORRENT_ENGINE_DOWNLOAD_H +#define RTORRENT_ENGINE_DOWNLOAD_H + +#include +#include + +namespace engine { + +class Download { +public: + Download(torrent::Download d) : m_download(d) {} + + std::string get_hash() { return m_download.get_hash(); } + torrent::Download& get_download() { return m_download; } + + void open() { m_download.open(); } + void close() { m_download.close(); } + + void hash_check(bool resume = false) { m_download.hash_check(resume); } + + bool operator == (const std::string& str) { return str == m_download.get_hash(); } + +private: + torrent::Download m_download; +}; + +} + +#endif diff --git a/src/engine/download_list.cc b/src/engine/download_list.cc new file mode 100644 index 00000000..e7d5456f --- /dev/null +++ b/src/engine/download_list.cc @@ -0,0 +1,39 @@ +#include "config.h" + +#include +#include +#include +#include + +#include "download_list.h" + +namespace engine { + +DownloadList::iterator +DownloadList::create(std::istream& str) { + iterator itr = Base::insert(end(), torrent::download_create(str)); + + itr->get_download().signal_hash_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_hash_done), + itr->get_hash())); + + return itr; +} + +void +DownloadList::erase(iterator itr) { + torrent::download_remove(itr->get_hash()); + + Base::erase(itr); +} + +void +DownloadList::receive_hash_done(const std::string& str) { + iterator itr = std::find(begin(), end(), str); + + if (itr == end()) + throw torrent::client_error("DownloadList received hash check done, but couldn't find the download"); + + itr->get_download().start(); +} + +} diff --git a/src/engine/download_list.h b/src/engine/download_list.h new file mode 100644 index 00000000..d316c99e --- /dev/null +++ b/src/engine/download_list.h @@ -0,0 +1,33 @@ +#ifndef RTORRENT_ENGINE_DOWNLOAD_LIST_H +#define RTORRENT_ENGINE_DOWNLOAD_LIST_H + +#include + +#include "download.h" + +namespace engine { + +class DownloadList : private std::list { +public: + typedef std::list Base; + + using Base::iterator; + using Base::const_iterator; + using Base::reverse_iterator; + using Base::const_reverse_iterator; + + using Base::begin; + using Base::end; + using Base::rbegin; + using Base::rend; + + iterator create(std::istream& str); + void erase(iterator itr); + +private: + void receive_hash_done(const std::string& str); +}; + +} + +#endif diff --git a/src/engine/downloads.cc b/src/engine/downloads.cc deleted file mode 100644 index dcaf9526..00000000 --- a/src/engine/downloads.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include "config.h" - -#include - -#include "downloads.h" - -namespace engine { - -void -Downloads::create(std::istream& str) { - torrent::Download d = torrent::download_create(str); - - Base::push_back(d); -} - -void -Downloads::erase(iterator itr) { - torrent::download_remove(itr->get_hash()); - - Base::erase(itr); -} - -} diff --git a/src/engine/downloads.h b/src/engine/downloads.h deleted file mode 100644 index 03ffa34c..00000000 --- a/src/engine/downloads.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef RTORRENT_ENGINE_DOWNLOADS_H -#define RTORRENT_ENGINE_DOWNLOADS_H - -#include -#include - -namespace engine { - -class Downloads : private std::list { -public: - typedef std::list Base; - - using Base::iterator; - using Base::const_iterator; - using Base::reverse_iterator; - using Base::const_reverse_iterator; - - using Base::begin; - using Base::end; - using Base::rbegin; - using Base::rend; - - void create(std::istream& str); - void erase(iterator itr); -}; - -} - -#endif diff --git a/src/engine/poll.cc b/src/engine/poll.cc index 6b27fbb4..6eb4140d 100644 --- a/src/engine/poll.cc +++ b/src/engine/poll.cc @@ -2,8 +2,11 @@ #include #include +#include +#include #include "poll.h" +#include "curl_get.h" namespace engine { @@ -13,12 +16,22 @@ Poll::poll() { FD_ZERO(&m_writeSet); FD_ZERO(&m_exceptSet); - m_maxFd = 1; + torrent::mark(&m_readSet, &m_writeSet, &m_exceptSet, &m_maxFd); + m_maxFd = std::max(m_maxFd, 1); + if (m_readStdin) FD_SET(0, &m_readSet); - timeval timeout = {60, 0}; + if (m_curlStack.is_busy()) + m_curlStack.fdset(&m_readSet, &m_writeSet, &m_exceptSet, &m_maxFd); + + uint64_t t = torrent::get(torrent::TIME_SELECT); + + if (t > 10000000) + t = 10000000; + + timeval timeout = {t / 1000000, t % 1000000}; m_maxFd = select(m_maxFd, &m_readSet, &m_writeSet, &m_exceptSet, &timeout); @@ -34,6 +47,16 @@ Poll::work() { while ((key = getch()) >= 0) m_readStdin(key); } + + if (m_curlStack.is_busy()) + m_curlStack.perform(); + + torrent::work(&m_readSet, &m_writeSet, &m_exceptSet, m_maxFd); +} + +void +Poll::register_http() { + torrent::Http::set_factory(sigc::bind(sigc::ptr_fun(&engine::CurlGet::new_object), &m_curlStack)); } } diff --git a/src/engine/poll.h b/src/engine/poll.h index 66b638aa..22a5626e 100644 --- a/src/engine/poll.h +++ b/src/engine/poll.h @@ -4,6 +4,8 @@ #include #include +#include "curl_stack.h" + namespace engine { class Poll { @@ -17,6 +19,8 @@ public: void poll(); void work(); + void register_http(); + void slot_read_stdin(SlotInt s) { m_readStdin = s; } private: @@ -27,6 +31,8 @@ private: fd_set m_readSet; fd_set m_writeSet; fd_set m_exceptSet; + + CurlStack m_curlStack; }; } diff --git a/src/main.cc b/src/main.cc index 89ba7224..29cb60c4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -3,17 +3,14 @@ #include #include #include -#include #include #include "display/canvas.h" #include "display/manager.h" -#include "display/window_downloads.h" +#include "display/window_download_list.h" #include "engine/poll.h" -#include "engine/curl_stack.h" -#include "engine/curl_get.h" -#include "engine/downloads.h" +#include "engine/download_list.h" #include "input/bindings.h" #include "input/manager.h" @@ -21,29 +18,32 @@ int main(int argc, char** argv) { try { - engine::Poll poll; - engine::Downloads downloads; - engine::CurlStack curlStack; - display::Canvas::init(); + + engine::Poll poll; + engine::DownloadList downloads; + display::Manager display; input::Manager inputManager; + inputManager.push_back(new input::Bindings); poll.slot_read_stdin(sigc::mem_fun(inputManager, &input::Manager::pressed)); + poll.register_http(); - display.push_back(new display::WindowDownloads(&downloads)); + display.push_back(new display::WindowDownloadList(&downloads)); torrent::initialize(); torrent::listen_open(6880, 6999); - torrent::Http::set_factory(sigc::bind(sigc::ptr_fun(&engine::CurlGet::new_object), &curlStack)); - for (int i = 1; i < argc; ++i) { std::fstream f(argv[i], std::ios::in); - downloads.create(f); + engine::DownloadList::iterator itr = downloads.create(f); + + itr->open(); + itr->hash_check(); } while (poll.is_running()) {