Skip to content

Commit

Permalink
updated SaveValue
Browse files Browse the repository at this point in the history
  • Loading branch information
BadRyuner committed Dec 9, 2022
1 parent 81ee146 commit de748e7
Showing 1 changed file with 48 additions and 39 deletions.
87 changes: 48 additions & 39 deletions PulsarModLoader/SaveValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,35 @@
using System.IO;
using System.Reflection;
using Valve.Newtonsoft.Json;
using Valve.Newtonsoft.Json.Linq;

namespace PulsarModLoader
{
[HarmonyPatch]
internal class SaveValueManager
{
[HarmonyPostfix]
[HarmonyPatch(typeof(PLGlobal), "OnApplicationQuit")]
private static void ForceSaveAllConfigsOnApplicationQuit()
{
PulsarModLoader.Utilities.Logger.Info("OnApplicationQuit");
foreach(object saveValue in AllSaveValues)
{
var type = saveValue.GetType();
var id = (string)AccessTools.Field(type, "id").GetValue(saveValue);
var mod = (Assembly)AccessTools.Field(type, "mod").GetValue(saveValue);
var value = AccessTools.Field(type, "_value").GetValue(saveValue);
ModToCacheValues[mod][id] = JToken.FromObject(value);
}

foreach(KeyValuePair<Assembly, JObject> keyValuePair in ModToCacheValues)
{
Assembly mod = keyValuePair.Key;
var cfg = GetConfigFile(mod);
File.WriteAllText(cfg, JsonConvert.SerializeObject(ModToCacheValues[mod], serializerSettings));
}
}

public static string GetConfigFolder()
{
string ModConfigDir = Path.Combine(Directory.GetCurrentDirectory(), "ModConfigs");
Expand All @@ -26,37 +50,26 @@ static SaveValueManager()
serializerSettings.Formatting = Formatting.Indented;
}

internal static void SaveValueFor(string id, Assembly mod, string value)
internal static T GetValueFor<T>(SaveValue<T> saveValue, T @default)
{
ModToCacheValues[mod][id] = value;
var cfg = GetConfigFile(mod);
File.WriteAllText(cfg, JsonConvert.SerializeObject(ModToCacheValues[mod], serializerSettings));
}
AllSaveValues.Add(saveValue);

internal static T GetValueFor<T>(string id, Assembly mod, T @default)
{
var cfg = GetConfigFile(mod);
if (ModToCacheValues.TryGetValue(mod, out var values))
var cfg = GetConfigFile(saveValue.mod); // Trying to open a config (Read | create a new one | take it from the cache)

if (ModToCacheValues.TryGetValue(saveValue.mod, out JObject values)) // try to access the processed configuration
{
if (values.TryGetValue(id, out var ret))
{
if (@default is Enum)
return (T)Enum.Parse(typeof(T), ret);

return (T)AccessTools.Method(@default.GetType(), "Parse", new Type[] { typeof(string) })
.Invoke(null, new[] { ret });
}
if (values.TryGetValue(saveValue.id, out JToken value)) // If it contains our field
return value.ToObject<T>(); // then parse and return
// otherwise add a default value to values and return it
}
else
else // If there is no such thing
{
ModToCacheValues.Add(mod, new Dictionary<string, string>());
ModToCacheValues[mod].Add(id, @default.ToString());
File.WriteAllText(cfg, JsonConvert.SerializeObject(ModToCacheValues[mod], serializerSettings));
return @default;
ModToCacheValues.Add(saveValue.mod, new JObject()); // create an empty config
}

ModToCacheValues[mod].Add(id, @default.ToString());
return @default;
ModToCacheValues[saveValue.mod].Add(saveValue.id, JToken.FromObject(@default)); // add the missing value
File.WriteAllText(cfg, JsonConvert.SerializeObject(ModToCacheValues[saveValue.mod], serializerSettings)); // save file
return @default; // return default
}

private static string GetConfigFile(Assembly mod)
Expand All @@ -65,45 +78,41 @@ private static string GetConfigFile(Assembly mod)
string newFile = Path.Combine(GetConfigFolder(), mod.GetName().Name + ".json");
ModToConfigFile.Add(mod, newFile);
if (!ModToCacheValues.ContainsKey(mod) && File.Exists(newFile))
ModToCacheValues.Add(mod, JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(newFile)));
ModToCacheValues.Add(mod, JObject.Parse(File.ReadAllText(newFile)));
return newFile;
}

private static Dictionary<Assembly, string> ModToConfigFile = new Dictionary<Assembly, string>();

private static Dictionary<Assembly, Dictionary<string, string>> ModToCacheValues =
new Dictionary<Assembly, Dictionary<string, string>>();
private static Dictionary<Assembly, JObject> ModToCacheValues =
new Dictionary<Assembly, JObject>();

private static List<object> AllSaveValues = new List<object>();
}

public class SaveValue<T> : IEquatable<T>
{
public SaveValue(string id, T @defualt)
public SaveValue(string id, T @default)
{
this.id = id;
this.mod = Assembly.GetCallingAssembly();
_value = SaveValueManager.GetValueFor(id, mod, @defualt);
_value = SaveValueManager.GetValueFor<T>(this, @default);
}

private string id;
private Assembly mod;
internal string id;
internal Assembly mod;

private T _value;
internal T _value;

public T Value
{
get => _value;
set
{
if (!_value.Equals(value)) SetValue(value);
_value = value;
}
}

private void SetValue(T newValue)
{
_value = newValue;
SaveValueManager.SaveValueFor(id, mod, newValue.ToString());
}

public static implicit operator T(SaveValue<T> v) => v._value;

public override bool Equals(object obj) => _value.Equals(obj);
Expand Down

0 comments on commit de748e7

Please sign in to comment.