Skip to content

Commit f28d4ef

Browse files
committed
minor optimizations in watcher code
1 parent b8d1760 commit f28d4ef

4 files changed

Lines changed: 49 additions & 4 deletions

File tree

docs/release-notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* For players:
66
* The installer now deletes obsolete files from very old SMAPI versions again. (This was removed in SMAPI 4.0, but many players still had very old versions.)
77
* The installer now deletes Error Handler automatically if it's at the default path.
8+
* Minor optimizations.
89
* Updated mod compatibility list.
910

1011
* For mod authors:

src/SMAPI/Framework/StateTracking/ChestTracker.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ public void Update()
7474
public void Reset()
7575
{
7676
// update stack sizes
77-
foreach (Item item in this.StackSizes.Keys.ToArray().Concat(this.Added))
77+
foreach (Item item in this.StackSizes.Keys)
78+
this.StackSizes[item] = item.Stack;
79+
foreach (Item item in this.Added)
7880
this.StackSizes[item] = item.Stack;
7981

8082
// update watcher

src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Collections.Generic;
2-
using System.Linq;
32
using StardewModdingAPI.Framework.StateTracking.Comparers;
43
using StardewValley;
54

@@ -14,6 +13,9 @@ internal class WorldLocationsSnapshot
1413
/// <summary>A map of tracked locations.</summary>
1514
private readonly Dictionary<GameLocation, LocationSnapshot> LocationsDict = new(new ObjectReferenceComparer<GameLocation>());
1615

16+
/// <summary>The pooled list instance for <see cref="GetMissingLocations"/>.</summary>
17+
private static readonly List<GameLocation> PooledMissingLocations = new();
18+
1719

1820
/*********
1921
** Accessors
@@ -36,7 +38,7 @@ public void Update(WorldLocationsTracker watcher)
3638
this.LocationList.Update(watcher.IsLocationListChanged, watcher.Added, watcher.Removed);
3739

3840
// remove missing locations
39-
foreach (var key in this.LocationsDict.Keys.Where(key => !watcher.HasLocationTracker(key)).ToArray())
41+
foreach (var key in this.GetMissingLocations(watcher))
4042
this.LocationsDict.Remove(key);
4143

4244
// update locations
@@ -48,5 +50,26 @@ public void Update(WorldLocationsTracker watcher)
4850
snapshot.Update(locationWatcher);
4951
}
5052
}
53+
54+
55+
/*********
56+
** Private methods
57+
*********/
58+
/// <summary>Get the watched locations which no longer exist in the world, if any.</summary>
59+
/// <param name="watcher">The location list tracker.</param>
60+
private List<GameLocation> GetMissingLocations(WorldLocationsTracker watcher)
61+
{
62+
List<GameLocation> list = WorldLocationsSnapshot.PooledMissingLocations;
63+
if (list.Count > 0)
64+
list.Clear();
65+
66+
foreach (GameLocation location in this.LocationsDict.Keys)
67+
{
68+
if (!watcher.HasLocationTracker(location))
69+
list.Add(location);
70+
}
71+
72+
return list;
73+
}
5174
}
5275
}

src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ internal class WorldLocationsTracker : IWatcher
3030
/// <summary>A lookup of registered buildings and their indoor location.</summary>
3131
private readonly Dictionary<Building, GameLocation?> BuildingIndoors = new(new ObjectReferenceComparer<Building>());
3232

33+
/// <summary>The pooled list instance for <see cref="GetLocationsWhoseBuildingsChanged"/>.</summary>
34+
private static readonly List<LocationTracker> PooledLocationsWithBuildingsChanged = new();
35+
3336

3437
/*********
3538
** Accessors
@@ -95,7 +98,7 @@ public void Update()
9598
}
9699

97100
// detect building changed
98-
foreach (LocationTracker watcher in this.Locations.Where(p => p.BuildingsWatcher.IsChanged).ToArray())
101+
foreach (LocationTracker watcher in this.GetLocationsWhoseBuildingsChanged())
99102
{
100103
this.Remove(watcher.BuildingsWatcher.Removed);
101104
this.Add(watcher.BuildingsWatcher.Added);
@@ -261,5 +264,21 @@ private IEnumerable<IWatcher> GetWatchers()
261264
foreach (LocationTracker watcher in this.Locations)
262265
yield return watcher;
263266
}
267+
268+
/// <summary>Get the locations whose building list changed, if any.</summary>
269+
private List<LocationTracker> GetLocationsWhoseBuildingsChanged()
270+
{
271+
List<LocationTracker> list = WorldLocationsTracker.PooledLocationsWithBuildingsChanged;
272+
if (list.Count > 0)
273+
list.Clear();
274+
275+
foreach (LocationTracker watcher in this.LocationDict.Values)
276+
{
277+
if (watcher.IsChanged)
278+
list.Add(watcher);
279+
}
280+
281+
return list;
282+
}
264283
}
265284
}

0 commit comments

Comments
 (0)