static void fetch_parent(lua_State *L, int index) { lua_getuservalue(L, 1); lua_rawgeti(L, -1, index+1); // A child may not exist, but the name is valid. (empty dummy child) if (!lua_isnil(L, -1)) { ref_parent(L, lua_gettop(L), 1); } }
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); lua_rawgeti(L, -1, index+1); if (lua_isnil(L, -1)) { lua_pop(L, 1); } else { struct sprite * c = lua_touserdata(L, -1); if (c == child) { // mount not change return 0; } if (!c->multimount) { // try to remove parent ref lua_getuservalue(L, -1); if (lua_istable(L, -1)) { lua_pushnil(L); lua_rawseti(L, -2, 0); } lua_pop(L, 2); } else { lua_pop(L, 1); } } if (child == NULL) { sprite_mount(s, index, NULL); lua_pushnil(L); lua_rawseti(L, -2, index+1); } else { if (child->parent) { unlink_parent(L, child, 3); } sprite_mount(s, index, child); lua_pushvalue(L, 3); lua_rawseti(L, -2, index+1); if (!child->multimount) { // multimount has no parent // set child's new parent ref_parent(L, 3, 1); } } return 0; }
static struct sprite * lookup(lua_State *L, struct sprite * spr) { int i; struct sprite * root = (struct sprite *)lua_touserdata(L, -1); lua_getuservalue(L,-1); for (i=0;sprite_component(root, i)>=0;i++) { struct sprite * child = root->data.children[i]; if (child) { lua_rawgeti(L, -1, i+1); // parent, reftable, child if (child == spr) { int child_index = lua_gettop(L); int parent_index = child_index - 2; ref_parent(L, child_index, parent_index); lua_replace(L,-2); // parent return child; } else { lua_pop(L,1); } } } lua_pop(L,1); return NULL; }