@@ -252,8 +252,44 @@ local compatible_file_extensions = {
252252---- ----------------------------------------------------------------------------------------------------
253253---- ----------------------------------------------------------------------------------------------------
254254
255+ -- this value can be used to remove values when updating the current state
256+ local NIL_STATE = {}
257+
258+ local function get_state (level )
259+ -- bypasses the readonly reference and grabs the original table and metatable
260+ local s = getmetatable (state ).__index
261+ local mt = getmetatable (s )
262+
263+ -- travels up the state chain until it finds a mt of the same level as `level`
264+ -- this mt will be pointing to a state table of one level lower, which is what we want to point to
265+ while mt .level > level do
266+ s = mt .__index
267+ mt = getmetatable (s )
268+
269+ if not mt or not mt .level then return nil end
270+ end
271+
272+ return s , mt
273+ end
274+
275+ -- prints the current state values
276+ local function print_state ()
277+ local i = 0
278+ while true do
279+ s , mt = get_state (i )
280+ if not s then error (' failed to get state of level ' .. i ) end
281+ if mt .level ~= i then break end
282+
283+ for k , v in pairs (s ) do
284+ print (i , k , v )
285+ end
286+
287+ i = i + 1
288+ end
289+ end
290+
255291-- the values table will be made readonly and set as part of the state - do not use values after passing to this function!
256- local function update_state (level , values )
292+ local function set_state (level , values )
257293 local new_mt = { level = level }
258294 setmetatable (values , new_mt )
259295
@@ -262,19 +298,35 @@ local function update_state(level, values)
262298 return state
263299 end
264300
265- -- bypasses the readonly reference and grabs the original table and metatable
266- local mutable_state = getmetatable (state ).__index
267- local mt = getmetatable (mutable_state )
268-
269- -- travels up the state chain until it finds a mt of the same level as `level`
270- -- this mt will be pointing to a state table of one level lower, which is what we want to point to
271- while (mt .level > level ) do mt = getmetatable (mt .__index ) end
272- new_mt .__index = mt .__index
301+ local s , mt = get_state (level )
302+ if not mt then error (' failed to get state of level ' .. level ) end
303+ new_mt .__index = mt .level == level and mt .__index or s
273304
274305 state = API .read_only (values )
275306 return state
276307end
277308
309+ -- updates the current state values of the particular level
310+ local function update_state (level , values )
311+ local s , mt = get_state (level )
312+ if not mt then error (' failed to get state of level ' .. level ) end
313+
314+ if mt .level ~= level then
315+ set_state (level , values )
316+ return
317+ end
318+
319+ local new_state = API .copy_table (s , 1 )
320+ for k , v in pairs (values ) do
321+ if v == NIL_STATE then new_state [k ] = nil
322+ else new_state [k ] = v end
323+ end
324+
325+ setmetatable (new_state , mt )
326+ state = API .read_only (new_state )
327+ return state
328+ end
329+
278330-- metatable of methods to manage the cache
279331local __cache = {}
280332
0 commit comments