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).
actual IPreference defaults according to Defaults.ini. This way, we can
access default values immediately, without having to load and parse a
file. Since this simply changes the value in the preference, this doesn't
use any more memory.
saving them; that's up to PrefsManager.
Treat IPreference as a simple data holder, with simple facilities for
looking them up by name, converting to/from strings, and storing to/from
an XNode, but with no application-specific code to save to disk. This
can be used alone as a way for code to configure things internally, even
for uses that have no notion of storing user preferences (eg. unit tests),
and other programs can use it to store preferences in entirely different
ways (SMPackage could use it to store to the registry). PrefsManager is
layered on top, to implement StepMania's particular use of Preference
(saving and loading INIs), but isn't needed for Preference to be useful.
This also makes Preference only use XNode, not the more specialized IniFile.
(One piece is missing: several low-level places, eg. Dialog, want to set
a preference and write it to disk immediately. The only way to do that
is to have access to PREFSMAN. FIXME.)
for conversions. This way, Preference doesn't need to know about every enum
type used with it. (This means that you can't construct a Preference<T,U> from T,
since you don't know U, which led to the previous ScreenOptionsMasterPrefs.cpp
change.)
hard enough keeping straight which arbitrary options screen an option
is in without having a separate categorization for the INI. (This will
simplify later changes.)
didn't make it work, since there was no cast overload to bool&, etc; it
just forced the (non-POD) type to that type, which resulted in the struct
being clobbered.