diff options
Diffstat (limited to 'indra/newview/scripts/lua/require')
-rw-r--r-- | indra/newview/scripts/lua/require/LLChatListener.lua | 2 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/UI.lua | 7 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/UI/Floater.lua (renamed from indra/newview/scripts/lua/require/Floater.lua) | 0 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/UI/popup.lua | 82 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/popup.lua | 53 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/util.lua | 65 |
6 files changed, 143 insertions, 66 deletions
diff --git a/indra/newview/scripts/lua/require/LLChatListener.lua b/indra/newview/scripts/lua/require/LLChatListener.lua index 428dca881e..82b28966ce 100644 --- a/indra/newview/scripts/lua/require/LLChatListener.lua +++ b/indra/newview/scripts/lua/require/LLChatListener.lua @@ -23,7 +23,7 @@ function LLChatListener:handleMessages(event_data) end function LLChatListener:start() - waitfor = leap.WaitFor:new(-1, self.name) + waitfor = leap.WaitFor(-1, self.name) function waitfor:filter(pump, data) if pump == "LLNearbyChat" then return data diff --git a/indra/newview/scripts/lua/require/UI.lua b/indra/newview/scripts/lua/require/UI.lua index 464e6547ea..bbcae3514a 100644 --- a/indra/newview/scripts/lua/require/UI.lua +++ b/indra/newview/scripts/lua/require/UI.lua @@ -1,10 +1,13 @@ -- Engage the viewer's UI local leap = require 'leap' -local Timer = (require 'timers').Timer local mapargs = require 'mapargs' +local Timer = (require 'timers').Timer +local util = require 'util' -local UI = {} +-- Allow lazily accessing UI submodules on demand, e.g. a reference to +-- UI.Floater lazily loads the UI/Floater module. +local UI = util.submoduledir({}, 'UI') -- *************************************************************************** -- registered menu actions diff --git a/indra/newview/scripts/lua/require/Floater.lua b/indra/newview/scripts/lua/require/UI/Floater.lua index d057a74386..d057a74386 100644 --- a/indra/newview/scripts/lua/require/Floater.lua +++ b/indra/newview/scripts/lua/require/UI/Floater.lua diff --git a/indra/newview/scripts/lua/require/UI/popup.lua b/indra/newview/scripts/lua/require/UI/popup.lua new file mode 100644 index 0000000000..8ccf3b87f3 --- /dev/null +++ b/indra/newview/scripts/lua/require/UI/popup.lua @@ -0,0 +1,82 @@ +local leap = require 'leap' +local mapargs = require 'mapargs' +local util = require 'util' + +-- notification is any name defined in notifications.xml as +-- <notification name=> +-- vars is a table providing values for [VAR] substitution keys in the +-- notification body +-- payload prepopulates the response table +-- wait=false means fire and forget, returning nil +-- wait=true waits for user response: +-- * If the viewer returns a table containing exactly one key=true pair, +-- popup() returns just that key. If the key is a string containing an +-- underscore, e.g. 'OK_okcancelbuttons', it's truncated at the first +-- underscore, e.g. 'OK'. +-- * Otherwise the viewer's response is returned unchanged. To suppress the +-- above transformations, pass a non-empty payload table; this will cause +-- the viewer to return a table with at least two keys. +local popup = util.setmetamethods{ + -- this gets called when a consumer calls popup(notification, vars, payload) + __call = function(self, ...) + local args = mapargs('notification,vars,payload,wait', ...) + -- we use convenience argument names different from 'LLNotifications' + -- listener + newargs = {op='requestAdd', + name=args.notification, + substitutions=args.vars, + payload=args.payload} + -- Specifically test (wait == false), NOT (not wait), because we treat + -- nil (omitted, default true) differently than false (explicitly + -- DON'T wait). + if args.wait == false then + leap.send('LLNotifications', newargs) + else + local response = leap.request('LLNotifications', newargs).response + -- response is typically a table. It might have multiple keys, + -- e.g. if caller passed non-empty payload. In that case, just + -- return the whole thing. + if type(response) ~= 'table' then + return response + end + -- get first key=value pair, if any + local key, value = next(response) + if (not key) or next(response, key) then + -- key == nil means response is empty + -- next(response, non-nil first key) ~= nil means at least two keys + return response + end + -- Here response is a table containing exactly one key. The + -- notifications system typically returns a table of the form + -- {OK_okcancelbuttons=true}, which is tricky to test for because it + -- varies with each set of buttons. + if value == true then + -- change {key=true} to plain key + response = key + if type(response) == 'string' then + -- change 'OK_okcancelbuttons' to plain 'OK' + response = string.split(response, '_')[1] + end + end + return response + end + end +} + +function popup:alert(message, payload) + return self('GenericAlert', {MESSAGE=message, payload=payload}) +end + +function popup:alertOK(message, payload) + return self('GenericAlertOK', {MESSAGE=message, payload=payload}) +end + +function popup:alertYesCancel(message, payload) + return self('GenericAlertYesCancel', {MESSAGE=message, payload=payload}) +end + +function popup:tip(message, payload) + self{'SystemMessageTip', {MESSAGE=message, payload=payload}, wait=false} +end + +return popup diff --git a/indra/newview/scripts/lua/require/popup.lua b/indra/newview/scripts/lua/require/popup.lua deleted file mode 100644 index 3aaadf85ba..0000000000 --- a/indra/newview/scripts/lua/require/popup.lua +++ /dev/null @@ -1,53 +0,0 @@ -local leap = require 'leap' -local mapargs = require 'mapargs' - --- notification is any name defined in notifications.xml as --- <notification name=> --- vars is a table providing values for [VAR] substitution keys in the --- notification body --- payload prepopulates the response table --- wait=false means fire and forget, otherwise wait for user response -local popup_meta = { - -- setting this function as getmetatable(popup).__call() means this gets - -- called when a consumer calls popup(notification, vars, payload) - __call = function(self, ...) - local args = mapargs('notification,vars,payload,wait', ...) - -- we use convenience argument names different from 'LLNotifications' - -- listener - args.name = args.notification - args.notification = nil - args.substitutions = args.vars - args.vars = nil - local wait = args.wait - args.wait = nil - args.op = 'requestAdd' - -- Specifically test (wait == false), NOT (not wait), because we treat - -- nil (omitted, default true) differently than false (explicitly - -- DON'T wait). - if wait == false then - leap.send('LLNotifications', args) - else - return leap.request('LLNotifications', args).response - end - end -} - -local popup = setmetatable({}, popup_meta) - -function popup:alert(message) - return self('GenericAlert', {MESSAGE=message}) -end - -function popup:alertOK(message) - return self('GenericAlertOK', {MESSAGE=message}) -end - -function popup:alertYesCancel(message) - return self('GenericAlertYesCancel', {MESSAGE=message}) -end - -function popup:tip(message) - self{'SystemMessageTip', {MESSAGE=message}, wait=false} -end - -return popup 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 |