From 0182bfbfba562cd5100d730ef81d2641263c438b Mon Sep 17 00:00:00 2001 From: rakshasa Date: Fri, 4 May 2007 20:29:07 +0000 Subject: [PATCH] * Finished moving the normal commands to the new system. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@899 e378c898-3ddf-0310-93e7-cc216c733640 --- src/command_events.cc | 62 +++++++++++++ src/command_helpers.cc | 2 - src/command_helpers.h | 16 +++- src/command_network.cc | 83 ++++++++++++++++- src/command_scheduler.h | 2 +- src/option_handler_rules.cc | 174 ------------------------------------ 6 files changed, 159 insertions(+), 180 deletions(-) diff --git a/src/command_events.cc b/src/command_events.cc index 26fafb7c..ec5ffe90 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -46,11 +46,13 @@ #include "core/download_list.h" #include "core/manager.h" #include "utils/command_slot.h" +#include "utils/command_variable.h" #include "utils/parse.h" #include "globals.h" #include "control.h" #include "command_helpers.h" +#include "command_scheduler.h" torrent::Object apply_on_state_change(core::DownloadList::slot_map* slotMap, const torrent::Object& rawArgs) { @@ -169,11 +171,58 @@ apply_remove_untied() { return torrent::Object(); } +torrent::Object +apply_schedule(const torrent::Object& rawArgs) { + const torrent::Object::list_type& args = rawArgs.as_list(); + + if (args.size() < 4) + throw torrent::input_error("Too few arguments."); + + torrent::Object::list_type::const_iterator itr = args.begin(); + + const std::string& arg1 = (itr++)->as_string(); + const std::string& arg2 = (itr++)->as_string(); + const std::string& arg3 = (itr++)->as_string(); + + control->command_scheduler()->parse(arg1, arg2, arg3, utils::convert_list_to_command(itr, args.end())); + + return torrent::Object(); +} + +void apply_load(const std::string& arg) { control->core()->try_create_download_expand(arg, false, false, true); } +void apply_load_verbose(const std::string& arg) { control->core()->try_create_download_expand(arg, false, true, true); } +void apply_load_start(const std::string& arg) { control->core()->try_create_download_expand(arg, true, false, true); } +void apply_load_start_verbose(const std::string& arg) { control->core()->try_create_download_expand(arg, true, true, true); } + +void apply_import(const std::string& path) { if (!control->variable()->process_file(path.c_str())) throw torrent::input_error("Could not open option file: " + path); } +void apply_try_import(const std::string& path) { if (!control->variable()->process_file(path.c_str())) control->core()->push_log("Could not read resource file: " + path); } + +void +apply_close_low_diskspace(int64_t arg) { + core::Manager::DListItr itr = control->core()->download_list()->begin(); + + while ((itr = std::find_if(itr, control->core()->download_list()->end(), std::mem_fun(&core::Download::is_downloading))) != control->core()->download_list()->end()) { + if ((*itr)->file_list()->free_diskspace() < (uint64_t)arg) { + control->core()->download_list()->close(*itr); + + (*itr)->set_hash_failed(true); + (*itr)->set_message(std::string("Low diskspace.")); + } + + ++itr; + } +} + void initialize_command_events() { utils::VariableMap* variables = control->variable(); core::DownloadList* downloadList = control->core()->download_list(); + ADD_VARIABLE_BOOL("check_hash", true); + + ADD_VARIABLE_BOOL("session_lock", true); + ADD_VARIABLE_BOOL("session_on_completion", true); + ADD_COMMAND_SLOT_PRIVATE("on_insert", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_insert())); ADD_COMMAND_SLOT_PRIVATE("on_erase", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_erase())); ADD_COMMAND_SLOT_PRIVATE("on_open", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_open())); @@ -191,4 +240,17 @@ initialize_command_events() { ADD_COMMAND_SLOT_PRIVATE("stop_untied", call_string, utils::object_fn(&apply_stop_untied)); ADD_COMMAND_SLOT_PRIVATE("close_untied", call_string, utils::object_fn(&apply_close_untied)); ADD_COMMAND_SLOT_PRIVATE("remove_untied", call_string, utils::object_fn(&apply_remove_untied)); + + ADD_COMMAND_LIST("schedule", rak::ptr_fn(&apply_schedule)); + ADD_COMMAND_STRING_UN("schedule_remove", rak::make_mem_fun(control->command_scheduler(), &CommandScheduler::erase_str)); + + ADD_COMMAND_STRING_UN("import", std::ptr_fun(&apply_import)); + ADD_COMMAND_STRING_UN("try_import", std::ptr_fun(&apply_try_import)); + + ADD_COMMAND_STRING_UN("load", std::ptr_fun(&apply_load)); + ADD_COMMAND_STRING_UN("load_verbose", std::ptr_fun(&apply_load_verbose)); + ADD_COMMAND_STRING_UN("load_start", std::ptr_fun(&apply_load_start)); + ADD_COMMAND_STRING_UN("load_start_verbose", std::ptr_fun(&apply_load_start_verbose)); + + ADD_COMMAND_VALUE_UN("close_low_diskspace", std::ptr_fun(&apply_close_low_diskspace)); } diff --git a/src/command_helpers.cc b/src/command_helpers.cc index bde9fe98..f25c5a03 100644 --- a/src/command_helpers.cc +++ b/src/command_helpers.cc @@ -50,7 +50,6 @@ utils::CommandSlot* commandSlotsItr = commandSlots; utils::CommandVariable commandVariables[COMMAND_VARIABLES_SIZE]; utils::CommandVariable* commandVariablesItr = commandVariables; -void initialize_variables(); void initialize_download_variables(); void initialize_command_events(); void initialize_command_local(); @@ -59,7 +58,6 @@ void initialize_command_ui(); void initialize_commands() { - initialize_variables(); initialize_download_variables(); initialize_command_events(); initialize_command_network(); diff --git a/src/command_helpers.h b/src/command_helpers.h index 99f87822..149962bc 100644 --- a/src/command_helpers.h +++ b/src/command_helpers.h @@ -46,8 +46,8 @@ namespace utils { // By using a static array we avoid allocating the variables on the // heap. This should reduce memory use and improve cache locality. -#define COMMAND_SLOTS_SIZE 50 -#define COMMAND_VARIABLES_SIZE 50 +#define COMMAND_SLOTS_SIZE 100 +#define COMMAND_VARIABLES_SIZE 100 #define ADDING_COMMANDS @@ -101,9 +101,21 @@ add_variable("get_" key, "set_" key, key, &utils::CommandVariable::get_string, & ADD_COMMAND_COPY("set_" key, call_string, "i:s", "") \ ADD_COMMAND_SLOT("get_" key, call_unknown, utils::object_void_fn(get), "s:", "") +#define ADD_COMMAND_VOID(key, slot) \ + ADD_COMMAND_SLOT(key, call_unknown, utils::object_void_fn(slot), "i:", "") + +#define ADD_COMMAND_VALUE(key, slot) \ + ADD_COMMAND_SLOT(key, call_value, slot, "i:i", "") + +#define ADD_COMMAND_VALUE_UN(key, slot) \ + ADD_COMMAND_SLOT(key, call_value, utils::object_value_fn(slot), "i:i", "") + #define ADD_COMMAND_STRING(key, slot) \ ADD_COMMAND_SLOT(key, call_string, slot, "i:s", "") +#define ADD_COMMAND_STRING_UN(key, slot) \ + ADD_COMMAND_SLOT(key, call_string, utils::object_string_fn(slot), "i:s", "") + #define ADD_COMMAND_LIST(key, slot) \ ADD_COMMAND_SLOT(key, call_list, slot, "i:", "") diff --git a/src/command_network.cc b/src/command_network.cc index 86dfb0cc..96a4e857 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -38,11 +38,17 @@ #include #include -#include #include +#include +#include +#include +#include "core/download.h" #include "core/download_list.h" +#include "core/download_store.h" #include "core/manager.h" +#include "rpc/fast_cgi.h" +#include "rpc/xmlrpc.h" #include "ui/root.h" #include "utils/command_slot.h" #include "utils/command_variable.h" @@ -114,10 +120,53 @@ apply_tos(const torrent::Object& rawArg) { return torrent::Object(); } +void apply_hash_read_ahead(int arg) { torrent::set_hash_read_ahead(arg << 20); } +void apply_hash_interval(int arg) { torrent::set_hash_interval(arg * 1000); } +void apply_encoding_list(const std::string& arg) { torrent::encoding_list()->push_back(arg); } + +void +apply_enable_trackers(int64_t arg) { + for (core::Manager::DListItr itr = control->core()->download_list()->begin(), last = control->core()->download_list()->end(); itr != last; ++itr) { + + torrent::TrackerList tl = (*itr)->download()->tracker_list(); + + for (int i = 0, last = tl.size(); i < last; ++i) + if (arg) + tl.get(i).enable(); + else + tl.get(i).disable(); + + if (arg && !control->variable()->get_value("get_use_udp_trackers")) + (*itr)->enable_udp_trackers(false); + } +} + +void +apply_fast_cgi(const std::string& arg) { + if (control->fast_cgi() != NULL) + throw torrent::input_error("FastCGI already enabled."); + + if (control->xmlrpc() == NULL) { + control->set_xmlrpc(new rpc::XmlRpc); + control->xmlrpc()->set_slot_call_command(rak::mem_fn(control->variable(), &utils::VariableMap::call_command)); + + for (utils::VariableMap::const_iterator itr = control->variable()->begin(), last = control->variable()->end(); itr != last; itr++) + if (itr->second.m_flags & utils::VariableMap::flag_public_xmlrpc) + control->xmlrpc()->insert_command(itr->first, itr->second.m_parm, itr->second.m_doc); + } + + control->set_fast_cgi(new rpc::FastCgi(arg)); + control->fast_cgi()->set_slot_process(rak::mem_fn(control->xmlrpc(), &rpc::XmlRpc::process)); +} + void initialize_command_network() { utils::VariableMap* variables = control->variable(); // core::DownloadList* downloadList = control->core()->download_list(); + torrent::ConnectionManager* cm = torrent::connection_manager(); + core::CurlStack* httpStack = control->core()->get_poll_manager()->get_http_stack(); + core::DownloadList* dList = control->core()->download_list(); + core::DownloadStore* dStore = control->core()->download_store(); ADD_VARIABLE_BOOL("use_udp_trackers", true); @@ -150,4 +199,36 @@ initialize_command_network() { ADD_COMMAND_STRING_TRI("bind", rak::make_mem_fun(control->core(), &core::Manager::set_bind_address), rak::make_mem_fun(control->core(), &core::Manager::bind_address)); ADD_COMMAND_STRING_TRI("ip", rak::make_mem_fun(control->core(), &core::Manager::set_local_address), rak::make_mem_fun(control->core(), &core::Manager::local_address)); ADD_COMMAND_STRING_TRI("proxy_address", rak::make_mem_fun(control->core(), &core::Manager::set_proxy_address), rak::make_mem_fun(control->core(), &core::Manager::proxy_address)); + ADD_COMMAND_STRING_TRI("http_proxy", rak::make_mem_fun(httpStack, &core::CurlStack::set_http_proxy), rak::make_mem_fun(httpStack, &core::CurlStack::http_proxy)); + + ADD_COMMAND_VALUE_TRI("send_buffer_size", rak::make_mem_fun(cm, &torrent::ConnectionManager::set_send_buffer_size), rak::make_mem_fun(cm, &torrent::ConnectionManager::send_buffer_size)); + ADD_COMMAND_VALUE_TRI("receive_buffer_size", rak::make_mem_fun(cm, &torrent::ConnectionManager::set_receive_buffer_size), rak::make_mem_fun(cm, &torrent::ConnectionManager::receive_buffer_size)); + + ADD_COMMAND_VALUE_TRI("max_uploads_global", rak::make_mem_fun(control->ui(), &ui::Root::set_max_uploads_global), rak::make_mem_fun(control->ui(), &ui::Root::max_uploads_global)); + ADD_COMMAND_VALUE_TRI("max_downloads_global", rak::make_mem_fun(control->ui(), &ui::Root::set_max_downloads_global), rak::make_mem_fun(control->ui(), &ui::Root::max_downloads_global)); + + ADD_COMMAND_VALUE_TRI("hash_max_tries", std::ptr_fun(&torrent::set_hash_max_tries), rak::ptr_fun(&torrent::hash_max_tries)); + ADD_COMMAND_VALUE_TRI("max_open_files", std::ptr_fun(&torrent::set_max_open_files), rak::ptr_fun(&torrent::max_open_files)); + ADD_COMMAND_VALUE_TRI("max_open_sockets", rak::make_mem_fun(cm, &torrent::ConnectionManager::set_max_size), rak::make_mem_fun(cm, &torrent::ConnectionManager::max_size)); + ADD_COMMAND_VALUE_TRI("max_open_http", rak::make_mem_fun(httpStack, &core::CurlStack::set_max_active), rak::make_mem_fun(httpStack, &core::CurlStack::max_active)); + + ADD_COMMAND_STRING_UN("fast_cgi", std::ptr_fun(&apply_fast_cgi)); + + ADD_COMMAND_VALUE_TRI("hash_read_ahead", std::ptr_fun(&apply_hash_read_ahead), rak::ptr_fun(torrent::hash_read_ahead)); + ADD_COMMAND_VALUE_TRI("hash_interval", std::ptr_fun(&apply_hash_interval), rak::ptr_fun(torrent::hash_interval)); + + ADD_COMMAND_VALUE_UN("enable_trackers", std::ptr_fun(&apply_enable_trackers)); + ADD_COMMAND_STRING_UN("encoding_list", std::ptr_fun(&apply_encoding_list)); + + // Not really network stuff: + ADD_VARIABLE_BOOL("handshake_log", false); + ADD_VARIABLE_STRING("tracker_dump", ""); + + ADD_VARIABLE_STRING("directory", "./"); + + ADD_COMMAND_STRING_TRI("session", rak::make_mem_fun(dStore, &core::DownloadStore::set_path), rak::make_mem_fun(dStore, &core::DownloadStore::path)); + ADD_COMMAND_VOID("session_save", rak::make_mem_fun(dList, &core::DownloadList::session_save)); + +// ADD_VARIABLE_VALUE_TRI_OCT("umask", rak::mem_fn(control, &Control::set_umask), rak::mem_fn(control, &Control::umask)); + ADD_COMMAND_STRING_TRI("working_directory", rak::make_mem_fun(control, &Control::set_working_directory), rak::make_mem_fun(control, &Control::working_directory)); } diff --git a/src/command_scheduler.h b/src/command_scheduler.h index c72f7c0a..37c8ff3a 100644 --- a/src/command_scheduler.h +++ b/src/command_scheduler.h @@ -68,7 +68,7 @@ public: // safe to call erase on end(). iterator insert(const std::string& key); void erase(iterator itr); - void erase(const std::string& key) { erase(find(key)); } + void erase_str(const std::string& key) { erase(find(key)); } void parse(const std::string& key, const std::string& bufAbsolute, const std::string& bufInterval, const std::string& command); diff --git a/src/option_handler_rules.cc b/src/option_handler_rules.cc index 3b111dcd..55e2ac2b 100644 --- a/src/option_handler_rules.cc +++ b/src/option_handler_rules.cc @@ -85,180 +85,6 @@ namespace core { path_expand(std::vector* paths, const std::string& pattern); } -// void -// apply_new_string(const std::string& args) { -// std::string::const_iterator split = std::find(args.begin(), args.end(), ','); - -// std::string key = - -// if (control->variable()->has(args)) - -// variables->insert("tracker_dump", new utils::VariableAny(std::string())); -// } - -void apply_hash_read_ahead(int arg) { torrent::set_hash_read_ahead(arg << 20); } -void apply_hash_interval(int arg) { torrent::set_hash_interval(arg * 1000); } - -void apply_load(const std::string& arg) { control->core()->try_create_download_expand(arg, false, false, true); } -void apply_load_verbose(const std::string& arg) { control->core()->try_create_download_expand(arg, false, true, true); } -void apply_load_start(const std::string& arg) { control->core()->try_create_download_expand(arg, true, false, true); } -void apply_load_start_verbose(const std::string& arg) { control->core()->try_create_download_expand(arg, true, true, true); } - -void -apply_close_low_diskspace(int64_t arg) { - core::Manager::DListItr itr = control->core()->download_list()->begin(); - - while ((itr = std::find_if(itr, control->core()->download_list()->end(), std::mem_fun(&core::Download::is_downloading))) != control->core()->download_list()->end()) { - if ((*itr)->file_list()->free_diskspace() < (uint64_t)arg) { - control->core()->download_list()->close(*itr); - - (*itr)->set_hash_failed(true); - (*itr)->set_message(std::string("Low diskspace.")); - } - - ++itr; - } -} - -void -apply_encoding_list(const std::string& arg) { - torrent::encoding_list()->push_back(arg); -} - -void -apply_enable_trackers(const std::string& arg) { - bool state = (arg != "no"); - - for (core::Manager::DListItr itr = control->core()->download_list()->begin(), last = control->core()->download_list()->end(); itr != last; ++itr) { - - torrent::TrackerList tl = (*itr)->download()->tracker_list(); - - for (int i = 0, last = tl.size(); i < last; ++i) - if (state) - tl.get(i).enable(); - else - tl.get(i).disable(); - - if (state && !control->variable()->get_value("get_use_udp_trackers")) - (*itr)->enable_udp_trackers(false); - } -} - -void -apply_fast_cgi(const std::string& arg) { - if (control->fast_cgi() != NULL) - throw torrent::input_error("FastCGI already enabled."); - - if (control->xmlrpc() == NULL) { - control->set_xmlrpc(new rpc::XmlRpc); - control->xmlrpc()->set_slot_call_command(rak::mem_fn(control->variable(), &utils::VariableMap::call_command)); - - for (utils::VariableMap::const_iterator itr = control->variable()->begin(), last = control->variable()->end(); itr != last; itr++) - if (itr->second.m_flags & utils::VariableMap::flag_public_xmlrpc) - control->xmlrpc()->insert_command(itr->first, itr->second.m_parm, itr->second.m_doc); - } - - control->set_fast_cgi(new rpc::FastCgi(arg)); - control->fast_cgi()->set_slot_process(rak::mem_fn(control->xmlrpc(), &rpc::XmlRpc::process)); -} - -void -apply_import(const std::string& path) { - if (!control->variable()->process_file(path.c_str())) - throw torrent::input_error("Could not open option file: " + path); -} - -void -apply_try_import(const std::string& path) { - if (!control->variable()->process_file(path.c_str())) - control->core()->push_log("Could not read resource file: " + path); -} - -torrent::Object -apply_schedule(const torrent::Object& rawArgs) { - const torrent::Object::list_type& args = rawArgs.as_list(); - - if (args.size() < 4) - throw torrent::input_error("Too few arguments."); - - torrent::Object::list_type::const_iterator itr = args.begin(); - - const std::string& arg1 = (itr++)->as_string(); - const std::string& arg2 = (itr++)->as_string(); - const std::string& arg3 = (itr++)->as_string(); - - control->command_scheduler()->parse(arg1, arg2, arg3, utils::convert_list_to_command(itr, args.end())); - - return torrent::Object(); -} - -void -initialize_variables() { - utils::VariableMap* variables = control->variable(); - - ADD_VARIABLE_BOOL("check_hash", true); - - ADD_VARIABLE_BOOL("handshake_log", false); - ADD_VARIABLE_BOOL("session_lock", true); - ADD_VARIABLE_BOOL("session_on_completion", true); - - ADD_VARIABLE_STRING("tracker_dump", ""); - - variables->insert("session", new utils::VariableStringSlot(rak::mem_fn(control->core()->download_store(), &core::DownloadStore::path), - rak::mem_fn(control->core()->download_store(), &core::DownloadStore::set_path))); - variables->insert("session_save", new utils::VariableVoidSlot(rak::mem_fn(control->core()->download_list(), &core::DownloadList::session_save))); - - ADD_VARIABLE_STRING("directory", "./"); - - variables->insert("http_proxy", new utils::VariableStringSlot(rak::mem_fn(control->core()->get_poll_manager()->get_http_stack(), &core::CurlStack::http_proxy), - rak::mem_fn(control->core()->get_poll_manager()->get_http_stack(), &core::CurlStack::set_http_proxy))); - variables->insert("fast_cgi", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_fast_cgi))); - -// ADD_VARIABLE_VALUE("max_chunks_queued", 0); - variables->insert("max_uploads_global", new utils::VariableValueSlot(rak::mem_fn(control->ui(), &ui::Root::max_uploads_global), - rak::mem_fn(control->ui(), &ui::Root::set_max_uploads_global))); - variables->insert("max_downloads_global", new utils::VariableValueSlot(rak::mem_fn(control->ui(), &ui::Root::max_downloads_global), - rak::mem_fn(control->ui(), &ui::Root::set_max_downloads_global))); - - variables->insert("hash_max_tries", new utils::VariableValueSlot(rak::ptr_fn(&torrent::hash_max_tries), rak::ptr_fn(&torrent::set_hash_max_tries))); - variables->insert("max_open_files", new utils::VariableValueSlot(rak::ptr_fn(&torrent::max_open_files), rak::ptr_fn(&torrent::set_max_open_files))); - variables->insert("max_open_sockets", new utils::VariableValueSlot(rak::mem_fn(torrent::connection_manager(), &torrent::ConnectionManager::max_size), - rak::mem_fn(torrent::connection_manager(), &torrent::ConnectionManager::set_max_size))); - variables->insert("max_open_http", new utils::VariableValueSlot(rak::mem_fn(control->core()->get_poll_manager()->get_http_stack(), &core::CurlStack::max_active), - rak::mem_fn(control->core()->get_poll_manager()->get_http_stack(), &core::CurlStack::set_max_active))); - - variables->insert("import", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_import))); - variables->insert("try_import", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_try_import))); - - ADD_COMMAND_LIST("schedule", rak::ptr_fn(&apply_schedule)); - variables->insert("schedule_remove", new utils::VariableStringSlot(NULL, rak::mem_fn(control->command_scheduler(), &CommandScheduler::erase))); - - variables->insert("download_scheduler", new utils::VariableVoidSlot(rak::mem_fn(control->scheduler(), &core::Scheduler::update))); - - variables->insert("send_buffer_size", new utils::VariableValueSlot(rak::mem_fn(torrent::connection_manager(), &torrent::ConnectionManager::send_buffer_size), - rak::mem_fn(torrent::connection_manager(), &torrent::ConnectionManager::set_send_buffer_size))); - - variables->insert("receive_buffer_size", new utils::VariableValueSlot(rak::mem_fn(torrent::connection_manager(), &torrent::ConnectionManager::receive_buffer_size), - rak::mem_fn(torrent::connection_manager(), &torrent::ConnectionManager::set_receive_buffer_size))); - - variables->insert("hash_read_ahead", new utils::VariableValueSlot(rak::ptr_fn(torrent::hash_read_ahead), rak::ptr_fn(&apply_hash_read_ahead))); - variables->insert("hash_interval", new utils::VariableValueSlot(rak::ptr_fn(torrent::hash_interval), rak::ptr_fn(&apply_hash_interval))); - - variables->insert("umask", new utils::VariableValueSlot(rak::mem_fn(control, &Control::umask), rak::mem_fn(control, &Control::set_umask), 8)); - variables->insert("working_directory", new utils::VariableStringSlot(rak::mem_fn(control, &Control::working_directory), - rak::mem_fn(control, &Control::set_working_directory))); - - variables->insert("load", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_load))); - variables->insert("load_verbose", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_load_verbose))); - variables->insert("load_start", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_load_start))); - variables->insert("load_start_verbose", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_load_start_verbose))); - - variables->insert("close_low_diskspace", new utils::VariableValueSlot(rak::value_fn(int64_t()), rak::ptr_fn(&apply_close_low_diskspace))); - - variables->insert("enable_trackers", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_enable_trackers))); - variables->insert("encoding_list", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_encoding_list))); -} - template utils::Variable* var_d_value(Target target, GetFunc getFunc, SetFunc setFunc) {