Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.IO;
- using System.Runtime.Serialization.Formatters.Binary;
- using UnityEngine;
- using ParnassianStudios.General.Collections;
- namespace ParnassianStudios.General.Project
- {
- /// <summary>
- /// A singleton-like database for game preferences.
- /// </summary>
- [CreateAssetMenu(fileName = "LocalPrefs", menuName = "Local Prefs")]
- public class LocalPrefs : ScriptableObject, ISerializationCallbackReceiver
- {
- /// <summary>
- /// The local path to the runtime LocalPrefs, from PersistentDataStorage.
- /// </summary>
- public const string PATH_LOCAL = "LocalPrefs.sd";
- /// <summary>
- /// The short path to the default LocalPrefs database, from Resources
- /// </summary>
- public const string PATH_DEFAULT = "LocalPrefs";
- /// <summary>
- /// The full path to the default LocalPrefs database, from Assets
- /// </summary>
- public const string PATH_DEFAULT_FULL = @"Assets/Resources/LocalPrefs.asset";
- // self-singleton reference
- private static LocalPrefs _instance;
- public static LocalPrefs instance
- {
- get
- {
- if (_instance == null)
- {
- // first try loading from the local file, if we're not in the editor
- if (!Application.isEditor)
- {
- _instance = LoadPrefsFromFile(Application.persistentDataPath + PATH_LOCAL);
- }
- // if still null, load the default database instead
- if (_instance == null)
- {
- _instance = Resources.Load<LocalPrefs>(PATH_DEFAULT);
- if (_instance == null)
- _instance = ScriptableObject.CreateInstance<LocalPrefs>();
- _instance._dirty = true;
- }
- }
- return _instance;
- }
- }
- // contains unsaved changes
- private bool _dirty = false;
- // string-keyed collections
- [SerializeField]
- private List<StringStringKVP> _stringKeyedStrings;
- [SerializeField]
- private List<StringIntKVP> _stringKeyedInts;
- [SerializeField]
- private List<StringFloatKVP> _stringKeyedFloats;
- [SerializeField]
- private List<StringBoolKVP> _stringKeyedBools;
- // string-keyed lookups
- [System.NonSerialized]
- private Dictionary<string, string> _stringKeyedStringsLookup;
- [System.NonSerialized]
- private Dictionary<string, int> _stringKeyedIntsLookup;
- [System.NonSerialized]
- private Dictionary<string, float> _stringKeyedFloatsLookup;
- [System.NonSerialized]
- private Dictionary<string, bool> _stringKeyedBoolsLookup;
- // int-keyed collections
- [SerializeField]
- private List<IntStringKVP> _intKeyedStrings;
- [SerializeField]
- private List<IntIntKVP> _intKeyedInts;
- [SerializeField]
- private List<IntFloatKVP> _intKeyedFloats;
- [SerializeField]
- private List<IntBoolKVP> _intKeyedBools;
- // int-keyed lookups
- [System.NonSerialized]
- private Dictionary<int, string> _intKeyedStringsLookup;
- [System.NonSerialized]
- private Dictionary<int, int> _intKeyedIntsLookup;
- [System.NonSerialized]
- private Dictionary<int, float> _intKeyedFloatsLookup;
- [System.NonSerialized]
- private Dictionary<int, bool> _intKeyedBoolsLookup;
- // gets called whenever the object is serialized in the editor
- void ISerializationCallbackReceiver.OnBeforeSerialize() { }
- // gets called whenever the object is deserialized in the editor
- void ISerializationCallbackReceiver.OnAfterDeserialize()
- {
- InitializeAllLookups();
- }
- // gets called at runtime just before the scene loads
- [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
- private static void RuntimeInitializeOnLoad()
- {
- instance.InitializeAllLookups();
- }
- /// <summary>
- /// Will initialize all of the lookup tables in the class. Because these are not
- /// serialized by the Unity serialization system, they need to be reconstructed
- /// whenever the data arrays are changed- this is the reason for both the
- /// serialization callback and runtime initialization method above.
- /// </summary>
- private void InitializeAllLookups()
- {
- InitializeLookup(ref _stringKeyedStringsLookup, _stringKeyedStrings.CastList<StringStringKVP, KVP<string, string>>());
- InitializeLookup(ref _stringKeyedIntsLookup, _stringKeyedInts.CastList<StringIntKVP, KVP<string, int>>());
- InitializeLookup(ref _stringKeyedFloatsLookup, _stringKeyedFloats.CastList<StringFloatKVP, KVP<string, float>>());
- InitializeLookup(ref _stringKeyedBoolsLookup, _stringKeyedBools.CastList<StringBoolKVP, KVP<string, bool>>());
- InitializeLookup(ref _intKeyedStringsLookup, _intKeyedStrings.CastList<IntStringKVP, KVP<int, string>>());
- InitializeLookup(ref _intKeyedIntsLookup, _intKeyedInts.CastList<IntIntKVP, KVP<int, int>>());
- InitializeLookup(ref _intKeyedFloatsLookup, _intKeyedFloats.CastList<IntFloatKVP, KVP<int, float>>());
- InitializeLookup(ref _intKeyedBoolsLookup, _intKeyedBools.CastList<IntBoolKVP, KVP<int, bool>>());
- }
- /// <summary>
- /// Initializes the String-keyed lookup table.
- /// </summary>
- private void InitializeLookup<T1, T2>(ref Dictionary<T1, T2> lookup, IList<KVP<T1, T2>> list)
- {
- if (lookup == null)
- lookup = new Dictionary<T1, T2>();
- else
- lookup.Clear();
- for (int i = 0; i < list.Count; i++)
- lookup[list[i].Key] = list[i].Value;
- }
- /// <summary>
- /// Returns a bool indicating that the key exists in the database.
- /// </summary>
- public static bool HasString(string key)
- {
- return instance._stringKeyedStringsLookup.ContainsKey(key);
- }
- /// <summary>
- /// Returns a bool indicating that the key exists in the database.
- /// </summary>
- public static bool HasString(int key)
- {
- return instance._intKeyedStringsLookup.ContainsKey(key);
- }
- /// <summary>
- /// Returns the string stored for the given key, if any.
- /// </summary>
- public static string GetString(string key)
- {
- if (instance._stringKeyedStringsLookup.ContainsKey(key))
- return instance._stringKeyedStringsLookup[key];
- return default(string);
- }
- /// <summary>
- /// Returns the string stored for the given key, if any.
- /// </summary>
- public static string GetString(int key)
- {
- if (instance._intKeyedStringsLookup.ContainsKey(key))
- return instance._intKeyedStringsLookup[key];
- return default(string);
- }
- /// <summary>
- /// Sets the string value to the given key.
- /// </summary>
- public static void SetString(string key, string value)
- {
- var kvp = instance._stringKeyedStrings.FirstOrDefault(t => t.Key.Equals(key));
- if (kvp != null)
- {
- if (kvp.Value != value)
- {
- kvp.Value = value;
- instance._dirty = true;
- }
- }
- else
- {
- instance._stringKeyedStrings.Add(new StringStringKVP(key, value));
- instance._dirty = true;
- }
- instance._stringKeyedStringsLookup[key] = value;
- }
- /// <summary>
- /// Sets the string value to the given key.
- /// </summary>
- public static void SetString(int key, string value)
- {
- var kvp = instance._intKeyedStrings.FirstOrDefault(t => t.Key.Equals(key));
- if (kvp != null)
- {
- if (kvp.Value != value)
- {
- kvp.Value = value;
- instance._dirty = true;
- }
- }
- else
- {
- instance._intKeyedStrings.Add(new IntStringKVP(key, value));
- instance._dirty = true;
- }
- instance._intKeyedStringsLookup[key] = value;
- }
- /// <summary>
- /// Returns a bool indicating that the key exists in the database.
- /// </summary>
- public static bool HasInt(string key)
- {
- return instance._stringKeyedIntsLookup.ContainsKey(key);
- }
- /// <summary>
- /// Returns a bool indicating that the key exists in the database.
- /// </summary>
- public static bool HasInt(int key)
- {
- return instance._intKeyedIntsLookup.ContainsKey(key);
- }
- /// <summary>
- /// Returns the int stored for the given key, if any.
- /// </summary>
- public static int GetInt(string key)
- {
- if (instance._stringKeyedIntsLookup.ContainsKey(key))
- return instance._stringKeyedIntsLookup[key];
- return default(int);
- }
- /// <summary>
- /// Returns the int stored for the given key, if any.
- /// </summary>
- public static int GetInt(int key)
- {
- if (instance._intKeyedIntsLookup.ContainsKey(key))
- return instance._intKeyedIntsLookup[key];
- return default(int);
- }
- /// <summary>
- /// Sets the int value to the given key.
- /// </summary>
- public static void SetInt(string key, int value)
- {
- var kvp = instance._stringKeyedInts.FirstOrDefault(t => t.Key.Equals(key));
- if (kvp != null)
- {
- if (kvp.Value != value)
- {
- kvp.Value = value;
- instance._dirty = true;
- }
- }
- else
- {
- instance._stringKeyedInts.Add(new StringIntKVP(key, value));
- instance._dirty = true;
- }
- instance._stringKeyedIntsLookup[key] = value;
- }
- /// <summary>
- /// Sets the int value to the given key.
- /// </summary>
- public static void SetInt(int key, int value)
- {
- var kvp = instance._intKeyedInts.FirstOrDefault(t => t.Key.Equals(key));
- if (kvp != null)
- {
- if (kvp.Value != value)
- {
- kvp.Value = value;
- instance._dirty = true;
- }
- }
- else
- {
- instance._intKeyedInts.Add(new IntIntKVP(key, value));
- instance._dirty = true;
- }
- instance._intKeyedIntsLookup[key] = value;
- }
- /// <summary>
- /// Returns a bool indicating that the key exists in the database.
- /// </summary>
- public static bool HasFloat(string key)
- {
- return instance._stringKeyedFloatsLookup.ContainsKey(key);
- }
- /// <summary>
- /// Returns a bool indicating that the key exists in the database.
- /// </summary>
- public static bool HasFloat(int key)
- {
- return instance._intKeyedFloatsLookup.ContainsKey(key);
- }
- /// <summary>
- /// Returns the float stored for the given key, if any.
- /// </summary>
- public static float GetFloat(string key)
- {
- if (instance._stringKeyedFloatsLookup.ContainsKey(key))
- return instance._stringKeyedFloatsLookup[key];
- return default(float);
- }
- /// <summary>
- /// Returns the float stored for the given key, if any.
- /// </summary>
- public static float GetFloat(int key)
- {
- if (instance._intKeyedFloatsLookup.ContainsKey(key))
- return instance._intKeyedFloatsLookup[key];
- return default(float);
- }
- /// <summary>
- /// Sets the float value to the given key.
- /// </summary>
- public static void SetFloat(string key, float value)
- {
- var kvp = instance._stringKeyedFloats.FirstOrDefault(t => t.Key.Equals(key));
- if (kvp != null)
- {
- if (kvp.Value != value)
- {
- kvp.Value = value;
- instance._dirty = true;
- }
- }
- else
- {
- instance._stringKeyedFloats.Add(new StringFloatKVP(key, value));
- instance._dirty = true;
- }
- instance._stringKeyedFloatsLookup[key] = value;
- }
- /// <summary>
- /// Sets the float value to the given key.
- /// </summary>
- public static void SetFloat(int key, float value)
- {
- var kvp = instance._intKeyedFloats.FirstOrDefault(t => t.Key.Equals(key));
- if (kvp != null)
- {
- if (kvp.Value != value)
- {
- kvp.Value = value;
- instance._dirty = true;
- }
- }
- else
- {
- instance._intKeyedFloats.Add(new IntFloatKVP(key, value));
- instance._dirty = true;
- }
- instance._intKeyedFloatsLookup[key] = value;
- }
- /// <summary>
- /// Returns a bool indicating that the key exists in the database.
- /// </summary>
- public static bool HasBool(string key)
- {
- return instance._stringKeyedBoolsLookup.ContainsKey(key);
- }
- /// <summary>
- /// Returns a bool indicating that the key exists in the database.
- /// </summary>
- public static bool HasBool(int key)
- {
- return instance._intKeyedBoolsLookup.ContainsKey(key);
- }
- /// <summary>
- /// Returns the bool stored for the given key, if any.
- /// </summary>
- public static bool GetBool(string key)
- {
- if (instance._stringKeyedBoolsLookup.ContainsKey(key))
- return instance._stringKeyedBoolsLookup[key];
- return default(bool);
- }
- /// <summary>
- /// Returns the bool stored for the given key, if any.
- /// </summary>
- public static bool GetBool(int key)
- {
- if (instance._intKeyedBoolsLookup.ContainsKey(key))
- return instance._intKeyedBoolsLookup[key];
- return default(bool);
- }
- /// <summary>
- /// Sets the bool value to the given key.
- /// </summary>
- public static void SetBool(string key, bool value)
- {
- var kvp = instance._stringKeyedBools.FirstOrDefault(t => t.Key.Equals(key));
- if (kvp != null)
- {
- if (kvp.Value != value)
- {
- kvp.Value = value;
- instance._dirty = true;
- }
- }
- else
- {
- instance._stringKeyedBools.Add(new StringBoolKVP(key, value));
- instance._dirty = true;
- }
- instance._stringKeyedBoolsLookup[key] = value;
- }
- /// <summary>
- /// Sets the bool value to the given key.
- /// </summary>
- public static void SetBool(int key, bool value)
- {
- var kvp = instance._intKeyedBools.FirstOrDefault(t => t.Key.Equals(key));
- if (kvp != null)
- {
- if (kvp.Value != value)
- {
- kvp.Value = value;
- instance._dirty = true;
- }
- }
- else
- {
- instance._intKeyedBools.Add(new IntBoolKVP(key, value));
- instance._dirty = true;
- }
- instance._intKeyedBoolsLookup[key] = value;
- }
- /// <summary>
- /// Loads LocalPrefs from a file location and returns it.
- /// </summary>
- public static LocalPrefs LoadPrefsFromFile(string path)
- {
- try
- {
- byte[] byteArray = File.ReadAllBytes(path);
- BinaryFormatter bf = new BinaryFormatter();
- using (MemoryStream ms = new MemoryStream(byteArray))
- {
- return (LocalPrefs)bf.Deserialize(ms);
- }
- }
- catch
- {
- }
- return null;
- }
- /// <summary>
- /// Saves LocalPrefs to a file location.
- /// </summary>
- public static void SavePrefsToFile(LocalPrefs prefsToSave, string path)
- {
- if (prefsToSave._dirty)
- {
- try
- {
- BinaryFormatter bf = new BinaryFormatter();
- using (MemoryStream ms = new MemoryStream())
- {
- bf.Serialize(ms, prefsToSave);
- byte[] byteArray = ms.ToArray();
- using (var file = File.Open(path, FileMode.Create))
- {
- var binary = new BinaryWriter(file);
- binary.Write(prefsToSave);
- }
- }
- }
- catch
- {
- }
- prefsToSave._dirty = false;
- }
- }
- // this garbage is required for serializing the lists properly, because reasons
- [System.Serializable]
- private class StringStringKVP : KVP<string, string>
- {
- public StringStringKVP(string key, string value)
- : base(key, value) { }
- }
- [System.Serializable]
- private class StringIntKVP : KVP<string, int>
- {
- public StringIntKVP(string key, int value)
- : base(key, value) { }
- }
- [System.Serializable]
- private class StringFloatKVP : KVP<string, float>
- {
- public StringFloatKVP(string key, float value)
- : base(key, value) { }
- }
- [System.Serializable]
- private class StringBoolKVP : KVP<string, bool>
- {
- public StringBoolKVP(string key, bool value)
- : base(key, value) { }
- }
- [System.Serializable]
- private class IntStringKVP : KVP<int, string>
- {
- public IntStringKVP(int key, string value)
- : base(key, value) { }
- }
- [System.Serializable]
- private class IntIntKVP : KVP<int, int>
- {
- public IntIntKVP(int key, int value)
- : base(key, value) { }
- }
- [System.Serializable]
- private class IntFloatKVP : KVP<int, float>
- {
- public IntFloatKVP(int key, float value)
- : base(key, value) { }
- }
- [System.Serializable]
- private class IntBoolKVP : KVP<int, bool>
- {
- public IntBoolKVP(int key, bool value)
- : base(key, value) { }
- }
- /// <summary>
- /// Base "KeyValuePair" serializable class for prefs collections
- /// </summary>
- [System.Serializable]
- private class KVP<T1, T2> : System.IEquatable<KVP<T1, T2>>
- {
- public T1 Key;
- public T2 Value;
- public KVP(T1 key, T2 value)
- {
- this.Key = key;
- this.Value = value;
- }
- public override int GetHashCode()
- {
- unchecked { return Key.GetHashCode() + Value.GetHashCode(); }
- }
- public override bool Equals(object obj)
- {
- if (typeof(KVP<T1, T2>).IsAssignableFrom(obj.GetType()))
- return this.Equals((KVP<T1, T2>)obj);
- return false;
- }
- public bool Equals(KVP<T1, T2> other)
- {
- return Key.Equals(other.Key) && Value.Equals(other.Value);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment