wip allow inheriting object method types

This commit is contained in:
Redo
2025-10-03 17:47:26 -05:00
parent fe9ee3cc2b
commit 34345a7eeb
6 changed files with 43 additions and 13 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -4,10 +4,13 @@ cd /d %~dp0
set buildargs=-Wall -Werror -m32 -shared -Isrc -Iinc/tsfuncs -Iinc/lua -lpsapi -L. -llua5.1 -static-libgcc -static-libstdc++ set buildargs=-Wall -Werror -m32 -shared -Isrc -Iinc/tsfuncs -Iinc/lua -lpsapi -L. -llua5.1 -static-libgcc -static-libstdc++
echo on echo on
g++ src/bllua4.cpp %buildargs% -o BlockLua.dll && g++ -DBLLUA_UNSAFE src/bllua4.cpp %buildargs% -o BlockLua-Unsafe.dll
g++ src/bllua4.cpp %buildargs% -o BlockLua.dll
@rem && g++ -DBLLUA_UNSAFE src/bllua4.cpp %buildargs% -o BlockLua-Unsafe.dll
@rem objdump -d BlockLua.dll > BlockLua.dll.dump.txt
@rem objdump -d BlockLua-Unsafe.dll > BlockLua-Unsafe.dll.dump.txt
@echo off @echo off
rem objdump -d BlockLua.dll > BlockLua.dll.dump.txt
rem objdump -d BlockLua-Unsafe.dll > BlockLua-Unsafe.dll.dump.txt
pause pause

Binary file not shown.

View File

@@ -40,7 +40,7 @@ Lua scripting for Blockland
### Advanced ### Advanced
`sched = bl.schedule(timeMs, function, args...)` - Schedule a Lua function to be called later, similar to schedule in Torque `sched = bl.schedule(timeMs, function, args...)` - Schedule a Lua function to be called later, similar to schedule in Torque
`sched:cancel()` - Cancel a previously scheduled timer `sched:cancel()` - Cancel a previously scheduled timer
`hitObject, hisPos, hitNormal = bl.raycast(vector{startPosX,y,z}, vector{endPosX,y,z}, 'objtype'/{'objtypes',...}, ignoreObjects...?)` - Cast a ray in the world over objects of the specified type(s) (possibly excluding some objects), and return the object hit, the position of the hit, and the normal vector to the surface hit. See the Types section for a list of valid object types. `hitObject, hitPos, hitNormal = bl.raycast(vector{startPosX,y,z}, vector{endPosX,y,z}, 'objtype'/{'objtypes',...}, ignoreObjects...?)` - Cast a ray in the world over objects of the specified type(s) (possibly excluding some objects), and return the object hit, the position of the hit, and the normal vector to the surface hit. See the Types section for a list of valid object types.
`for object in bl.boxSearch(vector{centerX,y,z}, vector{sizeX,y,z}, 'objtype'/{'objtypes',...}) do` - Find all objects in the world of the specified type(s) whose bounding box overlaps with the specified box. See the Types section for a list of valid object types. `for object in bl.boxSearch(vector{centerX,y,z}, vector{sizeX,y,z}, 'objtype'/{'objtypes',...}) do` - Find all objects in the world of the specified type(s) whose bounding box overlaps with the specified box. See the Types section for a list of valid object types.
`for object in bl.radiusSearch(vector{centerX,y,z}, radius, 'objtype'/{'objtypes',...}) do` - Find all objects of the specified type(s) whose bounding box overlaps with the specified sphere. See the Types section for a list of valid object types. `for object in bl.radiusSearch(vector{centerX,y,z}, radius, 'objtype'/{'objtypes',...}) do` - Find all objects of the specified type(s) whose bounding box overlaps with the specified sphere. See the Types section for a list of valid object types.
`bl.serverCmd('commandName', function(client, args...) code() end)` - Register a /-command on the server `bl.serverCmd('commandName', function(client, args...) code() end)` - Register a /-command on the server
@@ -84,6 +84,13 @@ Require replaces `.` with `/` in the path, and then searches for files in the fo
Like in standard Lua, modules loaded using `require` are only executed the first time `require` is called with that path. Subsequent calls simply return the result from the initial execution. To allow hot reloading, use `dofile`. Like in standard Lua, modules loaded using `require` are only executed the first time `require` is called with that path. Subsequent calls simply return the result from the initial execution. To allow hot reloading, use `dofile`.
### TBD
- bl.class
- bl.new
- bl.datablock
- vector
- Extended standard library functions
## Type Conversion ## Type Conversion
When a TorqueScript function is called from Lua or vice-versa, the arguments and return value must be converted between the two languages' type systems. When a TorqueScript function is called from Lua or vice-versa, the arguments and return value must be converted between the two languages' type systems.
TorqueScript stores no type information; all values in TorqueScript are strings. So it's necessary to make some inferences when converting values between the two languages. TorqueScript stores no type information; all values in TorqueScript are strings. So it's necessary to make some inferences when converting values between the two languages.

View File

@@ -151,13 +151,21 @@ end
local function arglistToTs(args) local function arglistToTs(args)
return map(args, valToTs) return map(args, valToTs)
end end
function bl.type(name,typ) function bl.type(name, typ)
if typ~='bool' and typ~='boolean' and typ~='object' and typ~=nil then if typ~='bool' and typ~='boolean' and typ~='object' and typ~=nil then
error('bl.type: can only set type to \'bool\' or \'object\' or nil', 2) end error('bl.type: can only set type to \'bool\' or \'object\' or nil', 2) end
if not isValidFuncNameNsArgn(name) then if not isValidFuncNameNsArgn(name) then
error('bl.type: invalid function or variable name \''..name..'\'', 2) end error('bl.type: invalid function or variable name \''..name..'\'', 2) end
if typ=='bool' then typ='boolean' end if typ=='bool' then typ='boolean' end
bl._forceType[name:lower()] = typ bl._forceType[name:lower()] = typ
-- apply to children (wip)
--local class, rest = name:match('^([a-zA-Z0-9_]+)(::.+)$')
--if not class then
-- class, rest = name:match('^([a-zA-Z0-9_]+)(%..+)$') end
--if class then
--
--end
end end
@@ -199,6 +207,12 @@ function bl.isFunction(a1, a2)
end end
-- Torque object pseudo-class -- Torque object pseudo-class
local tsClassMeta = {
__tostring = function(t)
return 'torqueClass:'..t._name..
(t._inherit and (':'..t._inherit) or '')
end,
}
bl._objectUserMetas = bl._objectUserMetas or {} bl._objectUserMetas = bl._objectUserMetas or {}
function bl.class(name, inherit) function bl.class(name, inherit)
if not ( type(name)=='string' and isValidFuncName(name) ) then if not ( type(name)=='string' and isValidFuncName(name) ) then
@@ -207,9 +221,13 @@ function bl.class(name, inherit)
error('bl.class: argument #2: inherit name must be a string or nil', 2) end error('bl.class: argument #2: inherit name must be a string or nil', 2) end
name = name:lower() name = name:lower()
local met = bl._objectUserMetas[name] or {} local met = bl._objectUserMetas[name] or {
_name = name,
_inherit = nil,
_children = {},
}
bl._objectUserMetas[name] = met bl._objectUserMetas[name] = met
met._name = name setmetatable(met, tsClassMeta)
if inherit then if inherit then
inherit = inherit:lower() inherit = inherit:lower()
@@ -218,12 +236,14 @@ function bl.class(name, inherit)
if not inh then error('bl.class: argument #2: \''..inherit..'\' is not the '.. if not inh then error('bl.class: argument #2: \''..inherit..'\' is not the '..
'name of an existing class', 2) end 'name of an existing class', 2) end
local inhI = bl._objectUserMetas[name]._inherit inh._children[name] = true
local inhI = met._inherit
if inhI and inhI~=inh then if inhI and inhI~=inh then
error('bl.class: argument #2: class already exists and '.. error('bl.class: argument #2: class already exists and '..
'inherits a different parent.', 2) end 'inherits a different parent.', 2) end
bl._objectUserMetas[name]._inherit = inh met._inherit = inh
end end
end end
local function objectInheritedMetas(name) local function objectInheritedMetas(name)
@@ -418,7 +438,7 @@ toTsObject = function(idiS)
_tsObjectId = _bllua_ts.callobj(idiS, 'getId' ), _tsObjectId = _bllua_ts.callobj(idiS, 'getId' ),
_tsName = _bllua_ts.callobj(idiS, 'getName' ), _tsName = _bllua_ts.callobj(idiS, 'getName' ),
_tsNamespace = className, _tsNamespace = className,
_tsClassName = className:lower() _tsClassName = className:lower(),
} }
setmetatable(obj, tsObjectMeta) setmetatable(obj, tsObjectMeta)
@@ -438,7 +458,7 @@ local tsMeta = {
__index = function(t, name) __index = function(t, name)
if getmetatable(t)[name] then if getmetatable(t)[name] then
return getmetatable(t)[name] return getmetatable(t)[name]
elseif bl._objectUserMetas[name:lower()] then elseif type(name)=='string' and bl._objectUserMetas[name:lower()] then
return bl._objectUserMetas[name:lower()] return bl._objectUserMetas[name:lower()]
else else
if type(name)=='number' then if type(name)=='number' then
@@ -491,7 +511,7 @@ function bl.tobool(val)
--val~='0' and --val~='0' and
val~=0 val~=0
end end
function bl.toobject(id) function bl.object(id)
if type(id)=='table' and id._tsObjectId then if type(id)=='table' and id._tsObjectId then
return id return id
elseif type(id)=='string' or type(id)=='number' then elseif type(id)=='string' or type(id)=='number' then