diff options
author | nat-goodspeed <nat@lindenlab.com> | 2024-08-28 10:23:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-28 10:23:53 -0400 |
commit | 6f454ad8366ed33bbe199c3fc3ed69e6d3448cec (patch) | |
tree | 05f856f85c00194c6c43ca23cacb7021a50ffa33 /indra/newview/scripts/lua/require/util.lua | |
parent | c225b44a59ddd6b84105ace4181b3ca9f7439bfa (diff) | |
parent | 7b21acd39745d265548eeb62d687cde9febb1f7a (diff) |
Merge pull request #2416 from secondlife/lua-lazymod
Allow UI to have lazily-loaded submodules.
Diffstat (limited to 'indra/newview/scripts/lua/require/util.lua')
-rw-r--r-- | indra/newview/scripts/lua/require/util.lua | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/indra/newview/scripts/lua/require/util.lua b/indra/newview/scripts/lua/require/util.lua index bfbfc8637c..40737a159a 100644 --- a/indra/newview/scripts/lua/require/util.lua +++ b/indra/newview/scripts/lua/require/util.lua @@ -15,16 +15,9 @@ local util = {} -- util.classctor(MyClass, MyClass.construct) -- return MyClass function util.classctor(class, ctor) - -- get the metatable for the passed class - local mt = getmetatable(class) - if mt == nil then - -- if it doesn't already have a metatable, then create one - mt = {} - setmetatable(class, mt) - end - -- now that class has a metatable, set its __call method to the specified - -- constructor method (class.new if not specified) - mt.__call = ctor or class.new + -- set class's __call metamethod to the specified constructor function + -- (class.new if not specified) + util.setmetamethods{class, __call=(ctor or class.new)} end -- check if array-like table contains certain value @@ -66,4 +59,56 @@ function util.equal(t1, t2) return util.empty(temp) end +-- Find or create the metatable for a specified table (a new empty table if +-- omitted), and to that metatable assign the specified keys. +-- Setting multiple keys at once is more efficient than a function to set only +-- one at a time, e.g. setametamethod(). +-- t = util.setmetamethods{__index=readfunc, __len=lenfunc} +-- returns a new table with specified metamethods __index, __len +-- util.setmetamethods{t, __call=action} +-- finds or creates the metatable for existing table t and sets __call +-- util.setmetamethods{table=t, __call=action} +-- same as util.setmetamethods{t, __call=action} +function util.setmetamethods(specs) + -- first determine the target table + assert(not (specs.table and specs[1]), + "Pass setmetamethods table either as positional or table=, not both") + local t = specs.table or specs[1] or {} + -- remove both ways of specifying table, leaving only the metamethods + specs.table = nil + specs[1] = nil + local mt = getmetatable(t) + if not mt then + -- t doesn't already have a metatable: just set specs + setmetatable(t, specs) + else + -- t already has a metatable: copy specs into it + local key, value + for key, value in pairs(specs) do + mt[key] = value + end + end + -- having set or enriched t's metatable, return t + return t +end + +-- On the passed module (i.e. table), set an __index metamethod such that +-- referencing module.submodule lazily requires(path/submodule). +-- The loaded submodule is cached in the module table so it need not be passed +-- to require() again. +-- 'path', like any require() string, can be relative to LuaRequirePath. +-- Returns the enriched module, permitting e.g. +-- mymod = util.submoduledir({}, 'mymod') +function util.submoduledir(module, path) + return util.setmetamethods{ + module, + __index=function(t, key) + local mod = require(`{path}/{key}`) + -- cache the submodule + t[key] = mod + return mod + end + } +end + return util |