From 03e0dd33a847a83d975282c6caf6b926306e7b57 Mon Sep 17 00:00:00 2001 From: gregorycu Date: Tue, 27 Jan 2015 00:46:55 +1100 Subject: Optimize minetest.get_(all)_craft_recipe(s) Signed off by: ShadowNinja, kwolekr --- src/script/lua_api/l_craft.cpp | 172 ++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 97 deletions(-) (limited to 'src/script/lua_api/l_craft.cpp') diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp index 8f8efbfbc..40342871d 100644 --- a/src/script/lua_api/l_craft.cpp +++ b/src/script/lua_api/l_craft.cpp @@ -173,7 +173,7 @@ int ModApiCraft::l_register_craft(lua_State *L) CraftDefinition *def = new CraftDefinitionShaped( output, width, recipe, replacements); - craftdef->registerCraft(def); + craftdef->registerCraft(def, getServer(L)); } /* CraftDefinitionShapeless @@ -205,7 +205,7 @@ int ModApiCraft::l_register_craft(lua_State *L) CraftDefinition *def = new CraftDefinitionShapeless( output, recipe, replacements); - craftdef->registerCraft(def); + craftdef->registerCraft(def, getServer(L)); } /* CraftDefinitionToolRepair @@ -216,7 +216,7 @@ int ModApiCraft::l_register_craft(lua_State *L) CraftDefinition *def = new CraftDefinitionToolRepair( additional_wear); - craftdef->registerCraft(def); + craftdef->registerCraft(def, getServer(L)); } /* CraftDefinitionCooking @@ -246,7 +246,7 @@ int ModApiCraft::l_register_craft(lua_State *L) CraftDefinition *def = new CraftDefinitionCooking( output, recipe, cooktime, replacements); - craftdef->registerCraft(def); + craftdef->registerCraft(def, getServer(L)); } /* CraftDefinitionFuel @@ -270,7 +270,7 @@ int ModApiCraft::l_register_craft(lua_State *L) CraftDefinition *def = new CraftDefinitionFuel( recipe, burntime, replacements); - craftdef->registerCraft(def); + craftdef->registerCraft(def, getServer(L)); } else { @@ -326,56 +326,80 @@ int ModApiCraft::l_get_craft_result(lua_State *L) return 2; } + +void push_craft_recipe(lua_State *L, IGameDef *gdef, + const CraftDefinition *recipe, + const CraftOutput &tmpout) +{ + CraftInput input = recipe->getInput(tmpout, gdef); + CraftOutput output = recipe->getOutput(input, gdef); + + lua_newtable(L); // items + std::vector::const_iterator iter = input.items.begin(); + for (u16 j = 1; iter != input.items.end(); iter++, j++) { + if (iter->empty()) + continue; + lua_pushstring(L, iter->name.c_str()); + lua_rawseti(L, -2, j); + } + lua_setfield(L, -2, "items"); + setintfield(L, -1, "width", input.width); + switch (input.method) { + case CRAFT_METHOD_NORMAL: + lua_pushstring(L, "normal"); + break; + case CRAFT_METHOD_COOKING: + lua_pushstring(L, "cooking"); + break; + case CRAFT_METHOD_FUEL: + lua_pushstring(L, "fuel"); + break; + default: + lua_pushstring(L, "unknown"); + } + lua_setfield(L, -2, "type"); + lua_pushstring(L, tmpout.item.c_str()); + lua_setfield(L, -2, "output"); +} + +void push_craft_recipes(lua_State *L, IGameDef *gdef, + const std::vector &recipes, + const CraftOutput &output) +{ + lua_createtable(L, recipes.size(), 0); + + if (recipes.empty()) { + lua_pushnil(L); + return; + } + + std::vector::const_iterator it = recipes.begin(); + for (unsigned i = 0; it != recipes.end(); ++it) { + lua_newtable(L); + push_craft_recipe(L, gdef, *it, output); + lua_rawseti(L, -2, ++i); + } +} + + // get_craft_recipe(result item) int ModApiCraft::l_get_craft_recipe(lua_State *L) { NO_MAP_LOCK_REQUIRED; - int k = 1; - int input_i = 1; - std::string o_item = luaL_checkstring(L,input_i); + std::string item = luaL_checkstring(L, 1); + Server *server = getServer(L); + CraftOutput output(item, 0); + std::vector recipes = server->cdef() + ->getCraftRecipes(output, server, 1); - IGameDef *gdef = getServer(L); - ICraftDefManager *cdef = gdef->cdef(); - CraftInput input; - CraftOutput output(o_item,0); - bool got = cdef->getCraftRecipe(input, output, gdef); - lua_newtable(L); // output table - if(got){ - lua_newtable(L); - for(std::vector::const_iterator - i = input.items.begin(); - i != input.items.end(); i++, k++) - { - if (i->empty()) - { - continue; - } - lua_pushinteger(L,k); - lua_pushstring(L,i->name.c_str()); - lua_settable(L, -3); - } - lua_setfield(L, -2, "items"); - setintfield(L, -1, "width", input.width); - switch (input.method) { - case CRAFT_METHOD_NORMAL: - lua_pushstring(L,"normal"); - break; - case CRAFT_METHOD_COOKING: - lua_pushstring(L,"cooking"); - break; - case CRAFT_METHOD_FUEL: - lua_pushstring(L,"fuel"); - break; - default: - lua_pushstring(L,"unknown"); - } - lua_setfield(L, -2, "type"); - } else { + if (recipes.empty()) { lua_pushnil(L); lua_setfield(L, -2, "items"); setintfield(L, -1, "width", 0); + return 1; } + push_craft_recipe(L, server, recipes[0], output); return 1; } @@ -384,59 +408,13 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L) { NO_MAP_LOCK_REQUIRED; - std::string o_item = luaL_checkstring(L,1); - IGameDef *gdef = getServer(L); - ICraftDefManager *cdef = gdef->cdef(); - CraftInput input; - CraftOutput output(o_item,0); - std::vector recipes_list; - recipes_list = cdef->getCraftRecipes(output, gdef); - if (recipes_list.empty()) { - lua_pushnil(L); - return 1; - } + std::string item = luaL_checkstring(L, 1); + Server *server = getServer(L); + CraftOutput output(item, 0); + std::vector recipes = server->cdef() + ->getCraftRecipes(output, server); - lua_createtable(L, recipes_list.size(), 0); - std::vector::const_iterator iter = recipes_list.begin(); - for (u16 i = 0; iter != recipes_list.end(); iter++) { - CraftOutput tmpout; - tmpout.item = ""; - tmpout.time = 0; - tmpout = (*iter)->getOutput(input, gdef); - std::string query = tmpout.item; - char *fmtpos, *fmt = &query[0]; - if (strtok_r(fmt, " ", &fmtpos) == output.item) { - input = (*iter)->getInput(output, gdef); - lua_newtable(L); - lua_newtable(L); // items - std::vector::const_iterator iter = input.items.begin(); - for (u16 j = 1; iter != input.items.end(); iter++, j++) { - if (iter->empty()) - continue; - lua_pushstring(L, iter->name.c_str()); - lua_rawseti(L, -2, j); - } - lua_setfield(L, -2, "items"); - setintfield(L, -1, "width", input.width); - switch (input.method) { - case CRAFT_METHOD_NORMAL: - lua_pushstring(L, "normal"); - break; - case CRAFT_METHOD_COOKING: - lua_pushstring(L, "cooking"); - break; - case CRAFT_METHOD_FUEL: - lua_pushstring(L, "fuel"); - break; - default: - lua_pushstring(L, "unknown"); - } - lua_setfield(L, -2, "type"); - lua_pushstring(L, &tmpout.item[0]); - lua_setfield(L, -2, "output"); - lua_rawseti(L, -2, ++i); - } - } + push_craft_recipes(L, server, recipes, output); return 1; } -- cgit v1.2.3