From 82381ada2ece968f0510f76d5f3f00c333c68b13 Mon Sep 17 00:00:00 2001 From: jyelon Date: Thu, 23 Dec 2021 14:38:01 -0500 Subject: [PATCH] Fix a bug in function registry, improve docs --- luprex/core/cpp/luastack.hpp | 8 --- luprex/core/cpp/source.cpp | 28 +++++---- luprex/core/cpp/util.cpp | 18 ++++++ luprex/core/cpp/util.hpp | 3 + luprex/core/cpp/world-accessor.cpp | 96 +++++++++++++++++++++++------- 5 files changed, 112 insertions(+), 41 deletions(-) diff --git a/luprex/core/cpp/luastack.hpp b/luprex/core/cpp/luastack.hpp index d05ebd3d..c91b7557 100644 --- a/luprex/core/cpp/luastack.hpp +++ b/luprex/core/cpp/luastack.hpp @@ -399,7 +399,6 @@ public: void movesortablekey(LuaSlot val, LuaStack &other, LuaSlot otherslot); - bool rawequal(LuaSlot v1, LuaSlot v2) const { return lua_rawequal(L_, v1, v2); } @@ -417,13 +416,6 @@ public: pop_any_value(target); } - template - void gettable(RT &target, LuaSlot tab, KT key) const { - push_any_value(key); - lua_gettable(L_, tab); - pop_any_value(target); - } - template void rawget(RT &target, LuaSlot tab, KT key) const { push_any_value(key); diff --git a/luprex/core/cpp/source.cpp b/luprex/core/cpp/source.cpp index 0b050a8f..1d92d3ae 100644 --- a/luprex/core/cpp/source.cpp +++ b/luprex/core/cpp/source.cpp @@ -497,21 +497,23 @@ void SourceDB::register_lua_builtins() { LS.getglobaltable(globals); auto regs = LuaFunctionReg::all(); for (LuaFunctionReg *reg : regs) { - std::string funcname; - std::string classname; - get_reg_name(reg, classname, funcname); - if (classname.empty()) { - LS.rawget(func, globals, funcname); - if (LS.iscfunction(func)) { - reg->set_func(lua_tocfunction(L, func.index())); - } - } else { - LS.rawget(classtab, globals, classname); - if (LS.istable(classtab)) { - LS.rawget(func, classtab, funcname); + if (reg->get_func() == nullptr) { + std::string funcname; + std::string classname; + get_reg_name(reg, classname, funcname); + if (classname.empty()) { + LS.rawget(func, globals, funcname); if (LS.iscfunction(func)) { reg->set_func(lua_tocfunction(L, func.index())); } + } else { + LS.rawget(classtab, globals, classname); + if (LS.istable(classtab)) { + LS.rawget(func, classtab, funcname); + if (LS.iscfunction(func)) { + reg->set_func(lua_tocfunction(L, func.index())); + } + } } } } @@ -534,7 +536,7 @@ std::string SourceDB::function_docs(const LuaStack &LS0, LuaSlot fn) { std::string funcname; get_reg_name(reg, classname, funcname); std::ostringstream oss; - util::StringVec docs = util::split_lines(reg->get_docs()); + util::StringVec docs = util::split_docstring(reg->get_docs()); for (const std::string &line : docs) { oss << "-- " << line << std::endl; } diff --git a/luprex/core/cpp/util.cpp b/luprex/core/cpp/util.cpp index 8629652c..5ef0f848 100644 --- a/luprex/core/cpp/util.cpp +++ b/luprex/core/cpp/util.cpp @@ -177,6 +177,24 @@ StringVec split_lines(const std::string &s) { return result; } +StringVec split_docstring(const std::string &s) { + StringVec result; + int start = 0; + for (int i = 0; i < int(s.size()); i++) { + if (s[i]=='|') { + int len = i-start; + if ((len > 0)||(start > 0)) { + result.push_back(s.substr(start, i-start)); + } + start = i + 1; + } + } + if (start < int(s.size())) { + result.push_back(s.substr(start, s.size()-start)); + } + return result; +} + std::string join(const StringVec &strs, const std::string &sep) { if (strs.empty()) return ""; std::ostringstream oss; diff --git a/luprex/core/cpp/util.hpp b/luprex/core/cpp/util.hpp index 3ef38b38..999d0b56 100644 --- a/luprex/core/cpp/util.hpp +++ b/luprex/core/cpp/util.hpp @@ -70,6 +70,9 @@ StringVec split(const std::string &s, char sep); // Split a string into multiple strings using \r or \n StringVec split_lines(const std::string &s); +// Split a string into multiple lines using |, remove any leading blank line. +StringVec split_docstring(const std::string &s); + // Join multiple strings into one string std::string join(const StringVec &strs, std::string sep); diff --git a/luprex/core/cpp/world-accessor.cpp b/luprex/core/cpp/world-accessor.cpp index d30bbe97..b7042a4e 100644 --- a/luprex/core/cpp/world-accessor.cpp +++ b/luprex/core/cpp/world-accessor.cpp @@ -17,7 +17,9 @@ static void tangible_getall(LuaStack &LS0, LuaSlot list, const util::IdVector &i LS.result(); } -LuaDefine(tangible_animstate, "tan", "get the final animation state of the tangible") { +LuaDefine(tangible_animstate, "tan", + "|Get the entire animation state of the tangible." + "|Returns six values: graphic,plane,x,y,z,facing.") { LuaArg tanobj; LuaRet graphic, plane, x, y, z, facing; LuaStack LS(L, tanobj, graphic, plane, x, y, z, facing); @@ -33,7 +35,25 @@ LuaDefine(tangible_animstate, "tan", "get the final animation state of the tangi return LS.result(); } -LuaDefine(tangible_animate, "tan,configtable", "add an animation step to the tangible") { +LuaDefine(tangible_xyz, "tan", + "|Get the current coordinates of the tangible." + "|Returns three values: x, y, z") { + LuaArg tanobj; + LuaRet x, y, z; + LuaStack LS(L, tanobj, x, y, z); + World *w = World::fetch_global_pointer(L); + Tangible *tan = w->tangible_get(LS, tanobj); + const AnimStep &aqback = tan->anim_queue_.back(); + LS.set(x, aqback.xyz().x); + LS.set(y, aqback.xyz().y); + LS.set(z, aqback.xyz().z); + return LS.result(); +} + +LuaDefine(tangible_animate, "tan,configtable", + "|Add an animation step to the tangible." + "|The configtable is a table containing any of the following:" + "|action,graphic,plane,x,y,z,facing") { LuaArg tanobj, config; LuaStack LS(L, tanobj, config); World *w = World::fetch_global_pointer(L); @@ -50,7 +70,11 @@ LuaDefine(tangible_animate, "tan,configtable", "add an animation step to the tan return LS.result(); } -LuaDefine(tangible_setclass, "tan,classname", "set the class of the tangible") { +LuaDefine(tangible_setclass, "tan,class", + "|Set the class of the tangible." + "|The class can be a 'class table' (ie, a table of methods), " + "|or it can be a string that names a class. The tangible is " + "|given an __index metamethod that points at the class table.") { LuaArg tanobj, classname; LuaVar classtab, mt; LuaStack LS(L, tanobj, classname, classtab, mt); @@ -66,7 +90,10 @@ LuaDefine(tangible_setclass, "tan,classname", "set the class of the tangible") { return LS.result(); } -LuaDefine(tangible_getclass, "tan", "get the class of the tangible, if any") { +LuaDefine(tangible_getclass, "tan", + "|Get the class of the tangible, if any." + "|The return value is a string, the class name, not" + "|the class table.") { LuaArg tanobj; LuaVar mt, classtab; LuaRet classname; @@ -84,7 +111,10 @@ LuaDefine(tangible_getclass, "tan", "get the class of the tangible, if any") { return LS.result(); } -LuaDefine(tangible_delete, "tan", "delete the specified tangible") { +LuaDefine(tangible_delete, "tan", + "|Delete the specified tangible." + "|This cannot be used to delete player tangibles," + "|To delete a player, use tangible.redirect") { LuaArg tanobj; LuaStack LS(L, tanobj); World *w = World::fetch_global_pointer(L); @@ -98,7 +128,10 @@ LuaDefine(tangible_delete, "tan", "delete the specified tangible") { return LS.result(); } -LuaDefine(tangible_build, "configtable", "build a new tangible object") { +LuaDefine(tangible_build, "configtable", + "|Build a new tangible object." + "|The configtable must contain: class,x,y,z,plane,graphic." + "|The configtable can optionally contain: facing.") { LuaArg config; LuaVar classname, classtab, mt; LuaRet database; @@ -148,7 +181,10 @@ LuaDefine(tangible_build, "configtable", "build a new tangible object") { return LS.result(); } -LuaDefine(tangible_get, "id", "get the tangible with the specified id (debugging only)") { +LuaDefine(tangible_get, "id", + "|Get the tangible with the specified id." + "|This is for debugging only and will be removed in" + "|the released version.") { LuaArg id; LuaVar tangibles; LuaRet database; @@ -162,7 +198,8 @@ LuaDefine(tangible_get, "id", "get the tangible with the specified id (debugging return LS.result(); } -LuaDefine(tangible_redirect, "tan1,tan2,bulldozetan1", "redirect is not working yet") { +LuaDefine(tangible_redirect, "tan1,tan2,bulldozetan1", + "|Redirect is not working yet") { LuaArg actor1, actor2, bldz; LuaStack LS(L, actor1, actor2, bldz); World *w = World::fetch_global_pointer(L); @@ -184,7 +221,10 @@ LuaDefine(tangible_redirect, "tan1,tan2,bulldozetan1", "redirect is not working return LS.result(); } -LuaDefine(tangible_id, "tan", "return the tangible's id number (debugging only)") { +LuaDefine(tangible_id, "tan", + "|Return the tangible's id number." + "|This is for debugging only and will be removed" + "|in the released version.") { LuaArg tanobj; LuaRet id; LuaStack LS(L, tanobj, id); @@ -196,7 +236,8 @@ LuaDefine(tangible_id, "tan", "return the tangible's id number (debugging only)" return LS.result(); } -LuaDefine(tangible_actor, "", "return the current actor") { +LuaDefine(tangible_actor, "", + "|Return the current actor.") { LuaRet actor; LuaVar tangibles; LuaStack LS(L, tangibles, actor); @@ -206,7 +247,8 @@ LuaDefine(tangible_actor, "", "return the current actor") { return LS.result(); } -LuaDefine(tangible_place, "", "return the current place") { +LuaDefine(tangible_place, "", + "|Return the current place.") { LuaRet place; LuaVar tangibles; LuaStack LS(L, tangibles, place); @@ -216,7 +258,11 @@ LuaDefine(tangible_place, "", "return the current place") { return LS.result(); } -LuaDefine(tangible_near, "tan,radius,omit_nowhere,omit_self", "scan near the specified tangible") { +LuaDefine(tangible_near, "tan,radius,omit_nowhere,omit_self", + "|Scan near the specified tangible." + "|If omit_nowhere is true, and the tangible is on the nowhere plane," + "|then the scan returns empty. If omit_self is true, then the " + "|tangible passed in is omitted from the results.") { LuaArg ltan, lradius, lomit_nowhere, lomit_self; LuaRet list; LuaStack LS(L, ltan, lradius, lomit_nowhere, lomit_self, list); @@ -231,7 +277,10 @@ LuaDefine(tangible_near, "tan,radius,omit_nowhere,omit_self", "scan near the spe return LS.result(); } -LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere", "scan the specified plane") { +LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere", + "|Scan the specified plane." + "|If omit_nowhere is true, and the plane is 'nowhere', then" + "|the scan returns empty.") { LuaArg lplane, lx, ly, lradius, lomit_nowhere; LuaRet list; LuaStack LS(L, lplane, lx, ly, lradius, lomit_nowhere, list); @@ -246,14 +295,16 @@ LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere", "scan the specified pl return LS.result(); } -LuaDefine(wait, "nticks", "wait the specified number of ticks") { +LuaDefine(wait, "nticks", + "|Wait the specified number of ticks.") { if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) { luaL_error(L, "Argument to wait must be a number."); } return lua_yield(L, 1); } -LuaDefine(tangible_nopredict, "", "stop predictive execution of this thread") { +LuaDefine(tangible_nopredict, "", + "|Stop predictive execution of this thread.") { if (lua_gettop(L) != 0) { luaL_error(L, "tangible.nopredict takes no arguments"); } @@ -265,7 +316,8 @@ LuaDefine(tangible_nopredict, "", "stop predictive execution of this thread") { } } -LuaDefine(pprint, "obj1,obj2,...", "pretty-print all the objects") { +LuaDefine(pprint, "obj1,obj2,...", + "|Pretty-print object or objects.") { World *w = World::fetch_global_pointer(L); std::ostream *ostream = w->lthread_print_stream(); LuaStack LS(L); @@ -277,19 +329,23 @@ LuaDefine(pprint, "obj1,obj2,...", "pretty-print all the objects") { return LS.result(); } -LuaDefine(print, "obj1,obj2,...", "print all the objects") { +LuaDefine(print, "obj1,obj2,...", + "|Print object or objects.") { World *w = World::fetch_global_pointer(L); std::ostream *ostream = w->lthread_print_stream(); LuaStack LS(L); - for (int i = 1; i <= lua_gettop(L); i++) { + int n = lua_gettop(L); + for (int i = 1; i <= n; i++) { LuaSpecial root(i); atomic_print(LS, root, false, ostream); - (*ostream) << std::endl; + if (i < n) (*ostream) << " "; } + (*ostream) << std::endl; return LS.result(); } -LuaDefine(doc, "function", "print documentation for specified function") { +LuaDefine(doc, "function", + "|Print documentation for specified function.") { World *w = World::fetch_global_pointer(L); std::ostream *ostream = w->lthread_print_stream(); LuaArg func;