allow calling namespaced torque functions

This commit is contained in:
Redo
2025-10-05 22:31:21 -05:00
parent 7da249cca1
commit edf31c178c
3 changed files with 34 additions and 13 deletions

Binary file not shown.

View File

@@ -12,12 +12,12 @@ Lua scripting for Blockland
## Quick Reference ## Quick Reference
### From TorqueScript ### From TorqueScript
`'print('hello world')` - Execute Lua code in the console by prepending a `'` (single quote) `'print('hello world')` - Execute Lua in the console by prepending a `'` (single quote)
`luaeval("code");` - Eval Lua code `luaeval("code");` - Execute Lua code
`luacall("funcName", %args);` - Call a Lua global function `luacall("funcName", %args...);` - Call a Lua global function
`luaexec("fileName");` - Execute a Lua file. Path rules are the same as executing .cs files. `luaexec("fileName");` - Execute a Lua file. Path rules are the same as executing .cs files.
`luaget("varName");` - Read a Lua global variable `luaget("varName");` - Read a Lua global variable
`luaset("varName");` - Write a Lua global variable `luaset("varName", %value);` - Write a Lua global variable
### From Lua ### From Lua
`bl.eval('code')` - Eval TorqueScript code `bl.eval('code')` - Eval TorqueScript code
@@ -181,7 +181,7 @@ TorqueScript stores no type information; all values in TorqueScript are strings.
All Lua code is sandboxed, and file access is confined to the default directories in the same way TorqueScript is. All Lua code is sandboxed, and file access is confined to the default directories in the same way TorqueScript is.
BlockLua also has access to any C libraries installed in the `modules/lualib` folder, so be careful throwing things in there. BlockLua also has access to any C libraries installed in the `modules/lualib` folder, so be careful throwing things in there.
### Unsafe Mode ### Unsafe Mode
BlockLua-Unsafe.dll can be built and used in place of BlockLua.dll (see compile.bat), to remove the sandboxing of Lua code. This allows Lua code to access any file and use any library, including ffi. BlockLua can be built in Unsafe Mode by specifying the `-DBLLUA_UNSAFE` compiler flag. This removes the sandboxing of Lua code, allowing it to access any file and use any library, including ffi.
Please do not publish add-ons that require unsafe mode. Please do not publish add-ons that require unsafe mode.
### List of Object Types ### List of Object Types

View File

@@ -479,6 +479,31 @@ toTsObject = function(idiS)
return obj return obj
end end
-- Allow bl['namespaced::function']()
local function safeNamespaceName(name)
return tostring(name:gsub(':', '_'))
end
local nscallArgStr = '%a,%b,%c,%d,%e,%f,%g,%h'
bl._cachedNamespaceCalls = {}
local function tsNamespacedCallTfname(name)
local tfname = bl._cachedNamespaceCalls[name]
if not tfname then
tfname = '_bllua_nscall_'..safeNamespaceName(name)
local tfcode = 'function '..tfname..'('..nscallArgStr..'){'..
name..'('..nscallArgStr..');}'
_bllua_ts.eval(tfcode)
bl._cachedNamespaceCalls[name] = tfname
end
return tfname
end
local function tsCallGen(name)
return function(...)
local args = {...}
local argsS = arglistToTs(args)
return valFromTs(_bllua_ts.call(name, unpack(argsS)), name)
end
end
-- Metatable for the global bl library -- Metatable for the global bl library
-- Allows accessing Torque objects, variables, and functions by indexing it -- Allows accessing Torque objects, variables, and functions by indexing it
local tsMeta = { local tsMeta = {
@@ -499,16 +524,12 @@ local tsMeta = {
local ns, rest = name:match('^([^:]+)::(.+)$') local ns, rest = name:match('^([^:]+)::(.+)$')
if not ns then error('ts index: invalid name \''..name..'\'', 2) end if not ns then error('ts index: invalid name \''..name..'\'', 2) end
if not rest:find('::') and tsIsFunctionNs(ns, rest) then if not rest:find('::') and tsIsFunctionNs(ns, rest) then
error('ts index: can\'t call a namespaced function from lua', 2) return tsCallGen(tsNamespacedCallTfname(name))
else else
return valFromTs(_bllua_ts.getvar(name), name) return valFromTs(_bllua_ts.getvar(name), name)
end end
elseif tsIsFunction(name) then elseif tsIsFunction(name) then
return function(...) return tsCallGen(name)
local args = {...}
local argsS = arglistToTs(args)
return valFromTs(_bllua_ts.call(name, unpack(argsS)), name)
end
elseif tsIsObject(name) then elseif tsIsObject(name) then
return toTsObject(name) return toTsObject(name)
else else
@@ -549,7 +570,7 @@ function bl.object(id)
elseif type(id)=='string' or type(id)=='number' then elseif type(id)=='string' or type(id)=='number' then
return toTsObject(tostring(id)) return toTsObject(tostring(id))
else else
error('bl.toobject: id must be a ts object, number, or string', 2) error('bl.object: id must be a ts object, number, or string', 2)
end end
end end
function bl.array(name, ...) function bl.array(name, ...)
@@ -557,7 +578,7 @@ function bl.array(name, ...)
return name..table.concat(rest, '_') return name..table.concat(rest, '_')
end end
function _bllua_call(fnameS, ...) function _bllua_call(fnameS, ...)
local args = arglistFromTs('lua:'..fnameS:lower(), {...}) local args = arglistFromTs('lua:'..fnameS:lower(), {...}) -- todo: allow this though bl.type
if not _G[fnameS] then if not _G[fnameS] then
error('luacall: no global lua function named \''..fnameS..'\'') end error('luacall: no global lua function named \''..fnameS..'\'') end
-- todo: library fields and object methods -- todo: library fields and object methods