mirror of
https://github.com/transmission/transmission
synced 2025-03-16 00:39:34 +00:00
refactor: move tr_torrent callbacks to tr_session (#3003)
* refactor: move tr_torrent callbacks to tr_session * Support tr_sessionSet* (#3044) Co-authored-by: Antoine Cœur <coeur@gmx.fr>
This commit is contained in:
parent
c1f5911fc7
commit
27fbfd8da6
9 changed files with 130 additions and 145 deletions
|
@ -813,8 +813,8 @@ Session::Session(tr_session* session)
|
|||
Session::~Session() = default;
|
||||
|
||||
Session::Impl::Impl(Session& core, tr_session* session)
|
||||
: core_(core)
|
||||
, session_(session)
|
||||
: core_{ core }
|
||||
, session_{ session }
|
||||
{
|
||||
raw_model_ = Gtk::ListStore::create(torrent_cols);
|
||||
sorted_model_ = Gtk::TreeModelSort::create(raw_model_);
|
||||
|
@ -828,6 +828,16 @@ Session::Impl::Impl(Session& core, tr_session* session)
|
|||
on_pref_changed(TR_KEY_peer_limit_global);
|
||||
on_pref_changed(TR_KEY_inhibit_desktop_hibernation);
|
||||
signal_prefs_changed.connect([this](auto key) { on_pref_changed(key); });
|
||||
|
||||
tr_sessionSetMetadataCallback(
|
||||
session_,
|
||||
[](auto* tor2, gpointer impl) { static_cast<Impl*>(impl)->on_torrent_metadata_changed(tor2); },
|
||||
this);
|
||||
tr_sessionSetCompletenessCallback(
|
||||
session_,
|
||||
[](auto* tor2, auto completeness, bool was_running, gpointer impl)
|
||||
{ static_cast<Impl*>(impl)->on_torrent_completeness_changed(tor2, completeness, was_running); },
|
||||
this);
|
||||
}
|
||||
|
||||
tr_session* Session::close()
|
||||
|
@ -986,16 +996,6 @@ void Session::Impl::add_torrent(tr_torrent* tor, bool do_notify)
|
|||
{
|
||||
gtr_notify_torrent_added(get_core_ptr(), tr_torrentId(tor));
|
||||
}
|
||||
|
||||
tr_torrentSetMetadataCallback(
|
||||
tor,
|
||||
[](auto* tor2, gpointer impl) { static_cast<Impl*>(impl)->on_torrent_metadata_changed(tor2); },
|
||||
this);
|
||||
tr_torrentSetCompletenessCallback(
|
||||
tor,
|
||||
[](auto* tor2, auto completeness, bool was_running, gpointer impl)
|
||||
{ static_cast<Impl*>(impl)->on_torrent_completeness_changed(tor2, completeness, was_running); },
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2579,10 +2579,7 @@ static void queuePulse(tr_session* session, tr_direction dir)
|
|||
{
|
||||
tr_torrentStartNow(tor);
|
||||
|
||||
if (tor->queue_started_callback != nullptr)
|
||||
{
|
||||
(*tor->queue_started_callback)(tor, tor->queue_started_user_data);
|
||||
}
|
||||
session->torrentQueueStarted(tor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2947,6 +2947,30 @@ static int bandwidthGroupWrite(tr_session const* session, std::string_view confi
|
|||
return ret;
|
||||
}
|
||||
|
||||
void tr_sessionSetQueueStartCallback(tr_session* session, tr_session::TorrentCallbackFunc callback, void* user_data)
|
||||
{
|
||||
session->setTorrentQueueStartedCallback(callback, user_data);
|
||||
}
|
||||
|
||||
void tr_sessionSetMetadataCallback(tr_session* session, tr_session::TorrentCallbackFunc callback, void* user_data)
|
||||
{
|
||||
session->setTorrentMetadataCallback(callback, user_data);
|
||||
}
|
||||
|
||||
void tr_sessionSetIdleLimitHitCallback(tr_session* session, tr_session::TorrentCallbackFunc callback, void* user_data)
|
||||
{
|
||||
session->setTorrentIdleLimitCallback(callback, user_data);
|
||||
}
|
||||
|
||||
void tr_sessionSetRatioLimitHitCallback(tr_session* session, tr_session::TorrentCallbackFunc callback, void* user_data)
|
||||
{
|
||||
session->setTorrentRatioLimitCallback(callback, user_data);
|
||||
}
|
||||
|
||||
void tr_sessionSetCompletenessCallback(tr_session* session, tr_session::CompletenessFunc func, void* user_data)
|
||||
{
|
||||
session->setTorrentCompletenessCallback(func, user_data);
|
||||
}
|
||||
///
|
||||
|
||||
void tr_session::closeTorrentFiles(tr_torrent* tor) noexcept
|
||||
|
|
|
@ -279,6 +279,65 @@ public:
|
|||
|
||||
//
|
||||
|
||||
using TorrentCallbackFunc = void (*)(tr_torrent*, void* user_data);
|
||||
|
||||
void setTorrentQueueStartedCallback(TorrentCallbackFunc cb, void* user_data)
|
||||
{
|
||||
queue_started_callback_ = std::make_pair(cb, user_data);
|
||||
}
|
||||
|
||||
void torrentQueueStarted(tr_torrent* tor)
|
||||
{
|
||||
invoke(tor, queue_started_callback_);
|
||||
}
|
||||
|
||||
void setTorrentMetadataCallback(TorrentCallbackFunc cb, void* user_data)
|
||||
{
|
||||
metadata_completed_callback_ = std::make_pair(cb, user_data);
|
||||
}
|
||||
|
||||
void torrentMetadataCompleted(tr_torrent* tor)
|
||||
{
|
||||
invoke(tor, metadata_completed_callback_);
|
||||
}
|
||||
|
||||
void setTorrentIdleLimitCallback(TorrentCallbackFunc cb, void* user_data)
|
||||
{
|
||||
idle_limit_callback_ = std::make_pair(cb, user_data);
|
||||
}
|
||||
|
||||
void torrentIdleLimitReached(tr_torrent* tor)
|
||||
{
|
||||
invoke(tor, idle_limit_callback_);
|
||||
}
|
||||
|
||||
void setTorrentRatioLimitCallback(TorrentCallbackFunc cb, void* user_data)
|
||||
{
|
||||
ratio_limit_callback_ = std::make_pair(cb, user_data);
|
||||
}
|
||||
|
||||
void torrentRatioLimitReached(tr_torrent* tor)
|
||||
{
|
||||
invoke(tor, ratio_limit_callback_);
|
||||
}
|
||||
|
||||
using CompletenessFunc = void (*)(tr_torrent*, tr_completeness, bool, void*);
|
||||
|
||||
void setTorrentCompletenessCallback(CompletenessFunc cb, void* user_data)
|
||||
{
|
||||
torrent_completeness_callback_ = std::make_pair(cb, user_data);
|
||||
}
|
||||
|
||||
void torrentCompletenessChanged(tr_torrent* tor, tr_completeness completeness, bool was_running)
|
||||
{
|
||||
if (auto& [func, data] = torrent_completeness_callback_; func != nullptr)
|
||||
{
|
||||
func(tor, completeness, was_running, data);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
[[nodiscard]] constexpr auto& openFiles() noexcept
|
||||
{
|
||||
return open_files_;
|
||||
|
@ -444,6 +503,16 @@ public:
|
|||
int peer_socket_tos_ = *tr_netTosFromName(TR_DEFAULT_PEER_SOCKET_TOS_STR);
|
||||
|
||||
private:
|
||||
using TorrentCallback = std::pair<TorrentCallbackFunc, void*>;
|
||||
|
||||
void invoke(tr_torrent* tor, TorrentCallback& cb)
|
||||
{
|
||||
if (auto& [func, data] = cb; func != nullptr)
|
||||
{
|
||||
func(tor, data);
|
||||
}
|
||||
}
|
||||
|
||||
static std::recursive_mutex session_mutex_;
|
||||
|
||||
tr_torrents torrents_;
|
||||
|
@ -456,6 +525,12 @@ private:
|
|||
std::string peer_congestion_algorithm_;
|
||||
std::optional<tr_address> external_ip_;
|
||||
|
||||
TorrentCallback idle_limit_callback_ = {};
|
||||
TorrentCallback metadata_completed_callback_ = {};
|
||||
TorrentCallback queue_started_callback_ = {};
|
||||
TorrentCallback ratio_limit_callback_ = {};
|
||||
std::pair<CompletenessFunc, void*> torrent_completeness_callback_ = {};
|
||||
|
||||
std::array<bool, TR_SCRIPT_N_TYPES> scripts_enabled_;
|
||||
bool blocklist_enabled_ = false;
|
||||
bool incomplete_dir_enabled_ = false;
|
||||
|
|
|
@ -466,11 +466,7 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor)
|
|||
|
||||
tor->isStopping = true;
|
||||
|
||||
/* maybe notify the client */
|
||||
if (tor->ratio_limit_hit_func != nullptr)
|
||||
{
|
||||
(*tor->ratio_limit_hit_func)(tor, tor->ratio_limit_hit_func_user_data);
|
||||
}
|
||||
tor->session->torrentRatioLimitReached(tor);
|
||||
}
|
||||
/* if we're seeding and reach our inactivity limit, stop the torrent */
|
||||
else if (tr_torrentIsSeedIdleLimitDone(tor))
|
||||
|
@ -479,12 +475,7 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor)
|
|||
|
||||
tor->isStopping = true;
|
||||
tor->finishedSeedingByIdle = true;
|
||||
|
||||
/* maybe notify the client */
|
||||
if (tor->idle_limit_hit_func != nullptr)
|
||||
{
|
||||
(*tor->idle_limit_hit_func)(tor, tor->idle_limit_hit_func_user_data);
|
||||
}
|
||||
tor->session->torrentIdleLimitReached(tor);
|
||||
}
|
||||
|
||||
if (tor->isStopping)
|
||||
|
@ -561,8 +552,6 @@ struct torrent_start_opts
|
|||
|
||||
static void torrentStart(tr_torrent* tor, torrent_start_opts opts);
|
||||
|
||||
static void tr_torrentFireMetadataCompleted(tr_torrent* tor);
|
||||
|
||||
static void torrentInitFromInfoDict(tr_torrent* tor)
|
||||
{
|
||||
tor->completion = tr_completion{ tor, &tor->blockInfo() };
|
||||
|
@ -590,7 +579,7 @@ void tr_torrent::setMetainfo(tr_torrent_metainfo const& tm)
|
|||
|
||||
torrentInitFromInfoDict(this);
|
||||
tr_peerMgrOnTorrentGotMetainfo(this);
|
||||
tr_torrentFireMetadataCompleted(this);
|
||||
this->session->torrentMetadataCompleted(this);
|
||||
this->setDirty();
|
||||
}
|
||||
|
||||
|
@ -1628,7 +1617,6 @@ void tr_torrentFree(tr_torrent* tor)
|
|||
|
||||
auto const lock = tor->unique_lock();
|
||||
|
||||
tr_torrentClearCompletenessCallback(tor);
|
||||
tr_runInEventThread(session, closeTorrent, tor);
|
||||
}
|
||||
}
|
||||
|
@ -1655,7 +1643,6 @@ static void removeTorrentInEventThread(tr_torrent* tor, bool delete_flag, tr_fil
|
|||
tor->metainfo_.files().remove(tor->currentDir(), tor->name(), delete_func_wrapper);
|
||||
}
|
||||
|
||||
tr_torrentClearCompletenessCallback(tor);
|
||||
closeTorrent(tor);
|
||||
}
|
||||
|
||||
|
@ -1692,45 +1679,6 @@ static char const* getCompletionString(int type)
|
|||
}
|
||||
}
|
||||
|
||||
static void fireCompletenessChange(tr_torrent* tor, tr_completeness status, bool wasRunning)
|
||||
{
|
||||
TR_ASSERT(status == TR_LEECH || status == TR_SEED || status == TR_PARTIAL_SEED);
|
||||
|
||||
if (tor->completeness_func != nullptr)
|
||||
{
|
||||
(*tor->completeness_func)(tor, status, wasRunning, tor->completeness_func_user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void tr_torrentSetCompletenessCallback(tr_torrent* tor, tr_torrent_completeness_func func, void* user_data)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
tor->completeness_func = func;
|
||||
tor->completeness_func_user_data = user_data;
|
||||
}
|
||||
|
||||
void tr_torrentClearCompletenessCallback(tr_torrent* torrent)
|
||||
{
|
||||
tr_torrentSetCompletenessCallback(torrent, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void tr_torrentSetRatioLimitHitCallback(tr_torrent* tor, tr_torrent_ratio_limit_hit_func func, void* user_data)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
tor->ratio_limit_hit_func = func;
|
||||
tor->ratio_limit_hit_func_user_data = user_data;
|
||||
}
|
||||
|
||||
void tr_torrentSetIdleLimitHitCallback(tr_torrent* tor, tr_torrent_idle_limit_hit_func func, void* user_data)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
tor->idle_limit_hit_func = func;
|
||||
tor->idle_limit_hit_func_user_data = user_data;
|
||||
}
|
||||
|
||||
static std::string buildLabelsString(tr_torrent const* tor)
|
||||
{
|
||||
auto buf = std::stringstream{};
|
||||
|
@ -1857,7 +1805,7 @@ void tr_torrent::recheckCompleteness()
|
|||
}
|
||||
}
|
||||
|
||||
fireCompletenessChange(this, completeness, wasRunning);
|
||||
this->session->torrentCompletenessChanged(this, completeness, wasRunning);
|
||||
|
||||
if (this->isDone() && wasLeeching && wasRunning)
|
||||
{
|
||||
|
@ -1876,28 +1824,6 @@ void tr_torrent::recheckCompleteness()
|
|||
}
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
static void tr_torrentFireMetadataCompleted(tr_torrent* tor)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
if (tor->metadata_func != nullptr)
|
||||
{
|
||||
(*tor->metadata_func)(tor, tor->metadata_func_user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void tr_torrentSetMetadataCallback(tr_torrent* tor, tr_torrent_metadata_func func, void* user_data)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
tor->metadata_func = func;
|
||||
tor->metadata_func_user_data = user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
*** File DND
|
||||
**/
|
||||
|
@ -2554,12 +2480,6 @@ static void torrentSetQueued(tr_torrent* tor, bool queued)
|
|||
}
|
||||
}
|
||||
|
||||
void tr_torrentSetQueueStartCallback(tr_torrent* torrent, void (*callback)(tr_torrent*, void*), void* user_data)
|
||||
{
|
||||
torrent->queue_started_callback = callback;
|
||||
torrent->queue_started_user_data = user_data;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
**** RENAME
|
||||
|
|
|
@ -650,21 +650,6 @@ public:
|
|||
* other peers */
|
||||
struct tr_incomplete_metadata* incompleteMetadata = nullptr;
|
||||
|
||||
tr_torrent_metadata_func metadata_func = nullptr;
|
||||
void* metadata_func_user_data = nullptr;
|
||||
|
||||
tr_torrent_completeness_func completeness_func = nullptr;
|
||||
void* completeness_func_user_data = nullptr;
|
||||
|
||||
tr_torrent_ratio_limit_hit_func ratio_limit_hit_func = nullptr;
|
||||
void* ratio_limit_hit_func_user_data = nullptr;
|
||||
|
||||
tr_torrent_idle_limit_hit_func idle_limit_hit_func = nullptr;
|
||||
void* idle_limit_hit_func_user_data = nullptr;
|
||||
|
||||
void* queue_started_user_data = nullptr;
|
||||
void (*queue_started_callback)(tr_torrent*, void* queue_started_user_data) = nullptr;
|
||||
|
||||
time_t peer_id_creation_time_ = 0;
|
||||
|
||||
time_t dhtAnnounceAt = 0;
|
||||
|
|
|
@ -691,11 +691,8 @@ void tr_sessionSetQueueStalledEnabled(tr_session*, bool);
|
|||
/** @return true if we're torrents idle for over N minutes will be flagged as 'stalled' */
|
||||
bool tr_sessionGetQueueStalledEnabled(tr_session const*);
|
||||
|
||||
/**
|
||||
**/
|
||||
|
||||
/** @brief Set a callback that is invoked when the queue starts a torrent */
|
||||
void tr_torrentSetQueueStartCallback(tr_torrent* torrent, void (*callback)(tr_torrent*, void*), void* user_data);
|
||||
void tr_sessionSetQueueStartCallback(tr_session* session, void (*callback)(tr_torrent*, void*), void* user_data);
|
||||
|
||||
/***
|
||||
****
|
||||
|
@ -1164,20 +1161,6 @@ enum tr_completeness
|
|||
TR_PARTIAL_SEED /* has the desired pieces, but not the entire torrent */
|
||||
};
|
||||
|
||||
/**
|
||||
* @param wasRunning whether or not the torrent was running when
|
||||
* it changed its completeness state
|
||||
*/
|
||||
using tr_torrent_completeness_func = void (*)( //
|
||||
tr_torrent* torrent,
|
||||
tr_completeness completeness,
|
||||
bool wasRunning,
|
||||
void* user_data);
|
||||
|
||||
using tr_torrent_ratio_limit_hit_func = void (*)(tr_torrent* torrent, void* user_data);
|
||||
|
||||
using tr_torrent_idle_limit_hit_func = void (*)(tr_torrent* torrent, void* user_data);
|
||||
|
||||
/**
|
||||
* Register to be notified whenever a torrent's "completeness"
|
||||
* changes. This will be called, for example, when a torrent
|
||||
|
@ -1191,9 +1174,10 @@ using tr_torrent_idle_limit_hit_func = void (*)(tr_torrent* torrent, void* user_
|
|||
*
|
||||
* @see tr_completeness
|
||||
*/
|
||||
void tr_torrentSetCompletenessCallback(tr_torrent* torrent, tr_torrent_completeness_func func, void* user_data);
|
||||
|
||||
void tr_torrentClearCompletenessCallback(tr_torrent* torrent);
|
||||
void tr_sessionSetCompletenessCallback(
|
||||
tr_session*,
|
||||
void (*callback)(tr_torrent*, tr_completeness, bool was_running, void*),
|
||||
void* user_data);
|
||||
|
||||
using tr_torrent_metadata_func = void (*)(tr_torrent* torrent, void* user_data);
|
||||
|
||||
|
@ -1203,7 +1187,7 @@ using tr_torrent_metadata_func = void (*)(tr_torrent* torrent, void* user_data);
|
|||
* This happens when a magnet link finishes downloading
|
||||
* metadata from its peers.
|
||||
*/
|
||||
void tr_torrentSetMetadataCallback(tr_torrent* tor, tr_torrent_metadata_func func, void* user_data);
|
||||
void tr_sessionSetMetadataCallback(tr_session*, void (*callback)(tr_torrent*, void*), void* user_data);
|
||||
|
||||
/**
|
||||
* Register to be notified whenever a torrent's ratio limit
|
||||
|
@ -1212,7 +1196,7 @@ void tr_torrentSetMetadataCallback(tr_torrent* tor, tr_torrent_metadata_func fun
|
|||
*
|
||||
* Has the same restrictions as tr_torrentSetCompletenessCallback
|
||||
*/
|
||||
void tr_torrentSetRatioLimitHitCallback(tr_torrent* torrent, tr_torrent_ratio_limit_hit_func func, void* user_data);
|
||||
void tr_sessionSetRatioLimitHitCallback(tr_session*, void (*callback)(tr_torrent*, void*), void* user_data);
|
||||
|
||||
/**
|
||||
* Register to be notified whenever a torrent's idle limit
|
||||
|
@ -1221,7 +1205,7 @@ void tr_torrentSetRatioLimitHitCallback(tr_torrent* torrent, tr_torrent_ratio_li
|
|||
*
|
||||
* Has the same restrictions as tr_torrentSetCompletenessCallback
|
||||
*/
|
||||
void tr_torrentSetIdleLimitHitCallback(tr_torrent* torrent, tr_torrent_idle_limit_hit_func func, void* user_data);
|
||||
void tr_sessionSetIdleLimitHitCallback(tr_session*, void (*callback)(tr_torrent*, void*), void* user_data);
|
||||
|
||||
/**
|
||||
* MANUAL ANNOUNCE
|
||||
|
|
|
@ -1812,11 +1812,11 @@ bool trashDataFile(char const* filename, tr_error** error)
|
|||
}
|
||||
}
|
||||
|
||||
tr_torrentSetQueueStartCallback(self.fHandle, startQueueCallback, (__bridge void*)(self));
|
||||
tr_torrentSetCompletenessCallback(self.fHandle, completenessChangeCallback, (__bridge void*)(self));
|
||||
tr_torrentSetRatioLimitHitCallback(self.fHandle, ratioLimitHitCallback, (__bridge void*)(self));
|
||||
tr_torrentSetIdleLimitHitCallback(self.fHandle, idleLimitHitCallback, (__bridge void*)(self));
|
||||
tr_torrentSetMetadataCallback(self.fHandle, metadataCallback, (__bridge void*)(self));
|
||||
tr_sessionSetQueueStartCallback(lib, startQueueCallback, (__bridge void*)(self));
|
||||
tr_sessionSetCompletenessCallback(lib, completenessChangeCallback, (__bridge void*)(self));
|
||||
tr_sessionSetRatioLimitHitCallback(lib, ratioLimitHitCallback, (__bridge void*)(self));
|
||||
tr_sessionSetIdleLimitHitCallback(lib, idleLimitHitCallback, (__bridge void*)(self));
|
||||
tr_sessionSetMetadataCallback(lib, metadataCallback, (__bridge void*)(self));
|
||||
|
||||
_fResumeOnWake = NO;
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ TEST_P(IncompleteDirTest, incompleteDir)
|
|||
{
|
||||
*static_cast<tr_completeness*>(vc) = c;
|
||||
};
|
||||
tr_torrentSetCompletenessCallback(tor, zeroes_completeness_func, &completeness);
|
||||
tr_sessionSetCompletenessCallback(session_, zeroes_completeness_func, &completeness);
|
||||
|
||||
struct TestIncompleteDirData
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue