Lunatic: various tweaks.

Going to extremes to avoid code duplication like the plague, but at
least it's great to learn about the whole function environment business.

git-svn-id: https://svn.eduke32.com/eduke32@3060 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-10-07 15:26:13 +00:00
parent 36687ab986
commit 1682eae693
3 changed files with 52 additions and 58 deletions

View file

@ -21,12 +21,15 @@ local gv_ = {
local dummy_empty_table = {} local dummy_empty_table = {}
-- This is for declarations of arrays or pointers which should not be -- This is for declarations of arrays or pointers which should not be
-- accessible through the "gv" global. The "defs_common" module require will -- accessible through the "gv" global. The "defs_common" module will
-- use this function. -- use this function.
-- NOTE: don't declare multiple pointers on one line (like int32_t *a, *b;)! --
-- NOTE: don't declare multiple pointers on one line (this is bad: "int32_t *a, *b")
-- and array *arguments* should be separated by a space, like
-- "int func(char arrayarg [16])"
function decl(str) function decl(str)
for varname in string.gmatch(str, "([%a_][%w_]*)[[(;]") do for varname in string.gmatch(str, "([%a_][%w_]*)[[(;]") do
-- print("protect "..varname) -- print("DUMMY "..varname)
gv_[varname] = dummy_empty_table gv_[varname] = dummy_empty_table
end end
@ -399,9 +402,10 @@ decl[[
uint32_t rand_jkiss_u32(rng_jkiss_t *s); uint32_t rand_jkiss_u32(rng_jkiss_t *s);
double rand_jkiss_dbl(rng_jkiss_t *s); double rand_jkiss_dbl(rng_jkiss_t *s);
void md4once(const unsigned char *block, unsigned int len, unsigned char digest[16]); void md4once(const unsigned char *block, unsigned int len, unsigned char digest [16]);
]] ]]
-- XXX: "digest" --> dummy? -- ^^^ The space between 'digest' and '[16]' is so that it's not added to the
-- dummy_empty_table (see regexp in decl()).
@ -800,7 +804,7 @@ setfenv(1, G_)
-- REMEMBER special position of 'tostring' (it's looked up and used as a global -- REMEMBER special position of 'tostring' (it's looked up and used as a global
-- from 'print') -- from 'print')
local function printkv(label, table) local function printkv(label, table)
print('========== Keys and values of '..label) print("========== Keys and values of "..label.." ("..tostring(table)..")")
for k,v in pairs(table) do for k,v in pairs(table) do
print(k .. ': ' .. tostring(v)) print(k .. ': ' .. tostring(v))
end end
@ -812,20 +816,22 @@ end
---=== Restricted access to C variables from Lunatic ===--- ---=== Restricted access to C variables from Lunatic ===---
local setmtonce = defs_c.setmtonce
-- error(..., 2) is to blame the caller and get its line numbers -- error(..., 2) is to blame the caller and get its line numbers
local tmpmt = { local tmpmt = {
__index = function() error('dummy variable: read access forbidden', 2) end, __index = function() error('dummy variable: read access forbidden', 2) end,
__newindex = function() error('dummy variable: write access forbidden', 2) end, __newindex = function() error('dummy variable: write access forbidden', 2) end,
} }
defs_c.setmtonce(dummy_empty_table, tmpmt) setmtonce(dummy_empty_table, tmpmt)
gv = gv_ gv = gv_
local tmpmt = { local tmpmt = {
__index = ffiC, __index = ffiC,
__newindex = function() error("cannot create new or write into existing fields of 'gv'", 2) end, __newindex = function() error("cannot create new or write into existing fields of 'gv'", 2) end,
} }
defs_c.setmtonce(gv, tmpmt) setmtonce(gv, tmpmt)
---- indirect C array access ---- ---- indirect C array access ----
local tmpmt = { local tmpmt = {
@ -838,33 +844,13 @@ local tmpmt = {
__newindex = function(tab, key, val) error('cannot write directly to player[] struct', 2) end, __newindex = function(tab, key, val) error('cannot write directly to player[] struct', 2) end,
} }
player = defs_c.setmtonce({}, tmpmt) player = setmtonce({}, tmpmt)
-- structs -- This will create 'sprite', 'wall', etc. HERE, i.e. in the environment of this chunk
sector = defs_c.sector; defs_c.create_globals(_G)
wall = defs_c.wall;
sprite = defs_c.sprite
spriteext = defs_c.spriteext
headspritesect = defs_c.headspritesect
headspritestat = defs_c.headspritestat
nextspritesect = defs_c.nextspritesect
nextspritestat = defs_c.nextspritestat
prevspritesect = defs_c.prevspritesect
prevspritestat = defs_c.prevspritestat
actor = defs_c.creategtab(ffiC.actor, ffiC.MAXSPRITES, 'actor[]') actor = defs_c.creategtab(ffiC.actor, ffiC.MAXSPRITES, 'actor[]')
-- functions
spritesofsect = defs_c.spritesofsect
spritesofstat = defs_c.spritesofstat
sectorsofbunch = defs_c.sectorsofbunch
getbunch = defs_c.getbunch
hitscan = defs_c.hitscan
function TEMP_getvollev() -- REMOVE function TEMP_getvollev() -- REMOVE
return ffiC.ud.volume_number+1, ffiC.ud.level_number+1 return ffiC.ud.volume_number+1, ffiC.ud.level_number+1
end end

View file

@ -6,9 +6,13 @@ local ffi = require("ffi")
local ffiC = ffi.C local ffiC = ffi.C
local error = error local error = error
local pairs = pairs
local setmetatable = setmetatable local setmetatable = setmetatable
local decl = decl local decl = decl
local getfenv = getfenv
local print=print
module(...) module(...)
@ -88,8 +92,7 @@ typedef struct {
local vec3_ct = ffi.typeof("vec3_t") local vec3_ct = ffi.typeof("vec3_t")
local hitdata_ct = ffi.typeof("hitdata_t") local hitdata_ct = ffi.typeof("hitdata_t")
-- TODO: add 'const' ffi.cdef[[const int32_t engine_main_arrays_are_static, engine_v8;]]
ffi.cdef[[int32_t engine_main_arrays_are_static, engine_v8;]]
--== Engine data and functions ==-- --== Engine data and functions ==--
@ -190,7 +193,7 @@ function setmtonce(tab, mt)
end end
---- indirect C array access ---- ---- indirect C array access ----
local tmpmt = { local sector_mt = {
__index = function(tab, key) __index = function(tab, key)
if (key >= 0 and key < ffiC.numsectors) then return ffiC.sector[key] end if (key >= 0 and key < ffiC.numsectors) then return ffiC.sector[key] end
error('out-of-bounds sector[] read access', 2) error('out-of-bounds sector[] read access', 2)
@ -198,9 +201,8 @@ local tmpmt = {
__newindex = function(tab, key, val) error('cannot write directly to sector[] struct', 2) end, __newindex = function(tab, key, val) error('cannot write directly to sector[] struct', 2) end,
} }
sector = setmtonce({}, tmpmt)
local tmpmt = { local wall_mt = {
__index = function(tab, key) __index = function(tab, key)
if (key >= 0 and key < ffiC.numwalls) then return ffiC.wall[key] end if (key >= 0 and key < ffiC.numwalls) then return ffiC.wall[key] end
error('out-of-bounds wall[] read access', 2) error('out-of-bounds wall[] read access', 2)
@ -208,7 +210,6 @@ local tmpmt = {
__newindex = function(tab, key, val) error('cannot write directly to wall[] struct', 2) end, __newindex = function(tab, key, val) error('cannot write directly to wall[] struct', 2) end,
} }
wall = setmtonce({}, tmpmt)
-- create a safe indirection for an ffi.C array -- create a safe indirection for an ffi.C array
function creategtab(ctab, maxidx, name) function creategtab(ctab, maxidx, name)
@ -228,8 +229,20 @@ function creategtab(ctab, maxidx, name)
return setmtonce(tab, tmpmt) return setmtonce(tab, tmpmt)
end end
local vars_to_ignore = {}
for varname,_ in pairs(getfenv(1)) do
-- print("IGNORE "..varname)
vars_to_ignore[varname] = true
end
--== ALL GLOBALS FROM HERE ON ARE EXPORTED UPWARDS (see create_globals() below) ==--
sector = setmtonce({}, sector_mt)
wall = setmtonce({}, wall_mt)
sprite = creategtab(ffiC.sprite, ffiC.MAXSPRITES, 'sprite[] struct') sprite = creategtab(ffiC.sprite, ffiC.MAXSPRITES, 'sprite[] struct')
spriteext = creategtab(ffiC.spriteext, ffiC.MAXSPRITES, 'spriteext[] struct') spriteext = creategtab(ffiC.spriteext, ffiC.MAXSPRITES, 'spriteext[] struct')
headspritesect = creategtab(ffiC.headspritesect, ffiC.MAXSECTORS, 'headspritesect[]') headspritesect = creategtab(ffiC.headspritesect, ffiC.MAXSECTORS, 'headspritesect[]')
-- TODO: allow sprite freelist access via the status list for CON compatibility? -- TODO: allow sprite freelist access via the status list for CON compatibility?
headspritestat = creategtab(ffiC.headspritestat, ffiC.MAXSTATUS, 'headspritestat[]') headspritestat = creategtab(ffiC.headspritestat, ffiC.MAXSTATUS, 'headspritestat[]')
@ -322,3 +335,18 @@ function hitscan(x,y,z, sectnum, vx,vy,vz, cliptype)
ffiC.hitscan(vec, sectnum, vx,vy,vz, hitdata, cliptype) ffiC.hitscan(vec, sectnum, vx,vy,vz, hitdata, cliptype)
return hitdata return hitdata
end end
-- This is supposed to be run from the file that 'require's this module to take
-- over the non-local variables from here into the global environment.
function create_globals(_G_their)
local _G_our = getfenv(1)
vars_to_ignore["create_globals"] = true
for varname,obj in pairs(_G_our) do
if (not vars_to_ignore[varname]) then
-- print("EXPORT "..varname)
_G_their[varname] = obj
end
end
end

View file

@ -8,27 +8,7 @@ local ffiC = ffi.C
decl = ffi.cdef decl = ffi.cdef
local defs_c = require("defs_common") local defs_c = require("defs_common")
-- structs defs_c.create_globals(_G)
sector = defs_c.sector;
wall = defs_c.wall;
sprite = defs_c.sprite
spriteext = defs_c.spriteext
headspritesect = defs_c.headspritesect
headspritestat = defs_c.headspritestat
nextspritesect = defs_c.nextspritesect
nextspritestat = defs_c.nextspritestat
prevspritesect = defs_c.prevspritesect
prevspritestat = defs_c.prevspritestat
-- functions
spritesofsect = defs_c.spritesofsect
spritesofstat = defs_c.spritesofstat
sectorsofbunch = defs_c.sectorsofbunch
getbunch = defs_c.getbunch
hitscan = defs_c.hitscan
--== Mapster32-specific initialization --== Mapster32-specific initialization