Created
November 27, 2012 13:16
-
-
Save vrld/4154182 to your computer and use it in GitHub Desktop.
Helpers for exposing (parts of) C++ structs to Lua, e.g. to be passed around in "glue code"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <lua_proxy.hpp> | |
#include <opencv.hpp> | |
// Exposing cv::Mat to Lua | |
template<> struct LuaXTraits<cv::Mat> | |
{ | |
constexpr static const char *name() | |
{ | |
return "Type.cv::Mat"; | |
} | |
}; | |
int l_imread(lua_State *L) | |
{ | |
const char *path = luaL_checkstring(L, 1); | |
cv::Mat img = cv::imread(path); | |
if (NULL != img.data) | |
{ | |
LuaProxy<cv::Mat>::push_new_with_mtable(L, new cv::Mat(img)); | |
return 1; | |
} | |
// else (see https://gist.github.com/4154228 for a shorter version of the following) | |
lua_pushnil(L); | |
luaL_Buffer b; | |
luaL_buffinit(L, &b); | |
luaL_addstring(&b, "Cannot read image from `"); | |
luaL_addstring(&b, path); | |
luaL_addstring(&b, "'."); | |
luaL_pushresult(&b); | |
return 2; | |
} | |
int l_imwrite(lua_State *L) | |
{ | |
cv::Mat *img = LuaProxy<cv::Mat>::get(L, 1); | |
const char *path = luaL_checkstring(L, 2); | |
if (cv::imwrite(path, *img)) | |
{ | |
lua_pushboolean(L, true); | |
return 1; | |
} | |
// else | |
lua_pushnil(L); | |
luaL_Buffer b; | |
luaL_buffinit(L, &b); | |
luaL_addstring(&b, "Cannot write image to `"); | |
luaL_addstring(&b, path); | |
luaL_addstring(&b, "'."); | |
luaL_pushresult(&b); | |
return 2; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <stdexcept> | |
#include <lua.hpp> | |
template<typename T> | |
struct LuaXTraits | |
{ | |
constexpr static const char *name() | |
{ | |
throw std::runtime_error("LuaXTraits<T> not implemented for this type!"); | |
return "Type.NeedsImplementation"; // never reached | |
} | |
}; | |
template<typename T> | |
struct LuaProxy | |
{ | |
T *ptr; | |
static T *push_new(lua_State *L, T *ptr) | |
{ | |
LuaProxy<T> *p = (LuaProxy<T> *)lua_newuserdata(L, sizeof(LuaProxy<T>)); | |
if (NULL == p) | |
luaL_error(L, "Cannot create new userdata!"); | |
p->ptr = ptr; | |
return ptr; | |
} | |
static int __gc(lua_State *L) | |
{ | |
LuaProxy *p = (LuaProxy<T> *)lua_touserdata(L, 1); | |
if (NULL != p && NULL != p->ptr) | |
delete p->ptr; | |
return 0; | |
} | |
static inline T *get(lua_State *L, int i) | |
{ | |
LuaProxy<T> *p = (LuaProxy<T> *)luaL_checkudata(L, i, LuaXTraits<T>::name()); | |
return p->ptr; | |
} | |
static int newmetatable(lua_State *L) | |
{ | |
int rc = luaL_newmetatable(L, LuaXTraits<T>::name()); | |
if (rc) | |
{ | |
lua_pushvalue(L, -1); | |
lua_setfield(L, -2, "__index"); | |
lua_pushcfunction(L, LuaProxy<T>::__gc); | |
lua_setfield(L, -2, "__gc"); | |
} | |
return rc; | |
} | |
static T *push_new_with_mtable(lua_State *L, T *ptr) | |
{ | |
push_new(L, ptr); | |
newmetatable(L); | |
lua_setmetatable(L, -2); | |
return ptr; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment