From 3ff4c0e3483b8c05fc7294ec69b4dba8fa866fcd Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 20 Feb 2016 17:28:41 -0500 Subject: [PATCH] add start of a tutorial --- Makefile.am | 2 + docs/index.rst | 2 + docs/makefile | 1 + docs/manual.rst | 5 +- docs/tutorial.rst | 124 +++++++++++++++++++++++++++++++++++ include/libtorrent/alert.hpp | 6 +- 6 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 docs/tutorial.rst diff --git a/Makefile.am b/Makefile.am index f3c0ef9df..ca7e224c8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -93,6 +93,8 @@ DOCS_PAGES = \ docs/udp_tracker_protocol.rst \ docs/utp.rst \ docs/streaming.rst \ + docs/tutorial.rst \ + docs/tutorial.html \ docs/reference-Alerts.html \ docs/reference-Bdecoding.html \ docs/reference-Bencoding.html \ diff --git a/docs/index.rst b/docs/index.rst index 085891b7f..3543475f4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,6 +7,7 @@ * download_ * features_ +* tutorial_ * examples_ * overview_ * `reference documentation`_ @@ -58,6 +59,7 @@ libtorrent .. _download: https://github.com/arvidn/libtorrent/releases .. _features: features.html +.. _tutorial: tutorial.html .. _contributing: contributing.html .. _building: building.html .. _examples: examples.html diff --git a/docs/makefile b/docs/makefile index 9499fd6ab..972099b5f 100644 --- a/docs/makefile +++ b/docs/makefile @@ -44,6 +44,7 @@ TARGETS = index \ tuning \ hacking \ streaming \ + tutorial \ $(REFERENCE_TARGETS) FIGURES = \ diff --git a/docs/manual.rst b/docs/manual.rst index 231bbaab8..48768ed7a 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -37,7 +37,10 @@ The basic usage is as follows: * save session state (see save_state()) * destruct session object -Each class and function is described in this manual. +Each class and function is described in this manual, you may want to have a +look at the tutorial_ as well. + +.. _tutorial: tutorial.html For a description on how to create torrent files, see create_torrent. diff --git a/docs/tutorial.rst b/docs/tutorial.rst new file mode 100644 index 000000000..05eb59714 --- /dev/null +++ b/docs/tutorial.rst @@ -0,0 +1,124 @@ +================= +libtorrent manual +================= + +:Author: Arvid Norberg, arvid@libtorrent.org +:Version: 1.1.0 + +.. contents:: Table of contents + :depth: 2 + :backlinks: none + +tutorial +======== + +The fundamental feature of starting and downloading torrents in libtorrent is +achieved by creating a *session*, which provides the context and a container for +torrents. This is done with via the session_ class, most of its interface is +documented under session_handle_ though. + +To add a torrent to the session, you fill in an add_torrent_params_ object and +pass it either to `add_torrent()`_ or `async_add_torrent()`_. + +``add_torrent()`` is a blocking call which returns a torrent_handle_. + +For example: + +.. code:: c++ + + #include + #include + #include + + namespace lt = libtorrent; + int main(int argc, char const* argv[]) + { + if (argc != 2) { + fprintf(stderr, "usage: %s \n"); + return 1; + } + lt::session ses; + + lt::add_torrent_params atp; + atp.url = argv[1]; + atp.save_path = "."; // save in current dir + lt::torrent_handle h = ses.add_torrent(atp); + + // ... + } + +Once you have a torrent_handle_, you can affect it as well as querying status. +First, let's extend the example to print out messages from the bittorrent engine +about progress and events happening under the hood. libtorrent has a mechanism +referred to as *alerts* to communicate back information to the client application. + +Clients can poll libtorrents for new alerts via the `pop_alerts()`_ call on the +session object. This call fills in a vector of alert pointers with all new +alerts since the last call to this function. The pointers are owned by the +session object at will become invalidated by the next call to `pop_alerts()`_. + +The alerts form a class hierarchy with alert_ as the root class. Each specific +kind of alert may include additional state, specific to the kind of message. All +alerts implement a message() function that prints out pertinent information +of the alert message. This can be convenient for simply logging events. + +For programatically react to certain events, use `alert_cast<>`_ to attempt +a down cast of an alert object to a more specific type. + +In order to print out events from libtorrent as well as exiting when the torrent +completes downloading, we can poll the session for alerts periodically and print +them out, as well as listening for the torrent_finished_alert_, which is posted +when a torrent completes. + +.. code:: c++ + + #include + + #include + #include + #include + #include + + namespace lt = libtorrent; + int main(int argc, char const* argv[]) + { + if (argc != 2) { + std::cerr << "usage: " << argv[0] << " " << std::endl; + return 1; + } + lt::session ses; + + lt::add_torrent_params atp; + atp.url = argv[1]; + atp.save_path = "."; // save in current dir + lt::torrent_handle h = ses.add_torrent(atp); + + bool done = false; + while (!done) { + std::vector alerts; + ses.pop_alerts(&alerts); + + for (lt::alert const* a : alerts) { + std::cout << a->message() << std::endl; + if (lt::alert_cast(a)) { + done = true; + } + } + } + } + +*TODO* cover async_add_torrent() +*TODO* cover post_torrent_updates() +*TODO* cover save_resume_data() + +.. _session: reference-Core.html#session +.. _session_handle: reference-Core.html#session_handle +.. _add_torrent_params: reference-Core.html#add_torrent_params +.. _`add_torrent()`: reference-Core.html#add_torrent() +.. _`async_add_torrent()`: reference-Core.html#add_torrent() +.. _torrent_handle: reference-Core.html#torrent_handle +.. _`pop_alerts()`: reference-Core.html#pop_alerts() +.. _`alert_cast<>`: reference-Alerts.html#alert_cast() +.. _torrent_finished_alert: reference-Alerts.html#torrent-finished-alert + + diff --git a/include/libtorrent/alert.hpp b/include/libtorrent/alert.hpp index 7b0487f0e..08751de51 100644 --- a/include/libtorrent/alert.hpp +++ b/include/libtorrent/alert.hpp @@ -310,15 +310,13 @@ namespace libtorrent { // When you get an alert, you can use ``alert_cast<>`` to attempt to cast the pointer to a // more specific alert type, in order to query it for more information. -template -T* alert_cast(alert* a) +template T* alert_cast(alert* a) { if (a == 0) return 0; if (a->type() == T::alert_type) return static_cast(a); return 0; } -template -T const* alert_cast(alert const* a) +template T const* alert_cast(alert const* a) { if (a == 0) return 0; if (a->type() == T::alert_type) return static_cast(a);