4#include "Etterna/Models/Lua/LuaReference.h"
10#define FOREACH_ENUM_N(e, max, var) \
11 for (e var = (e)0; (var) < (max); enum_add<e>((var), +1))
13#define FOREACH_ENUM(e, var) \
14 for (e var = (e)0; (var) < NUM_##e; enum_add<e>((var), +1))
17CheckEnum(lua_State* L,
23 bool bAllowAnything =
false) -> int;
31 static const char* szName;
42 const char** szNameArray,
43 std::unique_ptr<std::string>* pNameCache)
44 ->
const std::string&;
48 const std::string& X##ToString(X x); \
50static_assert(NUM_##X == ARRAYLEN(X##Names), "Size mismatch between "#X" enum and "#X"Names (Did you forget to add a string for a new enum entry?)"); \
52 const std::string& X##ToString(X x) \
55 static std::unique_ptr<std::string> as_##X##Name[NUM_##X + 2]; \
56 return EnumToString(x, NUM_##X, X##Names, as_##X##Name); \
59 namespace StringConversion { \
61 std::string ToString<X>(const X& value) \
63 return X##ToString(value); \
67#define XToLocalizedString(X) \
69 const std::string& X##ToLocalizedString(X x); \
71 const std::string& X##ToLocalizedString(X x) \
74 static std::unique_ptr<LocalizedString> g_##X##Name[NUM_##X]; \
75 if (g_##X##Name[0].get() == nullptr) { \
76 for (unsigned i = 0; i < NUM_##X; ++i) { \
77 std::unique_ptr<LocalizedString> ap( \
78 new LocalizedString(#X, X##ToString((X)i))); \
79 g_##X##Name[i] = std::move(ap); \
82 return g_##X##Name[x]->GetValue(); \
87 X StringTo##X(const std::string&); \
89 X StringTo##X(const std::string& s) \
92 for (unsigned i = 0; i < ARRAYLEN(X##Names); ++i) \
93 if (!CompareNoCase(s, X##Names[i])) \
98 namespace StringConversion \
102 bool FromString<X>(const std::string& sValue, X& out) \
104 out = StringTo##X(sValue); \
105 return out != X##_Invalid; \
121#if defined(__clang__)
122#pragma clang diagnostic push
123#pragma clang diagnostic ignored "-Wundefined-var-template"
124#elif defined(__GNUC__)
125#pragma GCC diagnostic push
126#pragma GCC diagnostic ignored "-Wundefined-var-template"
127#elif defined(_MSC_VER)
136 bool bAllowInvalid =
false,
137 bool bAllowAnything =
false) -> T
139 return static_cast<T
>(CheckEnum(L,
147#if defined(__clang__)
149#elif defined(__GNUC__)
151#elif defined(_MSC_VER)
157Push(lua_State* L, T iVal)
167 lua_rawgeti(L, -1, iVal + 1);
172SetMetatable(lua_State* L,
178#define LuaDeclareType(X)
182 template struct EnumTraits<X>; \
184 static void Lua##X(lua_State* L) \
190 std::string s = X##ToString(i); \
191 lua_pushstring(L, ((#X "_") + s).c_str()); \
192 lua_rawseti(L, -2, i + 1); \
194 EnumTraits<X>::EnumToString.SetFromStack(L); \
195 EnumTraits<X>::EnumToString.PushSelf(L); \
196 lua_setglobal(L, #X); \
200 std::string s = X##ToString(i); \
201 lua_pushstring(L, ((#X "_") + s).c_str()); \
202 lua_pushnumber(L, i); \
206 lua_pushstring(L, s.c_str()); \
207 lua_pushnumber(L, i); \
210 lua_pushnumber(L, i); \
211 lua_rawseti(L, -2, i); \
213 EnumTraits<X>::StringToEnum.SetFromStack(L); \
214 EnumTraits<X>::StringToEnum.PushSelf(L); \
215 Enum::SetMetatable( \
216 L, EnumTraits<X>::EnumToString, EnumTraits<X>::StringToEnum, #X); \
219 REGISTER_WITH_LUA_FUNCTION(Lua##X); \
222 X EnumTraits<X>::Invalid = X##_Invalid; \
225 const char* EnumTraits<X>::szName = #X; \
227 namespace LuaHelpers \
231 bool FromStack<X>(lua_State * L, X& Object, int iOffset) \
233 Object = Enum::Check<X>(L, iOffset, true); \
234 return Object != EnumTraits<X>::Invalid; \
238 namespace LuaHelpers \
242 void Push<X>(lua_State * L, const X& Object) \
244 Enum::Push<X>(L, Object); \
A self-cleaning Lua reference.
Definition LuaReference.h:10
Definition EnumHelper.h:27