Add plugin json storage

This commit is contained in:
Jack251970 2025-04-01 14:16:32 +08:00
parent 0e4e95a1b2
commit 24327533c6
4 changed files with 65 additions and 19 deletions

View file

@ -37,6 +37,7 @@ namespace Flow.Launcher.Infrastructure.Image
_hashGenerator = new ImageHashGenerator();
var usage = await LoadStorageToConcurrentDictionaryAsync();
_storage.ClearData();
ImageCache.Initialize(usage);

View file

@ -4,6 +4,8 @@ using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using MemoryPack;
#nullable enable
namespace Flow.Launcher.Infrastructure.Storage
{
/// <summary>
@ -15,40 +17,53 @@ namespace Flow.Launcher.Infrastructure.Storage
/// </remarks>
public class BinaryStorage<T>
{
protected T? Data;
public const string FileSuffix = ".cache";
// Let the derived class to set the file path
public BinaryStorage(string filename, string directoryPath = null)
{
directoryPath ??= DataLocation.CacheDirectory;
Helper.ValidateDirectory(directoryPath);
protected string FilePath { get; init; } = null!;
FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
protected string DirectoryPath { get; init; } = null!;
// Let the derived class to set the file path
protected BinaryStorage()
{
}
public string FilePath { get; }
public BinaryStorage(string filename)
{
DirectoryPath = DataLocation.CacheDirectory;
Helper.ValidateDirectory(DirectoryPath);
FilePath = Path.Combine(DirectoryPath, $"{filename}{FileSuffix}");
}
public async ValueTask<T> TryLoadAsync(T defaultData)
{
if (Data != null)
return Data;
if (File.Exists(FilePath))
{
if (new FileInfo(FilePath).Length == 0)
{
Log.Error($"|BinaryStorage.TryLoad|Zero length cache file <{FilePath}>");
await SaveAsync(defaultData);
return defaultData;
Data = defaultData;
await SaveAsync();
}
await using var stream = new FileStream(FilePath, FileMode.Open);
var d = await DeserializeAsync(stream, defaultData);
return d;
Data = d;
}
else
{
Log.Info("|BinaryStorage.TryLoad|Cache file not exist, load default data");
await SaveAsync(defaultData);
return defaultData;
Data = defaultData;
await SaveAsync();
}
return Data;
}
private static async ValueTask<T> DeserializeAsync(Stream stream, T defaultData)
@ -56,7 +71,7 @@ namespace Flow.Launcher.Infrastructure.Storage
try
{
var t = await MemoryPackSerializer.DeserializeAsync<T>(stream);
return t;
return t ?? defaultData;
}
catch (System.Exception)
{
@ -65,6 +80,27 @@ namespace Flow.Launcher.Infrastructure.Storage
}
}
public async ValueTask SaveAsync()
{
await using var stream = new FileStream(FilePath, FileMode.Create);
await MemoryPackSerializer.SerializeAsync(stream, Data);
}
// For SavePluginSettings function
public void Save()
{
var serialized = MemoryPackSerializer.Serialize(Data);
File.WriteAllBytes(FilePath, serialized);
}
// ImageCache need to be converted into concurrent dictionary, so it does not need to cache loading results into Data
public void ClearData()
{
Data = default;
}
// ImageCache storages data in its class, so it needs to pass it to SaveAsync
public async ValueTask SaveAsync(T data)
{
await using var stream = new FileStream(FilePath, FileMode.Create);

View file

@ -0,0 +1,15 @@
using System.IO;
namespace Flow.Launcher.Infrastructure.Storage
{
public class PluginBinaryStorage<T> : BinaryStorage<T> where T : new()
{
public PluginBinaryStorage(string cacheName, string cacheDirectory)
{
DirectoryPath = cacheDirectory;
Helper.ValidateDirectory(DirectoryPath);
FilePath = Path.Combine(DirectoryPath, $"{cacheName}{FileSuffix}");
}
}
}

View file

@ -10,7 +10,6 @@ namespace Flow.Launcher.Infrastructure.Storage
public PluginJsonStorage()
{
// C# related, add python related below
var dataType = typeof(T);
AssemblyName = dataType.Assembly.GetName().Name;
DirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, AssemblyName);
@ -18,10 +17,5 @@ namespace Flow.Launcher.Infrastructure.Storage
FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}");
}
public PluginJsonStorage(T data) : this()
{
Data = data;
}
}
}