refactor: use new tr_variant API in tr_session (#6006)

This commit is contained in:
Charles Kerr
2023-09-16 08:23:35 -05:00
committed by GitHub
parent 85a120faea
commit 6ead147620
15 changed files with 128 additions and 129 deletions

View File

@@ -256,7 +256,7 @@ int tr_main(int argc, char* argv[])
} }
} }
auto* const h = tr_sessionInit(config_dir.c_str(), false, &settings); auto* const h = tr_sessionInit(config_dir.c_str(), false, settings);
auto* const ctor = tr_ctorNew(h); auto* const ctor = tr_ctorNew(h);
tr_ctorSetPaused(ctor, TR_FORCE, false); tr_ctorSetPaused(ctor, TR_FORCE, false);
@@ -354,7 +354,7 @@ int tr_main(int argc, char* argv[])
} }
} }
tr_sessionSaveSettings(h, config_dir.c_str(), &settings); tr_sessionSaveSettings(h, config_dir.c_str(), settings);
printf("\n"); printf("\n");
tr_sessionClose(h); tr_sessionClose(h);

View File

@@ -684,7 +684,7 @@ void tr_daemon::reconfigure(void)
tr_variantDictAddBool(&newsettings, TR_KEY_rpc_enabled, true); tr_variantDictAddBool(&newsettings, TR_KEY_rpc_enabled, true);
newsettings.merge(tr_sessionLoadSettings(configDir, MyName)); newsettings.merge(tr_sessionLoadSettings(configDir, MyName));
tr_sessionSet(my_session_, &newsettings); tr_sessionSet(my_session_, newsettings);
tr_sessionReloadBlocklists(my_session_); tr_sessionReloadBlocklists(my_session_);
} }
} }
@@ -725,10 +725,10 @@ int tr_daemon::start([[maybe_unused]] bool foreground)
tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr); tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr);
tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr); tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr);
tr_formatter_speed_init(SpeedK, SpeedKStr, SpeedMStr, SpeedGStr, SpeedTStr); tr_formatter_speed_init(SpeedK, SpeedKStr, SpeedMStr, SpeedGStr, SpeedTStr);
session = tr_sessionInit(cdir, true, &settings_); session = tr_sessionInit(cdir, true, settings_);
tr_sessionSetRPCCallback(session, on_rpc_callback, this); tr_sessionSetRPCCallback(session, on_rpc_callback, this);
tr_logAddInfo(fmt::format(_("Loading settings from '{path}'"), fmt::arg("path", cdir))); tr_logAddInfo(fmt::format(_("Loading settings from '{path}'"), fmt::arg("path", cdir)));
tr_sessionSaveSettings(session, cdir, &settings_); tr_sessionSaveSettings(session, cdir, settings_);
auto sv = std::string_view{}; auto sv = std::string_view{};
(void)tr_variantDictFindStrView(&settings_, key_pidfile_, &sv); (void)tr_variantDictFindStrView(&settings_, key_pidfile_, &sv);
@@ -874,7 +874,7 @@ CLEANUP:
event_base_free(ev_base_); event_base_free(ev_base_);
tr_sessionSaveSettings(my_session_, cdir, &settings_); tr_sessionSaveSettings(my_session_, cdir, settings_);
tr_sessionClose(my_session_); tr_sessionClose(my_session_);
pumpLogMessages(logfile_, logfile_flush_); pumpLogMessages(logfile_, logfile_flush_);
printf(" done.\n"); printf(" done.\n");

View File

@@ -607,7 +607,7 @@ void Application::Impl::on_startup()
} }
/* initialize the libtransmission session */ /* initialize the libtransmission session */
session = tr_sessionInit(config_dir_.c_str(), true, &gtr_pref_get_all()); session = tr_sessionInit(config_dir_.c_str(), true, gtr_pref_get_all());
gtr_pref_flag_set(TR_KEY_alt_speed_enabled, tr_sessionUsesAltSpeed(session)); gtr_pref_flag_set(TR_KEY_alt_speed_enabled, tr_sessionUsesAltSpeed(session));
gtr_pref_int_set(TR_KEY_peer_port, tr_sessionGetPeerPort(session)); gtr_pref_int_set(TR_KEY_peer_port, tr_sessionGetPeerPort(session));

