using System; using System.Collections.Generic; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace PepperDash.Core.JsonToSimpl { /// /// Abstract base class for JsonToSimpl interactions /// public abstract class JsonToSimplMaster : IKeyed { /// /// Notifies of bool change /// public event EventHandler BoolChange; /// /// Notifies of ushort change /// public event EventHandler UshrtChange; /// /// Notifies of string change /// public event EventHandler StringChange; /// /// A collection of associated child modules /// protected List Children = new List(); /*****************************************************************************************/ /// /// Mirrors the Unique ID for now. /// public string Key { get { return UniqueID; } } /// /// A unique ID /// public string UniqueID { get; protected set; } /// /// Merely for use in debug messages /// public string DebugName { get { return _DebugName; } set { if (DebugName == null) _DebugName = ""; else _DebugName = value; } } string _DebugName = ""; /// /// This will be prepended to all paths to allow path swapping or for more organized /// sub-paths /// public string PathPrefix { get; set; } /// /// This is added to the end of all paths /// public string PathSuffix { get; set; } /// /// Enables debugging output to the console. Certain error messages will be logged to the /// system's error log regardless of this setting /// public bool DebugOn { get; set; } /// /// Ushort helper for Debug property /// public ushort UDebug { get { return (ushort)(DebugOn ? 1 : 0); } set { DebugOn = (value == 1); CrestronConsole.PrintLine("JsonToSimpl debug={0}", DebugOn); } } /// /// /// public JObject JsonObject { get; protected set; } /*****************************************************************************************/ /** Privates **/ // The JSON file in JObject form // For gathering the incoming data protected Dictionary UnsavedValues = new Dictionary(); /*****************************************************************************************/ /// /// SIMPL+ default constructor. /// public JsonToSimplMaster() { } /// /// Sets up class - overriding methods should always call this. /// /// public virtual void Initialize(string uniqueId) { UniqueID = uniqueId; J2SGlobal.AddMaster(this); // Should not re-add } /// /// Adds a child "module" to this master /// /// public void AddChild(JsonToSimplChildObjectBase child) { if (!Children.Contains(child)) { Children.Add(child); } } /// /// Called from the child to add changed or new values for saving /// public void AddUnsavedValue(string path, JValue value) { if (UnsavedValues.ContainsKey(path)) { Debug.Console(0, "Master[{0}] WARNING - Attempt to add duplicate value for path '{1}'.\r Ingoring. Please ensure that path does not exist on multiple modules.", UniqueID, path); } else UnsavedValues.Add(path, value); //Debug.Console(0, "Master[{0}] Unsaved size={1}", UniqueID, UnsavedValues.Count); } /// /// Saves the file /// public abstract void Save(); /// /// /// public static class JsonFixes { /// /// Deserializes a string into a JObject /// /// /// public static JObject ParseObject(string json) { using (var reader = new JsonTextReader(new StringReader(json))) { var startDepth = reader.Depth; var obj = JObject.Load(reader); if (startDepth != reader.Depth) throw new JsonSerializationException("Unenclosed json found"); return obj; } } /// /// Deserializes a string into a JArray /// /// /// public static JArray ParseArray(string json) { using (var reader = new JsonTextReader(new StringReader(json))) { var startDepth = reader.Depth; var obj = JArray.Load(reader); if (startDepth != reader.Depth) throw new JsonSerializationException("Unenclosed json found"); return obj; } } } /// /// Helper event /// /// /// /// protected void OnBoolChange(bool state, ushort index, ushort type) { if (BoolChange != null) { var args = new BoolChangeEventArgs(state, type); args.Index = index; BoolChange(this, args); } } /// /// Helper event /// /// /// /// protected void OnUshrtChange(ushort state, ushort index, ushort type) { if (UshrtChange != null) { var args = new UshrtChangeEventArgs(state, type); args.Index = index; UshrtChange(this, args); } } /// /// Helper event /// /// /// /// protected void OnStringChange(string value, ushort index, ushort type) { if (StringChange != null) { var args = new StringChangeEventArgs(value, type); args.Index = index; StringChange(this, args); } } } }