static struct sprite * newsprite(lua_State *L, struct sprite_pack *pack, int id) { if (id == ANCHOR_ID) { return newanchor(L); } int sz = sprite_size(pack, id); if (sz == 0) { return NULL; } struct sprite * s = (struct sprite *)lua_newuserdata(L, sz); sprite_init(s, pack, id, sz); int i; for (i=0;;i++) { int childid = sprite_component(s, i); if (childid < 0) break; if (i==0) { lua_newtable(L); lua_pushvalue(L,-1); lua_setuservalue(L, -3); // set uservalue for sprite } struct sprite *c = newsprite(L, pack, childid); if (c) { c->name = sprite_childname(s, i); sprite_mount(s, i, c); update_message(c, pack, id, i, s->frame); lua_rawseti(L, -2, i+1); } } if (i>0) { lua_pop(L,1); } return s; }
static int lmount(lua_State *L) { struct sprite *s = self(L); const char * name = luaL_checkstring(L,2); int index = sprite_child(s, name); if (index < 0) { return luaL_error(L, "No child name %s", name); } lua_getuservalue(L, 1); struct sprite * child = (struct sprite *)lua_touserdata(L, 3); if (child == NULL) { sprite_mount(s, index, NULL); lua_pushnil(L); lua_rawseti(L, -2, index+1); } else { if (child->parent) { return luaL_error(L, "Can't mount sprite %p twice,pre parent:%p: %s", child,child->parent,child->name); } sprite_mount(s, index, child); lua_pushvalue(L, 3); lua_rawseti(L, -2, index+1); } return 0; }
static void unlink_parent(lua_State *L, struct sprite * child, int idx) { lua_getuservalue(L, idx); // reftable lua_rawgeti(L, -1, 0); // reftable parent struct sprite * parent = lua_touserdata(L, -1); if (parent == NULL) { luaL_error(L, "No parent object"); } int index = sprite_child_ptr(parent, child); if (index < 0) { luaL_error(L, "Invalid child object"); } lua_getuservalue(L, -1); // reftable parent parentref lua_pushnil(L); lua_rawseti(L, -2, index+1); lua_pop(L, 3); sprite_mount(parent, index, NULL); }