diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2024-06-11 21:42:10 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2024-06-11 21:42:10 -0400 |
commit | 18c4dcc5998e061fe3ab54607665c775dd18c826 (patch) | |
tree | 69d84b90ca249c2a0877c7a368692b64d289be11 /indra/newview/scripts | |
parent | eae45eefb55410782559b4ace5350b2a99f63234 (diff) |
Allow Python-like 'object = ClassName(ctor args)' constructor calls.
The discussions we've read about Lua classes conventionally use
ClassName:new() as the constructor, and so far we've followed that convention.
But setting metaclass(ClassName).__call = ClassName.new permits Lua to respond
to calls of the form ClassName(ctor args) by implicitly calling
ClassName:new(ctor args).
Introduce util.classctor(). Calling util.classctor(ClassName) sets ClassName's
metaclass's __call to ClassName's constructor method. If the constructor method
is named something other than new(), pass ClassName.method as the second arg.
Use util.classctor() on each of our classes that defines a new() method.
Replace ClassName:new(args) calls with ClassName(args) calls throughout.
Diffstat (limited to 'indra/newview/scripts')
-rw-r--r-- | indra/newview/scripts/lua/ErrorQueue.lua | 5 | ||||
-rw-r--r-- | indra/newview/scripts/lua/Floater.lua | 3 | ||||
-rw-r--r-- | indra/newview/scripts/lua/Queue.lua | 4 | ||||
-rw-r--r-- | indra/newview/scripts/lua/WaitQueue.lua | 7 | ||||
-rw-r--r-- | indra/newview/scripts/lua/leap.lua | 13 | ||||
-rw-r--r-- | indra/newview/scripts/lua/qtest.lua | 12 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_luafloater_demo.lua | 2 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_luafloater_demo2.lua | 2 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_luafloater_gesture_list.lua | 2 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_luafloater_gesture_list2.lua | 2 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_timers.lua | 16 | ||||
-rw-r--r-- | indra/newview/scripts/lua/timers.lua | 3 | ||||
-rw-r--r-- | indra/newview/scripts/lua/util.lua | 25 |
13 files changed, 71 insertions, 25 deletions
diff --git a/indra/newview/scripts/lua/ErrorQueue.lua b/indra/newview/scripts/lua/ErrorQueue.lua index 13e4e92941..e6e9a5ef48 100644 --- a/indra/newview/scripts/lua/ErrorQueue.lua +++ b/indra/newview/scripts/lua/ErrorQueue.lua @@ -5,8 +5,11 @@ local WaitQueue = require('WaitQueue') local function dbg(...) end -- local dbg = require('printf') +local util = require('util') -local ErrorQueue = WaitQueue:new() +local ErrorQueue = WaitQueue() + +util.classctor(ErrorQueue) function ErrorQueue:Error(message) -- Setting Error() is a marker, like closing the queue. Once we reach the diff --git a/indra/newview/scripts/lua/Floater.lua b/indra/newview/scripts/lua/Floater.lua index 75696533e4..d057a74386 100644 --- a/indra/newview/scripts/lua/Floater.lua +++ b/indra/newview/scripts/lua/Floater.lua @@ -2,6 +2,7 @@ local leap = require 'leap' local fiber = require 'fiber' +local util = require 'util' -- list of all the events that a LLLuaFloater might send local event_list = leap.request("LLFloaterReg", {op="getFloaterEvents"}).events @@ -45,6 +46,8 @@ function Floater:new(path, extra) return obj end +util.classctor(Floater) + function Floater:show() -- leap.eventstream() returns the first response, and launches a -- background fiber to call the passed callback with all subsequent diff --git a/indra/newview/scripts/lua/Queue.lua b/indra/newview/scripts/lua/Queue.lua index 5ab2a8a72c..5bc72e4057 100644 --- a/indra/newview/scripts/lua/Queue.lua +++ b/indra/newview/scripts/lua/Queue.lua @@ -7,6 +7,8 @@ -- But had to resist -- For fear it might be too obscua. +local util = require 'util' + local Queue = {} function Queue:new() @@ -20,6 +22,8 @@ function Queue:new() return obj end +util.classctor(Queue) + -- Check if the queue is empty function Queue:IsEmpty() return self._first > self._last diff --git a/indra/newview/scripts/lua/WaitQueue.lua b/indra/newview/scripts/lua/WaitQueue.lua index 6bcb9d62c2..7e10d03295 100644 --- a/indra/newview/scripts/lua/WaitQueue.lua +++ b/indra/newview/scripts/lua/WaitQueue.lua @@ -4,14 +4,15 @@ local fiber = require('fiber') local Queue = require('Queue') +local util = require('util') local function dbg(...) end -- local dbg = require('printf') -local WaitQueue = Queue:new() +local WaitQueue = Queue() function WaitQueue:new() - local obj = Queue:new() + local obj = Queue() setmetatable(obj, self) self.__index = self @@ -20,6 +21,8 @@ function WaitQueue:new() return obj end +util.classctor(WaitQueue) + function WaitQueue:Enqueue(value) if self._closed then error("can't Enqueue() on closed Queue") diff --git a/indra/newview/scripts/lua/leap.lua b/indra/newview/scripts/lua/leap.lua index 8caae24e94..82f91ce9e9 100644 --- a/indra/newview/scripts/lua/leap.lua +++ b/indra/newview/scripts/lua/leap.lua @@ -43,6 +43,7 @@ local ErrorQueue = require('ErrorQueue') local inspect = require('inspect') local function dbg(...) end -- local dbg = require('printf') +local util = require('util') local leap = {} @@ -129,7 +130,7 @@ local function requestSetup(pump, data) -- because, unlike the WaitFor base class, WaitForReqid does not -- self-register on our waitfors list. Instead, capture the new -- WaitForReqid object in pending so dispatch() can find it. - local waitfor = leap.WaitForReqid:new(reqid) + local waitfor = leap.WaitForReqid(reqid) pending[reqid] = waitfor -- Pass reqid to send() to stamp it into (a copy of) the request data. dbg('requestSetup(%s, %s) storing %s', pump, data, waitfor.name) @@ -432,7 +433,7 @@ function leap.WaitFor:new(priority, name) self._id += 1 obj.name = 'WaitFor' .. self._id end - obj._queue = ErrorQueue:new() + obj._queue = ErrorQueue() obj._registered = false -- if no priority, then don't enable() - remember 0 is truthy if priority then @@ -442,6 +443,8 @@ function leap.WaitFor:new(priority, name) return obj end +util.classctor(leap.WaitFor) + -- Re-enable a disable()d WaitFor object. New WaitFor objects are -- enable()d by default. function leap.WaitFor:enable() @@ -514,13 +517,13 @@ function leap.WaitFor:exception(message) end -- ------------------------------ WaitForReqid ------------------------------- -leap.WaitForReqid = leap.WaitFor:new() +leap.WaitForReqid = leap.WaitFor() function leap.WaitForReqid:new(reqid) -- priority is meaningless, since this object won't be added to the -- priority-sorted waitfors list. Use the reqid as the debugging name -- string. - local obj = leap.WaitFor:new(nil, 'WaitForReqid(' .. reqid .. ')') + local obj = leap.WaitFor(nil, 'WaitForReqid(' .. reqid .. ')') setmetatable(obj, self) self.__index = self @@ -529,6 +532,8 @@ function leap.WaitForReqid:new(reqid) return obj end +util.classctor(leap.WaitForReqid) + function leap.WaitForReqid:filter(pump, data) -- Because we expect to directly look up the WaitForReqid object of -- interest based on the incoming ["reqid"] value, it's not necessary diff --git a/indra/newview/scripts/lua/qtest.lua b/indra/newview/scripts/lua/qtest.lua index 009446d0c3..9526f58b04 100644 --- a/indra/newview/scripts/lua/qtest.lua +++ b/indra/newview/scripts/lua/qtest.lua @@ -21,8 +21,8 @@ function resume(co, ...) end -- ------------------ Queue variables are instance-specific ------------------ -q1 = Queue:new() -q2 = Queue:new() +q1 = Queue() +q2 = Queue() q1:Enqueue(17) @@ -33,8 +33,8 @@ assert(q1:Dequeue() == nil) assert(q2:Dequeue() == nil) -- ----------------------------- test WaitQueue ------------------------------ -q1 = WaitQueue:new() -q2 = WaitQueue:new() +q1 = WaitQueue() +q2 = WaitQueue() result = {} values = { 1, 1, 2, 3, 5, 8, 13, 21 } @@ -76,7 +76,7 @@ print('result:', inspect(result)) assert(util.equal(values, result)) -- try incrementally enqueueing values -q3 = WaitQueue:new() +q3 = WaitQueue() result = {} values = { 'This', 'is', 'a', 'test', 'script' } @@ -124,7 +124,7 @@ print(string.format('%q', table.concat(result, ' '))) assert(util.equal(values, result)) -- ----------------------------- test ErrorQueue ----------------------------- -q4 = ErrorQueue:new() +q4 = ErrorQueue() result = {} values = { 'This', 'is', 'a', 'test', 'script' } diff --git a/indra/newview/scripts/lua/test_luafloater_demo.lua b/indra/newview/scripts/lua/test_luafloater_demo.lua index ab638dcdd1..65a31670c8 100644 --- a/indra/newview/scripts/lua/test_luafloater_demo.lua +++ b/indra/newview/scripts/lua/test_luafloater_demo.lua @@ -60,7 +60,7 @@ local resp = leap.request("LLFloaterReg", key) COMMAND_PUMP_NAME = resp.command_name reqid = resp.reqid -catch_events = leap.WaitFor:new(-1, "all_events") +catch_events = leap.WaitFor(-1, "all_events") function catch_events:filter(pump, data) if data.reqid == reqid then return data diff --git a/indra/newview/scripts/lua/test_luafloater_demo2.lua b/indra/newview/scripts/lua/test_luafloater_demo2.lua index 9e24237d28..3903d01e65 100644 --- a/indra/newview/scripts/lua/test_luafloater_demo2.lua +++ b/indra/newview/scripts/lua/test_luafloater_demo2.lua @@ -2,7 +2,7 @@ local Floater = require 'Floater' local leap = require 'leap' local startup = require 'startup' -local flt = Floater:new( +local flt = Floater( 'luafloater_demo.xml', {show_time_lbl = {"right_mouse_down", "double_click"}}) diff --git a/indra/newview/scripts/lua/test_luafloater_gesture_list.lua b/indra/newview/scripts/lua/test_luafloater_gesture_list.lua index 3d9a9b0ad4..a5fd325430 100644 --- a/indra/newview/scripts/lua/test_luafloater_gesture_list.lua +++ b/indra/newview/scripts/lua/test_luafloater_gesture_list.lua @@ -58,7 +58,7 @@ local key = {xml_path = XML_FILE_PATH, op = "showLuaFloater"} key.extra_events={gesture_list = {_event("double_click")}} handleEvents(leap.request("LLFloaterReg", key)) -catch_events = leap.WaitFor:new(-1, "all_events") +catch_events = leap.WaitFor(-1, "all_events") function catch_events:filter(pump, data) if data.reqid == reqid then return data diff --git a/indra/newview/scripts/lua/test_luafloater_gesture_list2.lua b/indra/newview/scripts/lua/test_luafloater_gesture_list2.lua index d702d09c51..bd397ef2a6 100644 --- a/indra/newview/scripts/lua/test_luafloater_gesture_list2.lua +++ b/indra/newview/scripts/lua/test_luafloater_gesture_list2.lua @@ -2,7 +2,7 @@ local Floater = require 'Floater' local LLGesture = require 'LLGesture' local startup = require 'startup' -local flt = Floater:new( +local flt = Floater( "luafloater_gesture_list.xml", {gesture_list = {"double_click"}}) diff --git a/indra/newview/scripts/lua/test_timers.lua b/indra/newview/scripts/lua/test_timers.lua index ed0de070f7..be5001aa16 100644 --- a/indra/newview/scripts/lua/test_timers.lua +++ b/indra/newview/scripts/lua/test_timers.lua @@ -6,9 +6,9 @@ local timers = require 'timers' -- is true, that timeUntilCall() is (true, close to 10), that cancel() returns -- true. After that, isRunning() is false, timeUntilCall() returns (false, 0), -- and a second cancel() returns false. -print('t0:new(10)') +print('t0(10)') start = os.clock() -t0 = timers.Timer:new(10, function() print('t0 fired at', os.clock() - start) end) +t0 = timers.Timer(10, function() print('t0 fired at', os.clock() - start) end) print('t0:isRunning(): ', t0:isRunning()) print('t0:timeUntilCall(): ', t0:timeUntilCall()) print('t0:cancel(): ', t0:cancel()) @@ -18,16 +18,16 @@ print('t0:cancel(): ', t0:cancel()) -- t1 is supposed to fire after 5 seconds, but it doesn't wait, so you see the -- t2 messages immediately after. -print('t1:new(5)') +print('t1(5)') start = os.clock() -t1 = timers.Timer:new(5, function() print('t1 fired at', os.clock() - start) end) +t1 = timers.Timer(5, function() print('t1 fired at', os.clock() - start) end) -- t2 illustrates that instead of passing a callback to new(), you can -- override the timer instance's tick() method. But t2 doesn't wait either, so -- you see the Timer(5) message immediately. -print('t2:new(2)') +print('t2(2)') start = os.clock() -t2 = timers.Timer:new(2) +t2 = timers.Timer(2) function t2:tick() print('t2 fired at', os.clock() - start) end @@ -37,7 +37,7 @@ end -- then the t1 callback message before the Timer(5) completion message. print('Timer(5) waiting') start = os.clock() -timers.Timer:new(5, 'wait') +timers.Timer(5, 'wait') print(string.format('Timer(5) waited %f seconds', os.clock() - start)) -- This test demonstrates a repeating timer. It also shows that you can (but @@ -50,7 +50,7 @@ print(string.format('Timer(5) waited %f seconds', os.clock() - start)) -- it's worth knowing that a coroutine timer callback can be used to manage -- more complex control flows. start = os.clock() -timers.Timer:new( +timers.Timer( 2, coroutine.wrap(function() for i = 1,5 do diff --git a/indra/newview/scripts/lua/timers.lua b/indra/newview/scripts/lua/timers.lua index e0d27a680d..e4938078dc 100644 --- a/indra/newview/scripts/lua/timers.lua +++ b/indra/newview/scripts/lua/timers.lua @@ -1,6 +1,7 @@ -- Access to the viewer's time-delay facilities local leap = require 'leap' +local util = require 'util' local timers = {} @@ -78,6 +79,8 @@ function timers.Timer:new(delay, callback, iterate) return obj end +util.classctor(timers.Timer) + function timers.Timer:tick() error('Pass a callback to Timer:new(), or override Timer:tick()') end diff --git a/indra/newview/scripts/lua/util.lua b/indra/newview/scripts/lua/util.lua index a2191288f6..bfbfc8637c 100644 --- a/indra/newview/scripts/lua/util.lua +++ b/indra/newview/scripts/lua/util.lua @@ -2,6 +2,31 @@ local util = {} +-- Allow MyClass(ctor args...) equivalent to MyClass:new(ctor args...) +-- Usage: +-- local MyClass = {} +-- function MyClass:new(...) +-- ... +-- end +-- ... +-- util.classctor(MyClass) +-- or if your constructor is named something other than MyClass:new(), e.g. +-- MyClass:construct(): +-- 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 +end + -- check if array-like table contains certain value function util.contains(t, v) return table.find(t, v) ~= nil |