diff --git a/luprex/cpp/core/globaldb.cpp b/luprex/cpp/core/globaldb.cpp index e2de6a1a..9a1778ab 100644 --- a/luprex/cpp/core/globaldb.cpp +++ b/luprex/cpp/core/globaldb.cpp @@ -1,72 +1,74 @@ #include "luastack.hpp" #include "globaldb.hpp" -LuaDefine(global_once, "name", "for a given string, returns true exactly once") { + +LuaDefine(global_set, "varname, value", + "|Store data in the global data table." + "|" + "|You can store global data using global.set, then you can" + "|retrieve it using global.get. You can also retrieve data using" + "|gv.varname, which is just shorthand for global.get. You may not" + "|store data using gv.varname=value, this yields the error 'Use " + "|global.set to store data in the global data table.'" + "|" + "|Values stored using global.set are difference transmitted to all" + "|connected clients immediately. When a new client connects," + "|he will receive all the global data." + "|" + "|The global data table is not the same thing as the lua " + "|environment table. Trying to store data in the lua environment" + "|table will seem to work, at first, but the data will not get" + "|difference transmitted, and will eventually be cleared and lost." + "|Therefore, it is essential that global data be stored in the" + "|global data table (using global.set) instead of in the lua" + "|environment table." + "|" + "|There are certain restrictions on the values that you store." + "|The value can contain strings, numbers, simple tables, and" + "|tangibles. Nothing else is allowed. Simple tables are tables" + "|that don't have metatables, and that aren't special tables such" + "|as classes, the lua environment table, the registry, or the like." + "|" + "|When you store the value, a recursive copy is made and stored." + "|When you call global.get, you obtain the copy. Any attempt to" + "|mutate the copy will fail with this lua error message: 'Tables" + "|returned by global.get are immutable.' This rule prevents'" + "|aliasing between global data and other data structures." + "|") { + return 0; +} + +LuaDefine(global_get, "varname", + "|Get data stored using global.set" + "|" + "|See doc(global.set) for information on how to store global data." + "|") { + return 0; +} + +LuaDefine(global_once, "name", + "|For a given string, returns true exactly once" + "|" + "|The semantics and difference transmission behavior of global.once" + "|are identical to the semantics of global.set, since global.once" + "|uses global.set under the covers." + "|") { LuaArg name; LuaRet flag; LuaVar oncedb, val; LuaStack LS(L, name, flag, oncedb, val); - - LS.guard_nopredict("global.once"); - - // Get a pointer to the oncedb. - LS.rawget(oncedb, LuaRegistry, "oncedb"); - if (!LS.istable(oncedb)) { - LS.set(flag, false); - return LS.result(); - } - - LS.checkstring(name, "name"); - LS.rawget(val, oncedb, name); - if (!LS.isnil(val)) { - LS.set(flag, false); - return LS.result(); - } - LS.rawset(oncedb, name, true); - LS.set(flag, true); - return LS.result(); + return 0; } - -LuaDefine(global_clearonce, "name", "reset the specified once-flag") { +LuaDefine(global_clearonce, "name", + "|Reset the specified once-flag" + "|" + "|The semantics and difference transmission behavior of global.clearonce" + "|are identical to the semantics of global.set, since global.once" + "|uses global.set under the covers." + "|") { LuaArg name; LuaVar oncedb; LuaStack LS(L, name, oncedb); - - LS.guard_nopredict("global.clearonce"); - - // Get a pointer to the oncedb. - LS.rawget(oncedb, LuaRegistry, "oncedb"); - if (!LS.istable(oncedb)) { - return LS.result(); - } - LS.checkstring(name, "name"); - LS.rawset(oncedb, name, LuaNil); - return LS.result(); -} - -LuaDefine(global_table, "globalname", "get a table where global data can be stored") { - LuaArg globalname; - LuaRet globaltab; - LuaVar globaldb; - LuaStack LS(L, globalname, globaltab, globaldb); - LS.checkstring(globalname, "globalname"); - - // Get a pointer to the globaldb. - LS.rawget(globaldb, LuaRegistry, "globaldb"); - - // Get the globaltab from the globaldb, sanity check it. - LS.rawget(globaltab, globaldb, globalname); - if (LS.istable(globaltab)) { - return LS.result(); - } else if (!LS.isnil(globaltab)) { - luaL_error(L, "%s is not a global", LS.ckstring(globalname).c_str()); - } - - // Create a new globaltab and store it in the globaldb. - LS.newtable(globaltab); - LS.rawset(globaldb, globalname, globaltab); - LS.rawset(globaltab, "__global", globalname); - LS.settabletype(globaltab, LUA_TT_GLOBALDB); - return LS.result(); + return 0; } diff --git a/luprex/cpp/core/table.cpp b/luprex/cpp/core/table.cpp index cc722c35..e3788b70 100644 --- a/luprex/cpp/core/table.cpp +++ b/luprex/cpp/core/table.cpp @@ -589,7 +589,17 @@ LuaDefine(table_nextsortedpair, "sortedpairs,dummy", "next function used by sort } } -LuaDefine(table_sortedpairs, "table", "iterate over table, sorting all keys") { +LuaDefine(table_sortedpairs, "table", + "|Iterate over table, sorting all keys" + "|" + "|Some keys can't be sorted. For example, you can use a closure" + "|as a table key. If you try to iterate over a table containing" + "|a non-sortable key, the error 'Cannot sort the table keys' will" + "|be generated." + "|" + "|See doc(genlt) for information about the sort order." + "|" + "|") { LuaArg tab; LuaRet closure, rtab, key; LuaStack LS(L, tab, closure, rtab, key); @@ -602,7 +612,17 @@ LuaDefine(table_sortedpairs, "table", "iterate over table, sorting all keys") { return LS.result(); } -LuaDefine(table_semisortedpairs, "table", "iterate over table, sorting those keys that can be sorted") { +LuaDefine(table_semisortedpairs, "table", + "|Iterate over table, sorting all the keys that can be sorted." + "|" + "|Some keys can't be sorted. For example, you can use a closure" + "|as a table key. If you try to iterate over a table containing" + "|a non-sortable key, the non-sortable elements will appear at" + "|the end of the iteration, after all the sortable elements. The" + "|non-sortable elements will be in an arbitrary order." + "|" + "|See doc(genlt) for information about the sort order." + "|") { LuaArg tab; LuaRet closure, rtab, key; LuaStack LS(L, tab, closure, rtab, key); @@ -612,7 +632,37 @@ LuaDefine(table_semisortedpairs, "table", "iterate over table, sorting those key return LS.result(); } -LuaDefine(genlt, "obj1,obj2", "return true if obj1 is less than obj2 in general ordering") { +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + +#define LUA_NUMTAGS 9 + +LuaDefine(genlt, "obj1,obj2", + "|Generalized less-than function" + "|" + "|This comparison function can compare any two objects. The" + "|return value is as follows:" + "|" + "|* Numbers are compared in the obvious numeric manner." + "|* Strings are compared alphabetically." + "|* Booleans are compared with false being less than true." + "|* Tables are all considered equal to other tables." + "|* Functions are all considered equal to other functions." + "|* Coroutines are all considered equal to other coroutines." + "|" + "|* Numbers are less than strings." + "|* Strings are less than booleans." + "|* Booleans are less than functions." + "|* Functions are less than coroutines." + "|* Coroutines are less than tables." + "|") { LuaArg o1,o2; LuaRet lt; LuaStack LS(L, o1, o2, lt); diff --git a/luprex/cpp/core/world-core.cpp b/luprex/cpp/core/world-core.cpp index 87e5e676..c7ec45b7 100644 --- a/luprex/cpp/core/world-core.cpp +++ b/luprex/cpp/core/world-core.cpp @@ -66,9 +66,8 @@ World::World(WorldType wt) { // Store the world type in the registry. LS.rawset(LuaRegistry, "worldtype", wt); - // Create the globaldb and oncedb in the registry. + // Create the globaldb in the registry. LS.rawset(LuaRegistry, "globaldb", LuaNewTable); - LS.rawset(LuaRegistry, "oncedb", LuaNewTable); // Initialize the SourceDB. At this stage, the sourcedb is // empty, so it's just populating the lua builtins. diff --git a/luprex/lua/control.lst b/luprex/lua/control.lst index f41943a2..4a6a9ba5 100644 --- a/luprex/lua/control.lst +++ b/luprex/lua/control.lst @@ -4,7 +4,6 @@ # ut-table.lua -ut-globaldb.lua ut-tablecmp.lua basics.lua uglyglobals.lua diff --git a/luprex/lua/ut-globaldb.lua b/luprex/lua/ut-globaldb.lua deleted file mode 100644 index 431ce663..00000000 --- a/luprex/lua/ut-globaldb.lua +++ /dev/null @@ -1,13 +0,0 @@ -makeclass("unittests") - -function unittests.globaldb() - local g1a = global.table("unittest-g1") - local g2a = global.table("unittest-g2") - local g1b = global.table("unittest-g1") - local g2b = global.table("unittest-g2") - assert(g1a == g1b) - assert(g2a == g2b) - assert(g1a.__global == "unittest-g1") - assert(g2a.__global == "unittest-g2") -end - diff --git a/luprex/lua/ut-tablecmp.lua b/luprex/lua/ut-tablecmp.lua index 53d5b101..5699b104 100644 --- a/luprex/lua/ut-tablecmp.lua +++ b/luprex/lua/ut-tablecmp.lua @@ -51,11 +51,6 @@ function unittests.diffcompare() -- Try a table containing a pointer to the global environment. assert(tdc({}, {a=_G}, {}, {}) == "a=globals;") - -- GlobalDB tables should be forced to NIL. - assert(tdc({}, {a=global.table("foo")}, {}, {a=global.table("foo")}) == "a=nil;"); - assert(tdc({}, {}, {}, {a=global.table("foo")}) == "a=nil;"); - assert(tdc({}, {a=global.table("foo")}, {}, {}) == ""); - -- Set up some numbered tables for tests involving such. local mtab10 = {} local stab10 = {} @@ -116,11 +111,6 @@ function unittests.diffapply() -- verify a table containing the global environment. assert(tda(tnmap, {a=_G}, {})) - -- GlobalDB tables should be forced to NIL. - rtab={a=3} - assert(not tda({}, {a=global.table("foo")}, rtab)) - assert(rtab.a == nil) - -- Unnumbered tables should be forced to NIL. rtab={a=3} assert(not tda({}, {a={}}, rtab))