diff options
Diffstat (limited to 'src/ode/body.c')
-rw-r--r-- | src/ode/body.c | 41 |
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; } |