Age | Commit message (Collapse) | Author |
|
The help string for each lua_function() must restate the function name and its
arguments. The help string is all that's shown; unless it restates the
function name, LL.help() output lists terse explanations for functions whose
names are not shown.
Make help() prepend "LL." to help output, because these functions must be
accessed via the "builtin" LL table instead of directly populating the global
Lua namespace.
Similarly, before string name lookup, remove "LL." prefix if specified.
|
|
|
|
|
|
On Mac it doesn't seem to matter, but on Windows, leaving it uninitialized can
produce garbage results and even crash the coroutine. This seems strange,
since we've been assuming lua_getinfo() treats its lua_Debug* as output-only.
|
|
We might decide to leave some of them in place.
|
|
so cleanup happens in reverse order, as is conventional.
Streamline LL.atexit() function: luaL_newmetatable() performs all the
find-or-create named Registry table logic.
|
|
lua_emplace<T>() was passing LL.atexit() a closure binding the new userdata
with a cleanup function. The trouble with that was that a strong reference to
the new userdata would prevent it ever being garbage collected, even if that
was the only remaining reference.
Instead, create a new weak table referencing the userdata, and bind that into
the cleanup function's closure. Then if the only remaining reference to the
userdata is from the weak table, the userdata can be collected.
Make lua_emplace_call_gc<T>() check the bound weak table in case the userdata
has in fact been collected.
Also, in lua_toclass<T>(), use luaL_checkudata() to synopsize comparing the
putative userdata's metatable against the one synthesized by lua_emplace<T>().
This saves several explicit steps.
|
|
source_path() previously reported the path of the module containing the
current (lowest-level) Lua function. The effect was that the Floater.lua
module would always try to look up the XUI file relative to
scripts/lua/require.
It makes more intuitive sense to make source_path() return the path containing
the top-level script, so that a script engaging the Floater.lua module looks
for the XUI file relative to the script.
|
|
Instead of deriving LuaListener from LLInstanceTracker with an int key,
generating a unique int key and storing that key in the Registry, use new
lua_emplace<LuaState>() to store the LuaListener directly in a Lua userdata
object in the Lua Registry.
Because lua_emplace<T>() uses LL.atexit() to guarantee that ~LuaState will
destroy the T object, we no longer need ~LuaState() to make a special call
specifically to destroy the LuaListener, if any. So we no longer need
LuaState::getListener() separate from obtainListener().
Since LuaListener is no longer an LLInstanceTracker subclass, make
LuaState::obtainListener() return LuaListener& rather than LuaListener::ptr_t.
|
|
Publish new LL.atexit() function that accepts a Lua function (or C++ closure)
and saves it (in Registry["atexit"] table) to call later.
Make ~LuaState() walk the Registry["atexit"] table, if it exists, calling each
function appended to that table.
(Consider using that mechanism to clean up a LuaListener, if one was
instantiated. Possibly also use for p.s. leap.run()? But that's run after
every expr() call, instead of only at ~LuaState() time. Pragmatically, though,
the distinction only matters for a LUA Debug Console LUA string with "clean
lua_State" unchecked.)
For use by future lua_function() entry points, lua_emplace<T>(ctor args...)
pushes a Lua userdata object containing a newly-constructed T instance --
actually a std::optional<T> to avoid double destruction. lua_emplace<T>() is
specifically intended to be usable even for T with a nontrivial destructor: it
gives the userdata a metatable with a __gc function that destroys the
contained T instance when the userdata is garbage collected. But since garbage
collection doesn't guarantee to clean up global variables with __gc methods,
lua_emplace<T>() also uses LL.atexit() to ensure that ~T() will run when the
LuaState is destroyed.
The companion to lua_emplace<T>() is lua_toclass<T>(), which returns a
non-nullptr T* if the referenced index is in fact a userdata created by
lua_emplace<T>() for the same T, that has not yet been destroyed. This lets
C++ code access a T previously embedded in Lua userdata.
|
|
We have log messages when a coroutine terminates abnormally, but we don't
report either when it starts or when it terminates normally. Address that.
|
|
It's helpful to see when expr() is actually going to start running a
particular Lua chunk. We already report not only when it's done, but also
if/when we start and finish a p.s. fiber.run() call.
|
|
|
|
to pick up Featurettes promotion + Brad's GitHub Windows build workaround.
|
|
#648: Release/materials featurette
|
|
|
|
|
|
|
|
instead of using mutual recursion to exhaust the read buffer.
|
|
|
|
|
|
The reqid is only distinct within a particular calling script.
|
|
Since timers presents a timers.Timer Lua class supporting queries and
cancellation, make TimersListener::scheduleAfter() and scheduleEvery() respond
immediately so the newly constructed Timer object has the reqid necessary to
perform those subsequent operations.
This requires that Lua invocations of these operations avoid calling the
caller's callback with that initial response.
Reinvent leap.generate() to return a Lua object supporting next() and done()
methods. A plain Lua coroutine that (indirectly) calls fiber.wait() confuses
the fiber scheduler, so avoid implementing generate() as a Lua coroutine.
Add a bit more leap.lua diagnostic output.
|
|
|
|
|
|
Otherwise we fall into the trap of destroying a joinable std::thread, which
calls std::terminate() and hence our crash-on-terminate() handler.
The previous ~ThreadPool() logic only joined threads if the queue wasn't
already closed, but evidently we can reach the destructor with the queue
closed but the threads not yet joined.
Fixes #1534.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Conflicts:
# doc/contributions.txt
# indra/newview/llfloaterimagepreview.cpp
|
|
|
|
|
|
Maintenance X
|
|
|
|
|
|
Instead of making LLEventPumps an LLHandleProvider, and storing an
LLHandle<LLEventPumps> in each LLEventPump instance, just make ~LLEventPump()
query LLEventPumps::instanceExists() before calling instance().
|
|
Rename LL::Timers::scheduleRepeating() to scheduleEvery().
|
|
(cherry picked from commit dc0b3aed4782e4e4835fd6b9d59d1d70b78be4a7)
|
|
|