using System; using System.IO; using Cysharp.Threading.Tasks; namespace Ubisoft.Hotel.Cache { public abstract class AbstractCacheDriver { /// /// Root folder of the cache subsystem managed by this driver (relative to CacheManager's root folder). It must not be left empty! /// public string RootFolder { get; protected set; } protected CacheSettings Settings { get; set; } protected CacheGlobalMetadata GlobalMetadata { get; set; } public bool IsEnabled { get { return Settings.IsEnabled; } } public bool IsOffline { get { return Settings.IsOffline; } } public bool IsGameVersionSensitive { get { return Settings.IsGameVersionSensitive; } } /// /// Registers the driver so that CacheManager is aware of its existance /// This allows the manager to perform some tasks globally, like invalidate all caches managed by each driver /// public async UniTask RegisterDriverAsync() { await CacheManager.GetInstance().RegisterDriverAsync(this); } /// /// Unregisters the driver from CacheManager, so it will no longer be aware of its existance /// public void UnRegisterDriver() { CacheManager.GetInstance().UnRegisterDriver(this); } /// /// Updates the game version in GlobalMetadata /// If the cache system is sensitive to game versions and major or minor differ, all caches managed by this driver are invalidated /// /// public async UniTask ApplyGameVersionAsync(string gameVersion) { if(gameVersion != GlobalMetadata.GameVersion) { CacheLogger.Channel.LogInformation($"Applying game version {gameVersion} to root folder {RootFolder}"); if (IsGameVersionSensitive) { // Invalidate data if major or minor differ Version existingVersion = new Version(GlobalMetadata.GameVersion); Version newVersion = new Version(gameVersion); if (existingVersion.Major != newVersion.Major || existingVersion.Minor != newVersion.Minor) { CacheLogger.Channel.LogInformation($"Invalidating root folder {RootFolder} due to game version mismatch: current ({GlobalMetadata.GameVersion}) != new ({gameVersion})"); InvalidateAll(); } } // Update the game version in metadata GlobalMetadata.GameVersion = gameVersion; await CacheManager.UpdateGlobalMetadataAsync(RootFolder, GlobalMetadata); } } /// /// Invalidates all caches managed by this driver /// public void InvalidateAll() { CacheManager.InvalidateAllFiles(RootFolder); } protected async UniTask InitAsync(CacheSettings settings) { if (settings == null) { CacheLogger.Channel.LogWarning("No settings were provided for this CacheDriver. Using default values (all settings to false)"); Settings = new CacheSettings() { IsEnabled = false, IsGameVersionSensitive = false, MustInvalidate = false, IsOffline = false }; } else { Settings = settings; } GlobalMetadata = await CacheManager.GetGlobalMetadataAsync(RootFolder); if (GlobalMetadata == null) { GlobalMetadata = new CacheGlobalMetadata() { GameVersion = "0.0.0" }; } if (Settings.MustInvalidate) { if (!GlobalMetadata.Invalidated || GlobalMetadata.GameVersion != CacheManager.GameVersion) { CacheLogger.Channel.LogInformation($"Forcing invalidation of root folder {RootFolder} (MustInvalidate = true)"); InvalidateAll(); // Mark cache as already invalidated to avoid doing it on every run GlobalMetadata.Invalidated = true; await CacheManager.UpdateGlobalMetadataAsync(RootFolder, GlobalMetadata); } } else if (GlobalMetadata.Invalidated) { // Reset Invalidated flag GlobalMetadata.Invalidated = false; await CacheManager.UpdateGlobalMetadataAsync(RootFolder, GlobalMetadata); } await RegisterDriverAsync(); } /// /// Returns the filepath without extension of a file relative to CacheManager's root folder /// /// /// protected string GetRelativeCacheFilepath(string filename) { return $"{RootFolder}/{Path.GetFileNameWithoutExtension(filename)}"; } } }