Created
September 20, 2022 12:43
-
-
Save codorizzi/44b4544f4f34c80ec9295e454cea9d9e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using Utilities.GameSettings; | |
namespace Framework.Map { | |
public class BuildingTypes : GameSetting<BuildingTypes, BuildingTypes.DataModel> { | |
#region Sub Classes / Enums | |
// requires static enum to be defined | |
public enum IdTypes { | |
Market = 0, | |
Hovel = 1, | |
} | |
// requires a data model to be defined, default values can be initialized here | |
public class DataModel : SettingModel { | |
[JsonProperty] public int Capacity = 2; | |
} | |
#endregion | |
#region Construction | |
protected override void Initialize() { | |
base.Initialize(typeof(IdTypes)); | |
} | |
#endregion | |
#region Static Methods | |
// these are optional | |
public static DataModel GetByType(IdTypes idTypes) { | |
return GetById(idTypes.ToString(), true); | |
} | |
public static DataModel GetByType(string name) { | |
return GetByName(name, true); | |
} | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using Newtonsoft.Json; | |
using UnityEngine; | |
namespace Utilities.GameSettings { | |
public abstract class GameSetting<TGameSetting, TDataModel> | |
where TGameSetting : GameSetting<TGameSetting, TDataModel>, new() | |
where TDataModel : SettingModel { | |
#region Exceptions | |
[Serializable] | |
class AmbiguousMatch : Exception { | |
public AmbiguousMatch() { } | |
public AmbiguousMatch(string message) : base(message) { } | |
} | |
#endregion | |
#region Static Properties | |
private static TGameSetting _instance; | |
// ReSharper disable once StaticMemberInGenericType | |
private static string _path = string.Empty; | |
public static TGameSetting Instance { | |
get { | |
_instance ??= DeserializeSettings(); | |
return _instance; | |
} | |
} | |
#endregion | |
#region Public Properties | |
[JsonProperty] public Dictionary<string, SettingModel> Data { get; protected set; } | |
#endregion | |
#region Abstract Methods | |
protected abstract void Initialize(); | |
/// <summary> | |
/// Initializes the settings. | |
/// </summary> | |
/// <param name="enumType">Type Enum</param> | |
/// <typeparam name="TDataModel">Setting Model</typeparam> | |
protected virtual void Initialize(Type enumType) { | |
Data ??= new Dictionary<string, SettingModel>(); | |
// for each enum value, create a new setting model | |
foreach (var value in Enum.GetValues(enumType)) { | |
int id = (int) value; | |
string name = value.ToString(); | |
SettingModel model = Activator.CreateInstance<TDataModel>(); | |
model.Id = id.ToString(); | |
model.Name = name; | |
Data.Add(name, model); | |
} | |
} | |
#endregion | |
#region Serialization | |
protected static TGameSetting DeserializeSettings() { | |
string path = GetPath(); | |
string json = File.ReadAllText(path); | |
TGameSetting settings = null; | |
try { | |
settings = JsonConvert.DeserializeObject<TGameSetting>(json, new JsonSerializerSettings() { | |
TypeNameHandling = TypeNameHandling.Auto | |
}); | |
} catch (JsonSerializationException) { } | |
if (settings != null) return settings; | |
// create new TGameSetting | |
settings = new TGameSetting(); | |
settings.Initialize(); | |
settings.SerializeSettings(); | |
return settings; | |
} | |
public void SerializeSettings() { | |
string path = GetPath(); | |
string json = JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { | |
TypeNameHandling = TypeNameHandling.Auto | |
}); | |
File.WriteAllText(path, json); | |
} | |
public static void Serialize() { | |
Instance.SerializeSettings(); | |
} | |
#endregion | |
#region Access Methods | |
public static TDataModel GetById(string id, bool exact=false) { | |
if (exact) { | |
if(Instance.Data.ContainsKey(id)) return (TDataModel)Instance.Data[id]; | |
} else { | |
List<string> matches = Instance.Data.Keys.ToList().FindAll(key => key == id).ToList(); | |
switch (matches.Count) { | |
case > 1: | |
throw new AmbiguousMatch($"Multiple matches found for id: {id}"); | |
case 1: | |
return (TDataModel)Instance.Data[matches[0]]; | |
} | |
} | |
throw new Exception($"No matching id found for: {id}"); | |
} | |
public static TDataModel GetByName(string name, bool exact=false) { | |
if (exact) { | |
return (TDataModel)Instance.Data.Values.First(x => x.Name == name); | |
} | |
List<SettingModel> matches = Instance.Data.Values.ToList().FindAll(key => key.Name.Contains(name)).ToList(); | |
switch (matches.Count) { | |
case > 1: | |
throw new AmbiguousMatch($"Multiple matches found for name: {name}"); | |
case 1: | |
return (TDataModel)matches[0]; | |
} | |
throw new Exception($"No matching name found for: {name}"); | |
} | |
#endregion | |
#region Private Methods | |
private static string GetPath() { | |
if(_path != string.Empty) return _path; | |
string path = $"{Application.streamingAssetsPath}/json/{typeof(TGameSetting).Name}.json"; | |
if (!Directory.Exists(Path.GetDirectoryName(path))) { | |
string directory = Path.GetDirectoryName(path); | |
if(directory != null) | |
Directory.CreateDirectory(directory); | |
} | |
if (!File.Exists(path)) { | |
using (FileStream fs = File.Create(path)) { | |
fs.Close(); | |
} | |
} | |
return path; | |
} | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
namespace Utilities.GameSettings { | |
public abstract class SettingModel { | |
[JsonProperty] public string Id; | |
[JsonProperty] public string Name; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some test code that shows accessing the data.