Makeclass cleaned up
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
LuaDefine(globaldb_enable, "c") {
|
||||
LuaVar globaldb;
|
||||
LuaStack LS(L, globaldb);
|
||||
LS.getfield(globaldb, LuaRegistry, "globaldb");
|
||||
LS.rawget(globaldb, LuaRegistry, "globaldb");
|
||||
if (!LS.istable(globaldb)) {
|
||||
LS.newtable(globaldb);
|
||||
LS.setfield(LuaRegistry, "globaldb", globaldb);
|
||||
LS.rawset(LuaRegistry, "globaldb", globaldb);
|
||||
}
|
||||
return LS.result();
|
||||
}
|
||||
@@ -26,7 +26,7 @@ LuaDefine(globaldb_global, "f") {
|
||||
LuaStack LS(L, globalname, globaltab, globaldb);
|
||||
|
||||
// Get a pointer to the globaldb.
|
||||
LS.getfield(globaldb, LuaRegistry, "globaldb");
|
||||
LS.rawget(globaldb, LuaRegistry, "globaldb");
|
||||
if (!LS.istable(globaldb)) {
|
||||
luaL_error(L, "globaldb is not enabled");
|
||||
}
|
||||
@@ -44,6 +44,6 @@ LuaDefine(globaldb_global, "f") {
|
||||
// Create a new globaltab and store it in the globaldb.
|
||||
LS.newtable(globaltab);
|
||||
LS.rawset(globaldb, globalname, globaltab);
|
||||
LS.setfield(globaltab, "__global", globalname);
|
||||
LS.rawset(globaltab, "__global", globalname);
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ LuaDefine(gui_create, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(gui_add_menu_item, "c") {
|
||||
LuaDefine(gui_menu_item, "c") {
|
||||
LuaArg lgui, lid;
|
||||
LuaStack LS(L, lgui, lid);
|
||||
Gui *gui = LS.ckuserdata<Gui>(lgui);
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "luaconsole.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
|
||||
static bool is_single_letter(const std::string &s) {
|
||||
return ((s.size() == 1) && (s[0] >= 'a') && (s[0] <= 'z'));
|
||||
}
|
||||
|
||||
LuaConsole::LuaConsole() {
|
||||
lua_state_ = lua_open();
|
||||
@@ -52,14 +58,16 @@ void LuaConsole::add(std::string line) {
|
||||
// Try to interpret it as a special command.
|
||||
if (lines_ == 1) {
|
||||
split_words();
|
||||
if ((words_.size() >= 1)&&(words_[0].size() == 1)) {
|
||||
action_ = DO_COMMAND;
|
||||
return;
|
||||
if (words_.size() >= 1) {
|
||||
if (is_single_letter(words_[0]) || (util::validinteger(words_[0]))) {
|
||||
action_ = DO_COMMAND;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
words_.clear();
|
||||
|
||||
// Strip the leading punctuation from lua commands.
|
||||
// Translate lua expression with leading '=' to 'return'
|
||||
std::string partial;
|
||||
if (raw_input_[0] == '=') {
|
||||
partial = std::string("return ") + raw_input_.substr(1);
|
||||
@@ -67,7 +75,7 @@ void LuaConsole::add(std::string line) {
|
||||
partial = raw_input_;
|
||||
}
|
||||
|
||||
// Analyze lua expressions.
|
||||
// Try to parse the lua expression
|
||||
int top = lua_gettop(lua_state_);
|
||||
int status = luaL_loadbuffer(lua_state_, partial.c_str(), partial.size(), "=stdin");
|
||||
if (status == LUA_ERRSYNTAX)
|
||||
|
||||
@@ -189,33 +189,17 @@ int LuaStack::next(LuaSlot tab, LuaSlot key, LuaSlot value) const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool LuaStack::isemptytable(LuaSlot tab) const {
|
||||
if (lua_istable(L_, tab)) {
|
||||
lua_pushnil(L_);
|
||||
if (lua_next(L_, tab) == 0) {
|
||||
return true;
|
||||
}
|
||||
lua_pop(L_, 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LuaStack::newtable(LuaSlot target) const {
|
||||
lua_newtable(L_);
|
||||
lua_replace(L_, target);
|
||||
}
|
||||
|
||||
void LuaStack::makeclass(LuaSlot classtab, LuaSlot classname) const {
|
||||
int top = lua_gettop(L_);
|
||||
checkstring(classname);
|
||||
|
||||
// Special case: if the classname is _G, return global env.
|
||||
lua_pushstring(L_, "_G");
|
||||
int eqlg = lua_equal(L_, -1, classname.index());
|
||||
lua_settop(L_, top);
|
||||
if (eqlg) {
|
||||
set(classtab, LuaGlobals);
|
||||
return;
|
||||
// Special case: if the classname is _G, detect and error.
|
||||
if (equal(classname, "_G")) {
|
||||
luaL_error(L_, "_G is explicitly not allowed as a class name");
|
||||
}
|
||||
|
||||
// Get the classtab from the global environment.
|
||||
@@ -236,6 +220,19 @@ void LuaStack::makeclass(LuaSlot classtab, LuaSlot classname) const {
|
||||
setfield(classtab, "__class", classname);
|
||||
}
|
||||
|
||||
void LuaStack::makesubtable(LuaSlot sub, LuaSlot tab, const char *name) const {
|
||||
rawget(sub, tab, name);
|
||||
if (istable(sub)) {
|
||||
return;
|
||||
} else if (isnil(sub)) {
|
||||
newtable(sub);
|
||||
rawset(tab, name, sub);
|
||||
return;
|
||||
} else {
|
||||
luaL_error(L_, "%s is not a table", name);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaStack::setlightuserdata(LuaSlot target, void *p) const {
|
||||
lua_pushlightuserdata(L_, p);
|
||||
lua_replace(L_, target);
|
||||
|
||||
@@ -426,7 +426,7 @@ public:
|
||||
|
||||
void newtable(LuaSlot target) const;
|
||||
|
||||
void makeclass(LuaSlot tab, LuaSlot name) const;
|
||||
void makesubtable(LuaSlot sub, LuaSlot tab, const char *name) const;
|
||||
|
||||
void setlightuserdata(LuaSlot target, void *p) const;
|
||||
|
||||
@@ -456,11 +456,26 @@ public:
|
||||
void clearuserdata(LuaSlot target) { clear_tagged_pointer(target); }
|
||||
|
||||
int next(LuaSlot tab, LuaSlot key, LuaSlot value) const;
|
||||
bool isemptytable(LuaSlot s) const;
|
||||
|
||||
bool equal(LuaSlot v1, LuaSlot v2) {
|
||||
void makeclass(LuaSlot tab, LuaSlot name) const;
|
||||
|
||||
void makeclass(LuaSlot tab, const char *name) const {
|
||||
push_any_value(name);
|
||||
LuaSpecial classname(lua_gettop(L_));
|
||||
makeclass(tab, classname);
|
||||
lua_pop(L_, 1);
|
||||
}
|
||||
|
||||
bool equal(LuaSlot v1, LuaSlot v2) const {
|
||||
return lua_equal(L_, v1, v2);
|
||||
}
|
||||
|
||||
bool equal(LuaSlot v1, const char *name) const {
|
||||
push_any_value(name);
|
||||
bool result = lua_equal(L_, v1, -1);
|
||||
lua_pop(L_, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
void set(T1 &target, T2 value) const {
|
||||
|
||||
@@ -40,6 +40,16 @@ LuaDefine(source_makeclass, "f") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(source_maketangible, "f") {
|
||||
LuaArg classname;
|
||||
LuaRet classtab;
|
||||
LuaVar subtab;
|
||||
LuaStack LS(L, classname, classtab, subtab);
|
||||
LS.makeclass(classtab, classname);
|
||||
LS.makesubtable(subtab, classtab, "action");
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
// Load the builtins.
|
||||
|
||||
static void load_builtin(lua_State *L, const char *name, lua_CFunction func) {
|
||||
@@ -189,18 +199,22 @@ static void source_clear_globals(lua_State *L) {
|
||||
// Restore the lua builtins from the backup snapshot.
|
||||
//
|
||||
static void source_restore_builtins(lua_State *L) {
|
||||
LuaVar snapshot, key, value, skey, svalue, subglobal;
|
||||
LuaStack LS(L, snapshot, key, value, skey, svalue, subglobal);
|
||||
LuaVar snapshot, key, value, skey, svalue, target;
|
||||
LuaStack LS(L, snapshot, key, value, skey, svalue, target);
|
||||
|
||||
LS.getfield(snapshot, LuaRegistry, "source_snapshot_builtins");
|
||||
LS.setfield(LuaGlobals, "_G", LuaGlobals);
|
||||
LS.set(key, LuaNil);
|
||||
while (LS.next(snapshot, key, value) != 0) {
|
||||
LS.checktable(value);
|
||||
LS.makeclass(subglobal, key);
|
||||
if (LS.equal(key, "_G")) {
|
||||
LS.set(target, LuaGlobals);
|
||||
} else {
|
||||
LS.makeclass(target, key);
|
||||
}
|
||||
LS.set(skey, LuaNil);
|
||||
while (LS.next(value, skey, svalue) != 0) {
|
||||
LS.rawset(subglobal, skey, svalue);
|
||||
LS.rawset(target, skey, svalue);
|
||||
}
|
||||
}
|
||||
LS.result();
|
||||
|
||||
@@ -109,13 +109,18 @@ void TextGame::do_menu_command(const StringVec &cmd) {
|
||||
|
||||
void TextGame::do_choose_command(const StringVec &cmd) {
|
||||
int64_t index;
|
||||
if (cmd.size() == 2) {
|
||||
index = util::strtoint(cmd[1], -1);
|
||||
if (cmd.size() == 1) {
|
||||
index = util::strtoint(cmd[0], -1);
|
||||
} else {
|
||||
std::cerr << "c command (choose) expects a menu line number" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cerr << "Choose command (index " << index << ") not implemented yet." << std::endl;
|
||||
const Gui::EltVec &elts = gui_.elts();
|
||||
if ((index < 0) || (index >= int(elts.size()))) {
|
||||
std::cerr << "No menu item #" << index << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cerr << "Choosing menu item: " << elts[index].id() << std::endl;
|
||||
}
|
||||
|
||||
void TextGame::do_snapshot_command(const StringVec &cmd) {
|
||||
@@ -143,14 +148,13 @@ void TextGame::do_quit_command(const StringVec &cmd) {
|
||||
}
|
||||
|
||||
void TextGame::do_command(const StringVec &words) {
|
||||
switch (words[0][0]) {
|
||||
case 'v': do_view_command(words); break;
|
||||
case 'm': do_menu_command(words); break;
|
||||
case 'c': do_choose_command(words); break;
|
||||
case 'q': do_quit_command(words); break;
|
||||
case 's': do_snapshot_command(words); break;
|
||||
case 'r': do_rollback_command(words); break;
|
||||
default:
|
||||
if (words[0] == "v") do_view_command(words);
|
||||
else if (words[0] == "m") do_menu_command(words);
|
||||
else if (words[0] == "q") do_quit_command(words);
|
||||
else if (words[0] == "s") do_snapshot_command(words);
|
||||
else if (words[0] == "r") do_rollback_command(words);
|
||||
else if (util::validinteger(words[0])) do_choose_command(words);
|
||||
else {
|
||||
std::cerr << "Unknown command: " << words[0] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ std::string toupper(std::string input) {
|
||||
return input;
|
||||
}
|
||||
|
||||
bool validinteger(const std::string &value) {
|
||||
char *endptr;
|
||||
strtoll(value.c_str(), &endptr, 10);
|
||||
return (endptr == value.c_str() + value.size());
|
||||
}
|
||||
|
||||
int64_t strtoint(const std::string &value, int64_t errval) {
|
||||
char *endptr;
|
||||
int64_t result = strtoll(value.c_str(), &endptr, 10);
|
||||
|
||||
@@ -18,6 +18,9 @@ using stringset = std::set<std::string>;
|
||||
std::string tolower(std::string input);
|
||||
std::string toupper(std::string input);
|
||||
|
||||
// Return true if the string can be parsed as an integer.
|
||||
bool validinteger(const std::string &value);
|
||||
|
||||
// String to integer. Returns errval if the number is not parseable.
|
||||
int64_t strtoint(const std::string &value, int64_t errval);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ void Tangible::be_a_player() {
|
||||
LuaVar classtab, mt, place, tangibles;
|
||||
LuaStack LS(world_->state(), classtab, mt, place, tangibles);
|
||||
|
||||
LS.call(classtab, source_makeclass, "player");
|
||||
LS.makeclass(classtab, "player");
|
||||
LS.getfield(tangibles, LuaRegistry, "tangibles");
|
||||
LS.rawget(place, tangibles, anim_queue_.get_id());
|
||||
LS.getmetatable(mt, place);
|
||||
|
||||
Reference in New Issue
Block a user