Inventory: Send dirty lists where appropriate (#8742)
[oweals/minetest.git] / src / client / game.cpp
index 6ad87d351b9be776a21bc8ebd9db5b5bad75bbae..5bf41bcd6efd0bb99ed83bdacc1d92923849f29e 100644 (file)
@@ -599,7 +599,6 @@ struct GameRunData {
        bool dig_instantly;
        bool digging_blocked;
        bool left_punch;
-       bool update_wielded_item_trigger;
        bool reset_jump_timer;
        float nodig_delay_timer;
        float dig_time;
@@ -689,8 +688,8 @@ protected:
        bool handleCallbacks();
        void processQueues();
        void updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime);
-       void addProfilerGraphs(const RunStats &stats, const FpsControl &draw_times, f32 dtime);
        void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
+       void updateProfilerGraphs(ProfilerGraph *graph);
 
        // Input related
        void processUserInput(f32 dtime);
@@ -751,7 +750,6 @@ protected:
                        const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
        void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                        const CameraOrientation &cam);
-       void updateProfilerGraphs(ProfilerGraph *graph);
 
        // Misc
        void limitFps(FpsControl *fps_timings, f32 *dtime);
@@ -1019,7 +1017,6 @@ bool Game::startup(bool *kill,
        // Reinit runData
        runData = GameRunData();
        runData.time_from_last_punch = 10.0;
-       runData.update_wielded_item_trigger = true;
 
        m_game_ui->initFlags();
 
@@ -1082,10 +1079,12 @@ void Game::run()
                        previous_screen_size = current_screen_size;
                }
 
-               /* Must be called immediately after a device->run() call because it
-                * uses device->getTimer()->getTime()
-                */
+               // Calculate dtime =
+               //    RenderingEngine::run() from this iteration
+               //  + Sleep time until the wanted FPS are reached
                limitFps(&draw_times, &dtime);
+               
+               // Prepare render data for next iteration
 
                updateStats(&stats, draw_times, dtime);
                updateInteractTimers(dtime);
@@ -1722,7 +1721,8 @@ void Game::processQueues()
 }
 
 
