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)}";
}
}
}