From 4faa92e05a549f9988ac4a2ac5f55a418365dbb0 Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 15 Jan 2025 14:24:12 +0000 Subject: [PATCH] Implemented `ItemBaseCacheService` --- Core/Services/ItemBaseClassService.cs | 99 +++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 6 deletions(-) diff --git a/Core/Services/ItemBaseClassService.cs b/Core/Services/ItemBaseClassService.cs index d5f52823..7219edd1 100644 --- a/Core/Services/ItemBaseClassService.cs +++ b/Core/Services/ItemBaseClassService.cs @@ -1,18 +1,51 @@ -using Core.Annotations; +using Core.Annotations; using Core.Models.Eft.Common.Tables; +using ILogger = Core.Models.Utils.ILogger; namespace Core.Services; [Injectable(InjectionType.Singleton)] public class ItemBaseClassService { + private readonly ILogger _logger; + private readonly DatabaseService _databaseService; + private readonly LocalisationService _localisationService; + + private bool _cacheGenerated; + private Dictionary> _itemBaseClassesCache; + + public ItemBaseClassService( + ILogger logger, + DatabaseService databaseService, + LocalisationService localisationService) + { + _logger = logger; + _databaseService = databaseService; + _localisationService = localisationService; + } + /** * Create cache and store inside ItemBaseClassService * Store a dict of an items tpl to the base classes it and its parents have */ public void HydrateItemBaseClassCache() { - throw new NotImplementedException(); + // Clear existing cache + _itemBaseClassesCache = new Dictionary>(); + + var items = _databaseService.GetItems(); + var filteredDbItems = (items).Where((x) => x.Value.Type == "Item"); + foreach (var item in filteredDbItems) { + var itemIdToUpdate = item.Value.Id; + if (!_itemBaseClassesCache.ContainsKey(item.Value.Id)) + { + _itemBaseClassesCache[item.Value.Id] = []; + } + + AddBaseItems(itemIdToUpdate, item.Value); + } + + _cacheGenerated = true; } /** @@ -22,7 +55,13 @@ public class ItemBaseClassService */ protected void AddBaseItems(string itemIdToUpdate, TemplateItem item) { - throw new NotImplementedException(); + _itemBaseClassesCache[itemIdToUpdate].Add(item.Parent); + var parent = _databaseService.GetItems()[item.Parent]; + + if (parent.Parent != "") + { + AddBaseItems(itemIdToUpdate, parent); + } } /** @@ -33,7 +72,45 @@ public class ItemBaseClassService */ public bool ItemHasBaseClass(string itemTpl, List baseClasses) { - throw new NotImplementedException(); + if (!_cacheGenerated) + { + HydrateItemBaseClassCache(); + } + + if (itemTpl is null) + { + _logger.Warning("Unable to check itemTpl base class as value passed is null"); + + return false; + } + + // The cache is only generated for item templates with `_type === "Item"`, so return false for any other type, + // including item templates that simply don't exist. + if (!CachedItemIsOfItemType(itemTpl)) + { + return false; + } + + // No item in cache + if (_itemBaseClassesCache.ContainsKey(itemTpl)) + { + return _itemBaseClassesCache[itemTpl].Any(baseClasses.Contains); + } + + _logger.Debug(_localisationService.GetText("baseclass-item_not_found", itemTpl)); + + // Not found in cache, Hydrate again - some mods add items late + HydrateItemBaseClassCache(); + + // Check for item again, return false if item not found a second time + if (_itemBaseClassesCache.ContainsKey(itemTpl)) + { + return _itemBaseClassesCache[itemTpl].Any(baseClasses.Contains); + } + + _logger.Warning(_localisationService.GetText("baseclass-item_not_found_failed", itemTpl)); + + return false; } /** @@ -43,7 +120,7 @@ public class ItemBaseClassService */ private bool CachedItemIsOfItemType(string itemTemplateId) { - throw new NotImplementedException(); + return _databaseService.GetItems()[itemTemplateId]?.Type == "Item"; } /** @@ -53,6 +130,16 @@ public class ItemBaseClassService */ public List GetItemBaseClasses(string itemTpl) { - throw new NotImplementedException(); + if (!_cacheGenerated) + { + HydrateItemBaseClassCache(); + } + + if (!_itemBaseClassesCache.ContainsKey(itemTpl)) + { + return []; + } + + return _itemBaseClassesCache[itemTpl]; } }