From 79f3fcccebf7eee70821854cffa7b719cfba2d1a Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 11 Feb 2011 21:35:37 +1300 Subject: [PATCH] Lazy actor loading --- OpenRA.Editor/ActorTool.cs | 6 ++-- OpenRA.Editor/LegacyMapImporter.cs | 10 ++++--- OpenRA.Editor/Surface.cs | 8 +++--- OpenRA.Game/Map.cs | 45 ++++++++++++++++++------------ OpenRA.Mods.RA/SpawnMapActors.cs | 2 +- 5 files changed, 41 insertions(+), 30 deletions(-) diff --git a/OpenRA.Editor/ActorTool.cs b/OpenRA.Editor/ActorTool.cs index 751d7302c7..5c17b2ff78 100644 --- a/OpenRA.Editor/ActorTool.cs +++ b/OpenRA.Editor/ActorTool.cs @@ -30,12 +30,12 @@ namespace OpenRA.Editor public void Apply(Surface surface) { - if (surface.Map.Actors.Any(a => a.Value.Location() == surface.GetBrushLocation())) + if (surface.Map.Actors.Value.Any(a => a.Value.Location() == surface.GetBrushLocation())) return; var owner = "Neutral"; var id = NextActorName(surface); - surface.Map.Actors[id] = new ActorReference(Actor.Info.Name.ToLowerInvariant()) + surface.Map.Actors.Value[id] = new ActorReference(Actor.Info.Name.ToLowerInvariant()) { new LocationInit( surface.GetBrushLocation() ), new OwnerInit( owner) @@ -48,7 +48,7 @@ namespace OpenRA.Editor for (; ; ) { var possible = "Actor{0}".F(id++); - if (!surface.Map.Actors.ContainsKey(possible)) return possible; + if (!surface.Map.Actors.Value.ContainsKey(possible)) return possible; } } } diff --git a/OpenRA.Editor/LegacyMapImporter.cs b/OpenRA.Editor/LegacyMapImporter.cs index fc1ab8c7c8..f1995648fe 100644 --- a/OpenRA.Editor/LegacyMapImporter.cs +++ b/OpenRA.Editor/LegacyMapImporter.cs @@ -148,12 +148,12 @@ namespace OpenRA.Editor ReadCncOverlay(file); ReadCncTrees(file); } - */ + LoadActors(file, "STRUCTURES"); LoadActors(file, "UNITS"); LoadActors(file, "INFANTRY"); LoadSmudges(file, "SMUDGE"); - + */ foreach (var p in Players) LoadPlayer(file, p, (legacyMapFormat == IniMapFormat.RedAlert)); @@ -163,6 +163,7 @@ namespace OpenRA.Editor LocationFromMapOffset(int.Parse(kv.Value), MapSize))) .ToArray(); + /* // Add waypoint actors foreach( var kv in wps ) { @@ -170,6 +171,7 @@ namespace OpenRA.Editor a.Add(new LocationInit(kv.Second)); Map.Actors.Add("spawn" + kv.First, a); } + */ } static int2 LocationFromMapOffset(int offset, int mapSize) @@ -341,7 +343,7 @@ namespace OpenRA.Editor }); } } - */ + void ReadCncTrees(IniFile file) { IniSection terrain = file.GetSection("TERRAIN", true); @@ -417,7 +419,7 @@ namespace OpenRA.Editor } } - + */ void LoadSmudges(IniFile file, string section) { foreach (var s in file.GetSection(section, true)) diff --git a/OpenRA.Editor/Surface.cs b/OpenRA.Editor/Surface.cs index 4ba29f8263..e87067a4cd 100755 --- a/OpenRA.Editor/Surface.cs +++ b/OpenRA.Editor/Surface.cs @@ -152,8 +152,8 @@ namespace OpenRA.Editor Tool = null; - var key = Map.Actors.FirstOrDefault(a => a.Value.Location() == BrushLocation); - if (key.Key != null) Map.Actors.Remove(key.Key); + var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == BrushLocation); + if (key.Key != null) Map.Actors.Value.Remove(key.Key); if (Map.MapResources.Value[BrushLocation.X, BrushLocation.Y].type != 0) { @@ -338,7 +338,7 @@ namespace OpenRA.Editor Map.Bounds.Width * TileSet.TileSize * Zoom, Map.Bounds.Height * TileSet.TileSize * Zoom); - foreach (var ar in Map.Actors) + foreach (var ar in Map.Actors.Value) DrawActor(e.Graphics, ar.Value.Location(), ActorTemplates[ar.Value.Type], GetPaletteForActor(ar.Value)); @@ -347,7 +347,7 @@ namespace OpenRA.Editor if (Tool == null) { - var x = Map.Actors.FirstOrDefault(a => a.Value.Location() == GetBrushLocation()); + var x = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == GetBrushLocation()); if (x.Key != null) DrawActorBorder(e.Graphics, x.Value.Location(), ActorTemplates[x.Value.Type]); } diff --git a/OpenRA.Game/Map.cs b/OpenRA.Game/Map.cs index fff055989b..463cbb12b1 100644 --- a/OpenRA.Game/Map.cs +++ b/OpenRA.Game/Map.cs @@ -38,10 +38,10 @@ namespace OpenRA [FieldLoader.Load] public string Author; [FieldLoader.Load] public string Tileset; - public Dictionary Actors = new Dictionary(); + public Lazy> Actors; public int PlayerCount { get { return SpawnPoints.Count(); } } - public IEnumerable SpawnPoints { get { return Actors.Values.Where(a => a.Type == "mpspawn").Select(a => a.InitDict.Get().value); } } + public IEnumerable SpawnPoints { get { return Actors.Value.Values.Where(a => a.Type == "mpspawn").Select(a => a.InitDict.Get().value); } } [FieldLoader.Load] public Rectangle Bounds; @@ -90,7 +90,8 @@ namespace OpenRA { { new TileReference { type = tile.Key, index = (byte)0 } - } }) + } }), + Actors = Lazy.New(() => new Dictionary()) }; return map; @@ -120,11 +121,28 @@ namespace OpenRA if (MapFormat < 4) throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); - // Load actors - foreach (var kv in yaml.NodesDict["Actors"].NodesDict) - Actors.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.NodesDict)); - + Actors = Lazy.New(() => + { + var ret = new Dictionary(); + // Load actors + foreach (var kv in yaml.NodesDict["Actors"].NodesDict) + ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.NodesDict)); + + // Add waypoint actors + + if (MapFormat < 5) + foreach( var wp in yaml.NodesDict[ "Waypoints" ].NodesDict ) + { + string[] loc = wp.Value.Value.Split( ',' ); + var a = new ActorReference("mpspawn"); + a.Add(new LocationInit(new int2( int.Parse( loc[ 0 ] ), int.Parse( loc[ 1 ] ) ))); + ret.Add(wp.Key, a); + } + + return ret; + }); + // Load players foreach (var kv in yaml.NodesDict["Players"].NodesDict) { @@ -137,16 +155,7 @@ namespace OpenRA { // Define RequiresMod for map installer RequiresMod = Game.CurrentMods.Keys.First(); - - // Add waypoint actors - foreach( var wp in yaml.NodesDict[ "Waypoints" ].NodesDict ) - { - string[] loc = wp.Value.Value.Split( ',' ); - var a = new ActorReference("mpspawn"); - a.Add(new LocationInit(new int2( int.Parse( loc[ 0 ] ), int.Parse( loc[ 1 ] ) ))); - Actors.Add(wp.Key, a); - } - + var TopLeft = (int2)FieldLoader.GetValue( "", typeof(int2), yaml.NodesDict["TopLeft"].Value); var BottomRight = (int2)FieldLoader.GetValue( "", typeof(int2), yaml.NodesDict["BottomRight"].Value); Bounds = Rectangle.FromLTRB(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y); @@ -241,7 +250,7 @@ namespace OpenRA FieldSaver.Save( p.Value ) ) ).ToList() ) ); root.Add( new MiniYamlNode( "Actors", null, - Actors.Select( x => new MiniYamlNode( + Actors.Value.Select( x => new MiniYamlNode( x.Key, x.Value.Save() ) ).ToList() ) ); diff --git a/OpenRA.Mods.RA/SpawnMapActors.cs b/OpenRA.Mods.RA/SpawnMapActors.cs index 4eaf36f67d..5b5343146d 100644 --- a/OpenRA.Mods.RA/SpawnMapActors.cs +++ b/OpenRA.Mods.RA/SpawnMapActors.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA public void WorldLoaded(World world) { - foreach (var actorReference in world.Map.Actors) + foreach (var actorReference in world.Map.Actors.Value) { var initDict = actorReference.Value.InitDict; initDict.Add(new SkipMakeAnimsInit());