This is to provide parameters to loading Actor definitions, in a way that
does not need to be explicitly propagated to nested definitions; I want
loading a sub-definition to remain a simple function call with no mandatory
(prescribed) parameters. This provides a general context to pass information
to Lua about what it's loading, such as LoadingScreen.
These are scoped to the running thread, unlike global variables. This prevents
possible threading problems.
All thread variables are scoped: set a variable, do something, unset it; when
finished, all thread variables are unset.
These are no longer available after load. By design, to use these later,
use upvalues:
local color = lua.GetVar("color");
return Def.Quad {
OnCommand=cmd(diffuse,color);
}
-1 key
-2 value
-3 key
...
The top key and value can be removed or modified as required. The key at -3 should not be touched since it is required for the next iteration through the loop.
Stack management is simplified. Anything left on the stack above the key will be popped. After the loop terminates normally, the stack will be as it was before the loop was entered (no nil values to clean up).
with Lua bindings: they couldn't read from disk, or render, or do anything
else potentially time-consuming, because that would hold the Lua lock,
preventing other threads from using it.
before the ThemeMetric templates that use them. That's broken
and unreasonable, so change this around a bit and make FromStack
(and Push) templates.
Push() takes a bit of a trick. Some Push overloads push the
actual value: scalars (int, float), RageColor (pushes a table).
Others--most of them--push a reference to a C++ object. We
want the scalars to have a reference parameter type, so we
don't make extra copies of things like RageColor when we push
them. We need to pass C++ objects by pointer (we need to
push the actual object's pointer, not a pointer to a copy).
Further, pushing a scalar is a const operation, but pushing
a reference to an object is not.
To do both with the same template, we handle objects with
this slightly odd template:
template<> void LuaHelpers::Push<T*>( lua_State *L, T *const &pObject );
The actual overload (T) is eg. "Actor*"; this fits within the
general prototype, "Push(lua_State *L, const T &object)", giving
us a const reference to a (non-const) pointer to Actor, and we're
conceptually pushing the pointer.
The net effect of this is that 1: what was before compile errors
now becomes link time errors, but 2: these specializations
don't have to be in the headers (except for new ones for
Preference and BroadcastOnChange).