14 #include <unordered_map>
19 #if defined(__GNUC__) || defined(__GNUG__)
20 #define __forceinline __attribute__((always_inline))
23 #define INLINE __forceinline
31 typedef size_t StringLength;
32 typedef size_t ParameterCount;
33 typedef size_t ReturnCount;
61 template <
typename type>
125 template <
bool createTable>
135 template <
bool typeCheck,
typename inputType>
138 static const char *EXCEPTION_FORMAT =
"Expected %s (type ID %u) at stack index %u! Got type ID %u instead.";
143 static INLINE
bool resolve(lua_State *lua,
const int &index,
int *out)
145 const int type = lua_type(lua, index);
147 if (type != LUA_TNUMBER)
150 sprintf(error, EXCEPTION_FORMAT,
"integer (number) ", LUA_TNUMBER, index, type);
152 throw std::runtime_error(error);
155 *out = lua_tointeger(lua, index);
163 static INLINE
bool resolve(lua_State *lua,
const int &index,
float *out)
165 const int type = lua_type(lua, index);
167 if (type != LUA_TNUMBER)
170 sprintf(error, EXCEPTION_FORMAT,
"float (number)", LUA_TNUMBER, index, type);
172 throw std::runtime_error(error);
175 *out = lua_tonumber(lua, index);
183 static INLINE
bool resolve(lua_State *lua,
const int &index,
char *out)
185 const int type = lua_type(lua, index);
187 if (type != LUA_TSTRING)
190 sprintf(error, EXCEPTION_FORMAT,
"string", LUA_TSTRING, index, type);
192 throw std::runtime_error(error);
195 out =
const_cast<char *
>(lua_tostring(lua, index));
203 static INLINE
bool resolve(lua_State *lua,
const int &index,
void *out)
205 const int type = lua_type(lua, index);
207 if (type != LUA_TUSERDATA)
210 sprintf(error, EXCEPTION_FORMAT,
"user data", LUA_TUSERDATA, index, type);
212 throw std::runtime_error(error);
215 out =
const_cast<void *
>(lua_touserdata(lua, index));
224 static INLINE
bool resolve(lua_State *lua,
const int &index,
char *out)
226 const int type = lua_type(lua, index);
228 if (type != LUA_TSTRING)
231 out =
const_cast<char *
>(lua_tostring(lua, index));
239 static INLINE
bool resolve(lua_State *lua,
const int &index,
float *out)
241 const int type = lua_type(lua, index);
243 if (type != LUA_TNUMBER)
246 *out = lua_tonumber(lua, index);
254 static INLINE
bool resolve(lua_State *lua,
const int &index,
void *out)
256 const int type = lua_type(lua, index);
258 if (type != LUA_TUSERDATA)
261 out = lua_touserdata(lua, index);
269 static INLINE
bool resolve(lua_State *lua,
const int &index,
int *out)
271 const int type = lua_type(lua, index);
273 if (type != LUA_TNUMBER)
276 *out = lua_tointeger(lua, index);
293 void set(
const char *key,
const int &value)
295 static std::hash<const char *> hasher;
297 const size_t hash = hasher(key);
299 mIntegers[hash] = value;
300 mContents[hash] = &(mIntegers[hash]);
304 void set(
const char *key,
const float &value)
306 static std::hash<const char *> hasher;
308 const size_t hash = hasher(key);
310 mFloats[hash] = value;
311 mContents[hash] = &(mFloats[hash]);
315 void set(
const char *key,
const char *value)
317 static std::hash<const char *> hasher;
319 const size_t hash = hasher(key);
321 mStrings[hash] = value;
322 mContents[hash] = &(mStrings[hash]);
339 std::unordered_map<size_t, float> mFloats;
340 std::unordered_map<size_t, int> mIntegers;
341 std::unordered_map<size_t, std::string> mStrings;
343 std::unordered_map<size_t, void *> mContents;
346 std::unordered_map<size_t, std::pair<const char *, unsigned char>> mTypes;
354 mFloats = other.mFloats;
355 mStrings = other.mStrings;
356 mIntegers = other.mIntegers;
357 mContents = other.mContents;
358 mTypes = other.mTypes;
362 template <
typename outType>
363 void get(
const char *key, outType &out)
365 static std::hash<const char *> hasher;
367 const size_t hash = hasher(key);
369 if (mTypes.count(hash) == 0)
370 throw std::runtime_error(
"No such key!");
372 throw std::runtime_error(
"Mismatched types!");
374 out = *((outType*)(mContents[hash]));
377 void push(lua_State *lua)
379 lua_createtable(lua, 0, 0);
381 for (std::unordered_map<
size_t, std::pair<const char *, unsigned char>>::iterator it = mTypes.begin(); it != mTypes.end(); it++)
383 const size_t hash = (*it).first;
384 std::pair<const char *, unsigned char> current = (*it).second;
386 lua_pushstring(lua, current.first);
388 switch (current.second)
392 lua_pushnumber(lua, mFloats[hash]);
398 lua_pushstring(lua, mStrings[hash].c_str());
404 lua_pushinteger(lua, mIntegers[hash]);
410 reinterpret_cast<Table *
>(&mTables[hash])->push(lua);
415 lua_settable(lua, -3);
419 void setTable(
const char *key,
const ParentTable &value)
421 static std::hash<const char *> hasher;
423 const size_t hash = hasher(key);
425 mTables[hash] = value;
430 std::unordered_map<size_t, ParentTable> mTables;
435 void Table::get(
const char *key,
Table &out)
437 static std::hash<const char *> hasher;
439 const size_t hash = hasher(key);
441 if (mTypes.count(hash) == 0)
442 throw std::runtime_error(
"No such key!");
444 out.copy(mTables[hash]);
471 template <
typename... parameters>
472 static INLINE
void pushParameters(lua_State *lua,
const int &in, parameters... params)
474 lua_pushinteger(lua, in);
485 template <
typename... parameters>
486 static INLINE
void pushParameters(lua_State *lua,
const float &in, parameters... params)
488 lua_pushnumber(lua, in);
499 template <
typename... parameters>
500 static INLINE
void pushParameters(lua_State *lua,
const char *in, parameters... params)
502 lua_pushstring(lua, in);
513 template <
typename... parameters>
514 static INLINE
void pushParameters(lua_State *lua,
const bool &in, parameters... params)
516 lua_pushboolean(lua, in);
527 template <
bool createTable =
true,
typename... parameters>
528 static INLINE
void pushTable(lua_State *lua,
const char *key,
const int &value, parameters... params)
532 lua_pushstring(lua, key);
533 lua_pushinteger(lua, value);
534 lua_settable(lua, -3);
536 EasyLua::Utilities::pushTable<false>(lua, params...);
546 template <
bool createTable =
true,
typename... parameters>
547 static INLINE
void pushTable(lua_State *lua,
const char *key,
const float &value, parameters... params)
551 lua_pushstring(lua, key);
552 lua_pushnumber(lua, value);
553 lua_settable(lua, -3);
555 EasyLua::Utilities::pushTable<false>(lua, params...);
566 template <
bool createTable =
true,
typename... parameters>
567 static INLINE
void pushTable(lua_State *lua,
const char *key,
const double &value, parameters... params)
571 lua_pushstring(lua, key);
572 lua_pushnumber(lua, value);
573 lua_settable(lua, -3);
575 EasyLua::Utilities::pushTable<false>(lua, params...);
585 template <
bool createTable =
true,
typename... parameters>
586 static INLINE
void *
pushTable(lua_State *lua,
const char *key,
const bool &value, parameters... params)
590 lua_pushstring(lua, key);
591 lua_pushboolean(lua, value);
592 lua_settable(lua, -3);
594 EasyLua::Utilities::pushTable<false>(lua, params...);
604 template <
bool createTable =
true,
typename... parameters>
605 static INLINE
void pushTable(lua_State *lua,
const char *key,
const char *value, parameters... params)
609 lua_pushstring(lua, key);
610 lua_pushstring(lua, value);
611 lua_settable(lua, -3);
613 EasyLua::Utilities::pushTable<false>(lua, params...);
624 template <
typename... parameters>
627 EasyLua::Utilities::pushTable<false>(lua, params...);
635 template <
typename... parameters>
636 static INLINE
void *
Table(lua_State *lua, parameters... params)
638 const size_t currentTop = lua_gettop(lua);
640 EasyLua::Utilities::pushTable<true>(lua, params...);
649 template <
bool createTable =
true,
unsigned int index = 1,
typename... parameters>
650 static INLINE
void pushArray(lua_State *lua,
const int &value, parameters... params)
654 lua_pushinteger(lua, index);
655 lua_pushinteger(lua, value);
656 lua_settable(lua, -3);
658 EasyLua::Utilities::pushArray<false, index + 1>(lua, params...);
661 template <
bool createTable =
true,
unsigned int index = 1,
typename... parameters>
662 static INLINE
void pushArray(lua_State *lua,
const char *key,
const float &value, parameters... params)
666 lua_pushinteger(lua, index);
667 lua_pushnumber(lua, value);
668 lua_settable(lua, -3);
670 EasyLua::Utilities::pushArray<false, index + 1>(lua, params...);
673 template <
bool createTable =
true,
unsigned int index = 1,
typename... parameters>
674 static INLINE
void pushArray(lua_State *lua,
const char *key,
const double &value, parameters... params)
678 lua_pushinteger(lua, index);
679 lua_pushnumber(lua, value);
680 lua_settable(lua, -3);
682 EasyLua::Utilities::pushArray<false, index + 1>(lua, params...);
685 template <
bool createTable =
true,
unsigned int index = 1,
typename... parameters>
686 static INLINE
void pushArray(lua_State *lua,
const char *key,
const bool &value, parameters... params)
690 lua_pushinteger(lua, index);
691 lua_pushboolean(lua, value);
692 lua_settable(lua, -3);
694 EasyLua::Utilities::pushArray<false, index + 1>(lua, params...);
697 template <
bool createTable =
true,
unsigned int index = 1,
typename... parameters>
698 static INLINE
void pushArray(lua_State *lua,
const char *key,
const char *value, parameters... params)
702 lua_pushinteger(lua, index);
703 lua_pushstring(lua, value);
704 lua_settable(lua, -3);
706 EasyLua::Utilities::pushArray<false, index + 1>(lua, params...);
709 template <
bool createTable = true,
unsigned int index = 1>
710 static INLINE
void pushArray(lua_State *lua) { }
712 template <
bool typeException,
int index = 1,
typename... parameters>
713 static INLINE
int readStack(lua_State *lua,
float *out, parameters... params)
718 *out = luaL_checknumber(lua, index);
719 return EasyLua::Utilities::readStack<typeException, index + 1>(lua, params...);
722 template <
bool typeException,
int index = 1,
typename... parameters>
723 static INLINE
int readStack(lua_State *lua,
bool *out, parameters... params)
727 *out = luaL_checkinteger(lua, index);
728 return EasyLua::Utilities::readStack<typeException, index + 1>(lua, params...);
731 template <
bool typeException,
int index = 1,
typename... parameters>
732 static INLINE
int readStack(lua_State *lua,
int *out, parameters... params)
737 return EasyLua::Utilities::readStack<typeException, index + 1>(lua, params...);
740 template <
bool typeException,
int index = 1,
typename... parameters>
741 static INLINE
int readStack(lua_State *lua,
char *out,
const int &outLength, parameters... params)
747 const char *target = luaL_checkstring(lua, index);
750 unsigned int targetLength = strlen(target);
751 targetLength = outLength > targetLength ? targetLength : targetLength - outLength;
752 memcpy(out, target, targetLength);
754 return EasyLua::Utilities::readStack<typeException, index + 1>(lua, params...);
757 template <
bool typeException,
int index = 1,
typename... parameters>
758 static INLINE
int readStack(lua_State *lua, std::string *out, parameters... params)
760 char *outTest = 0x00;
765 out->assign(luaL_checkstring(lua, index));
767 return EasyLua::Utilities::readStack<typeException, index + 1>(lua, params...);
770 template <
bool typeException,
int index = 1,
typename... parameters>
771 static INLINE
int readStack(lua_State *lua,
void *out, parameters... params)
775 out = lua_touserdata(lua, index);
776 return EasyLua::Utilities::readStack<typeException, index + 1>(lua, params...);
779 static void printStack(lua_State *lua)
781 std::cout <<
"Lua Stack Dump ------ " << std::endl;
783 for (
int iteration = 0; iteration < lua_gettop(lua) + 1; iteration++)
785 const int currentType = lua_type(lua, iteration);
786 std::cout << iteration <<
": ";
792 std::cout <<
"NUMBER (" << LUA_TNUMBER <<
") = " << luaL_checknumber(lua, iteration);
798 std::cout <<
"STRING (" << LUA_TSTRING <<
") = '" << luaL_checkstring(lua, iteration) <<
"'";
804 std::cout <<
"FUNCTION (" << LUA_TFUNCTION <<
") ";
810 std::cout <<
"TABLE (" << LUA_TTABLE <<
") ";
816 std::cout <<
"UNKNOWN TYPE (" << currentType <<
") ";
820 std::cout << std::endl;
832 template <
typename... parameters>
833 static INLINE
void pushParameters(lua_State *lua,
const void *value, parameters... params)
836 lua_pushvalue(lua, 1);
864 template <
bool createTable = true>
865 static INLINE
void pushTable(lua_State *lua) { }
867 template <
bool createTable =
true,
typename... parameters>
868 static INLINE
void pushTable(lua_State *lua,
const char *key,
const void *value, parameters... params)
871 EasyLua::Utilities::pushTable<false>(lua, params...);
876 lua_pushstring(lua, key);
878 lua_settable(lua, -3);
881 template <
bool typeException,
int index = -1>
882 static INLINE
int readStack(lua_State *lua) {
return -1; }
891 template <
typename... parameters>
892 static INLINE
unsigned int call(lua_State *lua,
const char *methodName, parameters... params)
894 const int stackTop = lua_gettop(lua);
898 lua_getglobal(lua, methodName);
901 lua_call(lua,
sizeof...(params), LUA_MULTRET);
903 return lua_gettop(lua) - stackTop;
906 static INLINE
unsigned int call(lua_State *lua,
const char *methodName,
const EasyLua::ParameterCount ¶meterCount)
908 const int stackTop = lua_gettop(lua);
910 lua_getglobal(lua, methodName);
912 lua_call(lua, parameterCount, LUA_MULTRET);
914 return lua_gettop(lua) - stackTop;
917 template <
typename... parameters>
918 static INLINE std::pair<int, size_t> pcall(lua_State *lua,
const char *methodName, parameters... params)
920 const int stackTop = lua_gettop(lua);
922 lua_getglobal(lua, methodName);
925 return std::make_pair(lua_pcall(lua,
sizeof...(params), LUA_MULTRET, 0), lua_gettop(lua) - stackTop);
928 static INLINE std::pair<int, size_t> pcall(lua_State *lua,
const char *methodName,
const EasyLua::ParameterCount ¶meterCount)
930 const int stackTop = lua_gettop(lua);
932 lua_getglobal(lua, methodName);
933 return std::make_pair(lua_pcall(lua, parameterCount, LUA_MULTRET, 0), lua_gettop(lua) - stackTop);
936 static INLINE std::pair<int, size_t> pcall(lua_State *lua,
const char *methodName,
const char *errorHandler,
const EasyLua::ParameterCount ¶meterCount)
938 const int stackTop = lua_gettop(lua);
940 lua_getglobal(lua, errorHandler);
941 lua_getglobal(lua, methodName);
943 return std::make_pair(lua_pcall(lua, parameterCount, LUA_MULTRET, -2), lua_gettop(lua) - stackTop);
946 template <
typename... parameters>
947 static INLINE std::pair<int, size_t> pcall(lua_State *lua,
const char *methodName,
const char *errorHandler, parameters... params)
949 const int stackTop = lua_gettop(lua);
951 lua_getglobal(lua, errorHandler);
952 lua_getglobal(lua, methodName);
955 return std::make_pair(lua_pcall(lua,
sizeof...(params), LUA_MULTRET,
sizeof...(params) - 2), lua_gettop(lua) - stackTop);
This "namespace" contains a bulk of the EasyLua API that the end programmer should be concerned with...
Definition: easylua.hpp:459
static INLINE void pushTableComponents(lua_State *lua, parameters...params)
A helper method that can be used to push more components to the current table.
Definition: easylua.hpp:625
static INLINE void pushTable(lua_State *lua, const char *key, const int &value, parameters...params)
This is one among a family of methods that push a table containing arbitrary values to the Lua stack...
Definition: easylua.hpp:528
Definition: easylua.hpp:136
Definition: easylua.hpp:349
static INLINE void pushParameters(lua_State *lua, const bool &in, parameters...params)
This is one among a family of methods that push arbitrary values to the Lua stack.
Definition: easylua.hpp:514
static INLINE void pushParameters(lua_State *lua, const float &in, parameters...params)
This is one among a family of methods that push arbitrary values to the Lua stack.
Definition: easylua.hpp:486
static INLINE void pushParameters(lua_State *lua, const void *value, parameters...params)
This is one among a family of methods that push arbitrary values to the Lua stack.
Definition: easylua.hpp:833
static INLINE void * pushTable(lua_State *lua, const char *key, const bool &value, parameters...params)
This is one among a family of methods that push a table containing arbitrary values to the Lua stack...
Definition: easylua.hpp:586
The TypeIDResolver template struct is used to resolve EasyLua types to their internal EasyLua type id...
Definition: easylua.hpp:62
A class that represents Lua table objects. This can be used to read table returns from the Lua runtim...
Definition: easylua.hpp:290
String types.
Definition: easylua.hpp:41
Anything that is an integer.
Definition: easylua.hpp:39
Definition: easylua.hpp:126
static INLINE void pushParameters(lua_State *lua, const int &in, parameters...params)
This is one among a family of methods that push arbitrary values to the Lua stack.
Definition: easylua.hpp:472
Table types.
Definition: easylua.hpp:43
EASYLUA_TYPE
Enumeration representing the supported types in the EasyLua library.
Definition: easylua.hpp:36
This namespace contains all of the EasyLua API which is to prevent accidental naming conflicts...
Definition: easylua.hpp:29
Float types.
Definition: easylua.hpp:45
static INLINE void pushTable(lua_State *lua, const char *key, const char *value, parameters...params)
This is one among a family of methods that push a table containing arbitrary values to the Lua stack...
Definition: easylua.hpp:605
static INLINE void pushParameters(lua_State *lua, const char *in, parameters...params)
This is one among a family of methods that push arbitrary values to the Lua stack.
Definition: easylua.hpp:500
static INLINE void pushTable(lua_State *lua, const char *key, const float &value, parameters...params)
This is one among a family of methods that push a table containing arbitrary values to the Lua stack...
Definition: easylua.hpp:547
static INLINE void pushTable(lua_State *lua, const char *key, const double &value, parameters...params)
This is one among a family of methods that push a table containing arbitrary values to the Lua stack...
Definition: easylua.hpp:567