Stub out the new global.set and global.get operators

This commit is contained in:
2023-03-01 17:35:06 -05:00
parent 9ce34d950b
commit db234c2934
6 changed files with 115 additions and 88 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -4,7 +4,6 @@
#
ut-table.lua
ut-globaldb.lua
ut-tablecmp.lua
basics.lua
uglyglobals.lua

View File

@@ -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

View File

@@ -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))