Only update the loading screen from the main thread
Fixes the crash experienced by pchote. It's a hack but it's easy to get rid of and it will have to do for now, until the messy LoadScreen gets fixed.
This commit is contained in:
@@ -31,13 +31,16 @@ namespace OpenRA
|
|||||||
readonly Dictionary<string, TileSet> tileSetCache = new Dictionary<string, TileSet>();
|
readonly Dictionary<string, TileSet> tileSetCache = new Dictionary<string, TileSet>();
|
||||||
readonly Dictionary<string, SequenceCache> sequenceCaches = new Dictionary<string, SequenceCache>();
|
readonly Dictionary<string, SequenceCache> sequenceCaches = new Dictionary<string, SequenceCache>();
|
||||||
|
|
||||||
public Action OnProgress;
|
public event EventHandler LoadingProgress;
|
||||||
|
void RaiseProgress()
|
||||||
|
{
|
||||||
|
if (LoadingProgress != null)
|
||||||
|
LoadingProgress(this, new EventArgs());
|
||||||
|
}
|
||||||
|
|
||||||
public RulesetCache(ModData modData)
|
public RulesetCache(ModData modData)
|
||||||
{
|
{
|
||||||
this.modData = modData;
|
this.modData = modData;
|
||||||
|
|
||||||
OnProgress = () => { if (modData.LoadScreen != null) modData.LoadScreen.Display(); };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Ruleset LoadDefaultRules()
|
public Ruleset LoadDefaultRules()
|
||||||
@@ -57,31 +60,23 @@ namespace OpenRA
|
|||||||
Dictionary<string, string> movies;
|
Dictionary<string, string> movies;
|
||||||
Dictionary<string, TileSet> tileSets;
|
Dictionary<string, TileSet> tileSets;
|
||||||
|
|
||||||
OnProgress();
|
|
||||||
using (new PerfTimer("Actors"))
|
using (new PerfTimer("Actors"))
|
||||||
actors = LoadYamlRules(actorCache, m.Rules, map.RuleDefinitions, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y));
|
actors = LoadYamlRules(actorCache, m.Rules, map.RuleDefinitions, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y));
|
||||||
OnProgress();
|
|
||||||
using (new PerfTimer("Weapons"))
|
using (new PerfTimer("Weapons"))
|
||||||
weapons = LoadYamlRules(weaponCache, m.Weapons, map.WeaponDefinitions, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
|
weapons = LoadYamlRules(weaponCache, m.Weapons, map.WeaponDefinitions, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
|
||||||
OnProgress();
|
|
||||||
using (new PerfTimer("Voices"))
|
using (new PerfTimer("Voices"))
|
||||||
voices = LoadYamlRules(voiceCache, m.Voices, map.VoiceDefinitions, (k, _) => new SoundInfo(k.Value));
|
voices = LoadYamlRules(voiceCache, m.Voices, map.VoiceDefinitions, (k, _) => new SoundInfo(k.Value));
|
||||||
OnProgress();
|
|
||||||
using (new PerfTimer("Notifications"))
|
using (new PerfTimer("Notifications"))
|
||||||
notifications = LoadYamlRules(notificationCache, m.Notifications, map.NotificationDefinitions, (k, _) => new SoundInfo(k.Value));
|
notifications = LoadYamlRules(notificationCache, m.Notifications, map.NotificationDefinitions, (k, _) => new SoundInfo(k.Value));
|
||||||
OnProgress();
|
|
||||||
using (new PerfTimer("Music"))
|
using (new PerfTimer("Music"))
|
||||||
music = LoadYamlRules(musicCache, m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
|
music = LoadYamlRules(musicCache, m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
|
||||||
OnProgress();
|
|
||||||
using (new PerfTimer("Movies"))
|
using (new PerfTimer("Movies"))
|
||||||
movies = LoadYamlRules(movieCache, m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
movies = LoadYamlRules(movieCache, m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
||||||
OnProgress();
|
|
||||||
using (new PerfTimer("TileSets"))
|
using (new PerfTimer("TileSets"))
|
||||||
tileSets = LoadTileSets(tileSetCache, sequenceCaches, m.TileSets);
|
tileSets = LoadTileSets(tileSetCache, sequenceCaches, m.TileSets);
|
||||||
|
|
||||||
var sequences = sequenceCaches.ToDictionary(kvp => kvp.Key, kvp => new SequenceProvider(kvp.Value, map));
|
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);
|
return new Ruleset(actors, weapons, voices, notifications, music, movies, tileSets, sequences);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +85,8 @@ namespace OpenRA
|
|||||||
string[] files, List<MiniYamlNode> nodes,
|
string[] files, List<MiniYamlNode> nodes,
|
||||||
Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f)
|
Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f)
|
||||||
{
|
{
|
||||||
|
RaiseProgress();
|
||||||
|
|
||||||
var inputKey = string.Concat(string.Join("|", files), "|", nodes.WriteToString());
|
var inputKey = string.Concat(string.Join("|", files), "|", nodes.WriteToString());
|
||||||
|
|
||||||
var mergedNodes = files
|
var mergedNodes = files
|
||||||
@@ -105,12 +102,15 @@ namespace OpenRA
|
|||||||
|
|
||||||
t = f(wkv, wyy);
|
t = f(wkv, wyy);
|
||||||
itemCache.Add(key, t);
|
itemCache.Add(key, t);
|
||||||
|
|
||||||
|
RaiseProgress();
|
||||||
return t;
|
return t;
|
||||||
};
|
};
|
||||||
|
|
||||||
var yy = mergedNodes.ToDictionary(x => x.Key, x => x.Value);
|
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);
|
var itemSet = mergedNodes.ToDictionaryWithConflictLog(kv => kv.Key.ToLowerInvariant(), kv => wrap(kv, yy), "LoadYamlRules", null, null);
|
||||||
|
|
||||||
|
RaiseProgress();
|
||||||
return itemSet;
|
return itemSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,8 @@ namespace OpenRA.Graphics
|
|||||||
Dictionary<string, CursorSequence> cursors;
|
Dictionary<string, CursorSequence> cursors;
|
||||||
Cache<string, PaletteReference> palettes;
|
Cache<string, PaletteReference> palettes;
|
||||||
|
|
||||||
public Action OnProgress;
|
|
||||||
|
|
||||||
public CursorProvider(ModData modData)
|
public CursorProvider(ModData modData)
|
||||||
{
|
{
|
||||||
OnProgress = () => { if (modData.LoadScreen != null) modData.LoadScreen.Display(); };
|
|
||||||
|
|
||||||
var sequenceFiles = modData.Manifest.Cursors;
|
var sequenceFiles = modData.Manifest.Cursors;
|
||||||
|
|
||||||
cursors = new Dictionary<string, CursorSequence>();
|
cursors = new Dictionary<string, CursorSequence>();
|
||||||
@@ -65,8 +61,6 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
void LoadSequencesForCursor(SpriteLoader loader, string cursorSrc, MiniYaml cursor)
|
void LoadSequencesForCursor(SpriteLoader loader, string cursorSrc, MiniYaml cursor)
|
||||||
{
|
{
|
||||||
OnProgress();
|
|
||||||
|
|
||||||
foreach (var sequence in cursor.Nodes)
|
foreach (var sequence in cursor.Nodes)
|
||||||
cursors.Add(sequence.Key, new CursorSequence(loader, cursorSrc, cursor.Value, sequence.Value));
|
cursors.Add(sequence.Key, new CursorSequence(loader, cursorSrc, cursor.Value, sequence.Value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,12 +68,8 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
readonly Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> sequenceCache = new Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>();
|
readonly Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> sequenceCache = new Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>();
|
||||||
|
|
||||||
public Action OnProgress;
|
|
||||||
|
|
||||||
public SequenceCache(ModData modData, TileSet tileSet)
|
public SequenceCache(ModData modData, TileSet tileSet)
|
||||||
{
|
{
|
||||||
OnProgress = () => { if (modData.LoadScreen != null) modData.LoadScreen.Display(); };
|
|
||||||
|
|
||||||
this.modData = modData;
|
this.modData = modData;
|
||||||
|
|
||||||
spriteLoader = Exts.Lazy(() => new SpriteLoader(tileSet.Extensions, new SheetBuilder(SheetType.Indexed)));
|
spriteLoader = Exts.Lazy(() => new SpriteLoader(tileSet.Extensions, new SheetBuilder(SheetType.Indexed)));
|
||||||
@@ -87,8 +83,6 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> Load(List<MiniYamlNode> sequenceNodes)
|
IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> Load(List<MiniYamlNode> sequenceNodes)
|
||||||
{
|
{
|
||||||
OnProgress();
|
|
||||||
|
|
||||||
var sequenceFiles = modData.Manifest.Sequences;
|
var sequenceFiles = modData.Manifest.Sequences;
|
||||||
|
|
||||||
var nodes = sequenceFiles
|
var nodes = sequenceFiles
|
||||||
@@ -113,8 +107,6 @@ namespace OpenRA.Graphics
|
|||||||
sequenceCache.Add(key, t);
|
sequenceCache.Add(key, t);
|
||||||
items.Add(node.Key, t);
|
items.Add(node.Key, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnProgress();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>(items);
|
return new ReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>(items);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ namespace OpenRA
|
|||||||
LoadScreen.Display();
|
LoadScreen.Display();
|
||||||
WidgetLoader = new WidgetLoader(this);
|
WidgetLoader = new WidgetLoader(this);
|
||||||
RulesetCache = new RulesetCache(this);
|
RulesetCache = new RulesetCache(this);
|
||||||
|
RulesetCache.LoadingProgress += HandleLoadingProgress;
|
||||||
MapCache = new MapCache(this);
|
MapCache = new MapCache(this);
|
||||||
|
|
||||||
// HACK: Mount only local folders so we have a half-working environment for the asset installer
|
// 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);
|
GlobalFileSystem.Mount(dir);
|
||||||
|
|
||||||
defaultRules = Exts.Lazy(() => RulesetCache.LoadDefaultRules());
|
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()
|
public void InitializeLoaders()
|
||||||
|
|||||||
Reference in New Issue
Block a user