Skip to content

Instantly share code, notes, and snippets.

@cloudwu
Created February 21, 2017 03:46
Show Gist options
  • Save cloudwu/09fca725cb9177d809790b6a7ecdac20 to your computer and use it in GitHub Desktop.
Save cloudwu/09fca725cb9177d809790b6a7ecdac20 to your computer and use it in GitHub Desktop.
Direct access vector in lua from C
#include <lua.h>
#include <lauxlib.h>
#include <ltable.h>
#include <lstate.h>
#include <lobject.h>
#include <stdio.h>
#include <string.h>
#define MAGIC_VECTOR 1.23456789
struct vector_offset {
int x;
int y;
int z;
int magic;
};
#define X(t,vo) fltvalue(gval(gnode(t,(vo)->x)))
#define Y(t,vo) fltvalue(gval(gnode(t,(vo)->y)))
#define Z(t,vo) fltvalue(gval(gnode(t,(vo)->z)))
static int
find_key(const Table *t, const char * key) {
int i;
for (i=0;i<sizenode(t);i++) {
const TValue *v = gkey(gnode(t,i));
if (strcmp(svalue(v), key) == 0) {
return i;
}
}
return -1;
}
static void
vector_init(lua_State *L, struct vector_offset *vo) {
lua_createtable(L, 0, 4);
lua_pushnumber(L, 0);
lua_setfield(L, -2, "x");
lua_pushnumber(L, 0);
lua_setfield(L, -2, "y");
lua_pushnumber(L, 0);
lua_setfield(L, -2, "z");
lua_pushnumber(L, MAGIC_VECTOR);
lua_setfield(L, -2, "__vector3");
const Table * t = lua_topointer(L, -1);
vo->x = find_key(t, "x");
vo->y = find_key(t, "y");
vo->z = find_key(t, "z");
vo->magic = find_key(t, "__vector3");
}
static lua_Number
getfield(lua_State *L, int index, const char *key) {
lua_getfield(L, index, key);
lua_Number v = lua_tonumber(L, -1);
lua_pop(L, 1);
return v;
}
Table *
vector_get(lua_State *L, int index, struct vector_offset *vo) {
luaL_checktype(L, index, LUA_TTABLE);
Table *t = (Table *)lua_topointer(L, index);
const TValue *magic = gval(gnode(t,vo->magic));
if (!ttisfloat(magic) || fltvalue(magic) != MAGIC_VECTOR) {
// convert to vector struct
index = lua_absindex(L, index);
lua_Number x = getfield(L, index, "x");
lua_Number y = getfield(L, index, "y");
lua_Number z = getfield(L, index, "z");
// clear table
lua_pushnil(L);
while (lua_next(L, index) != 0) {
lua_pop(L, 1);
lua_pushvalue(L, -1);
lua_pushnil(L);
lua_rawset(L, index);
}
// copy values
luaH_resize(L, t, 0, 4);
lua_pushnumber(L, x);
lua_setfield(L, index, "x");
lua_pushnumber(L, y);
lua_setfield(L, index, "y");
lua_pushnumber(L, z);
lua_setfield(L, index, "z");
lua_pushnumber(L, MAGIC_VECTOR);
lua_setfield(L, index, "__vector3");
}
return t;
}
int
main() {
lua_State *L = luaL_newstate();
struct vector_offset vo;
vector_init(L, &vo);
printf("offset: x=%d y=%d z=%d magic=%d\n",
vo.x,vo.y,vo.z,vo.magic);
lua_newtable(L);
Table *t = vector_get(L, -1, &vo);
X(t,&vo) = 1;
Y(t,&vo) = 2;
Z(t,&vo) = 3;
printf("x=%f,%f\n",X(t,&vo), getfield(L, -1, "x"));
printf("y=%f,%f\n",Y(t,&vo), getfield(L, -1, "y"));
printf("z=%f,%f\n",Z(t,&vo), getfield(L, -1, "z"));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment