diff --git a/OpenRA.Game/GameRules/RulesetCache.cs b/OpenRA.Game/GameRules/RulesetCache.cs index c119e1c6c4..5c5d37d113 100755 --- a/OpenRA.Game/GameRules/RulesetCache.cs +++ b/OpenRA.Game/GameRules/RulesetCache.cs @@ -31,13 +31,16 @@ namespace OpenRA readonly Dictionary tileSetCache = new Dictionary(); readonly Dictionary sequenceCaches = new Dictionary(); - public Action OnProgress; + public event EventHandler LoadingProgress; + void RaiseProgress() + { + if (LoadingProgress != null) + LoadingProgress(this, new EventArgs()); + } public RulesetCache(ModData modData) { this.modData = modData; - - OnProgress = () => { if (modData.LoadScreen != null) modData.LoadScreen.Display(); }; } public Ruleset LoadDefaultRules() @@ -57,31 +60,23 @@ namespace OpenRA Dictionary movies; Dictionary tileSets; - OnProgress(); using (new PerfTimer("Actors")) actors = LoadYamlRules(actorCache, m.Rules, map.RuleDefinitions, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); - OnProgress(); using (new PerfTimer("Weapons")) weapons = LoadYamlRules(weaponCache, m.Weapons, map.WeaponDefinitions, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value)); - OnProgress(); using (new PerfTimer("Voices")) voices = LoadYamlRules(voiceCache, m.Voices, map.VoiceDefinitions, (k, _) => new SoundInfo(k.Value)); - OnProgress(); using (new PerfTimer("Notifications")) notifications = LoadYamlRules(notificationCache, m.Notifications, map.NotificationDefinitions, (k, _) => new SoundInfo(k.Value)); - OnProgress(); using (new PerfTimer("Music")) music = LoadYamlRules(musicCache, m.Music, new List(), (k, _) => new MusicInfo(k.Key, k.Value)); - OnProgress(); using (new PerfTimer("Movies")) movies = LoadYamlRules(movieCache, m.Movies, new List(), (k, v) => k.Value.Value); - OnProgress(); using (new PerfTimer("TileSets")) tileSets = LoadTileSets(tileSetCache, sequenceCaches, m.TileSets); var sequences = sequenceCaches.ToDictionary(kvp => kvp.Key, kvp => new SequenceProvider(kvp.Value, map)); - OnProgress(); return new Ruleset(actors, weapons, voices, notifications, music, movies, tileSets, sequences); } @@ -90,6 +85,8 @@ namespace OpenRA string[] files, List nodes, Func, T> f) { + RaiseProgress(); + var inputKey = string.Concat(string.Join("|", files), "|", nodes.WriteToString()); var mergedNodes = files @@ -105,12 +102,15 @@ namespace OpenRA t = f(wkv, wyy); itemCache.Add(key, t); + + RaiseProgress(); return t; }; var yy = mergedNodes.ToDictionary(x => x.Key, x => x.Value); var itemSet = mergedNodes.ToDictionaryWithConflictLog(kv => kv.Key.ToLowerInvariant(), kv => wrap(kv, yy), "LoadYamlRules", null, null); + RaiseProgress(); return itemSet; } diff --git a/OpenRA.Game/Graphics/CursorProvider.cs b/OpenRA.Game/Graphics/CursorProvider.cs index f5313905df..9c00994f49 100644 --- a/OpenRA.Game/Graphics/CursorProvider.cs +++ b/OpenRA.Game/Graphics/CursorProvider.cs @@ -22,12 +22,8 @@ namespace OpenRA.Graphics Dictionary cursors; Cache palettes; - public Action OnProgress; - public CursorProvider(ModData modData) { - OnProgress = () => { if (modData.LoadScreen != null) modData.LoadScreen.Display(); }; - var sequenceFiles = modData.Manifest.Cursors; cursors = new Dictionary(); @@ -65,8 +61,6 @@ namespace OpenRA.Graphics void LoadSequencesForCursor(SpriteLoader loader, string cursorSrc, MiniYaml cursor) { - OnProgress(); - foreach (var sequence in cursor.Nodes) cursors.Add(sequence.Key, new CursorSequence(loader, cursorSrc, cursor.Value, sequence.Value)); } diff --git a/OpenRA.Game/Graphics/SequenceProvider.cs b/OpenRA.Game/Graphics/SequenceProvider.cs index f250216dbf..73ee8ef1ac 100644 --- a/OpenRA.Game/Graphics/SequenceProvider.cs +++ b/OpenRA.Game/Graphics/SequenceProvider.cs @@ -68,12 +68,8 @@ namespace OpenRA.Graphics readonly Dictionary>> sequenceCache = new Dictionary>>(); - public Action OnProgress; - public SequenceCache(ModData modData, TileSet tileSet) { - OnProgress = () => { if (modData.LoadScreen != null) modData.LoadScreen.Display(); }; - this.modData = modData; spriteLoader = Exts.Lazy(() => new SpriteLoader(tileSet.Extensions, new SheetBuilder(SheetType.Indexed))); @@ -87,8 +83,6 @@ namespace OpenRA.Graphics IReadOnlyDictionary>> Load(List sequenceNodes) { - OnProgress(); - var sequenceFiles = modData.Manifest.Sequences; var nodes = sequenceFiles @@ -113,8 +107,6 @@ namespace OpenRA.Graphics sequenceCache.Add(key, t); items.Add(node.Key, t); } - - OnProgress(); } return new ReadOnlyDictionary>>(items); diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index cb9ba5cf91..4ad17eaaf7 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -42,6 +42,7 @@ namespace OpenRA LoadScreen.Display(); WidgetLoader = new WidgetLoader(this); RulesetCache = new RulesetCache(this); + RulesetCache.LoadingProgress += HandleLoadingProgress; MapCache = new MapCache(this); // HACK: Mount only local folders so we have a half-working environment for the asset installer @@ -50,6 +51,16 @@ namespace OpenRA GlobalFileSystem.Mount(dir); defaultRules = Exts.Lazy(() => RulesetCache.LoadDefaultRules()); + + initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; + } + + // HACK: Only update the loading screen if we're in the main thread. + int initialThreadId; + void HandleLoadingProgress(object sender, EventArgs e) + { + if (LoadScreen != null && System.Threading.Thread.CurrentThread.ManagedThreadId == initialThreadId) + LoadScreen.Display(); } public void InitializeLoaders()