summaryrefslogtreecommitdiff
path: root/indra/newview/scripts/lua/require
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/scripts/lua/require')
-rw-r--r--indra/newview/scripts/lua/require/LLChatListener.lua2
-rw-r--r--indra/newview/scripts/lua/require/UI.lua7
-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.lua82
-rw-r--r--indra/newview/scripts/lua/require/popup.lua53
-rw-r--r--indra/newview/scripts/lua/require/util.lua65
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