Overhaul of command parsing
This commit is contained in:
@@ -35,6 +35,12 @@ bool Gui::has_action(const std::string &action) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Gui::get_action(int index) {
|
||||||
|
if ((index < 0) || (index >= elts_.size())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return elts_[index].action();
|
||||||
|
}
|
||||||
|
|
||||||
LuaDefine(gui_menu_item, "c") {
|
LuaDefine(gui_menu_item, "c") {
|
||||||
Gui *gui = Gui::fetch_global_pointer(L);
|
Gui *gui = Gui::fetch_global_pointer(L);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
void clear() { elts_.clear(); }
|
void clear() { elts_.clear(); }
|
||||||
bool has_action(const std::string &action) const;
|
bool has_action(const std::string &action) const;
|
||||||
void menu_item(const std::string &action, const std::string &label);
|
void menu_item(const std::string &action, const std::string &label);
|
||||||
|
std::string get_action(int index);
|
||||||
|
|
||||||
// Put a pointer to a gui into the lua registry.
|
// Put a pointer to a gui into the lua registry.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ Invocation::Invocation() : kind_(KIND_INVALID), actor_(0), place_(0) {}
|
|||||||
Invocation::Invocation(Kind kind, int64_t actor, int64_t place, const std::string &action, const InvocationData &data)
|
Invocation::Invocation(Kind kind, int64_t actor, int64_t place, const std::string &action, const InvocationData &data)
|
||||||
: kind_(kind), actor_(actor), place_(place), action_(action), data_(data) {}
|
: kind_(kind), actor_(actor), place_(place), action_(action), data_(data) {}
|
||||||
|
|
||||||
|
Invocation::Invocation(Kind kind, int64_t actor, int64_t place, const std::string &action)
|
||||||
|
: kind_(kind), actor_(actor), place_(place), action_(action) {}
|
||||||
|
|
||||||
void Invocation::serialize(StreamBuffer *sb) const {
|
void Invocation::serialize(StreamBuffer *sb) const {
|
||||||
sb->write_uint8(kind_);
|
sb->write_uint8(kind_);
|
||||||
sb->write_int64(actor_);
|
sb->write_int64(actor_);
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
Invocation();
|
Invocation();
|
||||||
Invocation(Kind kind, int64_t actor, int64_t place, const std::string &action, const InvocationData &data);
|
Invocation(Kind kind, int64_t actor, int64_t place, const std::string &action, const InvocationData &data);
|
||||||
|
Invocation(Kind kind, int64_t actor, int64_t place, const std::string &action);
|
||||||
|
|
||||||
|
bool valid() const { return kind_ != KIND_INVALID; }
|
||||||
Kind kind() const { return kind_; }
|
Kind kind() const { return kind_; }
|
||||||
int64_t actor() const { return actor_; }
|
int64_t actor() const { return actor_; }
|
||||||
int64_t place() const { return place_; }
|
int64_t place() const { return place_; }
|
||||||
|
|||||||
@@ -96,29 +96,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_lua_command(const StringVec &words) {
|
void do_lua_command(const StringVec &words) {
|
||||||
if (words.size() != 2) {
|
send_invocation(Invocation(Invocation::KIND_LUA, actor_id_, actor_id_, words[1]));
|
||||||
stdostream() << "lua command (lua) takes a single string" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const std::string &exp = words[1];
|
|
||||||
InvocationData dummyresult;
|
|
||||||
Invocation inv(Invocation::KIND_LUA, actor_id_, actor_id_, exp, dummyresult);
|
|
||||||
send_invocation(inv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_syntax_command(const StringVec &words) {
|
void do_syntax_command(const StringVec &words) {
|
||||||
stdostream() << "Syntax Error: ";
|
stdostream() << "Syntax Error: " << words[1] << std::endl;
|
||||||
for (int i = 1; i < int(words.size()); i++) {
|
|
||||||
stdostream() << words[i] << " ";
|
|
||||||
}
|
|
||||||
stdostream() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_view_command(const StringVec &cmd) {
|
void do_view_command(const StringVec &cmd) {
|
||||||
if (cmd.size() != 1) {
|
|
||||||
stdostream() << "view command takes no arguments" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int64_t id : world_->get_near(actor_id_, 100, true)) {
|
for (int64_t id : world_->get_near(actor_id_, 100, true)) {
|
||||||
const Tangible *tan = world_->tangible_get(id);
|
const Tangible *tan = world_->tangible_get(id);
|
||||||
const AnimStep &aqback = tan->anim_queue_.back();
|
const AnimStep &aqback = tan->anim_queue_.back();
|
||||||
@@ -127,18 +112,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_menu_command(const StringVec &cmd) {
|
void do_menu_command(const StringVec &cmd) {
|
||||||
int64_t id;
|
|
||||||
if (cmd.size() == 1) {
|
|
||||||
id = actor_id_;
|
|
||||||
} else if (cmd.size() == 2) {
|
|
||||||
id = util::strtoint(cmd[1], -1);
|
|
||||||
} else {
|
|
||||||
stdostream() << "menu command expects a tangible ID or defaults to actor_id" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
world_to_asynchronous();
|
world_to_asynchronous();
|
||||||
gui_place_ = id;
|
gui_place_ = util::strtoint(cmd[1], actor_id_);
|
||||||
world_->update_gui(actor_id_, id, &gui_);
|
world_->update_gui(actor_id_, gui_place_, &gui_);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (const GuiElt &elt : gui_.elts()) {
|
for (const GuiElt &elt : gui_.elts()) {
|
||||||
stdostream() << index << " " << elt.label() << std::endl;
|
stdostream() << index << " " << elt.label() << std::endl;
|
||||||
@@ -147,32 +123,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_choose_command(const StringVec &cmd) {
|
void do_choose_command(const StringVec &cmd) {
|
||||||
int64_t index;
|
std::string action = gui_.get_action(util::strtoint(cmd[1], -1));
|
||||||
if (cmd.size() == 1) {
|
if (action == "") {
|
||||||
index = util::strtoint(cmd[0], -1);
|
stdostream() << "Invalid menu item #" << std::endl;
|
||||||
} else {
|
|
||||||
stdostream() << "choose command consists of a single menu line number" << std::endl;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const Gui::EltVec &elts = gui_.elts();
|
|
||||||
if ((index < 0) || (index >= int(elts.size()))) {
|
|
||||||
stdostream() << "No menu item #" << index << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string action = elts[index].action();
|
|
||||||
stdostream() << "Invoking plan: " << action << std::endl;
|
stdostream() << "Invoking plan: " << action << std::endl;
|
||||||
InvocationData dummyresult;
|
Invocation inv(Invocation::KIND_PLAN, actor_id_, gui_place_, action);
|
||||||
dummyresult["flavor"] = "chocolate";
|
|
||||||
dummyresult["color"] = "blue";
|
|
||||||
Invocation inv(Invocation::KIND_PLAN, actor_id_, gui_place_, action, dummyresult);
|
|
||||||
send_invocation(inv);
|
send_invocation(inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_quit_command(const util::StringVec &words) {
|
void do_quit_command(const util::StringVec &words) {
|
||||||
if (words.size() != 1) {
|
|
||||||
stdostream() << "quit command takes no arguments" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
abandon_server();
|
abandon_server();
|
||||||
stop_driver();
|
stop_driver();
|
||||||
}
|
}
|
||||||
@@ -184,9 +145,9 @@ public:
|
|||||||
else if (words[0] == "view") do_view_command(words);
|
else if (words[0] == "view") do_view_command(words);
|
||||||
else if (words[0] == "menu") do_menu_command(words);
|
else if (words[0] == "menu") do_menu_command(words);
|
||||||
else if (words[0] == "quit") do_quit_command(words);
|
else if (words[0] == "quit") do_quit_command(words);
|
||||||
else if (util::validinteger(words[0])) do_choose_command(words);
|
else if (words[0] == "choose") do_choose_command(words);
|
||||||
else {
|
else {
|
||||||
stdostream() << "Unknown command: " << words[0] << std::endl;
|
stdostream() << "Unsupported command: " << words[0] << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,29 +43,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_lua_command(const util::StringVec &words) {
|
void do_lua_command(const util::StringVec &words) {
|
||||||
if (words.size() != 2) {
|
master_->invoke(Invocation(Invocation::KIND_LUA, admin_id_, admin_id_, words[1]));
|
||||||
stdostream() << "lua command (lua) takes a single string" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const std::string &exp = words[1];
|
|
||||||
InvocationData dummyresult;
|
|
||||||
Invocation inv(Invocation::KIND_LUA, admin_id_, admin_id_, exp, dummyresult);
|
|
||||||
master_->invoke(inv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_syntax_command(const util::StringVec &words) {
|
void do_syntax_command(const util::StringVec &words) {
|
||||||
stdostream() << "Syntax Error: ";
|
stdostream() << "Syntax Error: " << words[1] << std::endl;
|
||||||
for (int i = 1; i < int(words.size()); i++) {
|
|
||||||
stdostream() << words[i] << " ";
|
|
||||||
}
|
|
||||||
stdostream() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_quit_command(const util::StringVec &words) {
|
void do_quit_command(const util::StringVec &words) {
|
||||||
if (words.size() != 1) {
|
|
||||||
stdostream() << "quit command takes no arguments" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
stop_driver();
|
stop_driver();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +60,7 @@ public:
|
|||||||
else if (words[0] == "syntax") do_syntax_command(words);
|
else if (words[0] == "syntax") do_syntax_command(words);
|
||||||
else if (words[0] == "quit") do_quit_command(words);
|
else if (words[0] == "quit") do_quit_command(words);
|
||||||
else {
|
else {
|
||||||
stdostream() << "Unknown command: " << words[0] << std::endl;
|
stdostream() << "Unsupported command: " << words[0] << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,65 @@ LuaConsole::StringVec LuaConsole::get_command() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaConsole::synerr(const std::string &msg) {
|
||||||
|
words_.clear();
|
||||||
|
words_.push_back("syntax");
|
||||||
|
words_.push_back(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaConsole::simplify(const StringVec &words) {
|
||||||
|
words_ = words;
|
||||||
|
if (words.size() == 0) {
|
||||||
|
return;
|
||||||
|
} else if (util::validinteger(words[0])) {
|
||||||
|
if (words.size() == 1) {
|
||||||
|
words_.clear();
|
||||||
|
words_.push_back("choose");
|
||||||
|
words_.push_back(words[0]);
|
||||||
|
} else {
|
||||||
|
synerr("/choose command takes no arguments");
|
||||||
|
}
|
||||||
|
} else if (words[0] == "choose") {
|
||||||
|
if ((words.size() == 2)&&(util::validinteger(words[1]))) {
|
||||||
|
// OK
|
||||||
|
} else {
|
||||||
|
synerr("/choose [menu-line-number]");
|
||||||
|
}
|
||||||
|
} else if (words[0] == "view") {
|
||||||
|
if (words.size() != 1) {
|
||||||
|
synerr("/view takes no arguments");
|
||||||
|
}
|
||||||
|
} else if (words[0] == "menu") {
|
||||||
|
if (words.size() == 1) {
|
||||||
|
words_.push_back("-");
|
||||||
|
} else if ((words.size() == 2)&&(util::validinteger(words[1]))) {
|
||||||
|
// OK
|
||||||
|
} else {
|
||||||
|
synerr("/menu [optional-tangible-id]");
|
||||||
|
}
|
||||||
|
} else if (words[0] == "quit") {
|
||||||
|
if (words.size() != 1) {
|
||||||
|
synerr("/quit takes no arguments");
|
||||||
|
}
|
||||||
|
} else if (words[0] == "snap") {
|
||||||
|
if (words.size() != 1) {
|
||||||
|
synerr("/snap takes no arguments");
|
||||||
|
}
|
||||||
|
} else if (words[0] == "roll") {
|
||||||
|
if (words.size() != 1) {
|
||||||
|
synerr("/roll takes no arguments");
|
||||||
|
}
|
||||||
|
} else if (words[0] == "tick") {
|
||||||
|
if ((words.size() == 2)&&(util::validinteger(words[1]))) {
|
||||||
|
// OK
|
||||||
|
} else {
|
||||||
|
synerr("/tick [optional-timestamp]");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synerr("unrecognized command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LuaConsole::clear_raw_input() {
|
void LuaConsole::clear_raw_input() {
|
||||||
raw_input_ = "";
|
raw_input_ = "";
|
||||||
lines_ = 0;
|
lines_ = 0;
|
||||||
@@ -52,10 +111,11 @@ void LuaConsole::add(std::string line) {
|
|||||||
raw_input_ += '\n';
|
raw_input_ += '\n';
|
||||||
lines_ += 1;
|
lines_ += 1;
|
||||||
prompt_ = ">> ";
|
prompt_ = ">> ";
|
||||||
|
words_.clear();
|
||||||
|
|
||||||
// Try to interpret it as a slash-command.
|
// Try to interpret it as a slash-command.
|
||||||
if ((lines_ == 1)&&(raw_input_[0] == '/')) {
|
if ((lines_ == 1)&&(raw_input_[0] == '/')) {
|
||||||
words_ = split_words(raw_input_.substr(1));
|
simplify(split_words(raw_input_.substr(1)));
|
||||||
clear_raw_input();
|
clear_raw_input();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,23 +8,28 @@
|
|||||||
// 1. Print the prompt suggested by 'get_prompt'.
|
// 1. Print the prompt suggested by 'get_prompt'.
|
||||||
// 2. Read a line of text from stdin.
|
// 2. Read a line of text from stdin.
|
||||||
// 3. Add the line to the LuaConsole using 'add'.
|
// 3. Add the line to the LuaConsole using 'add'.
|
||||||
// 4. Get the command words using 'get_command'.
|
// 4. Get the command word using get_command.
|
||||||
// 5. If the command is empty, do nothing.
|
// 5. If the command is empty, do nothing.
|
||||||
// 6. If the command is nonempty, execute it.
|
// 6. If the command is nonempty, get the args and execute it.
|
||||||
//
|
//
|
||||||
// The LuaConsole expects you to type one of three things:
|
// The LuaConsole expects you to type a lua command, or one
|
||||||
|
// of the following slash-commands:
|
||||||
//
|
//
|
||||||
// * Valid Lua Code.
|
// /quit - exit the program
|
||||||
// * Valid Lua Code preceded by '=' as shorthand for 'return'
|
// /view - display the nearby tangibles
|
||||||
// * A slash-command.
|
// /menu [tanid] - display the menu for tangible
|
||||||
|
// /snap - snapshot current state
|
||||||
|
// /roll - rollback to previous state
|
||||||
|
// /tick [timevalue] - advance the simulation clock
|
||||||
|
// /1234 - choose menu item 1234
|
||||||
//
|
//
|
||||||
// The 'get_command' returned by the luaconsole can be one of
|
// If you type anything else, the LuaConsole will generate a
|
||||||
// the following:
|
// syntax error. Note that not all of the commands above are
|
||||||
|
// supported in all interpreters.
|
||||||
//
|
//
|
||||||
// empty vector - still collecting input: do nothing.
|
// Once a command has been typed (or a syntax error has been
|
||||||
// lua <expr> - found a lua command: execute it as lua.
|
// typed), the LuaConsole will return the command. The command
|
||||||
// syntax <words> - detected a syntax error: print the error.
|
// can be fetched using command(), int_arg(), and str_arg()
|
||||||
// word word ... - read a slash-command: execute the command.
|
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -42,10 +47,12 @@ private:
|
|||||||
lua_State *lua_state_;
|
lua_State *lua_state_;
|
||||||
std::string raw_input_;
|
std::string raw_input_;
|
||||||
int lines_;
|
int lines_;
|
||||||
StringVec words_;
|
|
||||||
std::string prompt_;
|
std::string prompt_;
|
||||||
|
StringVec words_;
|
||||||
|
|
||||||
void clear_raw_input();
|
void clear_raw_input();
|
||||||
|
void simplify(const StringVec &words);
|
||||||
|
void synerr(const std::string &msg);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LuaConsole();
|
LuaConsole();
|
||||||
@@ -57,12 +64,11 @@ public:
|
|||||||
//
|
//
|
||||||
const std::string &get_prompt() { return prompt_; }
|
const std::string &get_prompt() { return prompt_; }
|
||||||
|
|
||||||
// Fetch the command to execute.
|
// Get the command words.
|
||||||
//
|
//
|
||||||
// You should fetch the command after calling 'add'.
|
// Note that the command words may not be exactly what
|
||||||
// Returns the empty vector if there is no command.
|
// the user typed. Typically, the LuaConsole simplifies
|
||||||
// If there is a command, the first word is the command word.
|
// the command before returning it to the caller.
|
||||||
// See the file comment for certain built-in command words.
|
|
||||||
//
|
//
|
||||||
StringVec get_command();
|
StringVec get_command();
|
||||||
|
|
||||||
|
|||||||
@@ -29,32 +29,15 @@ private:
|
|||||||
int64_t gui_place_;
|
int64_t gui_place_;
|
||||||
int64_t actor_id_;
|
int64_t actor_id_;
|
||||||
|
|
||||||
|
|
||||||
void do_lua_command(const StringVec &words) {
|
void do_lua_command(const StringVec &words) {
|
||||||
assert(world_->stack_is_clear());
|
world_->invoke(Invocation(Invocation::KIND_LUA, actor_id_, actor_id_, words[1]));
|
||||||
if (words.size() != 2) {
|
|
||||||
stdostream() << "lua command (lua) takes a single string" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const std::string &exp = words[1];
|
|
||||||
InvocationData dummyresult;
|
|
||||||
Invocation inv(Invocation::KIND_LUA, actor_id_, actor_id_, exp, dummyresult);
|
|
||||||
world_->invoke(inv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_syntax_command(const StringVec &words) {
|
void do_syntax_command(const StringVec &words) {
|
||||||
stdostream() << "Syntax Error: ";
|
stdostream() << "Syntax Error: " << words[1] << std::endl;
|
||||||
for (int i = 1; i < int(words.size()); i++) {
|
|
||||||
stdostream() << words[i] << " ";
|
|
||||||
}
|
|
||||||
stdostream() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_view_command(const StringVec &cmd) {
|
void do_view_command(const StringVec &cmd) {
|
||||||
if (cmd.size() != 1) {
|
|
||||||
stdostream() << "v command (view) takes no arguments" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int64_t id : world_->get_near(actor_id_, 100, true)) {
|
for (int64_t id : world_->get_near(actor_id_, 100, true)) {
|
||||||
const Tangible *tan = world_->tangible_get(id);
|
const Tangible *tan = world_->tangible_get(id);
|
||||||
const AnimStep &aqback = tan->anim_queue_.back();
|
const AnimStep &aqback = tan->anim_queue_.back();
|
||||||
@@ -63,17 +46,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_menu_command(const StringVec &cmd) {
|
void do_menu_command(const StringVec &cmd) {
|
||||||
int64_t id;
|
gui_place_ = util::strtoint(cmd[1], actor_id_);
|
||||||
if (cmd.size() == 1) {
|
world_->update_gui(actor_id_, gui_place_, &gui_);
|
||||||
id = actor_id_;
|
|
||||||
} else if (cmd.size() == 2) {
|
|
||||||
id = util::strtoint(cmd[1], -1);
|
|
||||||
} else {
|
|
||||||
stdostream() << "m command (menu) expects a tangible ID or defaults to actor_id" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gui_place_ = id;
|
|
||||||
world_->update_gui(actor_id_, id, &gui_);
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (const GuiElt &elt : gui_.elts()) {
|
for (const GuiElt &elt : gui_.elts()) {
|
||||||
stdostream() << index << " " << elt.label() << std::endl;
|
stdostream() << index << " " << elt.label() << std::endl;
|
||||||
@@ -82,60 +56,29 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_choose_command(const StringVec &cmd) {
|
void do_choose_command(const StringVec &cmd) {
|
||||||
int64_t index;
|
std::string action = gui_.get_action(util::strtoint(cmd[1], -1));
|
||||||
if (cmd.size() == 1) {
|
if (action == "") {
|
||||||
index = util::strtoint(cmd[0], -1);
|
stdostream() << "Invalid menu item #" << std::endl;
|
||||||
} else {
|
|
||||||
stdostream() << "c command (choose) expects a menu line number" << std::endl;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const Gui::EltVec &elts = gui_.elts();
|
Invocation inv(Invocation::KIND_PLAN, actor_id_, gui_place_, action);
|
||||||
if ((index < 0) || (index >= int(elts.size()))) {
|
stdostream() << "Invoking: " << inv.debug_string() << std::endl;
|
||||||
stdostream() << "No menu item #" << index << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string action = elts[index].action();
|
|
||||||
stdostream() << "Invoking plan: " << action << std::endl;
|
|
||||||
InvocationData dummyresult;
|
|
||||||
dummyresult["flavor"] = "chocolate";
|
|
||||||
dummyresult["color"] = "blue";
|
|
||||||
Invocation inv(Invocation::KIND_PLAN, actor_id_, gui_place_, action, dummyresult);
|
|
||||||
world_->invoke(inv);
|
world_->invoke(inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void do_snapshot_command(const StringVec &cmd) {
|
void do_snapshot_command(const StringVec &cmd) {
|
||||||
if (cmd.size() != 1) {
|
|
||||||
stdostream() << "s command (snapshot) takes no arguments" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
world_->snapshot();
|
world_->snapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_rollback_command(const StringVec &cmd) {
|
void do_rollback_command(const StringVec &cmd) {
|
||||||
if (cmd.size() != 1) {
|
|
||||||
stdostream() << "r command (rollback) takes no arguments" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
world_->rollback();
|
world_->rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_tick_command(const StringVec &cmd) {
|
void do_tick_command(const StringVec &cmd) {
|
||||||
int64_t clock;
|
world_->run_scheduled_threads(util::strtoint(cmd[1], -1));
|
||||||
if (cmd.size() == 2) {
|
|
||||||
clock = util::strtoint(cmd[1], -1);
|
|
||||||
} else {
|
|
||||||
stdostream() << "t command (tick) expects a time value" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
world_->run_scheduled_threads(clock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_quit_command(const StringVec &cmd) {
|
void do_quit_command(const StringVec &cmd) {
|
||||||
if (cmd.size() != 1) {
|
|
||||||
stdostream() << "q command (quit) takes no arguments" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
actor_id_ = 0;
|
actor_id_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,9 +92,9 @@ private:
|
|||||||
else if (words[0] == "snap") do_snapshot_command(words);
|
else if (words[0] == "snap") do_snapshot_command(words);
|
||||||
else if (words[0] == "roll") do_rollback_command(words);
|
else if (words[0] == "roll") do_rollback_command(words);
|
||||||
else if (words[0] == "tick") do_tick_command(words);
|
else if (words[0] == "tick") do_tick_command(words);
|
||||||
else if (util::validinteger(words[0])) do_choose_command(words);
|
else if (words[0] == "choose") do_choose_command(words);
|
||||||
else {
|
else {
|
||||||
stdostream() << "Unknown command: " << words[0] << std::endl;
|
stdostream() << "Unsupported command: " << words[0] << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,16 @@ StringVec split(const std::string &s, char sep) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string join(const StringVec &strs, const std::string &sep) {
|
||||||
|
if (strs.empty()) return "";
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << strs[0];
|
||||||
|
for (int i = 1; i < strs.size(); i++) {
|
||||||
|
oss << sep << strs[i];
|
||||||
|
}
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string repeat_string(const std::string &a, int n) {
|
std::string repeat_string(const std::string &a, int n) {
|
||||||
int len = a.size();
|
int len = a.size();
|
||||||
std::string result(len * n, ' ');
|
std::string result(len * n, ' ');
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ std::string hash_to_hex(const HashValue &hash);
|
|||||||
// Split a string into multiple strings
|
// Split a string into multiple strings
|
||||||
StringVec split(const std::string &s, char sep);
|
StringVec split(const std::string &s, char sep);
|
||||||
|
|
||||||
|
// Join multiple strings into one string
|
||||||
|
std::string join(const StringVec &strs, std::string sep);
|
||||||
|
|
||||||
// Return N repetitions of string A
|
// Return N repetitions of string A
|
||||||
std::string repeat_string(const std::string &a, int n);
|
std::string repeat_string(const std::string &a, int n);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user