A bizarre C++ wart wants us to declare FromStack overloads
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).
This commit is contained in:
@@ -127,9 +127,8 @@ const RString &EnumToString( int iVal, int iMax, const char **szNameArray, auto_
|
|||||||
return (X)(i+1); /*invalid*/ \
|
return (X)(i+1); /*invalid*/ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LuaDeclareType(X) \
|
// currently unused
|
||||||
namespace LuaHelpers { bool FromStack( lua_State *L, X &Object, int iOffset ); } \
|
#define LuaDeclareType(X)
|
||||||
namespace LuaHelpers { void Push( lua_State *L, const X &Object ); }
|
|
||||||
|
|
||||||
#define LuaXType(X) \
|
#define LuaXType(X) \
|
||||||
template struct EnumTraits<X>; \
|
template struct EnumTraits<X>; \
|
||||||
@@ -162,8 +161,8 @@ static void Lua##X(lua_State* L) \
|
|||||||
REGISTER_WITH_LUA_FUNCTION( Lua##X ); \
|
REGISTER_WITH_LUA_FUNCTION( Lua##X ); \
|
||||||
template<> X EnumTraits<X>::Invalid = enum_add2( NUM_##X, 1 ); \
|
template<> X EnumTraits<X>::Invalid = enum_add2( NUM_##X, 1 ); \
|
||||||
template<> const char *EnumTraits<X>::szName = #X; \
|
template<> const char *EnumTraits<X>::szName = #X; \
|
||||||
bool LuaHelpers::FromStack( lua_State *L, X &Object, int iOffset ) { Object = Enum::Check<X>( L, iOffset ); return true; } \
|
namespace LuaHelpers { template<> bool FromStack<X>( lua_State *L, X &Object, int iOffset ) { Object = Enum::Check<X>( L, iOffset ); return true; } } \
|
||||||
void LuaHelpers::Push( lua_State *L, const X &Object ) { Enum::Push<X>( L, Object ); }
|
namespace LuaHelpers { template<> void Push<X>( lua_State *L, const X &Object ) { Enum::Push<X>( L, Object ); } }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ public:
|
|||||||
void T::PushSelf( lua_State *L ) { Luna<B>::PushObject( L, Luna<T>::m_sClassName, this ); } \
|
void T::PushSelf( lua_State *L ) { Luna<B>::PushObject( L, Luna<T>::m_sClassName, this ); } \
|
||||||
static Luna##T registera##T; \
|
static Luna##T registera##T; \
|
||||||
/* Call PushSelf, so we always call the derived Luna<T>::Push. */ \
|
/* Call PushSelf, so we always call the derived Luna<T>::Push. */ \
|
||||||
namespace LuaHelpers { template<> void Push( lua_State *L, T *pObject ) { pObject->PushSelf( L ); } }
|
namespace LuaHelpers { template<> void Push<T*>( lua_State *L, T *const &pObject ) { pObject->PushSelf( L ); } }
|
||||||
|
|
||||||
#define DEFINE_METHOD( method_name, expr ) \
|
#define DEFINE_METHOD( method_name, expr ) \
|
||||||
static int method_name( T* p, lua_State *L ) { LuaHelpers::Push( L, p->expr ); return 1; }
|
static int method_name( T* p, lua_State *L ) { LuaHelpers::Push( L, p->expr ); return 1; }
|
||||||
|
|||||||
@@ -21,6 +21,19 @@ static LuaFunctionList *g_LuaFunctions = NULL;
|
|||||||
#pragma warning (disable : 4611)
|
#pragma warning (disable : 4611)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace LuaHelpers
|
||||||
|
{
|
||||||
|
template<> void Push<bool>( lua_State *L, const bool &Object );
|
||||||
|
template<> void Push<float>( lua_State *L, const float &Object );
|
||||||
|
template<> void Push<int>( lua_State *L, const int &Object );
|
||||||
|
template<> void Push<RString>( lua_State *L, const RString &Object );
|
||||||
|
|
||||||
|
template<> bool FromStack<bool>( Lua *L, bool &Object, int iOffset );
|
||||||
|
template<> bool FromStack<float>( Lua *L, float &Object, int iOffset );
|
||||||
|
template<> bool FromStack<int>( Lua *L, int &Object, int iOffset );
|
||||||
|
template<> bool FromStack<RString>( Lua *L, RString &Object, int iOffset );
|
||||||
|
}
|
||||||
|
|
||||||
struct ChunkReaderString
|
struct ChunkReaderString
|
||||||
{
|
{
|
||||||
ChunkReaderString( const RString &sBuf ): m_sBuf(sBuf) { m_bDone = false; }
|
ChunkReaderString( const RString &sBuf ): m_sBuf(sBuf) { m_bDone = false; }
|
||||||
@@ -68,16 +81,17 @@ void LuaManager::UnsetGlobal( const RString &sName )
|
|||||||
LUA->Release( L );
|
LUA->Release( L );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace LuaHelpers
|
||||||
|
{
|
||||||
|
template<> void Push<bool>( lua_State *L, const bool &Object ) { lua_pushboolean( L, Object ); }
|
||||||
|
template<> void Push<float>( lua_State *L, const float &Object ) { lua_pushnumber( L, Object ); }
|
||||||
|
template<> void Push<int>( lua_State *L, const int &Object ) { lua_pushinteger( L, Object ); }
|
||||||
|
template<> void Push<RString>( lua_State *L, const RString &Object ) { lua_pushlstring( L, Object.data(), Object.size() ); }
|
||||||
|
|
||||||
void LuaHelpers::Push( lua_State *L, const bool &Object ) { lua_pushboolean( L, Object ); }
|
template<> bool FromStack<bool>( Lua *L, bool &Object, int iOffset ) { Object = !!lua_toboolean( L, iOffset ); return true; }
|
||||||
void LuaHelpers::Push( lua_State *L, const float &Object ) { lua_pushnumber( L, Object ); }
|
template<> bool FromStack<float>( Lua *L, float &Object, int iOffset ) { Object = (float)lua_tonumber( L, iOffset ); return true; }
|
||||||
void LuaHelpers::Push( lua_State *L, const int &Object ) { lua_pushinteger( L, Object ); }
|
template<> bool FromStack<int>( Lua *L, int &Object, int iOffset ) { Object = lua_tointeger( L, iOffset ); return true; }
|
||||||
void LuaHelpers::Push( lua_State *L, const RString &Object ) { lua_pushlstring( L, Object.data(), Object.size() ); }
|
template<> bool FromStack<RString>( Lua *L, RString &Object, int iOffset )
|
||||||
|
|
||||||
bool LuaHelpers::FromStack( Lua *L, bool &Object, int iOffset ) { Object = !!lua_toboolean( L, iOffset ); return true; }
|
|
||||||
bool LuaHelpers::FromStack( Lua *L, float &Object, int iOffset ) { Object = (float)lua_tonumber( L, iOffset ); return true; }
|
|
||||||
bool LuaHelpers::FromStack( Lua *L, int &Object, int iOffset ) { Object = lua_tointeger( L, iOffset ); return true; }
|
|
||||||
bool LuaHelpers::FromStack( Lua *L, RString &Object, int iOffset )
|
|
||||||
{
|
{
|
||||||
size_t iLen;
|
size_t iLen;
|
||||||
const char *pStr = lua_tolstring( L, iOffset, &iLen );
|
const char *pStr = lua_tolstring( L, iOffset, &iLen );
|
||||||
@@ -88,6 +102,7 @@ bool LuaHelpers::FromStack( Lua *L, RString &Object, int iOffset )
|
|||||||
|
|
||||||
return pStr != NULL;
|
return pStr != NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LuaHelpers::CreateTableFromArrayB( Lua *L, const vector<bool> &aIn )
|
void LuaHelpers::CreateTableFromArrayB( Lua *L, const vector<bool> &aIn )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,17 +81,10 @@ namespace LuaHelpers
|
|||||||
void PushValueFunc( lua_State *L, int iArgs );
|
void PushValueFunc( lua_State *L, int iArgs );
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Push( lua_State *L, T *pObject );
|
void Push( lua_State *L, const T &Object );
|
||||||
|
|
||||||
void Push( lua_State *L, const bool &Object );
|
template<class T>
|
||||||
void Push( lua_State *L, const float &Object );
|
bool FromStack( lua_State *L, T &Object, int iOffset );
|
||||||
void Push( lua_State *L, const int &Object );
|
|
||||||
void Push( lua_State *L, const RString &Object );
|
|
||||||
|
|
||||||
bool FromStack( Lua *L, bool &Object, int iOffset );
|
|
||||||
bool FromStack( Lua *L, float &Object, int iOffset );
|
|
||||||
bool FromStack( Lua *L, int &Object, int iOffset );
|
|
||||||
bool FromStack( Lua *L, RString &Object, int iOffset );
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
bool Pop( lua_State *L, T &val )
|
bool Pop( lua_State *L, T &val )
|
||||||
|
|||||||
@@ -163,20 +163,23 @@ RString LuaReference::Serialize() const
|
|||||||
return sRet;
|
return sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaHelpers::FromStack( lua_State *L, LuaReference &Object, int iOffset )
|
namespace LuaHelpers
|
||||||
|
{
|
||||||
|
template<> bool FromStack<LuaReference>( lua_State *L, LuaReference &Object, int iOffset )
|
||||||
{
|
{
|
||||||
lua_pushvalue( L, iOffset );
|
lua_pushvalue( L, iOffset );
|
||||||
Object.SetFromStack( L );
|
Object.SetFromStack( L );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaHelpers::FromStack( lua_State *L, apActorCommands &Object, int iOffset )
|
template<> bool FromStack<apActorCommands>( lua_State *L, apActorCommands &Object, int iOffset )
|
||||||
{
|
{
|
||||||
LuaReference *pRef = new LuaReference;
|
LuaReference *pRef = new LuaReference;
|
||||||
FromStack( L, *pRef, iOffset );
|
FromStack( L, *pRef, iOffset );
|
||||||
Object = apActorCommands( pRef );
|
Object = apActorCommands( pRef );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LuaTable::LuaTable()
|
LuaTable::LuaTable()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,12 +51,6 @@ private:
|
|||||||
|
|
||||||
typedef AutoPtrCopyOnWrite<LuaReference> apActorCommands;
|
typedef AutoPtrCopyOnWrite<LuaReference> apActorCommands;
|
||||||
|
|
||||||
namespace LuaHelpers
|
|
||||||
{
|
|
||||||
bool FromStack( lua_State *L, LuaReference &Object, int iOffset );
|
|
||||||
bool FromStack( lua_State *L, apActorCommands &Object, int iOffset );
|
|
||||||
}
|
|
||||||
|
|
||||||
class LuaTable: public LuaReference
|
class LuaTable: public LuaReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#ifndef MessageManager_H
|
#ifndef MessageManager_H
|
||||||
#define MessageManager_H
|
#define MessageManager_H
|
||||||
|
|
||||||
|
#include "LuaManager.h"
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
|
|
||||||
enum Message
|
enum Message
|
||||||
@@ -201,6 +202,8 @@ public:
|
|||||||
bool operator != ( const T &other ) const { return val != other; }
|
bool operator != ( const T &other ) const { return val != other; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace LuaHelpers { template<class T> void Push( lua_State *L, const BroadcastOnChange<T> &Object ) { LuaHelpers::Push<T>( L, Object.Get() ); } }
|
||||||
|
|
||||||
template<class T, int N>
|
template<class T, int N>
|
||||||
class BroadcastOnChange1D
|
class BroadcastOnChange1D
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "EnumHelper.h"
|
#include "EnumHelper.h"
|
||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
|
#include "LuaManager.h"
|
||||||
class XNode;
|
class XNode;
|
||||||
|
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
@@ -115,6 +116,8 @@ private:
|
|||||||
void (*m_pfnValidate)(T& val);
|
void (*m_pfnValidate)(T& val);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace LuaHelpers { template<typename T, typename U> void Push( lua_State *L, const Preference<T, U> &Object ) { LuaHelpers::Push<T>( L, Object.Get() ); } }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class Preference1D
|
class Preference1D
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,11 +36,14 @@ void RageColor::FromStack( lua_State *L, int iPos )
|
|||||||
lua_pop( L, 5 );
|
lua_pop( L, 5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaHelpers::FromStack( lua_State *L, RageColor &Object, int iOffset )
|
namespace LuaHelpers
|
||||||
|
{
|
||||||
|
template<> bool FromStack<RageColor>( lua_State *L, RageColor &Object, int iOffset )
|
||||||
{
|
{
|
||||||
Object.FromStack( L, iOffset );
|
Object.FromStack( L, iOffset );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *CullModeNames[] =
|
static const char *CullModeNames[] =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -200,11 +200,6 @@ public:
|
|||||||
float r, g, b, a;
|
float r, g, b, a;
|
||||||
} SM_ALIGN(16);
|
} SM_ALIGN(16);
|
||||||
|
|
||||||
namespace LuaHelpers
|
|
||||||
{
|
|
||||||
bool FromStack( lua_State *L, RageColor &Object, int iOffset );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert floating-point 0..1 value to integer 0..255 value. *
|
/* Convert floating-point 0..1 value to integer 0..255 value. *
|
||||||
*
|
*
|
||||||
* As a test case,
|
* As a test case,
|
||||||
|
|||||||
@@ -72,10 +72,9 @@ public:
|
|||||||
{
|
{
|
||||||
if( m_sName != "" && THEME && THEME->IsThemeLoaded() )
|
if( m_sName != "" && THEME && THEME->IsThemeLoaded() )
|
||||||
{
|
{
|
||||||
using namespace LuaHelpers;
|
|
||||||
Lua *L = LUA->Get();
|
Lua *L = LUA->Get();
|
||||||
THEME->PushMetric( L, m_sGroup, m_sName );
|
THEME->PushMetric( L, m_sGroup, m_sName );
|
||||||
if( !FromStack(L, m_currentValue, -1) )
|
if( !LuaHelpers::FromStack(L, m_currentValue, -1) )
|
||||||
m_currentValue = T();
|
m_currentValue = T();
|
||||||
lua_pop( L, 1 );
|
lua_pop( L, 1 );
|
||||||
LUA->Release(L);
|
LUA->Release(L);
|
||||||
|
|||||||
Reference in New Issue
Block a user