View File

@@ -213,5 +213,5 @@ void gtr_pref_string_set(tr_quark const key, std::string_view value)
void gtr_pref_save(tr_session* session) void gtr_pref_save(tr_session* session)
{ {
tr_sessionSaveSettings(session, gl_confdir.c_str(), &getPrefs()); tr_sessionSaveSettings(session, gl_confdir.c_str(), getPrefs());
} }

View File

@@ -2350,7 +2350,7 @@ void addSessionField(tr_session const* s, tr_variant* d, tr_quark key)
break; break;
case TR_KEY_units: case TR_KEY_units:
tr_formatter_get_units(tr_variantDictAddDict(d, key, 0)); *tr_variantDictAdd(d, key) = tr_formatter_get_units();
break; break;
case TR_KEY_version: case TR_KEY_version:

View File

@@ -76,50 +76,55 @@ void bandwidthGroupRead(tr_session* session, std::string_view config_dir)
return; return;
} }
auto groups_var = tr_variant_serde::json().parse_file(filename); auto const groups_var = tr_variant_serde::json().parse_file(filename);
if (!groups_var) if (!groups_var)
{ {
return; return;
} }
auto idx = size_t{ 0 }; auto const* const groups_map = groups_var->get_if<tr_variant::Map>();
auto key = tr_quark{}; if (groups_map == nullptr)
tr_variant* dict = nullptr;
while (tr_variantDictChild(&*groups_var, idx, &key, &dict))
{ {
++idx; return;
}
auto name = tr_interned_string(key); for (auto const& [key, group_var] : *groups_map)
auto& group = session->getBandwidthGroup(name); {
auto const* const group_map = group_var.get_if<tr_variant::Map>();
if (group_map == nullptr)
{
continue;
}
auto& group = session->getBandwidthGroup(tr_interned_string{ key });
auto limits = tr_bandwidth_limits{}; auto limits = tr_bandwidth_limits{};
if (auto val = bool{}; tr_variantDictFindBool(dict, TR_KEY_uploadLimited, &val)) if (auto const* val = group_map->find_if<bool>(TR_KEY_uploadLimited); val != nullptr)
{ {
limits.up_limited = val; limits.up_limited = *val;
} }
if (auto val = bool{}; tr_variantDictFindBool(dict, TR_KEY_downloadLimited, &val)) if (auto const* val = group_map->find_if<bool>(TR_KEY_downloadLimited); val != nullptr)
{ {
limits.down_limited = val; limits.down_limited = *val;
} }
if (auto val = int64_t{}; tr_variantDictFindInt(dict, TR_KEY_uploadLimit, &val)) if (auto const* val = group_map->find_if<int64_t>(TR_KEY_uploadLimit); val != nullptr)
{ {
limits.up_limit_KBps = static_cast<tr_kilobytes_per_second_t>(val); limits.up_limit_KBps = static_cast<tr_kilobytes_per_second_t>(*val);
} }
if (auto val = int64_t{}; tr_variantDictFindInt(dict, TR_KEY_downloadLimit, &val)) if (auto const* val = group_map->find_if<int64_t>(TR_KEY_downloadLimit); val != nullptr)
{ {
limits.down_limit_KBps = static_cast<tr_kilobytes_per_second_t>(val); limits.down_limit_KBps = static_cast<tr_kilobytes_per_second_t>(*val);
} }
group.set_limits(&limits); group.set_limits(&limits);
if (auto honors = bool{}; tr_variantDictFindBool(dict, TR_KEY_honorsSessionLimits, &honors)) if (auto const* val = group_map->find_if<bool>(TR_KEY_honorsSessionLimits); val != nullptr)
{ {
group.honor_parent_limits(TR_UP, honors); group.honor_parent_limits(TR_UP, *val);
group.honor_parent_limits(TR_DOWN, honors); group.honor_parent_limits(TR_DOWN, *val);
} }
} }
} }
@@ -127,27 +132,24 @@ void bandwidthGroupRead(tr_session* session, std::string_view config_dir)
void bandwidthGroupWrite(tr_session const* session, std::string_view config_dir) void bandwidthGroupWrite(tr_session const* session, std::string_view config_dir)
{ {
auto const& groups = session->bandwidthGroups(); auto const& groups = session->bandwidthGroups();
auto groups_map = tr_variant::Map{ std::size(groups) };
auto groups_dict = tr_variant{};
tr_variantInitDict(&groups_dict, std::size(groups));
for (auto const& [name, group] : groups) for (auto const& [name, group] : groups)
{ {
auto const limits = group->get_limits(); auto const limits = group->get_limits();
auto group_map = tr_variant::Map{ 6U };
auto* const dict = tr_variantDictAddDict(&groups_dict, name.quark(), 5); group_map.try_emplace(TR_KEY_downloadLimit, limits.down_limit_KBps);
tr_variantDictAddStrView(dict, TR_KEY_name, name.sv()); group_map.try_emplace(TR_KEY_downloadLimited, limits.down_limited);
tr_variantDictAddBool(dict, TR_KEY_uploadLimited, limits.up_limited); group_map.try_emplace(TR_KEY_honorsSessionLimits, group->are_parent_limits_honored(TR_UP));
tr_variantDictAddInt(dict, TR_KEY_uploadLimit, limits.up_limit_KBps); group_map.try_emplace(TR_KEY_name, name.sv());
tr_variantDictAddBool(dict, TR_KEY_downloadLimited, limits.down_limited); group_map.try_emplace(TR_KEY_uploadLimit, limits.up_limit_KBps);
tr_variantDictAddInt(dict, TR_KEY_downloadLimit, limits.down_limit_KBps); group_map.try_emplace(TR_KEY_uploadLimited, limits.up_limited);
tr_variantDictAddBool(dict, TR_KEY_honorsSessionLimits, group->are_parent_limits_honored(TR_UP)); groups_map.try_emplace(name.quark(), std::move(group_map));
} }
auto const filename = tr_pathbuf{ config_dir, '/', BandwidthGroupsFilename }; tr_variant_serde::json().to_file(
tr_variant_serde::json().to_file(groups_dict, filename); tr_variant{ std::move(groups_map) },
tr_pathbuf{ config_dir, '/', BandwidthGroupsFilename });
} }
} // namespace bandwidth_group_helpers } // namespace bandwidth_group_helpers
void update_bandwidth(tr_session* session, tr_direction dir) void update_bandwidth(tr_session* session, tr_direction dir)
@@ -467,10 +469,7 @@ tr_variant tr_sessionGetSettings(tr_session const* session)
settings.merge(session->settings_.settings()); settings.merge(session->settings_.settings());
settings.merge(session->alt_speeds_.settings()); settings.merge(session->alt_speeds_.settings());
settings.merge(session->rpc_server_->settings()); settings.merge(session->rpc_server_->settings());
(*settings.get_if<tr_variant::Map>())[TR_KEY_message_level] = tr_logGetLevel();
tr_variantDictRemove(&settings, TR_KEY_message_level);
tr_variantDictAddInt(&settings, TR_KEY_message_level, tr_logGetLevel());
return settings; return settings;
} }
@@ -493,34 +492,31 @@ tr_variant tr_sessionLoadSettings(char const* config_dir, char const* app_name)
return settings; return settings;
} }
void tr_sessionSaveSettings(tr_session* session, char const* config_dir, tr_variant const* client_settings) void tr_sessionSaveSettings(tr_session* session, char const* config_dir, tr_variant const& client_settings)
{ {
using namespace bandwidth_group_helpers; using namespace bandwidth_group_helpers;
TR_ASSERT(client_settings != nullptr); TR_ASSERT(client_settings.holds_alternative<tr_variant::Map>());
TR_ASSERT(client_settings->holds_alternative<tr_variant::Map>());
tr_variant settings;
auto const filename = tr_pathbuf{ config_dir, "/settings.json"sv }; auto const filename = tr_pathbuf{ config_dir, "/settings.json"sv };
tr_variantInitDict(&settings, 0); // from highest to lowest precedence:
// - actual values
/* the existing file settings are the fallback values */ // - client settings
// - previous session's settings stored in settings.json
// - built-in defaults
auto settings = tr_sessionGetDefaultSettings();
if (auto const file_settings = tr_variant_serde::json().parse_file(filename); file_settings) if (auto const file_settings = tr_variant_serde::json().parse_file(filename); file_settings)
{ {
tr_variantMergeDicts(&settings, &*file_settings); settings.merge(*file_settings);
} }
settings.merge(client_settings);
/* the client's settings override the file settings */
tr_variantMergeDicts(&settings, client_settings);
/* the session's true values override the file & client settings */
settings.merge(tr_sessionGetSettings(session)); settings.merge(tr_sessionGetSettings(session));
/* save the result */ // save 'em
tr_variant_serde::json().to_file(settings, filename); tr_variant_serde::json().to_file(settings, filename);
/* Write bandwidth groups limits to file */ // write bandwidth groups limits to file
bandwidthGroupWrite(session, config_dir); bandwidthGroupWrite(session, config_dir);
} }
@@ -528,37 +524,51 @@ void tr_sessionSaveSettings(tr_session* session, char const* config_dir, tr_vari
struct tr_session::init_data struct tr_session::init_data
{ {
init_data(bool message_queuing_enabled_in, std::string_view config_dir_in, tr_variant const& settings_in)
: message_queuing_enabled{ message_queuing_enabled_in }
, config_dir{ config_dir_in }
, settings{ settings_in }
{
}
bool message_queuing_enabled; bool message_queuing_enabled;
std::string_view config_dir; std::string_view config_dir;
tr_variant* client_settings; tr_variant const& settings;
std::condition_variable_any done_cv; std::condition_variable_any done_cv;
}; };
tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled, tr_variant* client_settings) tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled, tr_variant const& client_settings)
{ {
using namespace bandwidth_group_helpers; using namespace bandwidth_group_helpers;
TR_ASSERT(client_settings != nullptr); TR_ASSERT(config_dir != nullptr);
TR_ASSERT(client_settings->holds_alternative<tr_variant::Map>()); TR_ASSERT(client_settings.holds_alternative<tr_variant::Map>());
tr_timeUpdate(time(nullptr)); tr_timeUpdate(time(nullptr));
// nice to start logging at the very beginning // settings order of precedence from highest to lowest:
if (auto val = int64_t{}; tr_variantDictFindInt(client_settings, TR_KEY_message_level, &val)) // - client settings
// - previous session's values in settings.json
// - hardcoded defaults
auto settings = tr_sessionLoadSettings(config_dir, nullptr);
settings.merge(client_settings);
// if logging is desired, start it now before doing more work
if (auto const* settings_map = client_settings.get_if<tr_variant::Map>(); settings_map != nullptr)
{ {
tr_logSetLevel(static_cast<tr_log_level>(val)); if (auto const* val = settings_map->find_if<bool>(TR_KEY_message_level); val != nullptr)
{
tr_logSetLevel(static_cast<tr_log_level>(*val));
}
} }
/* initialize the bare skeleton of the session object */ // initialize the bare skeleton of the session object
auto* const session = new tr_session{ config_dir, tr_variant::make_map() }; auto* const session = new tr_session{ config_dir, tr_variant::make_map() };
bandwidthGroupRead(session, config_dir); bandwidthGroupRead(session, config_dir);
auto data = tr_session::init_data{};
data.config_dir = config_dir;
data.message_queuing_enabled = message_queueing_enabled;
data.client_settings = client_settings;
// run initImpl() in the libtransmission thread // run initImpl() in the libtransmission thread
auto data = tr_session::init_data{ message_queueing_enabled, config_dir, settings };
auto lock = session->unique_lock(); auto lock = session->unique_lock();
session->runInSessionThread([&session, &data]() { session->initImpl(data); }); session->runInSessionThread([&session, &data]() { session->initImpl(data); });
data.done_cv.wait(lock); // wait for the session to be ready data.done_cv.wait(lock); // wait for the session to be ready
@@ -590,15 +600,11 @@ void tr_session::initImpl(init_data& data)
auto lock = unique_lock(); auto lock = unique_lock();
TR_ASSERT(am_in_session_thread()); TR_ASSERT(am_in_session_thread());
auto* const client_settings = data.client_settings; auto const& settings = data.settings;
TR_ASSERT(client_settings != nullptr); TR_ASSERT(settings.holds_alternative<tr_variant::Map>());
TR_ASSERT(client_settings->holds_alternative<tr_variant::Map>());
tr_logAddTrace(fmt::format("tr_sessionInit: the session's top-level bandwidth object is {}", fmt::ptr(&top_bandwidth_))); tr_logAddTrace(fmt::format("tr_sessionInit: the session's top-level bandwidth object is {}", fmt::ptr(&top_bandwidth_)));
auto settings = tr_sessionGetDefaultSettings();
tr_variantMergeDicts(&settings, client_settings);
#ifndef _WIN32 #ifndef _WIN32
/* Don't exit when writing on a broken socket */ /* Don't exit when writing on a broken socket */
(void)signal(SIGPIPE, SIG_IGN); (void)signal(SIGPIPE, SIG_IGN);
@@ -610,7 +616,7 @@ void tr_session::initImpl(init_data& data)
tr_logAddInfo(fmt::format(_("Transmission version {version} starting"), fmt::arg("version", LONG_VERSION_STRING))); tr_logAddInfo(fmt::format(_("Transmission version {version} starting"), fmt::arg("version", LONG_VERSION_STRING)));
setSettings(client_settings, true); setSettings(settings, true);
if (this->allowsLPD()) if (this->allowsLPD())
{ {
@@ -623,20 +629,16 @@ void tr_session::initImpl(init_data& data)
data.done_cv.notify_one(); data.done_cv.notify_one();
} }
void tr_session::setSettings(tr_variant* settings_dict, bool force) void tr_session::setSettings(tr_variant const& settings, bool force)
{ {
TR_ASSERT(am_in_session_thread()); TR_ASSERT(am_in_session_thread());
TR_ASSERT(settings_dict != nullptr); TR_ASSERT(settings.holds_alternative<tr_variant::Map>());
TR_ASSERT(settings_dict->holds_alternative<tr_variant::Map>());
// load the session settings setSettings(tr_session_settings{ settings }, force);
auto new_settings = tr_session_settings{};
new_settings.load(*settings_dict);
setSettings(std::move(new_settings), force);
// delegate loading out the other settings // delegate loading out the other settings
alt_speeds_.load(*settings_dict); alt_speeds_.load(settings);
rpc_server_->load(*settings_dict); rpc_server_->load(settings);
} }
void tr_session::setSettings(tr_session_settings&& settings_in, bool force) void tr_session::setSettings(tr_session_settings&& settings_in, bool force)
@@ -766,7 +768,7 @@ void tr_session::setSettings(tr_session_settings&& settings_in, bool force)
update_bandwidth(this, TR_DOWN); update_bandwidth(this, TR_DOWN);
} }
void tr_sessionSet(tr_session* session, tr_variant* settings) void tr_sessionSet(tr_session* session, tr_variant const& settings)
{ {
// do the work in the session thread // do the work in the session thread
auto done_promise = std::promise<void>{}; auto done_promise = std::promise<void>{};

View File

@@ -966,7 +966,7 @@ private:
struct init_data; struct init_data;
void initImpl(init_data&); void initImpl(init_data&);
void setSettings(tr_variant* settings_dict, bool force); void setSettings(tr_variant const& settings_map, bool force);
void setSettings(tr_session_settings&& settings, bool force); void setSettings(tr_session_settings&& settings, bool force);
void closeImplPart1(std::promise<void>* closed_promise, std::chrono::time_point<std::chrono::steady_clock> deadline); void closeImplPart1(std::promise<void>* closed_promise, std::chrono::time_point<std::chrono::steady_clock> deadline);
@@ -998,7 +998,7 @@ private:
friend tr_kilobytes_per_second_t tr_sessionGetSpeedLimit_KBps(tr_session const* session, tr_direction dir); friend tr_kilobytes_per_second_t tr_sessionGetSpeedLimit_KBps(tr_session const* session, tr_direction dir);
friend tr_port_forwarding_state tr_sessionGetPortForwarding(tr_session const* session); friend tr_port_forwarding_state tr_sessionGetPortForwarding(tr_session const* session);
friend tr_sched_day tr_sessionGetAltSpeedDay(tr_session const* session); friend tr_sched_day tr_sessionGetAltSpeedDay(tr_session const* session);
friend tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled, tr_variant* client_settings); friend tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled, tr_variant const& client_settings);
friend uint16_t tr_sessionGetPeerPort(tr_session const* session); friend uint16_t tr_sessionGetPeerPort(tr_session const* session);
friend uint16_t tr_sessionGetRPCPort(tr_session const* session); friend uint16_t tr_sessionGetRPCPort(tr_session const* session);
friend uint16_t tr_sessionSetPeerPortRandom(tr_session* session); friend uint16_t tr_sessionSetPeerPortRandom(tr_session* session);
@@ -1006,7 +1006,7 @@ private:
friend tr_variant tr_sessionGetSettings(tr_session const* s); friend tr_variant tr_sessionGetSettings(tr_session const* s);
friend void tr_sessionLimitSpeed(tr_session* session, tr_direction dir, bool limited); friend void tr_sessionLimitSpeed(tr_session* session, tr_direction dir, bool limited);
friend void tr_sessionReloadBlocklists(tr_session* session); friend void tr_sessionReloadBlocklists(tr_session* session);
friend void tr_sessionSet(tr_session* session, tr_variant* settings); friend void tr_sessionSet(tr_session* session, tr_variant const& settings);
friend void tr_sessionSetAltSpeedBegin(tr_session* session, size_t minutes_since_midnight); friend void tr_sessionSetAltSpeedBegin(tr_session* session, size_t minutes_since_midnight);
friend void tr_sessionSetAltSpeedDay(tr_session* session, tr_sched_day days); friend void tr_sessionSetAltSpeedDay(tr_session* session, tr_sched_day days);
friend void tr_sessionSetAltSpeedEnd(tr_session* session, size_t minutes_since_midnight); friend void tr_sessionSetAltSpeedEnd(tr_session* session, size_t minutes_since_midnight);

