Finer progress bar updates when initializing nodes
authorest31 <MTest31@outlook.com>
Sun, 15 Mar 2015 06:25:22 +0000 (07:25 +0100)
committerCraig Robbins <kde.psych@gmail.com>
Sun, 15 Mar 2015 12:01:52 +0000 (22:01 +1000)
The bar is only drawn when the user will notice a change, which prevents time overheads that this commit would cause, resulting from useless draws.

src/client.cpp
src/client.h
src/game.cpp
src/nodedef.cpp
src/nodedef.h

index 7d2fab1793a2535e5ef29b8fe2b0d49e5919f57b..8a9d62d2922df193eea653f69360a0ef77fedbe3 100644 (file)
@@ -1553,7 +1553,39 @@ float Client::mediaReceiveProgress()
                return 1.0; // downloader only exists when not yet done
 }
 
-void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
+typedef struct TextureUpdateArgs {
+       IrrlichtDevice *device;
+       gui::IGUIEnvironment *guienv;
+       u32 last_time_ms;
+       u16 last_percent;
+       const wchar_t* text_base;
+} TextureUpdateArgs;
+
+void texture_update_progress(void *args, u32 progress, u32 max_progress)
+{
+               TextureUpdateArgs* targs = (TextureUpdateArgs*) args;
+               u16 cur_percent = ceil(progress / (double) max_progress * 100.);
+
+               // update the loading menu -- if neccessary
+               bool do_draw = false;
+               u32 time_ms = targs->last_time_ms;
+               if (cur_percent != targs->last_percent) {
+                       targs->last_percent = cur_percent;
+                       time_ms = getTimeMs();
+                       // only draw when the user will notice something:
+                       do_draw = (time_ms - targs->last_time_ms > 100);
+               }
+
+               if (do_draw) {
+                       targs->last_time_ms = time_ms;
+                       std::basic_stringstream<wchar_t> strm;
+                       strm << targs->text_base << " " << targs->last_percent << "%...";
+                       draw_load_screen(strm.str(), targs->device, targs->guienv, 0,
+                               72 + (u16) ((18. / 100.) * (double) targs->last_percent));
+               }
+}
+
+void Client::afterContentReceived(IrrlichtDevice *device)
 {
        infostream<<"Client::afterContentReceived() started"<<std::endl;
        assert(m_itemdef_received); // pre-condition
@@ -1571,14 +1603,14 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
        // Rebuild shaders
        infostream<<"- Rebuilding shaders"<<std::endl;
        text = wgettext("Rebuilding shaders...");
-       draw_load_screen(text, device, guienv, 0, 75);
+       draw_load_screen(text, device, guienv, 0, 71);
        m_shsrc->rebuildShaders();
        delete[] text;
 
        // Update node aliases
        infostream<<"- Updating node aliases"<<std::endl;
        text = wgettext("Initializing nodes...");
-       draw_load_screen(text, device, guienv, 0, 80);
+       draw_load_screen(text, device, guienv, 0, 72);
        m_nodedef->updateAliases(m_itemdef);
        m_nodedef->setNodeRegistrationStatus(true);
        m_nodedef->runNodeResolverCallbacks();
@@ -1586,7 +1618,14 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
 
        // Update node textures and assign shaders to each tile
        infostream<<"- Updating node textures"<<std::endl;
-       m_nodedef->updateTextures(this);
+       TextureUpdateArgs tu_args;
+       tu_args.device = device;
+       tu_args.guienv = guienv;
+       tu_args.last_time_ms = getTimeMs();
+       tu_args.last_percent = 0;
+       tu_args.text_base =  wgettext("Initializing nodes");
+       m_nodedef->updateTextures(this, texture_update_progress, &tu_args);
+       delete[] tu_args.text_base;
 
        // Preload item textures and meshes if configured to
        if(g_settings->getBool("preload_item_visuals"))
index 9baa034dea82d952eec48d9715e706722bdb9ce5..a455213e9f95758c7577ff86dd9b1cf015ce4eab 100644 (file)
@@ -492,7 +492,7 @@ public:
 
        float mediaReceiveProgress();
 
-       void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
+       void afterContentReceived(IrrlichtDevice *device);
 
        float getRTT(void);
        float getCurRate(void);
index 7b6d2a3c19d6f0305f1dce3a7adaad7cbc14d5dc..937f6cb237c589e8a17d5c38ad6b0aff13091c18 100644 (file)
@@ -1998,7 +1998,7 @@ bool Game::createClient(const std::string &playername,
        }
 
        // Update cached textures, meshes and materials
-       client->afterContentReceived(device, g_fontengine->getFont());
+       client->afterContentReceived(device);
 
        /* Camera
         */
index a0dcf6b71e21d734924721296abc756c4daec65f..4aee1b1c6bc5e820aeb0be80e6a8dfdfb1fedd51 100644 (file)
@@ -398,7 +398,9 @@ public:
        virtual content_t set(const std::string &name, const ContentFeatures &def);
        virtual content_t allocateDummy(const std::string &name);
        virtual void updateAliases(IItemDefManager *idef);
-       virtual void updateTextures(IGameDef *gamedef);
+       virtual void updateTextures(IGameDef *gamedef,
+       /*argument: */void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress),
+       /*argument: */void *progress_callback_args);
        void serialize(std::ostream &os, u16 protocol_version);
        void deSerialize(std::istream &is);
 
@@ -715,7 +717,9 @@ void CNodeDefManager::updateAliases(IItemDefManager *idef)
 }
 
 
-void CNodeDefManager::updateTextures(IGameDef *gamedef)
+void CNodeDefManager::updateTextures(IGameDef *gamedef,
+       void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress),
+       void *progress_callback_args)
 {
 #ifndef SERVER
        infostream << "CNodeDefManager::updateTextures(): Updating "
@@ -738,7 +742,9 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef)
        bool use_normal_texture = enable_shaders &&
                (enable_bumpmapping || enable_parallax_occlusion);
 
-       for (u32 i = 0; i < m_content_features.size(); i++) {
+       u32 size = m_content_features.size();
+
+       for (u32 i = 0; i < size; i++) {
                ContentFeatures *f = &m_content_features[i];
 
                // Figure out the actual tiles to use
@@ -911,6 +917,8 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef)
                        recalculateBoundingBox(f->mesh_ptr[0]);
                        meshmanip->recalculateNormals(f->mesh_ptr[0], true, false);
                }
+
+               progress_callback(progress_callback_args, i, size);
        }
 #endif
 }
index a1c2e1b53df9227e0aac888e7140ff337c585068..bd13a7bb2af7155bd4e9442c5e1f36710f01c567 100644 (file)
@@ -378,7 +378,9 @@ public:
        /*
                Update tile textures to latest return values of TextueSource.
        */
-       virtual void updateTextures(IGameDef *gamedef)=0;
+       virtual void updateTextures(IGameDef *gamedef,
+       /*argument: */void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress),
+       /*argument: */void *progress_callback_args)=0;
 
        virtual void serialize(std::ostream &os, u16 protocol_version)=0;
        virtual void deSerialize(std::istream &is)=0;