Refactor luaconsole to make it easier to use
This commit is contained in:
@@ -34,10 +34,6 @@ public:
|
|||||||
channel_ = new_outgoing_channel("localhost:8085");
|
channel_ = new_outgoing_channel("localhost:8085");
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_lua(const std::string &lua) {
|
|
||||||
stdostream() << "Lua: " << lua << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void do_command(const util::StringVec &words) {
|
void do_command(const util::StringVec &words) {
|
||||||
stdostream() << "Command: ";
|
stdostream() << "Command: ";
|
||||||
for (const std::string &word : words) {
|
for (const std::string &word : words) {
|
||||||
@@ -46,27 +42,17 @@ public:
|
|||||||
stdostream() << std::endl;
|
stdostream() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void console_process(const std::string &line) {
|
|
||||||
console_.add(line);
|
|
||||||
int action = console_.action();
|
|
||||||
if (action == LuaConsole::DO_LUA) {
|
|
||||||
do_lua(console_.lua_expression());
|
|
||||||
console_.clear();
|
|
||||||
} else if (action == LuaConsole::DO_COMMAND) {
|
|
||||||
do_command(console_.words());
|
|
||||||
console_.clear();
|
|
||||||
} else if (action == LuaConsole::DO_SYNTAX) {
|
|
||||||
stdostream() << console_.syntax() << std::endl;
|
|
||||||
console_.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void event_update() {
|
virtual void event_update() {
|
||||||
// Check for keyboard input on stdin.
|
// Check for keyboard input on stdin.
|
||||||
while (true) {
|
while (true) {
|
||||||
std::string line = get_stdio_channel()->in()->readline();
|
std::string line = get_stdio_channel()->in()->readline();
|
||||||
if (line == "") break;
|
if (line == "") break;
|
||||||
console_process(line);
|
console_.add(line);
|
||||||
|
const util::StringVec &words = console_.words();
|
||||||
|
if (!words.empty()) {
|
||||||
|
do_command(words);
|
||||||
|
console_.clear();
|
||||||
|
}
|
||||||
get_stdio_channel()->out()->write_bytes(console_.get_prompt());
|
get_stdio_channel()->out()->write_bytes(console_.get_prompt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,11 @@ LuaConsole::~LuaConsole() {
|
|||||||
void LuaConsole::clear() {
|
void LuaConsole::clear() {
|
||||||
raw_input_ = "";
|
raw_input_ = "";
|
||||||
lines_ = 0;
|
lines_ = 0;
|
||||||
lua_expression_ = "";
|
|
||||||
words_.clear();
|
words_.clear();
|
||||||
syntax_ = "";
|
|
||||||
action_ = DO_NOTHING;
|
|
||||||
prompt_ = "> ";
|
prompt_ = "> ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LuaConsole::split_words() {
|
void LuaConsole::split_words() {
|
||||||
words_.clear();
|
words_.clear();
|
||||||
std::string acc;
|
std::string acc;
|
||||||
@@ -64,7 +62,7 @@ void LuaConsole::add(std::string line) {
|
|||||||
split_words();
|
split_words();
|
||||||
if (words_.size() >= 1) {
|
if (words_.size() >= 1) {
|
||||||
if (is_single_letter(words_[0]) || (util::validinteger(words_[0]))) {
|
if (is_single_letter(words_[0]) || (util::validinteger(words_[0]))) {
|
||||||
action_ = DO_COMMAND;
|
// We have a valid parsed command. Return it.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,19 +87,16 @@ void LuaConsole::add(std::string line) {
|
|||||||
size_t lmsg;
|
size_t lmsg;
|
||||||
const char *msg = lua_tolstring(lua_state_, -1, &lmsg);
|
const char *msg = lua_tolstring(lua_state_, -1, &lmsg);
|
||||||
const char *tp = msg + lmsg - leof;
|
const char *tp = msg + lmsg - leof;
|
||||||
if (strstr(msg, eof) == tp) {
|
if (strstr(msg, eof) != tp) {
|
||||||
action_ = DO_NOTHING;
|
words_.push_back("syntax");
|
||||||
} else {
|
words_.push_back(msg);
|
||||||
action_ = DO_SYNTAX;
|
|
||||||
syntax_ = msg;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
action_ = DO_LUA;
|
words_.push_back("lua");
|
||||||
lua_expression_ = partial;
|
words_.push_back(partial);
|
||||||
}
|
}
|
||||||
lua_settop(lua_state_, top);
|
lua_settop(lua_state_, top);
|
||||||
|
if (words_.empty()) {
|
||||||
if (action_ == DO_NOTHING) {
|
|
||||||
prompt_ = ">> ";
|
prompt_ = ">> ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,22 +3,26 @@
|
|||||||
// LuaConsole:
|
// LuaConsole:
|
||||||
//
|
//
|
||||||
// Used to parse commands that are being interactively typed
|
// Used to parse commands that are being interactively typed
|
||||||
// in by a user.
|
// in by a user. The common usage pattern is:
|
||||||
//
|
//
|
||||||
// The command syntax is always a single character command,
|
// 1. Print the prompt suggested by 'get_prompt'.
|
||||||
// followed by arguments. Only two commands are hardwired:
|
// 2. Read a line of text from stdin.
|
||||||
|
// 3. Add the line to the LuaConsole using 'add'.
|
||||||
|
// 4. Get the command words using 'words'.
|
||||||
|
// 5. If the words are empty, do nothing.
|
||||||
|
// 6. If the words contain something, execute and call 'clear'.
|
||||||
//
|
//
|
||||||
// l - evaluate lua expression
|
// The 'words' returned by the luaconsole can be empty, meaning
|
||||||
// r - evaluate lua expression with 'return' prepended
|
// that there's no command to execute. If the words are nonempty,
|
||||||
|
// then the first word is the command. There are two hardwired
|
||||||
|
// commands:
|
||||||
//
|
//
|
||||||
// The console expects you to add lines of text one at a time.
|
// lua <expr> - execute a lua expression
|
||||||
// After adding a line, the console will recommend one of these
|
// syntax <message> - print a syntax error message
|
||||||
// actions:
|
|
||||||
//
|
//
|
||||||
// 1. DO_NOTHING: Add more lines of text.
|
// If the first word is anything else, it means the user typed
|
||||||
// 2. DO_LUA: Evaluate a lua expression.
|
// that word on the command line. It is up to you to interpret
|
||||||
// 3. DO_OTHER: Execute a non-lua command.
|
// such commands.
|
||||||
// 4. DO_SYNTAX: Print a lua syntax error.
|
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -30,46 +34,34 @@
|
|||||||
|
|
||||||
class LuaConsole {
|
class LuaConsole {
|
||||||
public:
|
public:
|
||||||
enum {
|
|
||||||
DO_NOTHING, // We need more input text.
|
|
||||||
DO_COMMAND, // We have a valid slash command.
|
|
||||||
DO_LUA, // We have a valid lua expression.
|
|
||||||
DO_SYNTAX, // We have a syntax error.
|
|
||||||
};
|
|
||||||
using StringVec = std::vector<std::string>;
|
using StringVec = std::vector<std::string>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
lua_State *lua_state_;
|
lua_State *lua_state_;
|
||||||
int action_;
|
|
||||||
std::string raw_input_;
|
std::string raw_input_;
|
||||||
int lines_;
|
int lines_;
|
||||||
std::string lua_expression_;
|
|
||||||
StringVec words_;
|
StringVec words_;
|
||||||
std::string syntax_;
|
|
||||||
std::string prompt_;
|
std::string prompt_;
|
||||||
|
|
||||||
void split_words();
|
void split_words();
|
||||||
|
void clear_command();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LuaConsole();
|
LuaConsole();
|
||||||
~LuaConsole();
|
~LuaConsole();
|
||||||
|
|
||||||
// Get the recommended action.
|
|
||||||
int action() const { return action_; }
|
|
||||||
|
|
||||||
// Fetch the stored prompt. Also clears the stored prompt. You should fetch
|
// Fetch the stored prompt. Also clears the stored prompt. You should fetch
|
||||||
// and print the prompt after 'add' or 'clear'.
|
// and print the prompt after 'add' or 'clear'.
|
||||||
std::string get_prompt();
|
std::string get_prompt();
|
||||||
|
|
||||||
// When action is DO_COMMAND, get the command words.
|
// Get the command words.
|
||||||
|
//
|
||||||
|
// Returns the empty vector if there is no command.
|
||||||
|
// If there is a command, the first word is the command word.
|
||||||
|
// See the file comment for certain built-in command words.
|
||||||
|
//
|
||||||
const StringVec &words() const { return words_; }
|
const StringVec &words() const { return words_; }
|
||||||
|
|
||||||
// When action is DO_LUA, get the valid lua expression.
|
|
||||||
std::string lua_expression() const { return lua_expression_; }
|
|
||||||
|
|
||||||
// When action is DO_SYNTAX, get the syntax error.
|
|
||||||
const std::string &syntax() const { return syntax_; }
|
|
||||||
|
|
||||||
// Add a line of text that was just read from the console.
|
// Add a line of text that was just read from the console.
|
||||||
// If more input is needed, stores the ">> " prompt.
|
// If more input is needed, stores the ">> " prompt.
|
||||||
void add(std::string line);
|
void add(std::string line);
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ private:
|
|||||||
int64_t actor_id_;
|
int64_t actor_id_;
|
||||||
int64_t printbuffer_line_;
|
int64_t printbuffer_line_;
|
||||||
|
|
||||||
|
void do_lua_command(const StringVec &cmd);
|
||||||
|
void do_syntax_command(const StringVec &cmd);
|
||||||
void do_view_command(const StringVec &cmd);
|
void do_view_command(const StringVec &cmd);
|
||||||
void do_menu_command(const StringVec &cmd);
|
void do_menu_command(const StringVec &cmd);
|
||||||
void do_choose_command(const StringVec &cmd);
|
void do_choose_command(const StringVec &cmd);
|
||||||
@@ -36,7 +38,6 @@ private:
|
|||||||
void do_rollback_command(const StringVec &cmd);
|
void do_rollback_command(const StringVec &cmd);
|
||||||
void do_tick_command(const StringVec &cmd);
|
void do_tick_command(const StringVec &cmd);
|
||||||
|
|
||||||
void do_lua(const std::string &exp);
|
|
||||||
void do_command(const StringVec &exp);
|
void do_command(const StringVec &exp);
|
||||||
|
|
||||||
void check_redirects();
|
void check_redirects();
|
||||||
@@ -47,7 +48,25 @@ public:
|
|||||||
virtual void event_update();
|
virtual void event_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void TextGame::do_lua_command(const StringVec &words) {
|
||||||
|
assert(world_->stack_is_clear());
|
||||||
|
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 TextGame::do_syntax_command(const StringVec &words) {
|
||||||
|
stdostream() << "Syntax Error: ";
|
||||||
|
for (int i = 1; i < int(words.size()); i++) {
|
||||||
|
stdostream() << words[i] << " ";
|
||||||
|
}
|
||||||
|
stdostream() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void TextGame::do_view_command(const StringVec &cmd) {
|
void TextGame::do_view_command(const StringVec &cmd) {
|
||||||
if (cmd.size() != 1) {
|
if (cmd.size() != 1) {
|
||||||
@@ -102,12 +121,6 @@ void TextGame::do_choose_command(const StringVec &cmd) {
|
|||||||
world_->invoke(inv);
|
world_->invoke(inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextGame::do_lua(const std::string &exp) {
|
|
||||||
assert(world_->stack_is_clear());
|
|
||||||
InvocationData dummyresult;
|
|
||||||
Invocation inv(Invocation::KIND_LUA, actor_id_, actor_id_, exp, dummyresult);
|
|
||||||
world_->invoke(inv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextGame::do_snapshot_command(const StringVec &cmd) {
|
void TextGame::do_snapshot_command(const StringVec &cmd) {
|
||||||
if (cmd.size() != 1) {
|
if (cmd.size() != 1) {
|
||||||
@@ -146,7 +159,9 @@ void TextGame::do_quit_command(const StringVec &cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextGame::do_command(const StringVec &words) {
|
void TextGame::do_command(const StringVec &words) {
|
||||||
if (words[0] == "v") do_view_command(words);
|
if (words[0] == "lua") do_lua_command(words);
|
||||||
|
else if (words[0] == "syntax") do_syntax_command(words);
|
||||||
|
else if (words[0] == "v") do_view_command(words);
|
||||||
else if (words[0] == "m") do_menu_command(words);
|
else if (words[0] == "m") do_menu_command(words);
|
||||||
else if (words[0] == "q") do_quit_command(words);
|
else if (words[0] == "q") do_quit_command(words);
|
||||||
else if (words[0] == "s") do_snapshot_command(words);
|
else if (words[0] == "s") do_snapshot_command(words);
|
||||||
@@ -205,18 +220,11 @@ void TextGame::event_update()
|
|||||||
std::string line = get_stdio_channel()->in()->readline();
|
std::string line = get_stdio_channel()->in()->readline();
|
||||||
if (line == "") break;
|
if (line == "") break;
|
||||||
console_.add(line);
|
console_.add(line);
|
||||||
int action = console_.action();
|
const StringVec &words = console_.words();
|
||||||
if (action == LuaConsole::DO_LUA) {
|
if (!words.empty()) {
|
||||||
do_lua(console_.lua_expression());
|
do_command(words);
|
||||||
console_.clear();
|
console_.clear();
|
||||||
channel_printbuffer();
|
channel_printbuffer();
|
||||||
} else if (action == LuaConsole::DO_COMMAND) {
|
|
||||||
do_command(console_.words());
|
|
||||||
console_.clear();
|
|
||||||
channel_printbuffer();
|
|
||||||
} else if (action == LuaConsole::DO_SYNTAX) {
|
|
||||||
stdostream() << console_.syntax() << std::endl;
|
|
||||||
console_.clear();
|
|
||||||
}
|
}
|
||||||
check_redirects();
|
check_redirects();
|
||||||
if (actor_id_ == 0) {
|
if (actor_id_ == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user