View File

@@ -199,7 +199,7 @@ tr_variant tr_sessionLoadSettings(char const* config_dir, char const* app_name);
* @param client_settings the dictionary to save * @param client_settings the dictionary to save
* @see `tr_sessionLoadSettings()` * @see `tr_sessionLoadSettings()`
*/ */
void tr_sessionSaveSettings(tr_session* session, char const* config_dir, struct tr_variant const* client_settings); void tr_sessionSaveSettings(tr_session* session, char const* config_dir, tr_variant const& client_settings);
/** /**
* @brief Initialize a libtransmission session. * @brief Initialize a libtransmission session.
@@ -218,11 +218,11 @@ void tr_sessionSaveSettings(tr_session* session, char const* config_dir, struct
* @see `tr_sessionLoadSettings()` * @see `tr_sessionLoadSettings()`
* @see `tr_getDefaultConfigDir()` * @see `tr_getDefaultConfigDir()`
*/ */
tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled, struct tr_variant* settings); tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled, tr_variant const& settings);
/** @brief Update a session's settings from a benc dictionary /** @brief Update a session's settings from a benc dictionary
like to the one used in `tr_sessionInit()` */ like to the one used in `tr_sessionInit()` */
void tr_sessionSet(tr_session* session, struct tr_variant* settings); void tr_sessionSet(tr_session* session, tr_variant const& settings);
/** @brief Rescan the blocklists directory and /** @brief Rescan the blocklists directory and
reload whatever blocklist files are found there */ reload whatever blocklist files are found there */

