1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
#ifndef LUAUTIL_H
#define LUAUTIL_H
#pragma once
#include "LuaHeaders.h"
#include "LuaException.h"
#include "LuaConvert.h"
#include "LuaReference.h"
#include "scripting/ade.h"
#include <cstdlib>
namespace luacpp {
/**
* @brief Contains functions to convert C++ values to and from lua values.
*
* Currently the following types are supported:
* - `double`
* - `float`
* - `int`
* - `std::string`
* - `const char*` (only for pushing as using the pointer after it was removed from the stack is dangerous)
* - `bool`
* - `lua_CFunction`
* - `LuaTable` (only pop, use LuaValue version for pushing)
* - `LuaFunction` (only pop, use LuaValue version for pushing)
* - `LuaValue` (this will reference any value at the specified poition)
*/
namespace convert {
namespace internal {
bool isValidIndex(lua_State* state, int index);
bool ade_odata_helper(lua_State* L, int stackposition, size_t idx);
}
bool ade_odata_is_userdata_type(lua_State* L, int stackposition, size_t typeIdx, bool cleanup = true);
template<typename T>
bool ade_odata_is_userdata_type(lua_State* L, int stackposition, const T& obj_type) {
return ade_odata_is_userdata_type(L, stackposition, obj_type.GetIdx());
}
void pushValue(lua_State* luaState, const double& value);
void pushValue(lua_State* luaState, const float& value);
void pushValue(lua_State* luaState, const int& value);
void pushValue(lua_State* luaState, const size_t& value);
void pushValue(lua_State* luaState, const std::string& value);
void pushValue(lua_State* luaState, const char* value);
void pushValue(lua_State* luaState, const bool& value);
void pushValue(lua_State* luaState, const lua_CFunction& value);
template<typename T>
void pushValue(lua_State* L, scripting::ade_odata_setter<T>&& value) {
using namespace scripting;
//WMC - char must be 1 byte, foo.
static_assert(sizeof(char) == 1, "char must be 1 byte!");
//WMC - step by step
//Create new LUA object and get handle
auto newod = (char*)lua_newuserdata(L, sizeof(T));
//Create or get object metatable
luaL_getmetatable(L, ::scripting::internal::getTableEntry(value.idx).Name);
//Set the metatable for the object
lua_setmetatable(L, -2);
//Copy the actual object data to the Lua object
new(newod) T(std::move(value.value));
}
/**
* @brief Convenience function for string literals
*
* @param luaState The lua_State to push the values to
* @param value The value which should be pushed.
* @return void
*/
template<size_t N>
inline void pushValue(lua_State* luaState, const char(& value)[N]) {
pushValue(luaState, (const char*)value);
}
bool popValue(lua_State* luaState, float& target, int stackposition = -1, bool remove = true);
bool popValue(lua_State* luaState, double& target, int stackposition = -1, bool remove = true);
bool popValue(lua_State* luaState, int& target, int stackposition = -1, bool remove = true);
bool popValue(lua_State* luaState, size_t& target, int stackposition = -1, bool remove = true);
bool popValue(lua_State* luaState, std::string& target, int stackposition = -1, bool remove = true);
bool popValue(lua_State* luaState, bool& target, int stackposition = -1, bool remove = true);
bool popValue(lua_State* luaState, lua_CFunction& target, int stackposition = -1, bool remove = true);
template <typename T>
bool popValue(lua_State* L, scripting::ade_odata_getter<T>&& od, int stackposition = -1, bool remove = true)
{
// Use the helper to reduce the amount of code here
if (!internal::ade_odata_helper(L, stackposition, od.idx)) {
return false;
}
auto lua_ptr = lua_touserdata(L, stackposition);
// Copy the value over by using the standard copy constructor
*od.value_ptr = *reinterpret_cast<T*>(lua_ptr);
if (remove) {
lua_remove(L, stackposition);
}
return true;
}
template <typename T>
bool popValue(lua_State* L, scripting::ade_odata_ptr_getter<T>&& od, int stackposition = -1, bool remove = true)
{
// Use the helper to reduce the amount of code here
if (!internal::ade_odata_helper(L, stackposition, od.idx)) {
return false;
}
auto lua_ptr = lua_touserdata(L, stackposition);
// Only write the pointer value to the output pointer
*od.value_ptr = reinterpret_cast<T*>(lua_ptr);
if (remove) {
lua_remove(L, stackposition);
}
return true;
}
}
}
#endif
|