adspartan: asyncloader: change async loader to regular pointer

f9b25e888c
This commit is contained in:
T1ti
2024-08-26 03:22:37 +02:00
parent 56aab6b7c0
commit 63b92869e0
8 changed files with 35 additions and 18 deletions

View File

@@ -9,6 +9,14 @@
#include <algorithm> #include <algorithm>
#include <list> #include <list>
AsyncLoader* AsyncLoader::instance;
void AsyncLoader::setup(int threads)
{
// make sure there's always at least one thread otherwise nothing can load
instance = new AsyncLoader(std::max(1, threads));
}
bool AsyncLoader::is_loading() bool AsyncLoader::is_loading()
{ {
std::lock_guard<std::mutex> const lock (_guard); std::lock_guard<std::mutex> const lock (_guard);
@@ -146,8 +154,8 @@ AsyncLoader::AsyncLoader(int numThreads)
: _stop (false) : _stop (false)
{ {
// use half of the available threads // use half of the available threads
unsigned int maxThreads = std::thread::hardware_concurrency() / 2; // unsigned int maxThreads = std::thread::hardware_concurrency() / 2;
numThreads = maxThreads > numThreads ? maxThreads : numThreads; // numThreads = maxThreads > numThreads ? maxThreads : numThreads;
for (int i = 0; i < numThreads; ++i) for (int i = 0; i < numThreads; ++i)
{ {

View File

@@ -14,11 +14,17 @@
class AsyncLoader class AsyncLoader
{ {
public: public:
static AsyncLoader& instance() // static AsyncLoader& instance()
{ // {
static AsyncLoader async_loader(2); // static AsyncLoader async_loader(3);
return async_loader; // return async_loader;
} // }
// use regular pointer because unique_ptr was causing
// a significant performance hit
static AsyncLoader* instance;
static void setup(int threads);
//! Ownership is _not_ transferred. Call ensure_deletable to ensure //! Ownership is _not_ transferred. Call ensure_deletable to ensure
//! that a previously enqueued object can be destroyed. //! that a previously enqueued object can be destroyed.

View File

@@ -70,7 +70,7 @@ namespace Noggit
}() }()
); );
AsyncLoader::instance().queue_for_load(static_cast<AsyncObject*>(obj)); AsyncLoader::instance->queue_for_load(static_cast<AsyncObject*>(obj));
return obj; return obj;
} }
@@ -95,7 +95,7 @@ namespace Noggit
// always make sure an async object can be deleted before deleting it // always make sure an async object can be deleted before deleting it
if (!obj->finishedLoading()) if (!obj->finishedLoading())
{ {
AsyncLoader::instance().ensure_deletable(obj); AsyncLoader::instance->ensure_deletable(obj);
} }
{ {

View File

@@ -3711,7 +3711,7 @@ MapView::~MapView()
_world.reset(); _world.reset();
AsyncLoader::instance().reset_object_fail(); AsyncLoader::instance->reset_object_fail();
Noggit::Ui::selected_texture::texture.reset(); Noggit::Ui::selected_texture::texture.reset();
@@ -5800,7 +5800,7 @@ void MapView::save(save_mode mode)
// Save minimap creator model filters // Save minimap creator model filters
minimapTool->saveFiltersToJSON(); minimapTool->saveFiltersToJSON();
if (AsyncLoader::instance().important_object_failed_loading()) if (AsyncLoader::instance->important_object_failed_loading())
{ {
save = false; save = false;
QPushButton *yes, *no; QPushButton *yes, *no;
@@ -5873,7 +5873,7 @@ void MapView::save(save_mode mode)
NOGGIT_ACTION_MGR->purge(); NOGGIT_ACTION_MGR->purge();
AsyncLoader::instance().reset_object_fail(); AsyncLoader::instance->reset_object_fail();
_main_window->statusBar()->showMessage("Map saved", 2000); _main_window->statusBar()->showMessage("Map saved", 2000);

View File

@@ -204,6 +204,9 @@ namespace Noggit::Application
//All of the below should be Project Initalisation //All of the below should be Project Initalisation
srand(::time(nullptr)); srand(::time(nullptr));
// TODO : thread count setting
// AsyncLoader::setup(NoggitSettings.value("async_thread_count", 3).toInt());
AsyncLoader::setup(3);
} }
std::shared_ptr<Noggit::Application::NoggitApplicationConfiguration> NoggitApplication::getConfiguration() std::shared_ptr<Noggit::Application::NoggitApplicationConfiguration> NoggitApplication::getConfiguration()

View File

@@ -384,7 +384,7 @@ MapTile* MapIndex::loadTile(const TileIndex& tile, bool reloading, bool load_mod
MapTile* adt = mTiles[tile.z][tile.x].tile.get(); MapTile* adt = mTiles[tile.z][tile.x].tile.get();
AsyncLoader::instance().queue_for_load(adt); AsyncLoader::instance->queue_for_load(adt);
_n_loaded_tiles++; _n_loaded_tiles++;
return adt; return adt;
@@ -437,7 +437,7 @@ void MapIndex::unloadTile(const TileIndex& tile)
// otherwise it can be deleted before the log because it comes from the adt itself (see unloadTiles) // otherwise it can be deleted before the log because it comes from the adt itself (see unloadTiles)
Log << "Unloading Tile " << tile.x << "-" << tile.z << std::endl; Log << "Unloading Tile " << tile.x << "-" << tile.z << std::endl;
AsyncLoader::instance().ensure_deletable(mTiles[tile.z][tile.x].tile.get()); AsyncLoader::instance->ensure_deletable(mTiles[tile.z][tile.x].tile.get());
mTiles[tile.z][tile.x].tile.reset(); mTiles[tile.z][tile.x].tile.reset();
_n_loaded_tiles--; _n_loaded_tiles--;
} }

View File

@@ -1701,7 +1701,7 @@ bool WorldRender::saveMinimap(TileIndex const& tile_idx, MinimapRenderSettings*
unsigned counter = 0; unsigned counter = 0;
constexpr unsigned TIMEOUT = 5000; constexpr unsigned TIMEOUT = 5000;
while (AsyncLoader::instance().is_loading() || !mTile->finishedLoading()) while (AsyncLoader::instance->is_loading() || !mTile->finishedLoading())
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
counter++; counter++;

View File

@@ -436,15 +436,15 @@ QPixmap* PreviewRenderer::renderToPixmap()
tick(1.0f); tick(1.0f);
draw(); draw();
auto& async_loader = AsyncLoader::instance(); auto async_loader = AsyncLoader::instance;
if (async_loader.is_loading()) if (async_loader->is_loading())
{ {
// wait for the loader to finish // wait for the loader to finish
do do
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
} while (async_loader.is_loading()); } while (async_loader->is_loading());
// redraw // redraw
gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);