View File

@@ -851,34 +851,30 @@ std::string tr_formatter_mem_B(size_t bytes_per_second)
return formatter_get_size_str(mem_units, std::data(buf), bytes_per_second, std::size(buf)); return formatter_get_size_str(mem_units, std::data(buf), bytes_per_second, std::size(buf));
} }
void tr_formatter_get_units(void* vdict) tr_variant tr_formatter_get_units()
{ {
using namespace formatter_impl; using namespace formatter_impl;
auto* dict = static_cast<tr_variant*>(vdict); auto const make_units_vec = [](formatter_units const& units)
tr_variantDictReserve(dict, 6);
tr_variantDictAddInt(dict, TR_KEY_memory_bytes, mem_units[TR_FMT_KB].value);
tr_variant* l = tr_variantDictAddList(dict, TR_KEY_memory_units, std::size(mem_units));
for (auto const& unit : mem_units)
{ {
tr_variantListAddStr(l, std::data(unit.name)); auto units_vec = tr_variant::Vector{};
} units_vec.reserve(std::size(units));
std::transform(
std::begin(units),
std::end(units),
std::back_inserter(units_vec),
[](auto const& unit) { return std::data(unit.name); });
return units_vec;
};
tr_variantDictAddInt(dict, TR_KEY_size_bytes, size_units[TR_FMT_KB].value); auto units_map = tr_variant::Map{ 6U };
l = tr_variantDictAddList(dict, TR_KEY_size_units, std::size(size_units)); units_map.try_emplace(TR_KEY_memory_bytes, mem_units[TR_FMT_KB].value);
for (auto const& unit : size_units) units_map.try_emplace(TR_KEY_memory_units, make_units_vec(mem_units));
{ units_map.try_emplace(TR_KEY_size_bytes, size_units[TR_FMT_KB].value);
tr_variantListAddStr(l, std::data(unit.name)); units_map.try_emplace(TR_KEY_size_units, make_units_vec(size_units));
} units_map.try_emplace(TR_KEY_speed_bytes, speed_units[TR_FMT_KB].value);
units_map.try_emplace(TR_KEY_speed_units, make_units_vec(speed_units));
tr_variantDictAddInt(dict, TR_KEY_speed_bytes, speed_units[TR_FMT_KB].value); return tr_variant{ std::move(units_map) };
l = tr_variantDictAddList(dict, TR_KEY_speed_units, std::size(speed_units));
for (auto const& unit : speed_units)
{
tr_variantListAddStr(l, std::data(unit.name));
}
} }
// --- ENVIRONMENT // --- ENVIRONMENT

