Skip to content

Commit

Permalink
Add caching to improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
urbanyeti committed Dec 9, 2021
1 parent 54630a6 commit 0e4fdc1
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 22 deletions.
1 change: 1 addition & 0 deletions BetterFriendship/BetterFriendship/BetterFriendship.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="4.0.0" />
<PackageReference Include="System.Runtime.Caching" Version="5.0.0" />
</ItemGroup>

</Project>
18 changes: 17 additions & 1 deletion BetterFriendship/BetterFriendship/GameExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,23 @@ public static bool IsTownsfolk(this NPC npc)
&& npc is not TrashBear;
}

public static IEnumerable<(Object, int)> TakeTopPrioritized(this IEnumerable<(Object item, int taste)> items,
public static List<(Object, int)> GetTopGiftSuggestions(this NPC npc, ModConfig config)
{
return
Game1.player.Items.Where(x => x is Object)
.Select(x => (item: x as Object, taste: npc.getGiftTasteForThisItem(x)))
.Where(x => config.GiftPreference switch
{
"love" => x.taste is 0,
"like" => x.taste is 0 or 2,
"neutral" => x.taste is not 4 or 6,
_ => false
})
.TakeTopPrioritized(config)
.ToList();
}

private static IEnumerable<(Object, int)> TakeTopPrioritized(this IEnumerable<(Object item, int taste)> items,
ModConfig config)
{
if (config.OnlyHighestQuality)
Expand Down
54 changes: 48 additions & 6 deletions BetterFriendship/BetterFriendship/ModConfig.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,55 @@
namespace BetterFriendship
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace BetterFriendship
{
internal class ModConfig
internal class ModConfig : INotifyPropertyChanged
{
public bool DisplayTalkPrompts { get; set; } = true;
public string GiftPreference { get; set; } = "like";
public int GiftCycleCount { get; set; } = 5;
public int GiftCycleDelay { get; set; } = 2000;
public bool IgnoreMaxedFriendships { get; set; } = false;
public bool OnlyHighestQuality { get; set; } = false;
public bool DisplayBubbles { get; set; } = true;
public bool Debug { get; set; } = false;

private string _giftPreference = "like";
private int _giftCycleCount = 5;
private bool _onlyHighestQuality;

public string GiftPreference
{
get => _giftPreference;
set
{
_giftPreference = value;
OnPropertyChanged();
}
}

public int GiftCycleCount
{
get => _giftCycleCount;
set
{
_giftCycleCount = value;
OnPropertyChanged();
}
}

public bool OnlyHighestQuality
{
get => _onlyHighestQuality;
set
{
_onlyHighestQuality = value;
OnPropertyChanged();
}
}

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
58 changes: 45 additions & 13 deletions BetterFriendship/BetterFriendship/ModEntry.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Characters;
using Object = StardewValley.Object;
using System.Runtime.Caching;
using System.ComponentModel;

namespace BetterFriendship
{
Expand All @@ -11,6 +16,7 @@ public class ModEntry : Mod
{
private ModConfig Config { get; set; }
private BubbleDrawer BubbleDrawer { get; set; }
private readonly ObjectCache _cache = MemoryCache.Default;

/*********
** Public methods
Expand All @@ -25,6 +31,8 @@ public override void Entry(IModHelper helper)
helper.Events.GameLoop.GameLaunched += OnGameLaunched;
helper.Events.Input.ButtonPressed += OnButtonPressed;
helper.Events.Display.RenderedWorld += OnRenderedWorld;
helper.Events.Player.InventoryChanged += OnInventoryChanged;
Config.PropertyChanged += OnConfigChanged;
}

/// <summary>
Expand All @@ -46,7 +54,7 @@ private void OnGameLaunched(object sender, GameLaunchedEventArgs e)
/// <summary>Raised after the player presses a button on the keyboard, controller, or mouse.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private static void OnButtonPressed(object sender, ButtonPressedEventArgs e)
private void OnButtonPressed(object sender, ButtonPressedEventArgs e)
{
// ignore if player hasn't loaded a save yet
if (!Context.IsWorldReady)
Expand Down Expand Up @@ -81,17 +89,18 @@ npc is Child ||
continue;
}

var bestItems = Game1.player.Items.Where(x => x is Object)
.Select(x => (item: x as Object, taste: npc.getGiftTasteForThisItem(x)))
.Where(x => Config.GiftPreference switch
{
"love" => x.taste is 0,
"like" => x.taste is 0 or 2,
"neutral" => x.taste is not 4 or 6,
_ => false
})
.TakeTopPrioritized(Config)
.ToList();
List<(Object, int)> bestItems;

if (_cache.Contains(npc.Name))
{
bestItems = _cache.Get(npc.Name) as List<(Object, int)>;
}
else
{
bestItems = npc.GetTopGiftSuggestions(Config);
_cache.Add(new CacheItem(npc.Name, bestItems),
new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(5) });
}

BubbleDrawer.DrawBubble(Game1.spriteBatch, npc, bestItems,
true,
Expand All @@ -109,6 +118,20 @@ private static bool FriendshipCanDecay(NPC npc, Friendship friendship)
return (!isPreBouquet && friendship.Points < 2500) || (isPreBouquet && friendship.Points < 2000);
}


private void OnConfigChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName is not (nameof(ModConfig.GiftPreference) or nameof(ModConfig.GiftCycleCount)
or nameof(ModConfig.OnlyHighestQuality))) return;

foreach (var key in _cache.Select(x => x.Key)) _cache.Remove(key);
}

private void OnInventoryChanged(object sender, InventoryChangedEventArgs e)
{
foreach (var key in _cache.Select(x => x.Key)) _cache.Remove(key);
}

private void SetupConfigMenu(IGenericModConfigMenuApi configMenu)
{
configMenu.Register(
Expand Down Expand Up @@ -191,6 +214,15 @@ private void SetupConfigMenu(IGenericModConfigMenuApi configMenu)
getValue: () => Config.DisplayBubbles,
setValue: value => Config.DisplayBubbles = value
);

configMenu.AddBoolOption(
ModManifest,
name: () => "[!] Debug",
tooltip: () =>
"Debug",
getValue: () => Config.Debug,
setValue: value => Config.Debug = value
);
}
}
}
5 changes: 3 additions & 2 deletions BetterFriendship/BetterFriendship/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
"DisplayTalkPrompt": true,
"GiftPreference": "like",
"GiftCycleCount": 5,
"GiftCycleDelay": 2000,
"GiftCycleDelay": 150000,
"IgnoreMaxedFriendships": false,
"OnlyHighestQuality": false,
"DisplayBubbles": true
"DisplayBubbles": true,
"Debug" : false
}

0 comments on commit 0e4fdc1

Please sign in to comment.