Merge pull request #251 from MihailRis/lua-bytearray
add lua user types + bytearray
This commit is contained in:
@@ -68,19 +68,19 @@ local function floatOrDoubleToBytes(val, opt)
|
|||||||
if opt == 'd' then
|
if opt == 'd' then
|
||||||
val = mantissa
|
val = mantissa
|
||||||
for i = 1, 6 do
|
for i = 1, 6 do
|
||||||
table.insert(bytes, math.floor(val) % (2 ^ 8))
|
bytes[#bytes + 1] = math.floor(val) % (2 ^ 8)
|
||||||
val = math.floor(val / (2 ^ 8))
|
val = math.floor(val / (2 ^ 8))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
table.insert(bytes, math.floor(mantissa) % (2 ^ 8))
|
bytes[#bytes + 1] = math.floor(mantissa) % (2 ^ 8)
|
||||||
val = math.floor(mantissa / (2 ^ 8))
|
val = math.floor(mantissa / (2 ^ 8))
|
||||||
table.insert(bytes, math.floor(val) % (2 ^ 8))
|
bytes[#bytes + 1] = math.floor(val) % (2 ^ 8)
|
||||||
val = math.floor(val / (2 ^ 8))
|
val = math.floor(val / (2 ^ 8))
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(bytes, math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8))
|
bytes[#bytes + 1] = math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8)
|
||||||
val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8))
|
val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8))
|
||||||
table.insert(bytes, math.floor(sign * 128 + val) % (2 ^ 8))
|
bytes[#bytes + 1] = math.floor(sign * 128 + val) % (2 ^ 8)
|
||||||
val = math.floor((sign * 128 + val) / (2 ^ 8))
|
val = math.floor((sign * 128 + val) / (2 ^ 8))
|
||||||
|
|
||||||
if not endianness then
|
if not endianness then
|
||||||
|
|||||||
@@ -78,6 +78,21 @@ std::unique_ptr<ubyte[]> files::read_bytes(const fs::path& filename, size_t& len
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ubyte> files::read_bytes(const fs::path& filename) {
|
||||||
|
std::ifstream input(filename, std::ios::binary);
|
||||||
|
if (!input.is_open())
|
||||||
|
return {};
|
||||||
|
input.seekg(0, std::ios_base::end);
|
||||||
|
size_t length = input.tellg();
|
||||||
|
input.seekg(0, std::ios_base::beg);
|
||||||
|
|
||||||
|
std::vector<ubyte> data(length);
|
||||||
|
data.resize(length);
|
||||||
|
input.read((char*)data.data(), length);
|
||||||
|
input.close();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
std::string files::read_string(const fs::path& filename) {
|
std::string files::read_string(const fs::path& filename) {
|
||||||
size_t size;
|
size_t size;
|
||||||
std::unique_ptr<ubyte[]> bytes (read_bytes(filename, size));
|
std::unique_ptr<ubyte[]> bytes (read_bytes(filename, size));
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ namespace files {
|
|||||||
|
|
||||||
bool read(const fs::path&, char* data, size_t size);
|
bool read(const fs::path&, char* data, size_t size);
|
||||||
std::unique_ptr<ubyte[]> read_bytes(const fs::path&, size_t& length);
|
std::unique_ptr<ubyte[]> read_bytes(const fs::path&, size_t& length);
|
||||||
|
std::vector<ubyte> read_bytes(const fs::path&);
|
||||||
std::string read_string(const fs::path& filename);
|
std::string read_string(const fs::path& filename);
|
||||||
|
|
||||||
/// @brief Read JSON or BJSON file
|
/// @brief Read JSON or BJSON file
|
||||||
|
|||||||
@@ -109,18 +109,8 @@ static int l_file_mkdirs(lua::State* L) {
|
|||||||
static int l_file_read_bytes(lua::State* L) {
|
static int l_file_read_bytes(lua::State* L) {
|
||||||
fs::path path = resolve_path(lua::require_string(L, 1));
|
fs::path path = resolve_path(lua::require_string(L, 1));
|
||||||
if (fs::is_regular_file(path)) {
|
if (fs::is_regular_file(path)) {
|
||||||
size_t length = static_cast<size_t>(fs::file_size(path));
|
auto bytes = files::read_bytes(path);
|
||||||
|
return lua::newuserdata<lua::Bytearray>(L, std::move(bytes));
|
||||||
auto bytes = files::read_bytes(path, length);
|
|
||||||
|
|
||||||
lua::createtable(L, length, 0);
|
|
||||||
int newTable = lua::gettop(L);
|
|
||||||
|
|
||||||
for(size_t i = 0; i < length; i++) {
|
|
||||||
lua::pushinteger(L, bytes[i]);
|
|
||||||
lua::rawseti(L, i+1, newTable);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
throw std::runtime_error("file does not exists "+util::quote(path.u8string()));
|
throw std::runtime_error("file does not exists "+util::quote(path.u8string()));
|
||||||
}
|
}
|
||||||
@@ -151,10 +141,13 @@ static int l_file_write_bytes(lua::State* L) {
|
|||||||
|
|
||||||
fs::path path = resolve_path(lua::require_string(L, pathIndex));
|
fs::path path = resolve_path(lua::require_string(L, pathIndex));
|
||||||
|
|
||||||
|
if (auto bytearray = lua::touserdata<lua::Bytearray>(L, -1)) {
|
||||||
|
auto& bytes = bytearray->data();
|
||||||
|
return lua::pushboolean(L, files::write_bytes(path, bytes.data(), bytes.size()));
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<ubyte> bytes;
|
std::vector<ubyte> bytes;
|
||||||
|
|
||||||
int result = read_bytes_from_table(L, -1, bytes);
|
int result = read_bytes_from_table(L, -1, bytes);
|
||||||
|
|
||||||
if(result != 1) {
|
if(result != 1) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
#include "lua_custom_types.hpp"
|
||||||
|
|
||||||
|
#include "lua_util.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace lua;
|
||||||
|
|
||||||
|
|
||||||
|
Bytearray::Bytearray(size_t capacity)
|
||||||
|
: buffer(capacity) {
|
||||||
|
buffer.resize(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bytearray::Bytearray(std::vector<ubyte> buffer) : buffer(std::move(buffer)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Bytearray::~Bytearray() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_bytearray_append(lua::State* L) {
|
||||||
|
if (auto buffer = touserdata<Bytearray>(L, 1)) {
|
||||||
|
auto value = tointeger(L, 2);
|
||||||
|
buffer->data().push_back(static_cast<ubyte>(value));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_bytearray_insert(lua::State* L) {
|
||||||
|
auto buffer = touserdata<Bytearray>(L, 1);
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto& data = buffer->data();
|
||||||
|
auto index = tointeger(L, 2)-1;
|
||||||
|
if (static_cast<size_t>(index) > data.size()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto value = tointeger(L, 3);
|
||||||
|
data.insert(data.begin() + index, static_cast<ubyte>(value));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_bytearray_remove(lua::State* L) {
|
||||||
|
auto buffer = touserdata<Bytearray>(L, 1);
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto& data = buffer->data();
|
||||||
|
auto index = tointeger(L, 2)-1;
|
||||||
|
if (static_cast<size_t>(index) > data.size()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
data.erase(data.begin()+index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unordered_map<std::string, lua_CFunction> bytearray_methods {
|
||||||
|
{"append", lua::wrap<l_bytearray_append>},
|
||||||
|
{"insert", lua::wrap<l_bytearray_insert>},
|
||||||
|
{"remove", lua::wrap<l_bytearray_remove>},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int l_bytearray_meta_meta_call(lua::State* L) {
|
||||||
|
if (lua_istable(L, 2)) {
|
||||||
|
size_t len = objlen(L, 2);
|
||||||
|
std::vector<ubyte> buffer(len);
|
||||||
|
buffer.resize(len);
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
rawgeti(L, i+1);
|
||||||
|
buffer[i] = static_cast<ubyte>(tointeger(L, -1));
|
||||||
|
pop(L);
|
||||||
|
}
|
||||||
|
return newuserdata<Bytearray>(L, std::move(buffer));
|
||||||
|
}
|
||||||
|
auto size = tointeger(L, 2);
|
||||||
|
if (size < 0) {
|
||||||
|
throw std::runtime_error("size can not be less than 0");
|
||||||
|
}
|
||||||
|
return newuserdata<Bytearray>(L, static_cast<size_t>(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_bytearray_meta_index(lua::State* L) {
|
||||||
|
auto buffer = touserdata<Bytearray>(L, 1);
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto& data = buffer->data();
|
||||||
|
if (isstring(L, 2)) {
|
||||||
|
auto found = bytearray_methods.find(tostring(L, 2));
|
||||||
|
if (found != bytearray_methods.end()) {
|
||||||
|
return pushcfunction(L, found->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto index = tointeger(L, 2)-1;
|
||||||
|
if (static_cast<size_t>(index) > data.size()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return pushinteger(L, data[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_bytearray_meta_newindex(lua::State* L) {
|
||||||
|
auto buffer = touserdata<Bytearray>(L, 1);
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto& data = buffer->data();
|
||||||
|
auto index = static_cast<size_t>(tointeger(L, 2)-1);
|
||||||
|
auto value = tointeger(L, 3);
|
||||||
|
if (index >= data.size()) {
|
||||||
|
if (index == data.size()) {
|
||||||
|
data.push_back(static_cast<ubyte>(value));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
data[index] = static_cast<ubyte>(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_bytearray_meta_len(lua::State* L) {
|
||||||
|
if (auto buffer = touserdata<Bytearray>(L, 1)) {
|
||||||
|
return pushinteger(L, buffer->data().size());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_bytearray_meta_tostring(lua::State* L) {
|
||||||
|
auto buffer = touserdata<Bytearray>(L, 1);
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto& data = buffer->data();
|
||||||
|
if (data.size() > 512) {
|
||||||
|
return pushstring(L, "bytearray["+std::to_string(data.size())+"]{...}");
|
||||||
|
} else {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "bytearray[" << std::to_string(data.size()) << "]{";
|
||||||
|
for (size_t i = 0; i < data.size(); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
ss << " ";
|
||||||
|
}
|
||||||
|
ss << static_cast<uint>(data[i]);
|
||||||
|
}
|
||||||
|
ss << "}";
|
||||||
|
return pushstring(L, ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_bytearray_meta_add(lua::State* L) {
|
||||||
|
auto bufferA = touserdata<Bytearray>(L, 1);
|
||||||
|
auto bufferB = touserdata<Bytearray>(L, 2);
|
||||||
|
if (bufferA == nullptr || bufferB == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto& dataA = bufferA->data();
|
||||||
|
auto& dataB = bufferB->data();
|
||||||
|
|
||||||
|
std::vector<ubyte> ab;
|
||||||
|
ab.reserve(dataA.size() + dataB.size());
|
||||||
|
ab.insert(ab.end(), dataA.begin(), dataA.end());
|
||||||
|
ab.insert(ab.end(), dataB.begin(), dataB.end());
|
||||||
|
return newuserdata<Bytearray>(L, std::move(ab));
|
||||||
|
}
|
||||||
|
|
||||||
|
int Bytearray::createMetatable(lua::State* L) {
|
||||||
|
createtable(L, 0, 6);
|
||||||
|
pushcfunction(L, lua::wrap<l_bytearray_meta_index>);
|
||||||
|
setfield(L, "__index");
|
||||||
|
pushcfunction(L, lua::wrap<l_bytearray_meta_newindex>);
|
||||||
|
setfield(L, "__newindex");
|
||||||
|
pushcfunction(L, lua::wrap<l_bytearray_meta_len>);
|
||||||
|
setfield(L, "__len");
|
||||||
|
pushcfunction(L, lua::wrap<l_bytearray_meta_tostring>);
|
||||||
|
setfield(L, "__tostring");
|
||||||
|
pushcfunction(L, lua::wrap<l_bytearray_meta_add>);
|
||||||
|
setfield(L, "__add");
|
||||||
|
|
||||||
|
createtable(L, 0, 1);
|
||||||
|
pushcfunction(L, lua::wrap<l_bytearray_meta_meta_call>);
|
||||||
|
setfield(L, "__call");
|
||||||
|
setmetatable(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef LOGIC_SCRIPTING_LUA_LUA_CUSTOM_TYPES_HPP_
|
||||||
|
#define LOGIC_SCRIPTING_LUA_LUA_CUSTOM_TYPES_HPP_
|
||||||
|
|
||||||
|
#include "lua_commons.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace lua {
|
||||||
|
class Userdata {
|
||||||
|
public:
|
||||||
|
virtual ~Userdata() {};
|
||||||
|
virtual const std::string& getTypeName() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Bytearray : public Userdata {
|
||||||
|
std::vector<ubyte> buffer;
|
||||||
|
public:
|
||||||
|
Bytearray(size_t capacity);
|
||||||
|
Bytearray(std::vector<ubyte> buffer);
|
||||||
|
virtual ~Bytearray();
|
||||||
|
|
||||||
|
const std::string& getTypeName() const override {
|
||||||
|
return TYPENAME;
|
||||||
|
}
|
||||||
|
inline std::vector<ubyte>& data() {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int createMetatable(lua::State*);
|
||||||
|
inline static std::string TYPENAME = "bytearray";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LOGIC_SCRIPTING_LUA_LUA_CUSTOM_TYPES_HPP_
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "lua_engine.hpp"
|
#include "lua_engine.hpp"
|
||||||
|
|
||||||
#include "api_lua.hpp"
|
#include "api_lua.hpp"
|
||||||
|
#include "lua_custom_types.hpp"
|
||||||
#include "../../../debug/Logger.hpp"
|
#include "../../../debug/Logger.hpp"
|
||||||
#include "../../../util/stringutil.hpp"
|
#include "../../../util/stringutil.hpp"
|
||||||
|
|
||||||
@@ -45,7 +46,6 @@ static void create_libs(lua::State* L) {
|
|||||||
addfunc(L, "print", lua::wrap<l_print>);
|
addfunc(L, "print", lua::wrap<l_print>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
void lua::initialize() {
|
void lua::initialize() {
|
||||||
logger.info() << LUA_VERSION;
|
logger.info() << LUA_VERSION;
|
||||||
logger.info() << LUAJIT_VERSION;
|
logger.info() << LUAJIT_VERSION;
|
||||||
@@ -81,6 +81,8 @@ void lua::initialize() {
|
|||||||
|
|
||||||
createtable(L, 0, 0);
|
createtable(L, 0, 0);
|
||||||
setglobal(L, LAMBDAS_TABLE);
|
setglobal(L, LAMBDAS_TABLE);
|
||||||
|
|
||||||
|
newusertype<Bytearray, Bytearray::createMetatable>(L, "bytearray");
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua::finalize() {
|
void lua::finalize() {
|
||||||
|
|||||||
@@ -9,6 +9,15 @@ using namespace lua;
|
|||||||
|
|
||||||
static int nextEnvironment = 1;
|
static int nextEnvironment = 1;
|
||||||
|
|
||||||
|
std::unordered_map<std::type_index, std::string> lua::usertypeNames;
|
||||||
|
|
||||||
|
int lua::userdata_destructor(lua::State* L) {
|
||||||
|
if (auto obj = touserdata<Userdata>(L, 1)) {
|
||||||
|
obj->~Userdata();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::string lua::env_name(int env) {
|
std::string lua::env_name(int env) {
|
||||||
return "_ENV"+util::mangleid(env);
|
return "_ENV"+util::mangleid(env);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,16 @@
|
|||||||
#define LOGIC_SCRIPTING_LUA_UTIL_HPP_
|
#define LOGIC_SCRIPTING_LUA_UTIL_HPP_
|
||||||
|
|
||||||
#include "lua_commons.hpp"
|
#include "lua_commons.hpp"
|
||||||
|
#include "lua_custom_types.hpp"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
namespace lua {
|
namespace lua {
|
||||||
inline std::string LAMBDAS_TABLE = "$L";
|
inline std::string LAMBDAS_TABLE = "$L";
|
||||||
|
extern std::unordered_map<std::type_index, std::string> usertypeNames;
|
||||||
|
int userdata_destructor(lua::State* L);
|
||||||
|
|
||||||
std::string env_name(int env);
|
std::string env_name(int env);
|
||||||
|
|
||||||
@@ -42,6 +49,10 @@ namespace lua {
|
|||||||
inline const char* type_name(lua::State* L, int idx) {
|
inline const char* type_name(lua::State* L, int idx) {
|
||||||
return lua_typename(L, idx);
|
return lua_typename(L, idx);
|
||||||
}
|
}
|
||||||
|
inline int rawget(lua::State* L, int idx=-2) {
|
||||||
|
lua_rawget(L, idx);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
inline int rawgeti(lua::State* L, int n, int idx=-1) {
|
inline int rawgeti(lua::State* L, int n, int idx=-1) {
|
||||||
lua_rawgeti(L, idx, n);
|
lua_rawgeti(L, idx, n);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -230,6 +241,12 @@ namespace lua {
|
|||||||
inline bool isfunction(lua::State* L, int idx) {
|
inline bool isfunction(lua::State* L, int idx) {
|
||||||
return lua_isfunction(L, idx);
|
return lua_isfunction(L, idx);
|
||||||
}
|
}
|
||||||
|
inline bool isuserdata(lua::State* L, int idx) {
|
||||||
|
return lua_isuserdata(L, idx);
|
||||||
|
}
|
||||||
|
inline void setfield(lua::State* L, const std::string& name, int idx=-2) {
|
||||||
|
lua_setfield(L, idx, name.c_str());
|
||||||
|
}
|
||||||
inline bool toboolean(lua::State* L, int idx) {
|
inline bool toboolean(lua::State* L, int idx) {
|
||||||
return lua_toboolean(L, idx);
|
return lua_toboolean(L, idx);
|
||||||
}
|
}
|
||||||
@@ -245,7 +262,42 @@ namespace lua {
|
|||||||
inline const void* topointer(lua::State* L, int idx) {
|
inline const void* topointer(lua::State* L, int idx) {
|
||||||
return lua_topointer(L, idx);
|
return lua_topointer(L, idx);
|
||||||
}
|
}
|
||||||
inline glm::vec2 tovec2(lua::State* L, int idx) {
|
inline void setglobal(lua::State* L, const std::string& name) {
|
||||||
|
lua_setglobal(L, name.c_str());
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
inline T* touserdata(lua::State* L, int idx) {
|
||||||
|
if (void* rawptr = lua_touserdata(L, idx)) {
|
||||||
|
return static_cast<T*>(rawptr);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
template<class T, typename... Args>
|
||||||
|
inline int newuserdata(lua::State* L, Args&&... args) {
|
||||||
|
const auto& found = usertypeNames.find(typeid(T));
|
||||||
|
void* ptr = lua_newuserdata(L, sizeof(T));
|
||||||
|
new (ptr) T(args...);
|
||||||
|
|
||||||
|
if (found == usertypeNames.end()) {
|
||||||
|
log_error("usertype is not registred: "+std::string(typeid(T).name()));
|
||||||
|
} else if (getglobal(L, found->second)) {
|
||||||
|
setmetatable(L);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, lua_CFunction func>
|
||||||
|
inline void newusertype(lua::State* L, const std::string& name) {
|
||||||
|
usertypeNames[typeid(T)] = name;
|
||||||
|
func(L);
|
||||||
|
|
||||||
|
pushcfunction(L, userdata_destructor);
|
||||||
|
setfield(L, "__gc");
|
||||||
|
|
||||||
|
setglobal(L, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline glm::vec2 tovec2(lua::State* L, int idx) {
|
||||||
pushvalue(L, idx);
|
pushvalue(L, idx);
|
||||||
if (!istable(L, idx) || objlen(L, idx) < 2) {
|
if (!istable(L, idx) || objlen(L, idx) < 2) {
|
||||||
throw std::runtime_error("value must be an array of two numbers");
|
throw std::runtime_error("value must be an array of two numbers");
|
||||||
@@ -287,14 +339,6 @@ namespace lua {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setfield(lua::State* L, const std::string& name, int idx=-2) {
|
|
||||||
lua_setfield(L, idx, name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setglobal(lua::State* L, const std::string& name) {
|
|
||||||
lua_setglobal(L, name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char* require_string(lua::State* L, int idx) {
|
inline const char* require_string(lua::State* L, int idx) {
|
||||||
if (!isstring(L, idx)) {
|
if (!isstring(L, idx)) {
|
||||||
throw luaerror("string expected at "+std::to_string(idx));
|
throw luaerror("string expected at "+std::to_string(idx));
|
||||||
|
|||||||
Reference in New Issue
Block a user