using System;
using Dalamud;
using Dalamud.Logging;
using Dalamud.Plugin;
namespace Penumbra.GameData.Data;
///
/// A container base class that shares data through Dalamud but cares about the used language and version.
/// Inheritors should dispose their Dalamud Shares in DisposeInternal via DisposeTag and add them in their constructor via TryCatchData.
///
public abstract class DataSharer : IDisposable
{
protected readonly DalamudPluginInterface PluginInterface;
protected readonly int Version;
protected readonly ClientLanguage Language;
private bool _disposed;
protected DataSharer(DalamudPluginInterface pluginInterface, ClientLanguage language, int version)
{
PluginInterface = pluginInterface;
Language = language;
Version = version;
}
protected virtual void DisposeInternal()
{ }
public void Dispose()
{
if (_disposed)
return;
DisposeInternal();
GC.SuppressFinalize(this);
_disposed = true;
}
~DataSharer()
=> Dispose();
protected void DisposeTag(string tag)
=> PluginInterface.RelinquishData(GetVersionedTag(tag, Language, Version));
protected T TryCatchData(string tag, Func func) where T : class
{
try
{
return PluginInterface.GetOrCreateData(GetVersionedTag(tag, Language, Version), func);
}
catch (Exception ex)
{
PluginLog.Error($"Error creating shared actor data for {tag}:\n{ex}");
return func();
}
}
public static void DisposeTag(DalamudPluginInterface pi, string tag, ClientLanguage language, int version)
=> pi.RelinquishData(GetVersionedTag(tag, language, version));
public static T TryCatchData(DalamudPluginInterface pi, string tag, ClientLanguage language, int version, Func func)
where T : class
{
try
{
return pi.GetOrCreateData(GetVersionedTag(tag, language, version), func);
}
catch (Exception ex)
{
PluginLog.Error($"Error creating shared actor data for {tag}:\n{ex}");
return func();
}
}
private static string GetVersionedTag(string tag, ClientLanguage language, int version)
=> $"Penumbra.GameData.{tag}.{language}.V{version}";
}