View File

@@ -325,7 +325,7 @@ extern uint64_t tr_size_K; /* unused? */
/** @brief Format a file size from bytes into a user-readable string. */ /** @brief Format a file size from bytes into a user-readable string. */
[[nodiscard]] std::string tr_formatter_size_B(uint64_t bytes); [[nodiscard]] std::string tr_formatter_size_B(uint64_t bytes);
void tr_formatter_get_units(void* dict); struct tr_variant tr_formatter_get_units();
[[nodiscard]] static inline size_t tr_toSpeedBytes(size_t KBps) [[nodiscard]] static inline size_t tr_toSpeedBytes(size_t KBps)
{ {

View File

@@ -142,7 +142,7 @@ public:
// --- custom functions // --- custom functions
template<typename Type> template<typename Type>
[[nodiscard]] TR_CONSTEXPR20 auto TR_CONSTEXPR20 find_if(tr_quark const key) const noexcept [[nodiscard]] TR_CONSTEXPR20 auto find_if(tr_quark const key) const noexcept
{ {
auto const iter = find(key); auto const iter = find(key);
return iter != end() ? iter->second.get_if<Type>() : nullptr; return iter != end() ? iter->second.get_if<Type>() : nullptr;
@@ -319,9 +319,10 @@ public:
val_.emplace<std::monostate>(); val_.emplace<std::monostate>();
} }
void merge(tr_variant const& that) tr_variant& merge(tr_variant const& that)
{ {
std::visit(Merge{ *this }, that.val_); std::visit(Merge{ *this }, that.val_);
return *this;
} }
private: private:

View File

@@ -544,7 +544,7 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
tr_formatter_mem_init(1000, kbString.UTF8String, mbString.UTF8String, gbString.UTF8String, tbString.UTF8String); tr_formatter_mem_init(1000, kbString.UTF8String, mbString.UTF8String, gbString.UTF8String, tbString.UTF8String);
auto const default_config_dir = tr_getDefaultConfigDir("Transmission"); auto const default_config_dir = tr_getDefaultConfigDir("Transmission");
_fLib = tr_sessionInit(default_config_dir.c_str(), YES, &settings); _fLib = tr_sessionInit(default_config_dir.c_str(), YES, settings);
_fConfigDirectory = @(default_config_dir.c_str()); _fConfigDirectory = @(default_config_dir.c_str());
tr_sessionSetIdleLimitHitCallback(_fLib, onIdleLimitHit, (__bridge void*)(self)); tr_sessionSetIdleLimitHitCallback(_fLib, onIdleLimitHit, (__bridge void*)(self));

View File

@@ -356,8 +356,8 @@ void Session::start()
} }
else else
{ {
auto settings = tr_sessionLoadSettings(config_dir_.toUtf8().constData(), "qt"); auto const settings = tr_sessionLoadSettings(config_dir_.toUtf8().constData(), "qt");
session_ = tr_sessionInit(config_dir_.toUtf8().constData(), true, &settings); session_ = tr_sessionInit(config_dir_.toUtf8().constData(), true, settings);
rpc_.start(session_); rpc_.start(session_);

View File

@@ -309,7 +309,7 @@ TEST_F(SessionTest, honorsSettings)
tr_variantDictRemove(&settings, key); tr_variantDictRemove(&settings, key);
tr_variantDictAddBool(&settings, key, true); tr_variantDictAddBool(&settings, key, true);
} }
auto* session = tr_sessionInit(sandboxDir().data(), false, &settings); auto* session = tr_sessionInit(sandboxDir().data(), false, settings);
// confirm that these settings were enabled // confirm that these settings were enabled
EXPECT_TRUE(session->isPortRandom()); EXPECT_TRUE(session->isPortRandom());

View File

@@ -388,7 +388,7 @@ private:
tr_variantDictAddInt(settings, q, verbose ? TR_LOG_DEBUG : TR_LOG_ERROR); tr_variantDictAddInt(settings, q, verbose ? TR_LOG_DEBUG : TR_LOG_ERROR);
} }
return tr_sessionInit(sandboxDir().data(), !verbose, settings); return tr_sessionInit(sandboxDir().data(), !verbose, *settings);
} }
void sessionClose(tr_session* session) void sessionClose(tr_session* session)