向量函式庫範例

lua-users home
wiki

說明

這是包裝部分向量程式碼的非常簡單範例。函式 `lua_vec3libopen()` 使用 `luaL_openl()` 新增一個全域函式 `vector3()`,一個向量建構函式。建立一個標籤,使標籤方法 `gettable()` 和 `settable()` 能用來存取向量中的元素。請參閱測試程式碼以了解用法。

[!] VersionNotice:下列程式碼屬於較舊的 Lua 版本,Lua 4。某些已使用的功能,例如標籤方法 (settagmethod),已不再存在於 Lua 5,但已由元方法取代。

注意:下列程式碼使用一個靜態變數 TAG。這一點可以而且應該避免。我應該使用註冊表,但我懶得這麼做。我也可以使用 **當地** 於 `lua_vec3libopen()` 的 TAG,並將它用作 `vec3new()` 的 upvalue。我也懶得處理欄位名稱:我只看第一個字母。 --lhf

這個程式碼適用於 Lua 4.0。我已將它更新為 Lua 5.0 [在此處]。 --lhf

C 程式碼

/*
* 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...

RecentChanges · 喜好設定
編輯 · 歷程
上次於 2007 年 1 月 6 日下午 7:43 GMT 編輯 (diff)