From fb0c13f9f204e6761b765aaebb20f0bd37b9a5fd Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sun, 30 Jun 2013 20:38:35 +0000 Subject: [PATCH] Lunatic: serialization for cdata types, currently xmath.vec3 and ivec3. git-svn-id: https://svn.eduke32.com/eduke32@3914 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/lunatic/control.lua | 19 +++++++------- polymer/eduke32/source/lunatic/defs.ilua | 25 +++++++++++++++++++ .../eduke32/source/lunatic/defs_common.lua | 2 +- .../eduke32/source/lunatic/doc/lunatic.txt | 4 +-- polymer/eduke32/source/lunatic/savegame.lua | 4 ++- .../source/lunatic/test/delmusicsfx.lua | 6 +++++ polymer/eduke32/source/lunatic/xmath.lua | 17 ++++++++++++- polymer/eduke32/source/savegame.c | 2 +- 8 files changed, 64 insertions(+), 15 deletions(-) diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index b60e34b31..c5b3a8a20 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -41,8 +41,13 @@ local sector, wall, sprite = dc.sector, dc.wall, dc.sprite local wallsofsect = dc.wallsofsect local spritesofsect, spritesofstat = dc.spritesofsect, dc.spritesofstat -local OUR_NAME = "_con" -local OUR_REQUIRE_STRING = "local "..OUR_NAME.."=require'con'" +local OUR_REQUIRE_STRING = [[ + local _con=require'con' + local _ga,_av,_pv=_con._gamearray,_con.actorvar,_con.playervar +]] +local function our_get_require() + return OUR_REQUIRE_STRING +end module(...) @@ -1900,10 +1905,6 @@ local function serialize_array(ar, strtab, maxnum) return table.concat(strtab) end -local function our_get_require() - return OUR_REQUIRE_STRING -end - --- Game arrays --- @@ -2069,7 +2070,7 @@ local gamearray_methods = { _get_require = our_get_require, _serialize = function(gar) - local strtab = { OUR_NAME.."._gamearray(", tostring(gar._size), ",{" } + local strtab = { "_ga(", tostring(gar._size), ",{" } gar:_cleanup() return serialize_array(gar, strtab, gar._size) end, @@ -2149,7 +2150,7 @@ local actorvar_methods = { _get_require = our_get_require, _serialize = function(acv) - local strtab = { OUR_NAME..".actorvar(", tostring(acv._defval), ",{" } + local strtab = { "_av(", tostring(acv._defval), ",{" } -- NOTE: We also clean up when spawning a sprite, too. (See -- A_ResetVars() and related functions above.) acv:_cleanup() @@ -2191,7 +2192,7 @@ local playervar_methods = { _get_require = our_get_require, _serialize = function(plv) - local strtab = { OUR_NAME..".playervar(", tostring(plv._defval), ",{" } + local strtab = { "_pv(", tostring(plv._defval), ",{" } return serialize_array(plv, strtab, ffiC.MAXSPRITES) end, } diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 878df0df3..42b52506e 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -30,6 +30,10 @@ local tonumber = tonumber local tostring = tostring local type = type +-- Create a new module for passing stuff to other modules. +local lprivate = {} +require("package").loaded.lprivate = lprivate + require("jit.opt").start("maxmcode=10240") -- in KiB -- The "gv" global will provide access to C global *scalars* and safe functions. @@ -1433,6 +1437,27 @@ local allowed_modules = { con = con, } +do + local ctype_cansave = {} + + -- Register as "serializeable" the type of cdata object . + local function reg_serializable_cv(v) + assert(type(v)=="cdata") + assert(type(v._serialize)=="function") + -- NOTE: tonumber() on a ctype cdata object gets its LuaJIT-internal + -- ID, the one that would be shown with tostring(), e.g. + -- ctype + ctype_cansave[tonumber(ffi.typeof(v))] = true + end + + function lprivate.cansave_cdata(v) + return type(v)=="cdata" and ctype_cansave[tonumber(ffi.typeof(v))] + end + + reg_serializable_cv(allowed_modules.xmath.vec3()) + reg_serializable_cv(allowed_modules.xmath.ivec3()) +end + -- Protect base modules. local function basemodule_newindex() error("modifying base module table forbidden", 2) diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index c657ae789..b7089dfd3 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -363,7 +363,7 @@ function readintostr(fd, kopen4load_func) ffiC.kclose(fd); fd=-1 if (readlen ~= sz) then - error("INTERNAL ERROR: couldn't read \""..fn.."\" wholly") + error("INTERNAL ERROR: couldn't read file wholly") end return ffi.string(str, sz) diff --git a/polymer/eduke32/source/lunatic/doc/lunatic.txt b/polymer/eduke32/source/lunatic/doc/lunatic.txt index 51b0ca3c3..ffce850c7 100644 --- a/polymer/eduke32/source/lunatic/doc/lunatic.txt +++ b/polymer/eduke32/source/lunatic/doc/lunatic.txt @@ -1059,8 +1059,8 @@ Returns an approximation of the 2D Euclidean distance between points `pos1` and `pos2`, both of which can be any object indexable with `x` and `y`. [[vector_types]] -The types `xmath.vec3` and `xmath.ivec3` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The types `xmath.vec3` and `xmath.ivec3` [_serializeable_] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Another purpose of the `xmath` module is to provide _vector_ types that allow writing concise and clear code involving geometrical calculations. There are diff --git a/polymer/eduke32/source/lunatic/savegame.lua b/polymer/eduke32/source/lunatic/savegame.lua index 5e48a3a4f..c98d15352 100644 --- a/polymer/eduke32/source/lunatic/savegame.lua +++ b/polymer/eduke32/source/lunatic/savegame.lua @@ -13,6 +13,8 @@ local setmetatable = setmetatable local tostring = tostring local type = type +local cansave_cdata = require("lprivate").cansave_cdata + module(...) @@ -39,7 +41,7 @@ end local function isSerializeable(obj) - return (getmetatable(obj)=="serializeable") + return (getmetatable(obj)=="serializeable" or cansave_cdata(obj)) end -- 'Save buffer' class. Objects of this class keep track of a string buffer diff --git a/polymer/eduke32/source/lunatic/test/delmusicsfx.lua b/polymer/eduke32/source/lunatic/test/delmusicsfx.lua index 63ccd352b..365e935c9 100644 --- a/polymer/eduke32/source/lunatic/test/delmusicsfx.lua +++ b/polymer/eduke32/source/lunatic/test/delmusicsfx.lua @@ -3,6 +3,7 @@ local require = require local string = require("string") local con = require("con") +local xmath = require("xmath") local gv = gv local sprite = sprite @@ -31,6 +32,9 @@ tag.hi, tag.lo = 0, 0 -- Preliminary dummy of a local gamevar. local ournumjumps = 0 +local lastv = xmath.vec3() +ilastv = xmath.ivec3() + require "end_gamevars" -- We may cache globals defined in the gamevar section afterwards, but not @@ -67,6 +71,8 @@ function(aci, pli) if (nearesti >= 0) then local spr = sprite[nearesti] tag.lo, tag.hi = spr.lotag, spr.hitag + lastv.x, lastv.y, lastv.z = spr.x, spr.y, spr.z+0.5 + ilastv.x, ilastv.y, ilastv.z = spr.x, spr.y, spr.z actor.delete(nearesti) end diff --git a/polymer/eduke32/source/lunatic/xmath.lua b/polymer/eduke32/source/lunatic/xmath.lua index 6181350a7..19e3997da 100644 --- a/polymer/eduke32/source/lunatic/xmath.lua +++ b/polymer/eduke32/source/lunatic/xmath.lua @@ -12,6 +12,14 @@ local assert = assert local error = error local type = type +local OUR_REQUIRE_STRING = [[ + local _xm=require'xmath' + local _v,_iv=_xm.vec3,_xm.ivec3 +]] +local function our_get_require() + return OUR_REQUIRE_STRING +end + module(...) @@ -182,7 +190,7 @@ local vec3_mt = { return v:_ctor(v.x, v.y, v.z-zofs) end, - -- XXX: Rewrite using _serialize internal API instead. + -- Convenience for human-readable display. __tostring = function(a) return (a:_isi() and "i" or "").."vec3("..a.x..", "..a.y..", "..a.z..")" end, @@ -224,6 +232,13 @@ local vec3_mt = { _isi = function(v) return ffi.istype(ivec3_t, v) end, + + --- Serialization --- + _get_require = our_get_require, + + _serialize = function(v) + return (v:_isi() and "_iv" or "_v").."("..v.x..","..v.y..","..v.z..")" + end, }, } diff --git a/polymer/eduke32/source/savegame.c b/polymer/eduke32/source/savegame.c index 0b130ff98..2ecd06c73 100644 --- a/polymer/eduke32/source/savegame.c +++ b/polymer/eduke32/source/savegame.c @@ -1235,7 +1235,7 @@ int32_t sv_saveandmakesnapshot(FILE *fil, int8_t spot, int8_t recdiffsp, int8_t #ifdef LUNATIC if (!g_savedOK) { - OSD_Printf("sv_saveandmakesnapshot: failed serializing Lunatic gamevar %s.\n", + OSD_Printf("sv_saveandmakesnapshot: failed serializing Lunatic gamevar \"%s\".\n", g_failedVarname); g_failedVarname = NULL; return 1;