Optimize table creation
authorShadowNinja <shadowninja@minetest.net>
Sat, 30 Nov 2013 17:11:07 +0000 (12:11 -0500)
committerShadowNinja <shadowninja@minetest.net>
Sat, 30 Nov 2013 18:05:13 +0000 (13:05 -0500)
src/script/common/c_content.cpp
src/script/lua_api/l_craft.cpp
src/script/lua_api/l_env.cpp
src/script/lua_api/l_rollback.cpp
src/script/lua_api/l_server.cpp

index 65239ff1f51cc8c1ce7c9fffdc86c3389c0ffcb6..fd98e948028e6ca4dffd351238970f3465933dc8 100644 (file)
@@ -871,26 +871,13 @@ void read_groups(lua_State *L, int index,
 /******************************************************************************/
 void push_items(lua_State *L, const std::vector<ItemStack> &items)
 {
-       lua_pushcfunction(L, script_error_handler);
-       int errorhandler = lua_gettop(L);
-       // Get the table insert function
-       lua_getglobal(L, "table");
-       lua_getfield(L, -1, "insert");
-       int table_insert = lua_gettop(L);
        // Create and fill table
-       lua_newtable(L);
-       int table = lua_gettop(L);
-       for(u32 i=0; i<items.size(); i++){
-               ItemStack item = items[i];
-               lua_pushvalue(L, table_insert);
-               lua_pushvalue(L, table);
-               LuaItemStack::create(L, item);
-               if(lua_pcall(L, 2, 0, errorhandler))
-                       script_error(L);
+       lua_createtable(L, items.size(), 0);
+       std::vector<ItemStack>::const_iterator iter = items.begin();
+       for (u32 i = 0; iter != items.end(); iter++) {
+               LuaItemStack::create(L, *iter);
+               lua_rawseti(L, -2, ++i);
        }
-       lua_remove(L, -2); // Remove insert
-       lua_remove(L, -2); // Remove table
-       lua_remove(L, -2); // Remove error handler
 }
 
 /******************************************************************************/
index c5732bad2e1b0f2d966eefd4f18d8215205f3680..035abb78d97c19fa775fc12e6c5786cdf9627b24 100644 (file)
@@ -389,67 +389,52 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L)
        ICraftDefManager *cdef = gdef->cdef();
        CraftInput input;
        CraftOutput output(o_item,0);
-       std::vector<CraftDefinition*> recipes_list = cdef->getCraftRecipes(output, gdef);
-       if (recipes_list.empty())
-       {
+       std::vector<CraftDefinition*> recipes_list;
+       recipes_list = cdef->getCraftRecipes(output, gdef);
+       if (recipes_list.empty()) {
                lua_pushnil(L);
                return 1;
        }
-       // Get the table insert function
-       lua_getglobal(L, "table");
-       lua_getfield(L, -1, "insert");
-       int table_insert = lua_gettop(L);
-       lua_newtable(L);
-       int table = lua_gettop(L);
-       for (std::vector<CraftDefinition*>::const_iterator
-               i = recipes_list.begin();
-               i != recipes_list.end(); i++)
-       {
+
+       lua_createtable(L, recipes_list.size(), 0);
+       std::vector<CraftDefinition*>::const_iterator iter = recipes_list.begin();
+       for (u16 i = 0; iter != recipes_list.end(); iter++) {
                CraftOutput tmpout;
                tmpout.item = "";
                tmpout.time = 0;
-               CraftDefinition *def = *i;
-               tmpout = def->getOutput(input, gdef);
+               tmpout = (*iter)->getOutput(input, gdef);
                std::string query = tmpout.item;
                char *fmtpos, *fmt = &query[0];
-               if (strtok_r(fmt, " ", &fmtpos) == output.item)
-               {
-                       input = def->getInput(output, gdef);
-                       lua_pushvalue(L, table_insert);
-                       lua_pushvalue(L, table);
+               if (strtok_r(fmt, " ", &fmtpos) == output.item) {
+                       input = (*iter)->getInput(output, gdef);
                        lua_newtable(L);
-                       int k = 1;
-                       lua_newtable(L);
-                       for(std::vector<ItemStack>::const_iterator
-                               i = input.items.begin();
-                               i != input.items.end(); i++, k++)
-                       {
-                               if (i->empty())
+                       lua_newtable(L); // items
+                       std::vector<ItemStack>::const_iterator iter = input.items.begin();
+                       for (u16 j = 0; iter != input.items.end(); iter++) {
+                               if (iter->empty())
                                        continue;
-                               lua_pushinteger(L,k);
-                               lua_pushstring(L,i->name.c_str());
-                               lua_settable(L, -3);
+                               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");
+                                       lua_pushstring(L, "normal");
                                        break;
                                case CRAFT_METHOD_COOKING:
-                                       lua_pushstring(L,"cooking");
+                                       lua_pushstring(L, "cooking");
                                        break;
                                case CRAFT_METHOD_FUEL:
-                                       lua_pushstring(L,"fuel");
+                                       lua_pushstring(L, "fuel");
                                        break;
                                default:
-                                       lua_pushstring(L,"unknown");
-                               }
+                                       lua_pushstring(L, "unknown");
+                       }
                        lua_setfield(L, -2, "type");
                        lua_pushstring(L, &tmpout.item[0]);
                        lua_setfield(L, -2, "output");
-                       if (lua_pcall(L, 2, 0, 0))
-                               script_error(L);
+                       lua_rawseti(L, -2, ++i);
                }
        }
        return 1;
index a33882bdfba237fb35551aeee386e5edac5613c6..4a815039641ee0986f0f85a2749f21026faa38c2 100644 (file)
@@ -448,28 +448,20 @@ int ModApiEnvMod::l_get_player_by_name(lua_State *L)
 // minetest.get_objects_inside_radius(pos, radius)
 int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
 {
-       // Get the table insert function
-       lua_getglobal(L, "table");
-       lua_getfield(L, -1, "insert");
-       int table_insert = lua_gettop(L);
-
        GET_ENV_PTR;
 
        // Do it
        v3f pos = checkFloatPos(L, 1);
        float radius = luaL_checknumber(L, 2) * BS;
        std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
-       lua_newtable(L);
-       int table = lua_gettop(L);
-       for(std::set<u16>::const_iterator
-                       i = ids.begin(); i != ids.end(); i++){
-               ServerActiveObject *obj = env->getActiveObject(*i);
+       ScriptApiBase *script = getScriptApiBase(L);
+       lua_createtable(L, ids.size(), 0);
+       std::set<u16>::const_iterator iter = ids.begin();
+       for(u32 i = 0; iter != ids.end(); iter++) {
+               ServerActiveObject *obj = env->getActiveObject(*iter);
                // Insert object reference into table
-               lua_pushvalue(L, table_insert);
-               lua_pushvalue(L, table);
-               getScriptApiBase(L)->objectrefGetOrCreate(obj);
-               if(lua_pcall(L, 2, 0, 0))
-                       script_error(L);
+               script->objectrefGetOrCreate(obj);
+               lua_rawseti(L, -2, ++i);
        }
        return 1;
 }
@@ -579,25 +571,16 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
                ndef->getIds(lua_tostring(L, 3), filter);
        }
 
-       // Get the table insert function
-       lua_getglobal(L, "table");
-       lua_getfield(L, -1, "insert");
-       int table_insert = lua_gettop(L);
-
        lua_newtable(L);
-       int table = lua_gettop(L);
-       for(s16 x=minp.X; x<=maxp.X; x++)
-       for(s16 y=minp.Y; y<=maxp.Y; y++)
-       for(s16 z=minp.Z; z<=maxp.Z; z++)
-       {
-               v3s16 p(x,y,z);
+       u64 i = 0;
+       for(s16 x = minp.X; x <= maxp.X; x++)
+       for(s16 y = minp.Y; y <= maxp.Y; y++)
+       for(s16 z = minp.Z; z <= maxp.Z; z++) {
+               v3s16 p(x, y, z);
                content_t c = env->getMap().getNodeNoEx(p).getContent();
-               if(filter.count(c) != 0){
-                       lua_pushvalue(L, table_insert);
-                       lua_pushvalue(L, table);
+               if(filter.count(c) != 0) {
                        push_v3s16(L, p);
-                       if(lua_pcall(L, 2, 0, 0))
-                               script_error(L);
+                       lua_rawseti(L, -2, ++i);
                }
        }
        return 1;
index e7185b00b5bd48bd514e97a9a050d1d7da5bd3bd..b3685c8d1d2c6d7b2324666c081fff593838b272 100644 (file)
@@ -50,7 +50,6 @@ int ModApiRollback::l_rollback_get_node_actions(lua_State *L)
 
        lua_createtable(L, actions.size(), 0);
        for (unsigned int i = 1; iter != actions.end(); ++iter, ++i) {
-               lua_pushnumber(L, i); // Push index
                lua_createtable(L, 0, 5); // Make a table with enough space pre-allocated
 
                lua_pushstring(L, iter->actor.c_str());
@@ -68,7 +67,7 @@ int ModApiRollback::l_rollback_get_node_actions(lua_State *L)
                push_RollbackNode(L, iter->n_new);
                lua_setfield(L, -2, "newnode");
 
-               lua_settable(L, -3); // Add action table to main table
+               lua_rawseti(L, -2, i); // Add action table to main table
        }
 
        return 1;
index 19e2f1bcbe11f1efbd26ce5a1bba1b1482082201..9d3575a72b78ba8c311006ff968812ff8d1ccc4c 100644 (file)
@@ -229,16 +229,13 @@ int ModApiServer::l_get_modnames(lua_State *L)
        // mods_sorted; not great performance but the number of mods on a
        // server will likely be small.
        for(std::list<std::string>::iterator i = mods_unsorted.begin();
-               i != mods_unsorted.end(); ++i)
-       {
+                       i != mods_unsorted.end(); ++i) {
                bool added = false;
                for(std::list<std::string>::iterator x = mods_sorted.begin();
-                       x != mods_sorted.end(); ++x)
-               {
+                               x != mods_sorted.end(); ++x) {
                        // I doubt anybody using Minetest will be using
                        // anything not ASCII based :)
-                       if((*i).compare(*x) <= 0)
-                       {
+                       if(i->compare(*x) <= 0) {
                                mods_sorted.insert(x, *i);
                                added = true;
                                break;
@@ -248,25 +245,12 @@ int ModApiServer::l_get_modnames(lua_State *L)
                        mods_sorted.push_back(*i);
        }
 
-       // Get the table insertion function from Lua.
-       lua_getglobal(L, "table");
-       lua_getfield(L, -1, "insert");
-       int insertion_func = lua_gettop(L);
-
        // Package them up for Lua
-       lua_newtable(L);
-       int new_table = lua_gettop(L);
-       std::list<std::string>::iterator i = mods_sorted.begin();
-       while(i != mods_sorted.end())
-       {
-               lua_pushvalue(L, insertion_func);
-               lua_pushvalue(L, new_table);
-               lua_pushstring(L, (*i).c_str());
-               if(lua_pcall(L, 2, 0, 0) != 0)
-               {
-                       script_error(L);
-               }
-               ++i;
+       lua_createtable(L, mods_sorted.size(), 0);
+       std::list<std::string>::iterator iter = mods_sorted.begin();
+       for (u16 i = 0; iter != mods_sorted.end(); iter++) {
+               lua_pushstring(L, iter->c_str());
+               lua_rawseti(L, -2, ++i);
        }
        return 1;
 }