summaryrefslogtreecommitdiff
path: root/src/ode/body.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ode/body.c')
-rw-r--r--src/ode/body.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/src/ode/body.c b/src/ode/body.c
index 1284bb0..c844747 100644
--- a/src/ode/body.c
+++ b/src/ode/body.c
@@ -7,33 +7,56 @@
struct body_data_t {
lua_State *L;
int callback_ref;
+ int self;
+ int ref;
};
-struct body_t {
+struct body_wrap_t {
dBodyID id;
struct body_data_t data;
};
+int body0_ref = LUA_NOREF;
-void ode_push_body(lua_State *L, dBodyID bb)
+
+void ode_create_body(lua_State *L, dBodyID b)
{
- struct body_t *b = lua_newuserdata(L, sizeof(struct body_t));
- b->id = bb;
- if (bb != 0) {
- b->data.L = L;
- b->data.callback_ref = LUA_NOREF;
- dBodySetData(b->id, &(b->data));
+ struct body_wrap_t *wrap = lua_newuserdata(L, sizeof(struct body_wrap_t));
+ wrap->id = b;
+ if (b != 0) {
+ wrap->data.L = L;
+ lua_pushvalue(L, -1);
+ wrap->data.self = luaL_ref(L, LUA_REGISTRYINDEX);
+ wrap->data.callback_ref = LUA_NOREF;
+ wrap->data.ref = LUA_NOREF;
+ dBodySetData(b, &(wrap->data));
}
luaL_getmetatable(L, ode_body_tname);
lua_setmetatable(L, -2);
}
+void ode_push_body(lua_State *L, dBodyID b)
+{
+ if (b == NULL) {
+ if (body0_ref == LUA_NOREF) {
+ ode_create_body(L, 0);
+ body0_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+ lua_rawgeti(L, LUA_REGISTRYINDEX, body0_ref);
+ }
+ else {
+ struct body_data_t *data = dBodyGetData(b);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self);
+ }
+}
+
+
int dBodyCreate_bind(lua_State *L)
{
dWorldID *w = luaL_checkudata(L, 1, ode_world_tname);
dBodyID b = dBodyCreate(*w);
- ode_push_body(L, b);
+ ode_create_body(L, b);
return 1;
}