-void Game::updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime)
+void Game::updateProfilers(const RunStats &stats, const FpsControl &draw_times,
+               f32 dtime)
 {
        float profiler_print_interval =
                        g_settings->getFloat("profiler_print_interval");
@@ -1730,7 +1730,7 @@ void Game::updateProfilers(const RunStats &stats, const FpsControl &draw_times,
 
        if (profiler_print_interval == 0) {
                print_to_log = false;
-               profiler_print_interval = 5;
+               profiler_print_interval = 3;
        }
 
        if (profiler_interval.step(dtime, profiler_print_interval)) {
@@ -1743,25 +1743,14 @@ void Game::updateProfilers(const RunStats &stats, const FpsControl &draw_times,
                g_profiler->clear();
        }
 
-       addProfilerGraphs(stats, draw_times, dtime);
-}
-
-
-void Game::addProfilerGraphs(const RunStats &stats,
-               const FpsControl &draw_times, f32 dtime)
-{
-       g_profiler->graphAdd("mainloop_other",
-                       draw_times.busy_time / 1000.0f - stats.drawtime / 1000.0f);
-
-       if (draw_times.sleep_time != 0)
-               g_profiler->graphAdd("mainloop_sleep", draw_times.sleep_time / 1000.0f);
-       g_profiler->graphAdd("mainloop_dtime", dtime);
+       // Update update graphs
+       g_profiler->graphAdd("Time non-rendering [ms]",
+               draw_times.busy_time - stats.drawtime);
 
-       g_profiler->add("Elapsed time", dtime);
-       g_profiler->avg("FPS", 1. / dtime);
+       g_profiler->graphAdd("Sleep [ms]", draw_times.sleep_time);
+       g_profiler->graphAdd("FPS", 1.0f / dtime);
 }
 
-
 void Game::updateStats(RunStats *stats, const FpsControl &draw_times,
                f32 dtime)
 {
@@ -2475,7 +2464,7 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
        }
 
        // autoforward if set: simulate "up" key
-       if (player->getPlayerSettings().continuous_forward) {
+       if (player->getPlayerSettings().continuous_forward && !player->isDead()) {
                control.up = true;
                keypress_bits |= 1U << 0;
        }
@@ -2492,7 +2481,7 @@ inline void Game::step(f32 *dtime)
        bool can_be_and_is_paused =
                        (simple_singleplayer_mode && g_menumgr.pausesGame());
 
-       if (can_be_and_is_paused) {     // This is for a singleplayer server
+       if (can_be_and_is_paused) { // This is for a singleplayer server
                *dtime = 0;             // No time passes
        } else {
                if (server)
@@ -2926,7 +2915,7 @@ void Game::updateSound(f32 dtime)
                soundmaker->step(dtime);
 
        ClientMap &map = client->getEnv().getClientMap();
-       MapNode n = map.getNodeNoEx(player->getFootstepNodePos());
+       MapNode n = map.getNode(player->getFootstepNodePos());
        soundmaker->m_player_step_sound = nodedef_manager->get(n).sound_footstep;
 }
 
@@ -2954,7 +2943,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
        const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
 
        const ItemDefinition &selected_def = selected_item.getDefinition(itemdef_manager);
-       f32 d = BS * getToolRange(selected_def, hand_item.getDefinition(itemdef_manager));
+       f32 d = getToolRange(selected_def, hand_item.getDefinition(itemdef_manager));
 
        core::line3d<f32> shootline;
 
@@ -3105,7 +3094,7 @@ PointedThing Game::updatePointedThing(
                }
        } else if (result.type == POINTEDTHING_NODE) {
                // Update selection boxes
-               MapNode n = map.getNodeNoEx(result.node_undersurface);
+               MapNode n = map.getNode(result.node_undersurface);
                std::vector<aabb3f> boxes;
                n.getSelectionBoxes(nodedef, &boxes,
                        n.getNeighbors(result.node_undersurface, &map));
@@ -3132,12 +3121,12 @@ PointedThing Game::updatePointedThing(
                v3s16 p = floatToInt(pf, BS);
 
                // Get selection mesh light level
-               MapNode n = map.getNodeNoEx(p);
+               MapNode n = map.getNode(p);
                u16 node_light = getInteriorLight(n, -1, nodedef);
                u16 light_level = node_light;
 
                for (const v3s16 &dir : g_6dirs) {
-                       n = map.getNodeNoEx(p + dir);
+                       n = map.getNode(p + dir);
                        node_light = getInteriorLight(n, -1, nodedef);
                        if (node_light > light_level)
                                light_level = node_light;
@@ -3198,7 +3187,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
                m_game_ui->setInfoText(unescape_translate(utf8_to_wide(
                        meta->getString("infotext"))));
        } else {
-               MapNode n = map.getNodeNoEx(nodepos);
+               MapNode n = map.getNode(nodepos);
 
                if (nodedef_manager->get(n).tiledef[0].name == "unknown_node.png") {
                        m_game_ui->setInfoText(L"Unknown node: " +
@@ -3215,7 +3204,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
                if (meta && !meta->getString("formspec").empty() && !random_input
                                && !isKeyDown(KeyType::SNEAK)) {
                        // Report right click to server
-                       if (nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
+                       if (nodedef_manager->get(map.getNode(nodepos)).rightclickable) {
                                client->interact(INTERACT_PLACE, pointed);
                        }
 
@@ -3258,7 +3247,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
                                                SimpleSoundSpec();
 
                                if (def.node_placement_prediction.empty() ||
-                                               nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
+                                               nodedef_manager->get(map.getNode(nodepos)).rightclickable) {
                                        client->interact(INTERACT_PLACE, pointed); // Report to server
                                } else {
                                        soundmaker->m_player_rightpunch_sound =
@@ -3278,7 +3267,7 @@ bool Game::nodePlacementPrediction(const ItemDefinition &selected_def,
        MapNode node;
        bool is_valid_position;
 
-       node = map.getNodeNoEx(nodepos, &is_valid_position);
+       node = map.getNode(nodepos, &is_valid_position);
        if (!is_valid_position)
                return false;
 
@@ -3290,13 +3279,13 @@ bool Game::nodePlacementPrediction(const ItemDefinition &selected_def,
                v3s16 p = neighbourpos;
 
                // Place inside node itself if buildable_to
-               MapNode n_under = map.getNodeNoEx(nodepos, &is_valid_position);
+               MapNode n_under = map.getNode(nodepos, &is_valid_position);
                if (is_valid_position)
                {
                        if (nodedef->get(n_under).buildable_to)
                                p = nodepos;
                        else {
-                               node = map.getNodeNoEx(p, &is_valid_position);
+                               node = map.getNode(p, &is_valid_position);
                                if (is_valid_position &&!nodedef->get(node).buildable_to)
                                        return false;
                        }
@@ -3363,7 +3352,7 @@ bool Game::nodePlacementPrediction(const ItemDefinition &selected_def,
                        else
                                pp = p + v3s16(0, -1, 0);
 
-                       if (!nodedef->get(map.getNodeNoEx(pp)).walkable)
+                       if (!nodedef->get(map.getNode(pp)).walkable)
                                return false;
                }
 
@@ -3477,7 +3466,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
        // See also: serverpackethandle.cpp, action == 2
        LocalPlayer *player = client->getEnv().getLocalPlayer();
        ClientMap &map = client->getEnv().getClientMap();
-       MapNode n = client->getEnv().getClientMap().getNodeNoEx(nodepos);
+       MapNode n = client->getEnv().getClientMap().getNode(nodepos);
 
        // NOTE: Similar piece of code exists on the server side for
        // cheat detection.
@@ -3565,7 +3554,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
                        runData.nodig_delay_timer = 0.15;
 
                bool is_valid_position;
-               MapNode wasnode = map.getNodeNoEx(nodepos, &is_valid_position);
+               MapNode wasnode = map.getNode(nodepos, &is_valid_position);
                if (is_valid_position) {
                        if (client->moddingEnabled() &&
                                        client->getScript()->on_dignode(nodepos, wasnode)) {
@@ -3612,6 +3601,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
 void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                const CameraOrientation &cam)
 {
+       TimeTaker tt_update("Game::updateFrame()");
        LocalPlayer *player = client->getEnv().getLocalPlayer();
 
        /*
@@ -3636,7 +3626,6 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                direct_brightness = time_brightness;
                sunlight_seen = true;
        } else {
-               ScopeProfiler sp(g_profiler, "Detecting background light", SPT_AVG);
                float old_brightness = sky->getBrightness();
                direct_brightness = client->getEnv().getClientMap()
                                .getBackgroundBrightness(MYMIN(runData.fog_range * 1.2, 60 * BS),
@@ -3745,19 +3734,11 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        if (player->getWieldIndex() != runData.new_playeritem)
                client->setPlayerItem(runData.new_playeritem);
 
-       // Update local inventory if it has changed
-       if (client->getLocalInventoryUpdated()) {
-               //infostream<<"Updating local inventory"<<std::endl;
-               runData.update_wielded_item_trigger = true;
-       }
-
-       if (runData.update_wielded_item_trigger) {
+       if (client->updateWieldedItem()) {
                // Update wielded tool
                ItemStack selected_item, hand_item;
                ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
                camera->wield(tool_item);
-
-               runData.update_wielded_item_trigger = false;
        }
 
        /*
@@ -3810,7 +3791,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        */
        const video::SColor &skycolor = sky->getSkyColor();
 
-       TimeTaker tt_draw("mainloop: draw");
+       TimeTaker tt_draw("Draw scene");
        driver->beginScene(true, true, skycolor);
 
        bool draw_wield_tool = (m_game_ui->m_flags.show_hud &&
@@ -3870,7 +3851,8 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        driver->endScene();
 
        stats->drawtime = tt_draw.stop(true);
-       g_profiler->graphAdd("mainloop_draw", stats->drawtime / 1000.0f);
+       g_profiler->avg("Game::updateFrame(): draw scene [ms]", stats->drawtime);
+       g_profiler->graphAdd("Update frame [ms]", tt_update.stop(true));
 }
 
 /* Log times and stuff for visualization */