summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2011-08-21 12:53:00 +0000
committerrubidium <rubidium@openttd.org>2011-08-21 12:53:00 +0000
commit2987bcc79be454569ff9b22eaa4731736650e19e (patch)
treeab837bfcd58dd6c8afeed182f4f6dd40df4f98d7
parent5ea6064fab18eb7281f2d4adc3ba4d961b9c3f7f (diff)
downloadopenttd-2987bcc79be454569ff9b22eaa4731736650e19e.tar.xz
(svn r22796) -Codechange: run the NewGRF scanning in a separate thread
-rw-r--r--src/newgrf_config.cpp64
1 files changed, 59 insertions, 5 deletions
diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp
index f4974c144..fae656be5 100644
--- a/src/newgrf_config.cpp
+++ b/src/newgrf_config.cpp
@@ -17,6 +17,8 @@
#include "gfx_func.h"
#include "newgrf_text.h"
#include "window_func.h"
+#include "progress.h"
+#include "thread/thread.h"
#include "fileio_func.h"
#include "fios.h"
@@ -527,7 +529,14 @@ compatible_grf:
/** Helper for scanning for files with GRF as extension */
class GRFFileScanner : FileScanner {
+ uint next_update; ///< The next (realtime tick) we do update the screen.
+ uint num_scanned; ///< The number of GRFs we have scanned.
+
public:
+ GRFFileScanner() : next_update(_realtime_tick), num_scanned(0)
+ {
+ }
+
/* virtual */ bool AddFile(const char *filename, size_t basepath_length);
/** Do the scan for GRFs. */
@@ -571,6 +580,22 @@ bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length)
added = false;
}
+ this->num_scanned++;
+ if (this->next_update <= _realtime_tick) {
+ _modal_progress_work_mutex->EndCritical();
+ _modal_progress_paint_mutex->BeginCritical();
+
+ const char *name = NULL;
+ if (c->name != NULL) name = GetGRFStringFromGRFText(c->name->text);
+ if (name == NULL) name = c->filename;
+ DEBUG(grf, 0, "Scanning %i: %s", this->num_scanned, name);
+
+ _modal_progress_work_mutex->BeginCritical();
+ _modal_progress_paint_mutex->EndCritical();
+
+ this->next_update = _realtime_tick + 200;
+ }
+
if (!added) {
/* File couldn't be opened, or is either not a NewGRF or is a
* 'system' NewGRF or it's already known, so forget about it. */
@@ -595,11 +620,20 @@ static int CDECL GRFSorter(GRFConfig * const *p1, GRFConfig * const *p2)
}
/**
- * Scan for all NewGRFs.
+ * Really perform the scan for all NewGRFs.
* @param callback The callback to call after the scanning is complete.
*/
-void ScanNewGRFFiles(NewGRFScanCallback *callback)
+void DoScanNewGRFFiles(void *callback)
{
+ /* First set the modal progress. This ensures that it will eventually let go of the paint mutex. */
+ SetModalProgress(true);
+ _modal_progress_paint_mutex->BeginCritical();
+
+ /* Only then can we really start, especially by marking the whole screen dirty. Get those other windows hidden!. */
+ MarkWholeScreenDirty();
+ _modal_progress_work_mutex->BeginCritical();
+ _modal_progress_paint_mutex->EndCritical();
+
ClearGRFConfigList(&_all_grfs);
TarScanner::DoScan();
@@ -636,12 +670,32 @@ void ScanNewGRFFiles(NewGRFScanCallback *callback)
#endif
}
+ _modal_progress_work_mutex->EndCritical();
+ _modal_progress_paint_mutex->BeginCritical();
+
/* Yes... these are the NewGRF windows */
- InvalidateWindowClassesData(WC_SAVELOAD);
- InvalidateWindowData(WC_GAME_OPTIONS, 0, GOID_NEWGRF_RESCANNED);
- if (callback != NULL) callback->OnNewGRFsScanned();
+ InvalidateWindowClassesData(WC_SAVELOAD, 0, true);
+ InvalidateWindowData(WC_GAME_OPTIONS, 0, GOID_NEWGRF_RESCANNED, true);
+ if (callback != NULL) ((NewGRFScanCallback*)callback)->OnNewGRFsScanned();
+
+ DeleteWindowByClass(WC_MODAL_PROGRESS);
+ SetModalProgress(false);
+ MarkWholeScreenDirty();
+ _modal_progress_paint_mutex->EndCritical();
}
+/**
+ * Scan for all NewGRFs.
+ * @param callback The callback to call after the scanning is complete.
+ */
+void ScanNewGRFFiles(NewGRFScanCallback *callback)
+{
+ if (!ThreadObject::New(&DoScanNewGRFFiles, callback, NULL)) {
+ _modal_progress_work_mutex->EndCritical();
+ DoScanNewGRFFiles(callback);
+ _modal_progress_work_mutex->BeginCritical();
+ }
+}
/**
* Find a NewGRF in the scanned list.