From 32039006f588022223bca28daf250273302a3857 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sat, 13 Oct 2012 11:13:17 +0300 Subject: [PATCH] Refactor command handling to library/ --- include/core/command.hpp | 157 +--------- include/library/commands.hpp | 209 ++++++++++++ src/core/advdumper.cpp | 6 +- src/core/bsnes-legacy.cpp | 2 +- src/core/command.cpp | 260 +-------------- src/core/controller.cpp | 6 +- src/core/framebuffer.cpp | 2 +- src/core/framerate.cpp | 6 +- src/core/gambatte.cpp | 4 +- src/core/inthread.cpp | 43 +-- src/core/joystick.cpp | 2 +- src/core/keymapper.cpp | 14 +- src/core/loadlib.cpp | 2 +- src/core/mainloop.cpp | 70 ++--- src/core/memorymanip.cpp | 2 +- src/core/memorywatch.cpp | 4 +- src/core/misc.cpp | 3 + src/core/moviedata.cpp | 14 +- src/core/settings.cpp | 10 +- src/core/subtitles.cpp | 6 +- src/core/window.cpp | 24 +- src/library/commands.cpp | 471 ++++++++++++++++++++++++++++ src/lua/core.cpp | 2 +- src/lua/lua.cpp | 12 +- src/platform/libao/sound.cpp | 2 +- src/platform/portaudio/sound.cpp | 2 +- src/platform/sdl/graphicsfn.cpp | 16 +- src/platform/sdl/main.cpp | 4 +- src/platform/sdl/savesettings.cpp | 4 +- src/platform/wxwidgets/main.cpp | 6 +- src/platform/wxwidgets/settings.cpp | 14 +- src/util/lsnes-dumpavi.cpp | 2 +- 32 files changed, 828 insertions(+), 553 deletions(-) create mode 100644 include/library/commands.hpp create mode 100644 src/library/commands.cpp diff --git a/include/core/command.hpp b/include/core/command.hpp index 3d2abe9e..8c27ac64 100644 --- a/include/core/command.hpp +++ b/include/core/command.hpp @@ -4,161 +4,8 @@ #include #include #include +#include "library/commands.hpp" - -/** - * A command. - */ -class command -{ -public: -/** - * Register a new command. - * - * parameter cmd: The command to register. - * throws std::bad_alloc: Not enough memory. - */ - command(const std::string& cmd) throw(std::bad_alloc); - -/** - * Deregister a command. - */ - virtual ~command() throw(); - -/** - * Invoke a command. - * - * parameter arguments: Arguments to command. - * throws std::bad_alloc: Not enough memory. - * throws std::runtime_error: Command execution failed. - */ - virtual void invoke(const std::string& arguments) throw(std::bad_alloc, std::runtime_error) = 0; - -/** - * Look up and invoke a command. The command will undergo alias expansion and recursion checking. - * - * parameter cmd: Command to exeucte. - */ - static void invokeC(const std::string& cmd) throw(); -/** - * Get set of aliases. - */ - static std::set get_aliases() throw(std::bad_alloc); -/** - * Get alias - */ - static std::string get_alias_for(const std::string& aname) throw(std::bad_alloc); -/** - * Set alias - */ - static void set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc); -/** - * Is alias name valid. - */ - static bool valid_alias_name(const std::string& aname) throw(std::bad_alloc); -/** - * Get short help for command. - */ - virtual std::string get_short_help() throw(std::bad_alloc); - -/** - * Get long help for command. - */ - virtual std::string get_long_help() throw(std::bad_alloc); -private: - command(const command&); - command& operator=(const command&); - std::string commandname; -}; - -/** - * Mandatory filename - */ -struct arg_filename -{ -/** - * The filename itself. - */ - std::string v; -/** - * Return the filename. - * - * returns: The filename. - */ - operator std::string() { return v; } -}; - -/** - * Run command function helper. - * - * parameter fn: Function pointer to invoke. - * parameter a: The arguments to pass. - */ -template -void invoke_command_fn(void (*fn)(args... arguments), const std::string& a); - -/** - * Warp function pointer as command. - */ -template -class function_ptr_command : public command -{ -public: -/** - * Create a new command. - * - * parameter name: Name of the command - * parameter description Description for the command - * parameter help: Help for the command. - * parameter fn: Function to call on command. - */ - function_ptr_command(const std::string& name, const std::string& _description, const std::string& _help, - void (*_fn)(args... arguments)) throw(std::bad_alloc) - : command(name) - { - description = _description; - help = _help; - fn = _fn; - } -/** - * Destroy a commnad. - */ - ~function_ptr_command() throw() - { - } -/** - * Invoke a command. - * - * parameter a: Arguments to function. - */ - void invoke(const std::string& a) throw(std::bad_alloc, std::runtime_error) - { - invoke_command_fn(fn, a); - } -/** - * Get short description. - * - * returns: Description. - * throw std::bad_alloc: Not enough memory. - */ - std::string get_short_help() throw(std::bad_alloc) - { - return description; - } -/** - * Get long help. - * - * returns: help. - * throw std::bad_alloc: Not enough memory. - */ - std::string get_long_help() throw(std::bad_alloc) - { - return help; - } -private: - void (*fn)(args... arguments); - std::string description; - std::string help; -}; +extern command_group lsnes_cmd; #endif diff --git a/include/library/commands.hpp b/include/library/commands.hpp new file mode 100644 index 00000000..bddff25e --- /dev/null +++ b/include/library/commands.hpp @@ -0,0 +1,209 @@ +#ifndef _library_commands__hpp__included__ +#define _library_commands__hpp__included__ + +#include +#include +#include +#include +#include +#include "library/workthread.hpp" + +class command; + +/** + * A group of commands (with aliases). + */ +class command_group +{ +public: +/** + * Create a new command group. This also places some builtin commands in that new group. + */ + command_group() throw(std::bad_alloc); +/** + * Destroy a group. + */ + ~command_group() throw(); +/** + * Look up and invoke a command. The command will undergo alias expansion and recursion checking. + * + * parameter cmd: Command to exeucte. + */ + void invoke(const std::string& cmd) throw(); +/** + * Get set of aliases. + */ + std::set get_aliases() throw(std::bad_alloc); +/** + * Get alias + */ + std::string get_alias_for(const std::string& aname) throw(std::bad_alloc); +/** + * Set alias + */ + void set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc); +/** + * Is alias name valid. + */ + bool valid_alias_name(const std::string& aname) throw(std::bad_alloc); +/** + * Register a command. + */ + void register_command(const std::string& name, command& cmd) throw(std::bad_alloc); +/** + * Unregister a command. + */ + void unregister_command(const std::string& name) throw(std::bad_alloc); +/** + * Set the output stream. + */ + void set_output(std::ostream& s); +/** + * Set the OOM panic routine. + */ + void set_oom_panic(void (*fn)()); +private: + std::map commands; + std::set command_stack; + std::map> aliases; + mutex_class int_mutex; + std::ostream* output; + void (*oom_panic_routine)(); +}; + +/** + * A command. + */ +class command +{ +public: +/** + * Register a new command. + * + * parameter group: The group command will be part of. + * parameter cmd: The command to register. + * throws std::bad_alloc: Not enough memory. + */ + command(command_group& group, const std::string& cmd) throw(std::bad_alloc); + +/** + * Deregister a command. + */ + virtual ~command() throw(); + +/** + * Invoke a command. + * + * parameter arguments: Arguments to command. + * throws std::bad_alloc: Not enough memory. + * throws std::runtime_error: Command execution failed. + */ + virtual void invoke(const std::string& arguments) throw(std::bad_alloc, std::runtime_error) = 0; +/** + * Get short help for command. + */ + virtual std::string get_short_help() throw(std::bad_alloc); + +/** + * Get long help for command. + */ + virtual std::string get_long_help() throw(std::bad_alloc); +private: + command(const command&); + command& operator=(const command&); + std::string commandname; + command_group& in_group; +}; + +/** + * Mandatory filename + */ +struct arg_filename +{ +/** + * The filename itself. + */ + std::string v; +/** + * Return the filename. + * + * returns: The filename. + */ + operator std::string() { return v; } +}; + +/** + * Run command function helper. + * + * parameter fn: Function pointer to invoke. + * parameter a: The arguments to pass. + */ +template +void invoke_command_fn(void (*fn)(args... arguments), const std::string& a); + +/** + * Warp function pointer as command. + */ +template +class function_ptr_command : public command +{ +public: +/** + * Create a new command. + * + * parameter group: The group command will be part of. + * parameter name: Name of the command + * parameter description Description for the command + * parameter help: Help for the command. + * parameter fn: Function to call on command. + */ + function_ptr_command(command_group& group, const std::string& name, const std::string& _description, + const std::string& _help, void (*_fn)(args... arguments)) throw(std::bad_alloc) + : command(group, name) + { + description = _description; + help = _help; + fn = _fn; + } +/** + * Destroy a commnad. + */ + ~function_ptr_command() throw() + { + } +/** + * Invoke a command. + * + * parameter a: Arguments to function. + */ + void invoke(const std::string& a) throw(std::bad_alloc, std::runtime_error) + { + invoke_command_fn(fn, a); + } +/** + * Get short description. + * + * returns: Description. + * throw std::bad_alloc: Not enough memory. + */ + std::string get_short_help() throw(std::bad_alloc) + { + return description; + } +/** + * Get long help. + * + * returns: help. + * throw std::bad_alloc: Not enough memory. + */ + std::string get_long_help() throw(std::bad_alloc) + { + return help; + } +private: + void (*fn)(args... arguments); + std::string description; + std::string help; +}; + +#endif diff --git a/src/core/advdumper.cpp b/src/core/advdumper.cpp index d06b14ed..07e33f25 100644 --- a/src/core/advdumper.cpp +++ b/src/core/advdumper.cpp @@ -21,7 +21,7 @@ namespace throw std::runtime_error("Unknown dumper"); } - function_ptr_command start_dump("start-dump", "Start dumping", + function_ptr_command start_dump(lsnes_cmd, "start-dump", "Start dumping", "Syntax: start-dump \nSyntax: start-dump \n" "Start dumping using in mode to \n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { @@ -41,7 +41,7 @@ namespace d.start(mode, t2); }); - function_ptr_command end_dump("end-dump", "End dumping", + function_ptr_command end_dump(lsnes_cmd, "end-dump", "End dumping", "Syntax: end-dump \nEnd dumping using dumper \n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { auto r = regex("([^ \t]+)[ \t]*", t, "Command syntax error"); @@ -49,7 +49,7 @@ namespace d.end(); }); - function_ptr_command dumpersc("show-dumpers", "Show dumpers", + function_ptr_command dumpersc(lsnes_cmd, "show-dumpers", "Show dumpers", "Syntax: show-dumpers\nSyntax: show-dumpers \nShow dumpers or dumper modes for \n", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { auto a = adv_dumper::get_dumper_set(); diff --git a/src/core/bsnes-legacy.cpp b/src/core/bsnes-legacy.cpp index 63753479..31971f86 100644 --- a/src/core/bsnes-legacy.cpp +++ b/src/core/bsnes-legacy.cpp @@ -1153,7 +1153,7 @@ std::pair core_get_bus_map() return std::make_pair(0x1000000, 0x1000000); } -function_ptr_command dump_core("dump-core", "No description available", +function_ptr_command dump_core(lsnes_cmd, "dump-core", "No description available", "No description available\n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { std::vector out; diff --git a/src/core/command.cpp b/src/core/command.cpp index 0bd459e5..eab3b892 100644 --- a/src/core/command.cpp +++ b/src/core/command.cpp @@ -2,266 +2,8 @@ #include "library/globalwrap.hpp" #include "core/misc.hpp" #include "core/window.hpp" -#include "library/minmax.hpp" -#include "library/string.hpp" -#include "library/zip.hpp" #include #include -namespace -{ - globalwrap> commands; - std::set command_stack; - std::map> aliases; - - //Return the recursive mutex. - mutex& cmlock() - { - static mutex& m = mutex::aquire_rec(); - return m; - } - - class cmlock_hold - { - public: - cmlock_hold() { cmlock().lock(); } - ~cmlock_hold() { cmlock().unlock(); } - private: - cmlock_hold(const cmlock_hold& k); - cmlock_hold& operator=(const cmlock_hold& k); - }; - - - function_ptr_command run_script("run-script", "run file as a script", - "Syntax: run-script \nRuns file just as it would have been entered in the command line\n", - [](arg_filename filename) throw(std::bad_alloc, std::runtime_error) { - std::istream* o = NULL; - try { - o = &open_file_relative(filename, ""); - messages << "Running '" << std::string(filename) << "'" << std::endl; - std::string line; - while(std::getline(*o, line)) - command::invokeC(line); - delete o; - } catch(std::exception& e) { - delete o; - throw; - } - }); - - function_ptr_command<> show_aliases("show-aliases", "show aliases", - "Syntax: show-aliases\nShow expansions of all aliases\n", - []() throw(std::bad_alloc, std::runtime_error) { - cmlock_hold lck; - for(auto i : aliases) - for(auto j : i.second) - messages << "alias " << i.first << " " << j << std::endl; - }); - - function_ptr_command unalias_command("unalias-command", "unalias a command", - "Syntax: unalias-command \nClear expansion of alias \n", - [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { - auto r = regex("([^ \t]+)[ \t]*", t, "This command only takes one argument"); - if(!command::valid_alias_name(r[1])) - throw std::runtime_error("Illegal alias name"); - cmlock_hold lck; - aliases[r[1]].clear(); - messages << "Command '" << r[1] << "' unaliased" << std::endl; - }); - - function_ptr_command alias_command("alias-command", "alias a command", - "Syntax: alias-command \nAppend to expansion of alias \n" - "Valid alias names can't be empty nor start with '*' or '?'\n", - [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { - auto r = regex("([^ \t]+)[ \t]+([^ \t].*)", t, "Alias name and command needed"); - if(!command::valid_alias_name(r[1])) - throw std::runtime_error("Illegal alias name"); - cmlock_hold lck; - aliases[r[1]].push_back(r[2]); - messages << "Command '" << r[1] << "' aliased to '" << r[2] << "'" << std::endl; - }); -} - -command::command(const std::string& cmd) throw(std::bad_alloc) -{ - cmlock_hold lck; - if(commands().count(cmd)) - std::cerr << "WARNING: Command collision for " << cmd << "!" << std::endl; - commands()[commandname = cmd] = this; -} - -command::~command() throw() -{ - cmlock_hold lck; - commands().erase(commandname); -} - -void command::invokeC(const std::string& cmd) throw() -{ - try { - std::string cmd2 = strip_CR(cmd); - if(cmd2 == "?") { - //The special ? command. - cmlock_hold lck; - for(auto i : commands()) - messages << i.first << ": " << i.second->get_short_help() << std::endl; - return; - } - if(firstchar(cmd2) == '?') { - //?command. - cmlock_hold lck; - std::string rcmd = cmd2.substr(1, min(cmd2.find_first_of(" \t"), cmd2.length())); - if(firstchar(rcmd) != '*') { - //This may be an alias. - if(aliases.count(rcmd)) { - //Yup. - messages << rcmd << " is an alias for: " << std::endl; - size_t j = 0; - for(auto i : aliases[rcmd]) - messages << "#" << (++j) << ": " << i << std::endl; - return; - } - } else - rcmd = rcmd.substr(1); - if(!commands().count(rcmd)) - messages << "Unknown command '" << rcmd << "'" << std::endl; - else - messages << commands()[rcmd]->get_long_help() << std::endl; - return; - } - bool may_be_alias_expanded = true; - if(firstchar(cmd2) == '*') { - may_be_alias_expanded = false; - cmd2 = cmd2.substr(1); - } - //Now this gets painful as command handlers must not be invoked with lock held. - if(may_be_alias_expanded) { - std::list aexp; - { - cmlock_hold lck; - if(!aliases.count(cmd)) - goto not_alias; - aexp = aliases[cmd2]; - } - for(auto i : aexp) - invokeC(i); - return; - } -not_alias: - try { - size_t split = cmd2.find_first_of(" \t"); - std::string rcmd = cmd2.substr(0, min(split, cmd2.length())); - std::string args = cmd2.substr(min(cmd2.find_first_not_of(" \t", split), cmd2.length())); - command* cmdh = NULL; - { - cmlock_hold lck; - if(!commands().count(rcmd)) { - messages << "Unknown command '" << rcmd << "'" << std::endl; - return; - } - cmdh = commands()[rcmd]; - } - if(command_stack.count(cmd2)) - throw std::runtime_error("Recursive command invocation"); - command_stack.insert(cmd2); - cmdh->invoke(args); - command_stack.erase(cmd2); - return; - } catch(std::bad_alloc& e) { - OOM_panic(); - } catch(std::exception& e) { - messages << "Error: " << e.what() << std::endl; - command_stack.erase(cmd2); - return; - } - } catch(std::bad_alloc& e) { - OOM_panic(); - } -} - -std::string command::get_short_help() throw(std::bad_alloc) -{ - return "No description available"; -} - -std::string command::get_long_help() throw(std::bad_alloc) -{ - return "No help available on command " + commandname; -} - -std::set command::get_aliases() throw(std::bad_alloc) -{ - cmlock_hold lck; - std::set r; - for(auto i : aliases) - r.insert(i.first); - return r; -} - -std::string command::get_alias_for(const std::string& aname) throw(std::bad_alloc) -{ - cmlock_hold lck; - if(!valid_alias_name(aname)) - return ""; - if(aliases.count(aname)) { - std::string x; - for(auto i : aliases[aname]) - x = x + i + "\n"; - return x; - } else - return ""; -} - -void command::set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc) -{ - cmlock_hold lck; - if(!valid_alias_name(aname)) - return; - std::list newlist; - size_t avitr = 0; - while(avitr < avalue.length()) { - size_t nextsplit = min(avalue.find_first_of("\n", avitr), avalue.length()); - std::string x = strip_CR(avalue.substr(avitr, nextsplit - avitr)); - if(x.length() > 0) - newlist.push_back(x); - avitr = nextsplit + 1; - } - if(newlist.empty()) - aliases.erase(aname); - else - aliases[aname] = newlist; -} - -bool command::valid_alias_name(const std::string& aliasname) throw(std::bad_alloc) -{ - if(aliasname.length() == 0 || aliasname[0] == '?' || aliasname[0] == '*') - return false; - if(aliasname.find_first_of(" \t") < aliasname.length()) - return false; - return true; -} - -template<> -void invoke_command_fn(void (*fn)(const std::string& args), const std::string& args) -{ - fn(args); -} - -template<> -void invoke_command_fn(void (*fn)(), const std::string& args) -{ - if(args != "") - throw std::runtime_error("This command does not take arguments"); - fn(); -} - -template<> -void invoke_command_fn(void (*fn)(struct arg_filename a), const std::string& args) -{ - if(args == "") - throw std::runtime_error("Filename required"); - arg_filename b; - b.v = args; - fn(b); -} +command_group lsnes_cmd; diff --git a/src/core/controller.cpp b/src/core/controller.cpp index e5897a94..83315089 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -82,7 +82,7 @@ namespace controls.analog(pcid.first, pcid.second, x / 2 , y / 2); } - function_ptr_command autofire("autofire", "Set autofire pattern", + function_ptr_command autofire(lsnes_cmd, "autofire", "Set autofire pattern", "Syntax: autofire ...\nSet autofire pattern\n", [](const std::string& a) throw(std::bad_alloc, std::runtime_error) { auto r = regex(".*[^ \t].*", a, "Need at least one frame for autofire"); @@ -129,7 +129,7 @@ namespace public: button_action(const std::string& cmd, int _type, unsigned _controller, std::string _button) throw(std::bad_alloc) - : command(cmd) + : command(lsnes_cmd, cmd) { commandn = cmd; type = _type; @@ -176,7 +176,7 @@ namespace public: analog_action(const std::string& cmd, unsigned _controller) throw(std::bad_alloc) - : command(cmd) + : command(lsnes_cmd, cmd) { controller = _controller; } diff --git a/src/core/framebuffer.cpp b/src/core/framebuffer.cpp index 4bf46531..472842e9 100644 --- a/src/core/framebuffer.cpp +++ b/src/core/framebuffer.cpp @@ -139,7 +139,7 @@ namespace draw_special_screen(target, rl_corrupt); } - function_ptr_command take_screenshot_cmd("take-screenshot", "Takes a screenshot", + function_ptr_command take_screenshot_cmd(lsnes_cmd, "take-screenshot", "Takes a screenshot", "Syntax: take-screenshot \nSaves screenshot to PNG file \n", [](arg_filename file) throw(std::bad_alloc, std::runtime_error) { take_screenshot(file); diff --git a/src/core/framerate.cpp b/src/core/framerate.cpp index 965af5d7..f95bd4e6 100644 --- a/src/core/framerate.cpp +++ b/src/core/framerate.cpp @@ -137,19 +137,19 @@ namespace bool turboed = false; - function_ptr_command<> tturbo("toggle-turbo", "Toggle turbo", + function_ptr_command<> tturbo(lsnes_cmd, "toggle-turbo", "Toggle turbo", "Syntax: toggle-turbo\nToggle turbo mode.\n", []() throw(std::bad_alloc, std::runtime_error) { turboed = !turboed; }); - function_ptr_command<> pturbo("+turbo", "Activate turbo", + function_ptr_command<> pturbo(lsnes_cmd, "+turbo", "Activate turbo", "Syntax: +turbo\nActivate turbo mode.\n", []() throw(std::bad_alloc, std::runtime_error) { turboed = true; }); - function_ptr_command<> nturbo("-turbo", "Deactivate turbo", + function_ptr_command<> nturbo(lsnes_cmd, "-turbo", "Deactivate turbo", "Syntax: -turbo\nDeactivate turbo mode.\n", []() throw(std::bad_alloc, std::runtime_error) { turboed = false; diff --git a/src/core/gambatte.cpp b/src/core/gambatte.cpp index 10f417fa..0b8ef489 100644 --- a/src/core/gambatte.cpp +++ b/src/core/gambatte.cpp @@ -601,13 +601,13 @@ void core_set_poll_flag(unsigned pflag) std::vector cmp_save; -function_ptr_command<> cmp_save1("set-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) { +function_ptr_command<> cmp_save1(lsnes_cmd, "set-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) { if(!internal_rom) return; instance->saveState(cmp_save); }); -function_ptr_command<> cmp_save2("do-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) { +function_ptr_command<> cmp_save2(lsnes_cmd, "do-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) { std::vector x; if(!internal_rom) return; diff --git a/src/core/inthread.cpp b/src/core/inthread.cpp index 1ee62c77..88caced4 100644 --- a/src/core/inthread.cpp +++ b/src/core/inthread.cpp @@ -1297,12 +1297,12 @@ out_parsing: }; //The tangent function. - function_ptr_command<> ptangent("+tangent", "Voice tangent", + function_ptr_command<> ptangent(lsnes_cmd, "+tangent", "Voice tangent", "Syntax: +tangent\nVoice tangent.\n", []() throw(std::bad_alloc, std::runtime_error) { active_flag = true; }); - function_ptr_command<> ntangent("-tangent", "Voice tangent", + function_ptr_command<> ntangent(lsnes_cmd, "-tangent", "Voice tangent", "Syntax: -tangent\nVoice tangent.\n", []() throw(std::bad_alloc, std::runtime_error) { active_flag = false; @@ -1339,7 +1339,8 @@ uint64_t voicesub_parse_timebase(const std::string& n) namespace { - function_ptr_command<> list_streams("list-streams", "List streams ", "list-streams\nList known voice streams", + function_ptr_command<> list_streams(lsnes_cmd, "list-streams", "List streams ", "list-streams\n" + "List known voice streams", []() throw(std::bad_alloc, std::runtime_error) { umutex_class m2(current_collection_lock); if(!current_collection) { @@ -1359,7 +1360,7 @@ namespace messages << "-----------------------" << std::endl; }); - function_ptr_command delete_stream("delete-stream", "Delete a stream", + function_ptr_command delete_stream(lsnes_cmd, "delete-stream", "Delete a stream", "delete-stream \nDelete a voice stream with given ID.", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { umutex_class m2(current_collection_lock); @@ -1378,8 +1379,8 @@ namespace messages << "Deleted stream #" << id << "." << std::endl; }); - function_ptr_command play_stream("play-stream", "Play a stream", "play-stream \n" - "Play a voice stream with given ID.", + function_ptr_command play_stream(lsnes_cmd, "play-stream", "Play a stream", + "play-stream \nPlay a voice stream with given ID.", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { umutex_class m2(current_collection_lock); uint64_t id = parse_value(x); @@ -1402,8 +1403,8 @@ namespace messages << "Playing stream #" << id << "." << std::endl; }); - function_ptr_command change_timebase("change-timebase", "Change stream timebase", - "change-timebase \nChange timebase of given stream", + function_ptr_command change_timebase(lsnes_cmd, "change-timebase", + "Change stream timebase", "change-timebase \nChange timebase of given stream", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { umutex_class m2(current_collection_lock); if(!current_collection) { @@ -1459,15 +1460,16 @@ namespace messages << "Imported stream (" << st->length() / 48000.0 << "s) as ID #" << id << std::endl; } - function_ptr_command import_stream_c("import-stream-opus", "Import a opus stream", - "import-stream-opus \nImport opus stream from , starting at " + function_ptr_command import_stream_c(lsnes_cmd, "import-stream-opus", "Import a opus " + "stream", "import-stream-opus \nImport opus stream from , starting at " "", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { import_cmd_common(x, "opus", true); }); - function_ptr_command import_stream_p("import-stream-pcm", "Import a PCM stream", - "import-stream-pcm \nImport PCM stream from , starting at ", + function_ptr_command import_stream_p(lsnes_cmd, "import-stream-pcm", "Import a PCM " + "stream", "import-stream-pcm \nImport PCM stream from , starting at " + "", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { import_cmd_common(x, "pcm", false); }); @@ -1505,19 +1507,19 @@ namespace st->put_ref(); } - function_ptr_command export_stream_c("export-stream-opus", "Export a opus stream", - "export-stream-opus \nExport opus stream to ", + function_ptr_command export_stream_c(lsnes_cmd, "export-stream-opus", "Export a opus " + "stream", "export-stream-opus \nExport opus stream to ", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { export_cmd_common(x, "opus", true); }); - function_ptr_command export_stream_p("export-stream-pcm", "Export a PCM stream", - "export-stream-pcm \nExport PCM stream to ", + function_ptr_command export_stream_p(lsnes_cmd, "export-stream-pcm", + "Export a PCM stream", "export-stream-pcm \nExport PCM stream to ", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { export_cmd_common(x, "pcm", false); }); - function_ptr_command export_sstream("export-superstream", "Export superstream", + function_ptr_command export_sstream(lsnes_cmd, "export-superstream", "Export superstream", "export-superstream \nExport PCM superstream to ", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { umutex_class m2(current_collection_lock); @@ -1532,8 +1534,9 @@ namespace messages << "Superstream exported." << std::endl; }); - function_ptr_command load_collection("load-collection", "Load voice subtitling " - "collection", "load-collection \nLoad voice subtitling collection from ", + function_ptr_command load_collection(lsnes_cmd, "load-collection", + "Load voice subtitling collection", "load-collection \nLoad voice subtitling collection " + "from ", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { umutex_class m2(current_collection_lock); filesystem_ref newfs; @@ -1551,7 +1554,7 @@ namespace messages << "Loaded '" << x << "'" << std::endl; }); - function_ptr_command<> unload_collection("unload-collection", "Unload voice subtitling collection", + function_ptr_command<> unload_collection(lsnes_cmd, "unload-collection", "Unload voice subtitling collection", "unload-collection\nUnload voice subtitling collection", []() throw(std::bad_alloc, std::runtime_error) { umutex_class m2(current_collection_lock); diff --git a/src/core/joystick.cpp b/src/core/joystick.cpp index 31854876..c92726d9 100644 --- a/src/core/joystick.cpp +++ b/src/core/joystick.cpp @@ -15,7 +15,7 @@ namespace std::map, keygroup*> hats; unsigned joystick_count = 0; - function_ptr_command<> show_joysticks("show-joysticks", "Show joysticks", + function_ptr_command<> show_joysticks(lsnes_cmd, "show-joysticks", "Show joysticks", "Syntax: show-joysticks\nShow joystick data.\n", []() throw(std::bad_alloc, std::runtime_error) { messages << "Driver: " << joystick_plugin::name << std::endl; diff --git a/src/core/keymapper.cpp b/src/core/keymapper.cpp index bd69673a..2228a15b 100644 --- a/src/core/keymapper.cpp +++ b/src/core/keymapper.cpp @@ -18,7 +18,7 @@ namespace { - function_ptr_command bind_key("bind-key", "Bind a (pseudo-)key", + function_ptr_command bind_key(lsnes_cmd, "bind-key", "Bind a (pseudo-)key", "Syntax: bind-key [/] \nBind command to specified key (with specified " " modifiers)\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { @@ -30,7 +30,7 @@ namespace messages << r[4] << " bound to '" << r[5] << "'" << std::endl; }); - function_ptr_command unbind_key("unbind-key", "Unbind a (pseudo-)key", + function_ptr_command unbind_key(lsnes_cmd, "unbind-key", "Unbind a (pseudo-)key", "Syntax: unbind-key [/] \nUnbind specified key (with specified modifiers)\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { auto r = regex("(([^ /\t]*)/([^ /\t]*)[ \t]+)?([^ \t]+)[ \t]*", t, "Key required"); @@ -40,13 +40,13 @@ namespace messages << r[4] << " unbound" << std::endl; }); - function_ptr_command<> show_bindings("show-bindings", "Show active bindings", + function_ptr_command<> show_bindings(lsnes_cmd, "show-bindings", "Show active bindings", "Syntax: show-bindings\nShow bindings that are currently active.\n", []() throw(std::bad_alloc, std::runtime_error) { keymapper::dumpbindings(); }); - function_ptr_command<> show_inverse("show-inverse", "Show inverse bindings", + function_ptr_command<> show_inverse(lsnes_cmd, "show-inverse", "Show inverse bindings", "Syntax: show-inverse\nShow inversebindings that are currently active.\n", []() throw(std::bad_alloc, std::runtime_error) { for(auto i : inverse_key::get_ikeys()) @@ -604,7 +604,7 @@ signed keygroup::get_value() namespace { - function_ptr_command set_axis("set-axis", "Set mode of Joystick axis", + function_ptr_command set_axis(lsnes_cmd, "set-axis", "Set mode of Joystick axis", "Syntax: set-axis ...\nKnown options: disabled, axis, axis-inverse, pressure0-\n" "pressure0+, pressure-0, pressure-+, pressure+0, pressure+-\nminus=, zero=, plus=\n" "tolerance=\n", @@ -684,7 +684,7 @@ namespace keygroups()[r[1]]->change_calibration(p.cal_left, p.cal_center, p.cal_right, p.cal_tolerance); }); - function_ptr_command<> set_axismode("show-axes", "Show all joystick axes", + function_ptr_command<> set_axismode(lsnes_cmd, "show-axes", "Show all joystick axes", "Syntax: show-axes\n", []() throw(std::bad_alloc, std::runtime_error) { for(auto i = keygroups().begin(); i != keygroups().end(); ++i) { @@ -753,7 +753,7 @@ namespace std::string cmd = fixup_command_polarity(command, polarity); if(cmd == "") return; - command::invokeC(cmd); + lsnes_cmd.invoke(cmd); } }; diff --git a/src/core/loadlib.cpp b/src/core/loadlib.cpp index d1ddec58..655557ac 100644 --- a/src/core/loadlib.cpp +++ b/src/core/loadlib.cpp @@ -4,7 +4,7 @@ #include namespace { - function_ptr_command load_lib("load-library", "Load a library", + function_ptr_command load_lib(lsnes_cmd, "load-library", "Load a library", "Syntax: load-library \nLoad library \n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { try { diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index 4f8e9482..af4b8a0a 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -369,7 +369,7 @@ namespace } } _jukebox_size_listener; - function_ptr_command<> count_rerecords("count-rerecords", "Count rerecords", + function_ptr_command<> count_rerecords(lsnes_cmd, "count-rerecords", "Count rerecords", "Syntax: count-rerecords\nCounts rerecords.\n", []() throw(std::bad_alloc, std::runtime_error) { std::vector tmp; @@ -377,7 +377,7 @@ namespace messages << x << " rerecord(s)" << std::endl; }); - function_ptr_command quit_emulator("quit-emulator", "Quit the emulator", + function_ptr_command quit_emulator(lsnes_cmd, "quit-emulator", "Quit the emulator", "Syntax: quit-emulator [/y]\nQuits emulator (/y => don't ask for confirmation).\n", [](const std::string& args) throw(std::bad_alloc, std::runtime_error) { amode = ADVANCE_QUIT; @@ -385,7 +385,7 @@ namespace platform::cancel_wait(); }); - function_ptr_command<> unpause_emulator("unpause-emulator", "Unpause the emulator", + function_ptr_command<> unpause_emulator(lsnes_cmd, "unpause-emulator", "Unpause the emulator", "Syntax: unpause-emulator\nUnpauses the emulator.\n", []() throw(std::bad_alloc, std::runtime_error) { amode = ADVANCE_AUTO; @@ -394,7 +394,7 @@ namespace messages << "Unpaused" << std::endl; }); - function_ptr_command<> pause_emulator("pause-emulator", "(Un)pause the emulator", + function_ptr_command<> pause_emulator(lsnes_cmd, "pause-emulator", "(Un)pause the emulator", "Syntax: pause-emulator\n(Un)pauses the emulator.\n", []() throw(std::bad_alloc, std::runtime_error) { if(amode != ADVANCE_AUTO) { @@ -410,7 +410,7 @@ namespace } }); - function_ptr_command<> save_jukebox_prev("cycle-jukebox-backward", "Cycle save jukebox backwards", + function_ptr_command<> save_jukebox_prev(lsnes_cmd, "cycle-jukebox-backward", "Cycle save jukebox backwards", "Syntax: cycle-jukebox-backward\nCycle save jukebox backwards\n", []() throw(std::bad_alloc, std::runtime_error) { if(jukebox_size == 0) @@ -425,7 +425,7 @@ namespace information_dispatch::do_status_update(); }); - function_ptr_command<> save_jukebox_next("cycle-jukebox-forward", "Cycle save jukebox forwards", + function_ptr_command<> save_jukebox_next(lsnes_cmd, "cycle-jukebox-forward", "Cycle save jukebox forwards", "Syntax: cycle-jukebox-forward\nCycle save jukebox forwards\n", []() throw(std::bad_alloc, std::runtime_error) { if(jukebox_size == 0) @@ -440,7 +440,7 @@ namespace information_dispatch::do_status_update(); }); - function_ptr_command<> load_jukebox("load-jukebox", "Load save from jukebox", + function_ptr_command<> load_jukebox(lsnes_cmd, "load-jukebox", "Load save from jukebox", "Syntax: load-jukebox\nLoad save from jukebox\n", []() throw(std::bad_alloc, std::runtime_error) { if(jukebox_size == 0) @@ -448,7 +448,7 @@ namespace mark_pending_load(save_jukebox_name(save_jukebox_pointer), LOAD_STATE_CURRENT); }); - function_ptr_command<> save_jukebox_c("save-jukebox", "Save save to jukebox", + function_ptr_command<> save_jukebox_c(lsnes_cmd, "save-jukebox", "Save save to jukebox", "Syntax: save-jukebox\nSave save to jukebox\n", []() throw(std::bad_alloc, std::runtime_error) { if(jukebox_size == 0) @@ -456,7 +456,7 @@ namespace mark_pending_save(save_jukebox_name(save_jukebox_pointer), SAVE_STATE); }); - function_ptr_command<> padvance_frame("+advance-frame", "Advance one frame", + function_ptr_command<> padvance_frame(lsnes_cmd, "+advance-frame", "Advance one frame", "Syntax: +advance-frame\nAdvances the emulation by one frame.\n", []() throw(std::bad_alloc, std::runtime_error) { amode = ADVANCE_FRAME; @@ -466,7 +466,7 @@ namespace platform::set_paused(false); }); - function_ptr_command<> nadvance_frame("-advance-frame", "Advance one frame", + function_ptr_command<> nadvance_frame(lsnes_cmd, "-advance-frame", "Advance one frame", "No help available\n", []() throw(std::bad_alloc, std::runtime_error) { cancel_advance = true; @@ -474,7 +474,7 @@ namespace platform::set_paused(false); }); - function_ptr_command<> padvance_poll("+advance-poll", "Advance one subframe", + function_ptr_command<> padvance_poll(lsnes_cmd, "+advance-poll", "Advance one subframe", "Syntax: +advance-poll\nAdvances the emulation by one subframe.\n", []() throw(std::bad_alloc, std::runtime_error) { amode = ADVANCE_SUBFRAME; @@ -484,7 +484,7 @@ namespace platform::set_paused(false); }); - function_ptr_command<> nadvance_poll("-advance-poll", "Advance one subframe", + function_ptr_command<> nadvance_poll(lsnes_cmd, "-advance-poll", "Advance one subframe", "No help available\n", []() throw(std::bad_alloc, std::runtime_error) { cancel_advance = true; @@ -492,7 +492,7 @@ namespace platform::set_paused(false); }); - function_ptr_command<> advance_skiplag("advance-skiplag", "Skip to next poll", + function_ptr_command<> advance_skiplag(lsnes_cmd, "advance-skiplag", "Skip to next poll", "Syntax: advance-skiplag\nAdvances the emulation to the next poll.\n", []() throw(std::bad_alloc, std::runtime_error) { amode = ADVANCE_SKIPLAG_PENDING; @@ -500,7 +500,7 @@ namespace platform::set_paused(false); }); - function_ptr_command reset_c("reset", "Reset the SNES", + function_ptr_command reset_c(lsnes_cmd, "reset", "Reset the SNES", "Syntax: reset\nReset \nResets the SNES in beginning of the next frame.\n", [](const std::string& x) throw(std::bad_alloc, std::runtime_error) { if(x == "") @@ -509,56 +509,56 @@ namespace pending_reset_cycles = parse_value(x); }); - function_ptr_command load_c("load", "Load savestate (current mode)", + function_ptr_command load_c(lsnes_cmd, "load", "Load savestate (current mode)", "Syntax: load \nLoads SNES state from in current mode\n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { mark_pending_load(args, LOAD_STATE_CURRENT); }); - function_ptr_command load_smart_c("load-smart", "Load savestate (heuristic mode)", + function_ptr_command load_smart_c(lsnes_cmd, "load-smart", "Load savestate (heuristic mode)", "Syntax: load \nLoads SNES state from in heuristic mode\n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { mark_pending_load(args, LOAD_STATE_DEFAULT); }); - function_ptr_command load_state_c("load-state", "Load savestate (R/W)", + function_ptr_command load_state_c(lsnes_cmd, "load-state", "Load savestate (R/W)", "Syntax: load-state \nLoads SNES state from in Read/Write mode\n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { mark_pending_load(args, LOAD_STATE_RW); }); - function_ptr_command load_readonly("load-readonly", "Load savestate (RO)", + function_ptr_command load_readonly(lsnes_cmd, "load-readonly", "Load savestate (RO)", "Syntax: load-readonly \nLoads SNES state from in read-only mode\n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { mark_pending_load(args, LOAD_STATE_RO); }); - function_ptr_command load_preserve("load-preserve", "Load savestate (preserve input)", - "Syntax: load-preserve \nLoads SNES state from preserving input\n", + function_ptr_command load_preserve(lsnes_cmd, "load-preserve", "Load savestate (preserve " + "input)", "Syntax: load-preserve \nLoads SNES state from preserving input\n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { mark_pending_load(args, LOAD_STATE_PRESERVE); }); - function_ptr_command load_movie_c("load-movie", "Load movie", + function_ptr_command load_movie_c(lsnes_cmd, "load-movie", "Load movie", "Syntax: load-movie \nLoads SNES movie from \n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { mark_pending_load(args, LOAD_STATE_MOVIE); }); - function_ptr_command save_state("save-state", "Save state", + function_ptr_command save_state(lsnes_cmd, "save-state", "Save state", "Syntax: save-state \nSaves SNES state to \n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { mark_pending_save(args, SAVE_STATE); }); - function_ptr_command save_movie("save-movie", "Save movie", + function_ptr_command save_movie(lsnes_cmd, "save-movie", "Save movie", "Syntax: save-movie \nSaves SNES movie to \n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { mark_pending_save(args, SAVE_MOVIE); }); - function_ptr_command<> set_rwmode("set-rwmode", "Switch to read/write mode", + function_ptr_command<> set_rwmode(lsnes_cmd, "set-rwmode", "Switch to read/write mode", "Syntax: set-rwmode\nSwitches to read/write mode\n", []() throw(std::bad_alloc, std::runtime_error) { movb.get_movie().readonly_mode(false); @@ -568,7 +568,7 @@ namespace information_dispatch::do_status_update(); }); - function_ptr_command<> set_romode("set-romode", "Switch to read-only mode", + function_ptr_command<> set_romode(lsnes_cmd, "set-romode", "Switch to read-only mode", "Syntax: set-romode\nSwitches to read-only mode\n", []() throw(std::bad_alloc, std::runtime_error) { movb.get_movie().readonly_mode(true); @@ -577,7 +577,7 @@ namespace information_dispatch::do_status_update(); }); - function_ptr_command<> toggle_rwmode("toggle-rwmode", "Toggle read/write mode", + function_ptr_command<> toggle_rwmode(lsnes_cmd, "toggle-rwmode", "Toggle read/write mode", "Syntax: toggle-rwmode\nToggles read/write mode\n", []() throw(std::bad_alloc, std::runtime_error) { bool c = movb.get_movie().readonly_mode(); @@ -589,50 +589,50 @@ namespace information_dispatch::do_status_update(); }); - function_ptr_command<> repaint("repaint", "Redraw the screen", + function_ptr_command<> repaint(lsnes_cmd, "repaint", "Redraw the screen", "Syntax: repaint\nRedraws the screen\n", []() throw(std::bad_alloc, std::runtime_error) { redraw_framebuffer(); }); - function_ptr_command<> tpon("toggle-pause-on-end", "Toggle pause on end", "Toggle pause on end\n", + function_ptr_command<> tpon(lsnes_cmd, "toggle-pause-on-end", "Toggle pause on end", "Toggle pause on end\n", []() throw(std::bad_alloc, std::runtime_error) { bool newstate = !static_cast(pause_on_end); pause_on_end.set(newstate ? "1" : "0"); messages << "Pause-on-end is now " << (newstate ? "ON" : "OFF") << std::endl; }); - function_ptr_command<> rewind_movie("rewind-movie", "Rewind movie to the beginning", + function_ptr_command<> rewind_movie(lsnes_cmd, "rewind-movie", "Rewind movie to the beginning", "Syntax: rewind-movie\nRewind movie to the beginning\n", []() throw(std::bad_alloc, std::runtime_error) { mark_pending_load("SOME NONBLANK NAME", LOAD_STATE_BEGINNING); }); - function_ptr_command reload_rom2("reload-rom", "Reload the ROM image", + function_ptr_command reload_rom2(lsnes_cmd, "reload-rom", "Reload the ROM image", "Syntax: reload-rom []\nReload the ROM image from \n", [](const std::string& filename) throw(std::bad_alloc, std::runtime_error) { if(reload_rom(filename)) mark_pending_load("SOME NONBLANK NAME", LOAD_STATE_ROMRELOAD); }); - function_ptr_command<> cancel_save("cancel-saves", "Cancel all pending saves", "Syntax: cancel-save\n" - "Cancel pending saves\n", + function_ptr_command<> cancel_save(lsnes_cmd, "cancel-saves", "Cancel all pending saves", "Syntax: " + "cancel-save\nCancel pending saves\n", []() throw(std::bad_alloc, std::runtime_error) { queued_saves.clear(); messages << "Pending saves canceled." << std::endl; }); - function_ptr_command<> test1("test-1", "no description available", "No help available\n", + function_ptr_command<> test1(lsnes_cmd, "test-1", "no description available", "No help available\n", []() throw(std::bad_alloc, std::runtime_error) { redraw_framebuffer(screen_nosignal); }); - function_ptr_command<> test2("test-2", "no description available", "No help available\n", + function_ptr_command<> test2(lsnes_cmd, "test-2", "no description available", "No help available\n", []() throw(std::bad_alloc, std::runtime_error) { redraw_framebuffer(screen_corrupt); }); - function_ptr_command<> test3("test-3", "no description available", "No help available\n", + function_ptr_command<> test3(lsnes_cmd, "test-3", "no description available", "No help available\n", []() throw(std::bad_alloc, std::runtime_error) { while(1); }); diff --git a/src/core/memorymanip.cpp b/src/core/memorymanip.cpp index 6dc8ed0b..8237fa32 100644 --- a/src/core/memorymanip.cpp +++ b/src/core/memorymanip.cpp @@ -971,7 +971,7 @@ namespace { public: memorymanip_command(const std::string& cmd) throw(std::bad_alloc) - : command(cmd) + : command(lsnes_cmd, cmd) { _command = cmd; } diff --git a/src/core/memorywatch.cpp b/src/core/memorywatch.cpp index 44785a11..1fa9b530 100644 --- a/src/core/memorywatch.cpp +++ b/src/core/memorywatch.cpp @@ -400,14 +400,14 @@ void do_watch_memory() namespace { - function_ptr_command add_watch("add-watch", "Add a memory watch", + function_ptr_command add_watch(lsnes_cmd, "add-watch", "Add a memory watch", "Syntax: add-watch \nAdds a new memory watch\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { auto r = regex("([^ \t]+)[ \t]+(|[^ \t].*)", t, "Name and expression required."); set_watchexpr_for(r[1], r[2]); }); - function_ptr_command remove_watch("remove-watch", "Remove a memory watch", + function_ptr_command remove_watch(lsnes_cmd, "remove-watch", "Remove a memory watch", "Syntax: remove-watch \nRemoves a memory watch\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { auto r = regex("([^ \t]+)[ \t]*", t, "Name required."); diff --git a/src/core/misc.cpp b/src/core/misc.cpp index 42960599..e046a560 100644 --- a/src/core/misc.cpp +++ b/src/core/misc.cpp @@ -1,5 +1,6 @@ #include "lsnes.hpp" +#include "core/command.hpp" #include "core/memorymanip.hpp" #include "core/misc.hpp" #include "core/rom.hpp" @@ -243,6 +244,8 @@ void reached_main() { reached_main_flag = true; init_threaded_malloc(); + lsnes_cmd.set_oom_panic(OOM_panic); + lsnes_cmd.set_output(_messages()); } std::string bsnes_core_version; diff --git a/src/core/moviedata.cpp b/src/core/moviedata.cpp index 63de9289..769e004d 100644 --- a/src/core/moviedata.cpp +++ b/src/core/moviedata.cpp @@ -98,20 +98,20 @@ namespace } } mprefix; - function_ptr_command<> get_gamename("get-gamename", "Get the game name", + function_ptr_command<> get_gamename(lsnes_cmd, "get-gamename", "Get the game name", "Syntax: get-gamename\nPrints the game name\n", []() throw(std::bad_alloc, std::runtime_error) { messages << "Game name is '" << our_movie.gamename << "'" << std::endl; }); - function_ptr_command set_gamename("set-gamename", "Set the game name", + function_ptr_command set_gamename(lsnes_cmd, "set-gamename", "Set the game name", "Syntax: set-gamename \nSets the game name to \n", [](const std::string& args) throw(std::bad_alloc, std::runtime_error) { our_movie.gamename = args; messages << "Game name changed to '" << our_movie.gamename << "'" << std::endl; }); - function_ptr_command<> show_authors("show-authors", "Show the run authors", + function_ptr_command<> show_authors(lsnes_cmd, "show-authors", "Show the run authors", "Syntax: show-authors\nShows the run authors\n", []() throw(std::bad_alloc, std::runtime_error) { @@ -122,7 +122,7 @@ namespace messages << "End of authors list" << std::endl; }); - function_ptr_command add_author("add-author", "Add an author", + function_ptr_command add_author(lsnes_cmd, "add-author", "Add an author", "Syntax: add-author \nSyntax: add-author |\n" "Syntax: add-author |\nAdds a new author\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { @@ -131,7 +131,7 @@ namespace messages << (our_movie.authors.size() - 1) << ": " << g.first << "|" << g.second << std::endl; }); - function_ptr_command remove_author("remove-author", "Remove an author", + function_ptr_command remove_author(lsnes_cmd, "remove-author", "Remove an author", "Syntax: remove-author \nRemoves author with ID \n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { uint64_t index = parse_value(t); @@ -140,7 +140,7 @@ namespace our_movie.authors.erase(our_movie.authors.begin() + index); }); - function_ptr_command edit_author("edit-author", "Edit an author", + function_ptr_command edit_author(lsnes_cmd, "edit-author", "Edit an author", "Syntax: edit-author \nSyntax: edit-author |\n" "Syntax: edit-author |\nEdits author name\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { @@ -152,7 +152,7 @@ namespace our_movie.authors[index] = g; }); - function_ptr_command dump_coresave("dump-coresave", "Dump bsnes core state", + function_ptr_command dump_coresave(lsnes_cmd, "dump-coresave", "Dump bsnes core state", "Syntax: dump-coresave \nDumps core save to \n", [](const std::string& name) throw(std::bad_alloc, std::runtime_error) { auto x = save_core_state(); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 17b342a4..df761a06 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -13,7 +13,7 @@ namespace { globalwrap> settings; - function_ptr_command set_setting("set-setting", "set a setting", + function_ptr_command set_setting(lsnes_cmd, "set-setting", "set a setting", "Syntax: set-setting []\nSet setting to a new value. Omit to set to ''\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { auto r = regex("([^ \t]+)([ \t]+(|[^ \t].*))?", t, "Setting name required."); @@ -21,7 +21,7 @@ namespace messages << "Setting '" << r[1] << "' set to '" << r[3] << "'" << std::endl; }); - function_ptr_command unset_setting("unset-setting", "unset a setting", + function_ptr_command unset_setting(lsnes_cmd, "unset-setting", "unset a setting", "Syntax: unset-setting \nTry to unset a setting. Note that not all settings can be unset\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { auto r = regex("([^ \t]+)[ \t]*", t, "Expected setting name and nothing else"); @@ -29,7 +29,7 @@ namespace messages << "Setting '" << r[1] << "' unset" << std::endl; }); - function_ptr_command get_command("get-setting", "get value of a setting", + function_ptr_command get_command(lsnes_cmd, "get-setting", "get value of a setting", "Syntax: get-setting \nShow value of setting\n", [](const std::string& t) throw(std::bad_alloc, std::runtime_error) { auto r = regex("([^ \t]+)[ \t]*", t, "Expected setting name and nothing else"); @@ -40,7 +40,7 @@ namespace messages << "Setting '" << r[1] << "' is unset" << std::endl; }); - function_ptr_command<> show_settings("show-settings", "Show values of all settings", + function_ptr_command<> show_settings(lsnes_cmd, "show-settings", "Show values of all settings", "Syntax: show-settings\nShow value of all settings\n", []() throw(std::bad_alloc, std::runtime_error) { for(auto i : setting::get_settings_set()) { @@ -311,4 +311,4 @@ path_setting::operator std::string() { lock_holder lck(this); return path; -} \ No newline at end of file +} diff --git a/src/core/subtitles.cpp b/src/core/subtitles.cpp index 29a4f678..4893e227 100644 --- a/src/core/subtitles.cpp +++ b/src/core/subtitles.cpp @@ -96,7 +96,7 @@ namespace }; - function_ptr_command edit_subtitle("edit-subtitle", "Edit a subtitle", + function_ptr_command edit_subtitle(lsnes_cmd, "edit-subtitle", "Edit a subtitle", "Syntax: edit-subtitle \nAdd/Edit subtitle\n" "Syntax: edit-subtitle \nADelete subtitle\n", [](const std::string& args) throw(std::bad_alloc, std::runtime_error) { @@ -111,7 +111,7 @@ namespace our_movie.subtitles[key] = s_unescape(text); }); - function_ptr_command<> list_subtitle("list-subtitle", "List the subtitles", + function_ptr_command<> list_subtitle(lsnes_cmd, "list-subtitle", "List the subtitles", "Syntax: list-subtitle\nList the subtitles.\n", []() throw(std::bad_alloc, std::runtime_error) { for(auto i = our_movie.subtitles.rbegin(); i != our_movie.subtitles.rend(); i++) { @@ -120,7 +120,7 @@ namespace } }); - function_ptr_command save_s("save-subtitle", "Save subtitles in .sub format", + function_ptr_command save_s(lsnes_cmd, "save-subtitle", "Save subtitles in .sub format", "Syntax: save-subtitle \nSaves subtitles in .sub format to \n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { if(our_movie.subtitles.empty()) diff --git a/src/core/window.cpp b/src/core/window.cpp index 48eccea4..eaaa3877 100644 --- a/src/core/window.cpp +++ b/src/core/window.cpp @@ -127,7 +127,7 @@ namespace { bool queue_function_run = false; - function_ptr_command<> identify_key("show-plugins", "Show plugins in use", + function_ptr_command<> identify_key(lsnes_cmd, "show-plugins", "Show plugins in use", "Syntax: show-plugins\nShows plugins in use.\n", []() throw(std::bad_alloc, std::runtime_error) { messages << "Graphics:\t" << graphics_plugin::name << std::endl; @@ -135,7 +135,7 @@ namespace messages << "Joystick:\t" << joystick_plugin::name << std::endl; }); - function_ptr_command enable_sound("enable-sound", "Enable/Disable sound", + function_ptr_command enable_sound(lsnes_cmd, "enable-sound", "Enable/Disable sound", "Syntax: enable-sound \nEnable or disable sound.\n", [](const std::string& args) throw(std::bad_alloc, std::runtime_error) { switch(string_to_bool(args)) { @@ -156,7 +156,7 @@ namespace inverse_key ienable_sound("enable-sound on", "Sound‣Enable"); inverse_key idisable_sound("enable-sound off", "Sound‣Disable"); - function_ptr_command set_sound_device("set-sound-device", "Set sound device", + function_ptr_command set_sound_device(lsnes_cmd, "set-sound-device", "Set sound device", "Syntax: set-sound-device \nSet sound device to .\n", [](const std::string& args) throw(std::bad_alloc, std::runtime_error) { if(!audioapi_driver_initialized()) @@ -164,7 +164,7 @@ namespace platform::set_sound_device(args); }); - function_ptr_command<> get_sound_devices("show-sound-devices", "Show sound devices", + function_ptr_command<> get_sound_devices(lsnes_cmd, "show-sound-devices", "Show sound devices", "Syntax: show-sound-devices\nShow listing of available sound devices\n", []() throw(std::bad_alloc, std::runtime_error) { if(!audioapi_driver_initialized()) @@ -181,7 +181,7 @@ namespace << dname << ")" << std::endl; }); - function_ptr_command<> get_sound_status("show-sound-status", "Show sound status", + function_ptr_command<> get_sound_status(lsnes_cmd, "show-sound-status", "Show sound status", "Syntax: show-sound-status\nShow current sound status\n", []() throw(std::bad_alloc, std::runtime_error) { messages << "Sound plugin: " << audioapi_driver_name << std::endl; @@ -197,7 +197,7 @@ namespace } }); - function_ptr_command set_volume("set-volume", "Set sound volume", + function_ptr_command set_volume(lsnes_cmd, "set-volume", "Set sound volume", "Syntax: set-volume \nset-volume %\nset-volume dB\nSet sound volume\n", [](const std::string& value) throw(std::bad_alloc, std::runtime_error) { regex_results r; @@ -215,8 +215,8 @@ namespace audioapi_music_volume(parsed); }); - function_ptr_command set_volume2("set-voice-volume", "Set voice playback volume", - "Syntax: set-voice-volume \nset-voice-volume %\nset-voice-volume dB\n" + function_ptr_command set_volume2(lsnes_cmd, "set-voice-volume", "Set voice playback " + "volume", "Syntax: set-voice-volume \nset-voice-volume %\nset-voice-volume dB\n" "Set voice volume\n", [](const std::string& value) throw(std::bad_alloc, std::runtime_error) { regex_results r; @@ -234,9 +234,9 @@ namespace audioapi_voicep_volume(parsed); }); - function_ptr_command set_volume3("set-record-volume", "Set voice record volume", - "Syntax: set-record-volume \nset-record-volume %\nset-record-volume dB\n" - "Set record volume\n", + function_ptr_command set_volume3(lsnes_cmd, "set-record-volume", "Set voice record " + "volume", "Syntax: set-record-volume \nset-record-volume %\nset-record-volume " + "dB\nSet record volume\n", [](const std::string& value) throw(std::bad_alloc, std::runtime_error) { regex_results r; double parsed = 1; @@ -457,7 +457,7 @@ namespace std::string c = commands.front(); commands.pop_front(); queue_lock->unlock(); - command::invokeC(c); + lsnes_cmd.invoke(c); queue_lock->lock(); queue_function_run = true; } diff --git a/src/library/commands.cpp b/src/library/commands.cpp new file mode 100644 index 00000000..525693cb --- /dev/null +++ b/src/library/commands.cpp @@ -0,0 +1,471 @@ +#include "library/commands.hpp" +#include "library/globalwrap.hpp" +#include "library/minmax.hpp" +#include "library/string.hpp" +#include "library/zip.hpp" +#include +#include + +namespace +{ + struct run_script : public command + { + run_script(command_group& group, std::ostream*& _output) + : command(group, "run-script"), in_group(group), output(_output) + { + } + + ~run_script() throw() + { + } + + void invoke(const std::string& filename) throw(std::bad_alloc, std::runtime_error) + { + if(filename == "") { + (*output) << "Syntax: run-script " << std::endl; + return; + } + std::istream* o = NULL; + try { + o = &open_file_relative(filename, ""); + (*output) << "Running '" << std::string(filename) << "'" << std::endl; + std::string line; + while(std::getline(*o, line)) + in_group.invoke(line); + delete o; + } catch(std::exception& e) { + delete o; + throw; + } + } + + std::string get_short_help() throw(std::bad_alloc) + { + return "Run file as a script"; + } + + std::string get_long_help() throw(std::bad_alloc) + { + return "Syntax: run-script \nRuns file just as it would have been entered in " + "the command line\n"; + } + + command_group& in_group; + std::ostream*& output; + }; + + struct show_aliases : public command + { + show_aliases(command_group& group, std::ostream*& _output) + : command(group, "show-aliases"), in_group(group), output(_output) + { + } + + ~show_aliases() throw() + { + } + + void invoke(const std::string& filename) throw(std::bad_alloc, std::runtime_error) + { + if(filename != "") { + (*output) << "Syntax: show-aliases" << std::endl; + return; + } + auto aliases = in_group.get_aliases(); + for(auto i : aliases) { + std::string acmd = in_group.get_alias_for(i); + while(acmd != "") { + std::string j; + extract_token(acmd, j, "\n"); + if(j != "") + (*output) << "alias " << i << " " << j << std::endl; + } + } + } + + std::string get_short_help() throw(std::bad_alloc) + { + return "Show aliases"; + } + + std::string get_long_help() throw(std::bad_alloc) + { + return "Syntax: show-aliases\nShow expansions of all aliases\n"; + } + + command_group& in_group; + std::ostream*& output; + }; + + struct unalias_command : public command + { + unalias_command(command_group& group, std::ostream*& _output) + : command(group, "unalias-command"), in_group(group), output(_output) + { + } + + ~unalias_command() throw() + { + } + + void invoke(const std::string& t) throw(std::bad_alloc, std::runtime_error) + { + auto r = regex("([^ \t]+)[ \t]*", t, "This command only takes one argument"); + if(!in_group.valid_alias_name(r[1])) + throw std::runtime_error("Illegal alias name"); + in_group.set_alias_for(r[1], ""); + (*output) << "Command '" << r[1] << "' unaliased" << std::endl; + } + + std::string get_short_help() throw(std::bad_alloc) + { + return "Unalias a command"; + } + + std::string get_long_help() throw(std::bad_alloc) + { + return "Syntax: unalias-command \nClear expansion of alias \n"; + } + + command_group& in_group; + std::ostream*& output; + }; + + struct alias_command : public command + { + alias_command(command_group& group, std::ostream*& _output) + : command(group, "alias-command"), in_group(group), output(_output) + { + } + + ~alias_command() throw() + { + } + + void invoke(const std::string& t) throw(std::bad_alloc, std::runtime_error) + { + auto r = regex("([^ \t]+)[ \t]+([^ \t].*)", t, "Alias name and command needed"); + if(!in_group.valid_alias_name(r[1])) + throw std::runtime_error("Illegal alias name"); + std::string tmp = in_group.get_alias_for(r[1]); + tmp = tmp + r[2] + "\n"; + in_group.set_alias_for(r[1], tmp); + (*output) << "Command '" << r[1] << "' aliased to '" << r[2] << "'" << std::endl; + } + + std::string get_short_help() throw(std::bad_alloc) + { + return "Alias a command"; + } + + std::string get_long_help() throw(std::bad_alloc) + { + return "Syntax: alias-command \nAppend to expansion of alias " + "\nValid alias names can't be empty nor start with '*' or '?'\n"; + } + + command_group& in_group; + std::ostream*& output; + }; +} + +namespace +{ + void default_oom_panic() + { + std::cerr << "PANIC: Fatal error, can't continue: Out of memory." << std::endl; + exit(1); + } + + struct pending_registration + { + command_group* group; + std::string name; + command* toreg; + }; + + globalwrap reg_mutex; + globalwrap> ready_groups; + globalwrap> pending_registrations; + + void run_pending_registrations() + { + umutex_class m(reg_mutex()); + auto i = pending_registrations().begin(); + while(i != pending_registrations().end()) { + auto entry = i++; + if(ready_groups().count(entry->group)) { + entry->group->register_command(entry->name, *entry->toreg); + pending_registrations().erase(entry); + } + } + } + + void add_registration(command_group& group, const std::string& name, command& type) + { + { + umutex_class m(reg_mutex()); + if(ready_groups().count(&group)) { + group.register_command(name, type); + return; + } + pending_registration p; + p.group = &group; + p.name = name; + p.toreg = &type; + pending_registrations().push_back(p); + } + run_pending_registrations(); + } + + void delete_registration(command_group& group, const std::string& name) + { + { + umutex_class m(reg_mutex()); + if(ready_groups().count(&group)) + group.unregister_command(name); + else { + auto i = pending_registrations().begin(); + while(i != pending_registrations().end()) { + auto entry = i++; + if(entry->group == &group && entry->name == name) + pending_registrations().erase(entry); + } + } + } + } + + +} + +command::command(command_group& group, const std::string& cmd) throw(std::bad_alloc) + : in_group(group) +{ + add_registration(in_group, commandname = cmd, *this); +} + +command::~command() throw() +{ + delete_registration(in_group, commandname); +} + + +std::string command::get_short_help() throw(std::bad_alloc) +{ + return "No description available"; +} + +std::string command::get_long_help() throw(std::bad_alloc) +{ + return "No help available on command " + commandname; +} + +command_group::command_group() throw(std::bad_alloc) +{ + oom_panic_routine = default_oom_panic; + output = &std::cerr; + { + umutex_class m(reg_mutex()); + ready_groups().insert(this); + } + run_pending_registrations(); + //The builtin commands. + new run_script(*this, output); + new show_aliases(*this, output); + new unalias_command(*this, output); + new alias_command(*this, output); +} + +command_group::~command_group() throw() +{ + { + umutex_class m(reg_mutex()); + ready_groups().erase(this); + } +} + +void command_group::invoke(const std::string& cmd) throw() +{ + try { + std::string cmd2 = strip_CR(cmd); + if(cmd2 == "?") { + //The special ? command. + umutex_class lock(int_mutex); + for(auto i : commands) + (*output) << i.first << ": " << i.second->get_short_help() << std::endl; + return; + } + if(firstchar(cmd2) == '?') { + //?command. + umutex_class lock(int_mutex); + std::string rcmd = cmd2.substr(1, min(cmd2.find_first_of(" \t"), cmd2.length())); + if(firstchar(rcmd) != '*') { + //This may be an alias. + if(aliases.count(rcmd)) { + //Yup. + (*output) << rcmd << " is an alias for: " << std::endl; + size_t j = 0; + for(auto i : aliases[rcmd]) + (*output) << "#" << (++j) << ": " << i << std::endl; + return; + } + } else + rcmd = rcmd.substr(1); + if(!commands.count(rcmd)) + (*output) << "Unknown command '" << rcmd << "'" << std::endl; + else + (*output) << commands[rcmd]->get_long_help() << std::endl; + return; + } + bool may_be_alias_expanded = true; + if(firstchar(cmd2) == '*') { + may_be_alias_expanded = false; + cmd2 = cmd2.substr(1); + } + //Now this gets painful as command handlers must not be invoked with lock held. + if(may_be_alias_expanded) { + std::list aexp; + { + umutex_class lock(int_mutex); + if(!aliases.count(cmd)) + goto not_alias; + aexp = aliases[cmd2]; + } + for(auto i : aexp) + invoke(i); + return; + } +not_alias: + try { + size_t split = cmd2.find_first_of(" \t"); + std::string rcmd = cmd2.substr(0, min(split, cmd2.length())); + std::string args = cmd2.substr(min(cmd2.find_first_not_of(" \t", split), cmd2.length())); + command* cmdh = NULL; + { + umutex_class lock(int_mutex); + if(!commands.count(rcmd)) { + (*output) << "Unknown command '" << rcmd << "'" << std::endl; + return; + } + cmdh = commands[rcmd]; + } + if(command_stack.count(cmd2)) + throw std::runtime_error("Recursive command invocation"); + command_stack.insert(cmd2); + cmdh->invoke(args); + command_stack.erase(cmd2); + return; + } catch(std::bad_alloc& e) { + oom_panic_routine(); + } catch(std::exception& e) { + (*output) << "Error: " << e.what() << std::endl; + command_stack.erase(cmd2); + return; + } + } catch(std::bad_alloc& e) { + oom_panic_routine(); + } +} + +std::set command_group::get_aliases() throw(std::bad_alloc) +{ + umutex_class lock(int_mutex); + std::set r; + for(auto i : aliases) + r.insert(i.first); + return r; +} + +std::string command_group::get_alias_for(const std::string& aname) throw(std::bad_alloc) +{ + umutex_class lock(int_mutex); + if(!valid_alias_name(aname)) + return ""; + if(aliases.count(aname)) { + std::string x; + for(auto i : aliases[aname]) + x = x + i + "\n"; + return x; + } else + return ""; +} + +void command_group::set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc) +{ + umutex_class lock(int_mutex); + if(!valid_alias_name(aname)) + return; + std::list newlist; + size_t avitr = 0; + while(avitr < avalue.length()) { + size_t nextsplit = min(avalue.find_first_of("\n", avitr), avalue.length()); + std::string x = strip_CR(avalue.substr(avitr, nextsplit - avitr)); + if(x.length() > 0) + newlist.push_back(x); + avitr = nextsplit + 1; + } + if(newlist.empty()) + aliases.erase(aname); + else + aliases[aname] = newlist; +} + +bool command_group::valid_alias_name(const std::string& aliasname) throw(std::bad_alloc) +{ + if(aliasname.length() == 0 || aliasname[0] == '?' || aliasname[0] == '*') + return false; + if(aliasname.find_first_of(" \t") < aliasname.length()) + return false; + return true; +} + +void command_group::register_command(const std::string& name, command& cmd) throw(std::bad_alloc) +{ + umutex_class lock(int_mutex); + if(commands.count(name)) + std::cerr << "WARNING: Command collision for " << name << "!" << std::endl; + commands[name] = &cmd; +} + +void command_group::unregister_command(const std::string& name) throw(std::bad_alloc) +{ + umutex_class lock(int_mutex); + commands.erase(name); +} + +void command_group::set_output(std::ostream& s) +{ + output = &s; +} + +void command_group::set_oom_panic(void (*fn)()) +{ + if(fn) + oom_panic_routine = fn; + else + oom_panic_routine = default_oom_panic; +} + +template<> +void invoke_command_fn(void (*fn)(const std::string& args), const std::string& args) +{ + fn(args); +} + +template<> +void invoke_command_fn(void (*fn)(), const std::string& args) +{ + if(args != "") + throw std::runtime_error("This command does not take arguments"); + fn(); +} + +template<> +void invoke_command_fn(void (*fn)(struct arg_filename a), const std::string& args) +{ + if(args == "") + throw std::runtime_error("Filename required"); + arg_filename b; + b.v = args; + fn(b); +} diff --git a/src/lua/core.cpp b/src/lua/core.cpp index 3d002900..fd21a2da 100644 --- a/src/lua/core.cpp +++ b/src/lua/core.cpp @@ -44,7 +44,7 @@ namespace function_ptr_luafun lua_exec("exec", [](lua_State* LS, const std::string& fname) -> int { std::string text = get_string_argument(LS, 1, fname.c_str()); - command::invokeC(text); + lsnes_cmd.invoke(text); return 0; }); diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp index d2688174..b369ae6e 100644 --- a/src/lua/lua.cpp +++ b/src/lua/lua.cpp @@ -268,7 +268,7 @@ namespace } if(lua_requests_repaint) { lua_requests_repaint = false; - command::invokeC("repaint"); + lsnes_cmd.invoke("repaint"); } } @@ -307,7 +307,7 @@ namespace } if(lua_requests_repaint) { lua_requests_repaint = false; - command::invokeC("repaint"); + lsnes_cmd.invoke("repaint"); } } @@ -499,22 +499,22 @@ void lua_callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index namespace { - function_ptr_command evaluate_lua("evaluate-lua", "Evaluate expression in Lua VM", - "Syntax: evaluate-lua \nEvaluates in Lua VM.\n", + function_ptr_command evaluate_lua(lsnes_cmd, "evaluate-lua", "Evaluate expression in " + "Lua VM", "Syntax: evaluate-lua \nEvaluates in Lua VM.\n", [](const std::string& args) throw(std::bad_alloc, std::runtime_error) { if(args == "") throw std::runtime_error("Expected expression to evaluate"); do_eval_lua(args); }); - function_ptr_command run_lua("run-lua", "Run Lua script in Lua VM", + function_ptr_command run_lua(lsnes_cmd, "run-lua", "Run Lua script in Lua VM", "Syntax: run-lua \nRuns in Lua VM.\n", [](arg_filename args) throw(std::bad_alloc, std::runtime_error) { do_run_lua(args); }); - function_ptr_command<> reset_lua("reset-lua", "Reset the Lua VM", + function_ptr_command<> reset_lua(lsnes_cmd, "reset-lua", "Reset the Lua VM", "Syntax: reset-lua\nReset the Lua VM.\n", []() throw(std::bad_alloc, std::runtime_error) { diff --git a/src/platform/libao/sound.cpp b/src/platform/libao/sound.cpp index 2f0846d5..423c174d 100644 --- a/src/platform/libao/sound.cpp +++ b/src/platform/libao/sound.cpp @@ -115,7 +115,7 @@ namespace return true; } - function_ptr_command x("libao-set-id", "", "", + function_ptr_command x(lsnes_cmd, "libao-set-id", "", "", [](const std::string& value) throw(std::bad_alloc, std::runtime_error) { driver_id = parse_value(value); }); diff --git a/src/platform/portaudio/sound.cpp b/src/platform/portaudio/sound.cpp index 837ae039..f7c0e213 100644 --- a/src/platform/portaudio/sound.cpp +++ b/src/platform/portaudio/sound.cpp @@ -186,7 +186,7 @@ namespace return true; } - function_ptr_command x("portaudio", "", "", + function_ptr_command x(lsnes_cmd, "portaudio", "", "", [](const std::string& value) throw(std::bad_alloc, std::runtime_error) { messages << "Load: " << Pa_GetStreamCpuLoad(s) << std::endl; messages << "Rate: " << 1000000.0 * frames / (get_utime() - first_ts) << std::endl; diff --git a/src/platform/sdl/graphicsfn.cpp b/src/platform/sdl/graphicsfn.cpp index b1e8de6c..ba508a9f 100644 --- a/src/platform/sdl/graphicsfn.cpp +++ b/src/platform/sdl/graphicsfn.cpp @@ -131,43 +131,43 @@ namespace } } - function_ptr_command<> identify_key("identify-key", "Identify a key", + function_ptr_command<> identify_key(lsnes_cmd, "identify-key", "Identify a key", "Syntax: identify-key\nIdentifies a (pseudo-)key.\n", []() throw(std::bad_alloc, std::runtime_error) { identify_requested = true; wake_ui(); }); - function_ptr_command<> scroll_up("scroll-up", "Scroll messages a page up", + function_ptr_command<> scroll_up(lsnes_cmd, "scroll-up", "Scroll messages a page up", "Syntax: scroll-up\nScrolls message console backward one page.\n", []() throw(std::bad_alloc, std::runtime_error) { mutex::holder h(platform::msgbuf_lock()); platform::msgbuf.scroll_up_page(); }); - function_ptr_command<> scroll_fullup("scroll-fullup", "Scroll messages to beginning", + function_ptr_command<> scroll_fullup(lsnes_cmd, "scroll-fullup", "Scroll messages to beginning", "Syntax: scroll-fullup\nScrolls message console to its beginning.\n", []() throw(std::bad_alloc, std::runtime_error) { mutex::holder h(platform::msgbuf_lock()); platform::msgbuf.scroll_beginning(); }); - function_ptr_command<> scroll_fulldown("scroll-fulldown", "Scroll messages to end", + function_ptr_command<> scroll_fulldown(lsnes_cmd, "scroll-fulldown", "Scroll messages to end", "Syntax: scroll-fulldown\nScrolls message console to its end.\n", []() throw(std::bad_alloc, std::runtime_error) { mutex::holder h(platform::msgbuf_lock()); platform::msgbuf.scroll_end(); }); - function_ptr_command<> scrolldown("scroll-down", "Scroll messages a page down", + function_ptr_command<> scrolldown(lsnes_cmd, "scroll-down", "Scroll messages a page down", "Syntax: scroll-up\nScrolls message console forward one page.\n", []() throw(std::bad_alloc, std::runtime_error) { mutex::holder h(platform::msgbuf_lock()); platform::msgbuf.scroll_down_page(); }); - function_ptr_command<> toggle_console("toggle-console", "Toggle console between small and full window", - "Syntax: toggle-console\nToggles console between small and large.\n", + function_ptr_command<> toggle_console(lsnes_cmd, "toggle-console", "Toggle console between small and full " + "window", "Syntax: toggle-console\nToggles console between small and large.\n", []() throw(std::bad_alloc, std::runtime_error) { fullscreen_console = !fullscreen_console; wake_ui(); @@ -272,7 +272,7 @@ namespace platform::queue(emu_handle_identify, NULL, false); } - function_ptr_command exec_command_prefix("prompt-command", + function_ptr_command exec_command_prefix(lsnes_cmd, "prompt-command", "Prompt for command", "Syntax: prompt-command \nPrompts command with specified text.\n", [](const std::string& line) throw(std::bad_alloc, std::runtime_error) { delayed_cmd = line; diff --git a/src/platform/sdl/main.cpp b/src/platform/sdl/main.cpp index 851dab9a..063d6f5b 100644 --- a/src/platform/sdl/main.cpp +++ b/src/platform/sdl/main.cpp @@ -84,7 +84,7 @@ namespace if(o.length() >= 6 && o.substr(0, 6) == "--run=") { std::string file = o.substr(6); messages << "--- Running " << file << " --- " << std::endl; - command::invokeC("run-script " + file); + lsnes_cmd.invoke("run-script " + file); messages << "--- End running " << file << " --- " << std::endl; } } @@ -173,7 +173,7 @@ int main(int argc, char** argv) messages << "Saving per-user data to: " << get_config_path() << std::endl; messages << "--- Running lsnesrc --- " << std::endl; setting::set_storage_mode(true); - command::invokeC("run-script " + cfgpath + "/lsnes.rc"); + lsnes_cmd.invoke("run-script " + cfgpath + "/lsnes.rc"); setting::set_storage_mode(false); messages << "--- End running lsnesrc --- " << std::endl; diff --git a/src/platform/sdl/savesettings.cpp b/src/platform/sdl/savesettings.cpp index 1261447c..1068b566 100644 --- a/src/platform/sdl/savesettings.cpp +++ b/src/platform/sdl/savesettings.cpp @@ -47,8 +47,8 @@ namespace for(auto i : setting::get_invalid_values()) cfgfile << "set-setting " << i.first << " " << i.second << std::endl; //Aliases. - for(auto i : command::get_aliases()) { - std::string old_alias_value = command::get_alias_for(i); + for(auto i : lsnes_cmd.get_aliases()) { + std::string old_alias_value = lsnes_cmd.get_alias_for(i); while(old_alias_value != "") { std::string aliasline; size_t s = old_alias_value.find_first_of("\n"); diff --git a/src/platform/wxwidgets/main.cpp b/src/platform/wxwidgets/main.cpp index f58ecd62..49863415 100644 --- a/src/platform/wxwidgets/main.cpp +++ b/src/platform/wxwidgets/main.cpp @@ -200,8 +200,8 @@ end: for(auto i : setting::get_invalid_values()) cfgfile << "set-setting " << i.first << " " << i.second << std::endl; //Aliases. - for(auto i : command::get_aliases()) { - std::string old_alias_value = command::get_alias_for(i); + for(auto i : lsnes_cmd.get_aliases()) { + std::string old_alias_value = lsnes_cmd.get_alias_for(i); while(old_alias_value != "") { std::string aliasline; size_t s = old_alias_value.find_first_of("\n"); @@ -378,7 +378,7 @@ bool lsnes_app::OnInit() messages << "Saving per-user data to: " << get_config_path() << std::endl; messages << "--- Running lsnesrc --- " << std::endl; setting::set_storage_mode(true); - command::invokeC("run-script " + cfgpath + "/lsneswxw.rc"); + lsnes_cmd.invoke("run-script " + cfgpath + "/lsneswxw.rc"); setting::set_storage_mode(false); messages << "--- End running lsnesrc --- " << std::endl; diff --git a/src/platform/wxwidgets/settings.cpp b/src/platform/wxwidgets/settings.cpp index 5cb26947..7b47cf34 100644 --- a/src/platform/wxwidgets/settings.cpp +++ b/src/platform/wxwidgets/settings.cpp @@ -1088,14 +1088,14 @@ void wxeditor_esettings_aliases::on_add(wxCommandEvent& e) { try { std::string name = pick_text(this, "Enter alias name", "Enter name for the new alias:"); - if(!command::valid_alias_name(name)) { + if(!lsnes_cmd.valid_alias_name(name)) { show_message_ok(this, "Error", "Not a valid alias name: " + name, wxICON_EXCLAMATION); throw canceled_exception(); } - std::string old_alias_value = command::get_alias_for(name); + std::string old_alias_value = lsnes_cmd.get_alias_for(name); std::string newcmd = pick_text(this, "Edit alias", "Enter new commands for '" + name + "':", old_alias_value, true); - command::set_alias_for(name, newcmd); + lsnes_cmd.set_alias_for(name, newcmd); } catch(...) { } refresh(); @@ -1109,10 +1109,10 @@ void wxeditor_esettings_aliases::on_edit(wxCommandEvent& e) return; } try { - std::string old_alias_value = command::get_alias_for(name); + std::string old_alias_value = lsnes_cmd.get_alias_for(name); std::string newcmd = pick_text(this, "Edit alias", "Enter new commands for '" + name + "':", old_alias_value, true); - command::set_alias_for(name, newcmd); + lsnes_cmd.set_alias_for(name, newcmd); } catch(...) { } refresh(); @@ -1125,7 +1125,7 @@ void wxeditor_esettings_aliases::on_delete(wxCommandEvent& e) refresh(); return; } - command::set_alias_for(name, ""); + lsnes_cmd.set_alias_for(name, ""); refresh(); } @@ -1134,7 +1134,7 @@ void wxeditor_esettings_aliases::refresh() int n = select->GetSelection(); std::set bind; std::vector choices; - bind = command::get_aliases(); + bind = lsnes_cmd.get_aliases(); for(auto i : bind) { numbers[choices.size()] = i; choices.push_back(towxstring(i)); diff --git a/src/util/lsnes-dumpavi.cpp b/src/util/lsnes-dumpavi.cpp index 3b3a48a7..a25571b5 100644 --- a/src/util/lsnes-dumpavi.cpp +++ b/src/util/lsnes-dumpavi.cpp @@ -84,7 +84,7 @@ namespace for(auto i = cmdline.begin(); i != cmdline.end(); i++) { std::string a = *i; if(a.length() > 6 && a.substr(0, 6) == "--lua=") { - command::invokeC("run-lua " + a.substr(6)); + lsnes_cmd.invoke("run-lua " + a.substr(6)); } } }