向量库示例 |
|
这是一个非常简单的向量代码封装示例。函数 `lua_vec3libopen()` 使用 `luaL_openl()` 添加一个全局函数 `vector3()`,这是一个向量构造函数。创建了一个标签,以便可以使用标签方法 `gettable()` 和 `settable()` 来访问向量中的元素。有关用法,请参见测试代码。
[!] 版本说明:以下代码适用于旧版本的 Lua,Lua 4。某些使用的功能,例如标签方法(`settagmethod`),在 Lua 5 中不再存在,但已被元方法替换。
注意:以下代码使用静态变量 TAG。这可以避免,也应该避免。我应该使用注册表,但我太懒了。我也可以将 TAG 作为 `lua_vec3libopen()` 的局部变量,并将其用作 `vec3new()` 的上值。在处理字段名称方面我也很懒:我只查看第一个字母。--lhf
此代码适用于 Lua 4.0。我已经为 Lua 5.0 更新了它 [这里]。--lhf
/*
* vec3lib.c
* add 3d vectors to Lua
* this code is in the public domain
*/
#include "lua.h"
#include "lauxlib.h"
LUALIB_API int lua_vec3libopen (lua_State *L);
typedef struct { double a[3]; } Vector3;
static int TAG; /* lazy! */
static int vec3new(lua_State *L) {
Vector3* v;
lua_newuserdata(L,sizeof(Vector3));
lua_settag(L,TAG);
v=lua_touserdata(L,-1);
if (lua_gettop(L)>1) {
v->a[0]=luaL_check_number(L,1);
v->a[1]=luaL_check_number(L,2);
v->a[2]=luaL_check_number(L,3);
}
else
v->a[0] = v->a[1] = v->a[2] = 0;
return 1;
}
static int vec3get(lua_State *L) {
Vector3* v=lua_touserdata(L,1);
const char* i=luaL_check_string(L,2);
switch (*i) { /* lazy! */
case 'x': case 'r': lua_pushnumber(L,v->a[0]); break;
case 'y': case 'g': lua_pushnumber(L,v->a[1]); break;
case 'z': case 'b': lua_pushnumber(L,v->a[2]); break;
default: lua_pushnumber(L,0.0); break;
}
return 1;
}
static int vec3set(lua_State *L) {
Vector3* v=lua_touserdata(L,1);
const char* i=luaL_check_string(L,2);
double t=luaL_check_number(L,3);
switch (*i) { /* lazy! */
case 'x': case 'r': v->a[0]=t; break;
case 'y': case 'g': v->a[1]=t; break;
case 'z': case 'b': v->a[2]=t; break;
default: break;
}
return 1;
}
static const struct luaL_reg vec3lib[] = {
{"vector3", vec3new},
};
int lua_vec3libopen (lua_State *L) {
luaL_openl(L,vec3lib);
TAG=lua_newtag(L);
lua_pushcfunction(L,vec3get); lua_settagmethod(L,TAG,"gettable");
lua_pushcfunction(L,vec3set); lua_settagmethod(L,TAG,"settable");
return 0;
}
以下代码可用于测试它
-- a = vector3() a = vector3(10,20,30) print(a,tag(a)) print(a.x,a.y,a.z) print(a.t,a[1]) a.x,a.y,a.z=100,200,300 print(a.x,a.y,a.z) -- try also a.r, a.g, a.b, if you want to use vectors to store colors...