diff --git a/Ooui/Element.cs b/Ooui/Element.cs index 31da35a..0155daf 100644 --- a/Ooui/Element.cs +++ b/Ooui/Element.cs @@ -1,20 +1,71 @@ using System; +using System.Collections.Generic; +using System.Linq; namespace Ooui { public class Element { - public string Id { get; private set; } + public string Id { get; private set; } = GenerateId (); + + public HtmlMapping Mapping { get; private set; } + + readonly List messages = new List (); + readonly List stateMessages = new List (); public Element () { - Id = GenerateId (); + Mapping = HtmlMapping.Get (GetType ()); + LogCreate (); } - protected bool SetProperty (ref T backingStore, T newValue) + protected void Log (Message message) + { + messages.Add (message); + + switch (message.MessageType) { + case MessageType.Create: + stateMessages.Add (message); + break; + case MessageType.SetProperty: + { + var old = stateMessages.FirstOrDefault ( + x => x.MessageType == MessageType.SetProperty && + x.Member == message.Member); + if (old != null) { + stateMessages.Remove (old); + } + stateMessages.Add (message); + } + break; + } + } + + protected void LogCreate () + { + Log (new Message { + MessageType = MessageType.Create, + TargetId = Id, + Value = Mapping.TagName, + }); + } + + protected void LogSetProperty (string propertyName, object value) + { + var m = new Message { + MessageType = MessageType.SetProperty, + TargetId = Id, + Member = Mapping.GetMemberPath (propertyName), + }; + m.SetValue (value); + Log (m); + } + + protected bool SetProperty (ref T backingStore, T newValue, string propertyName = "") { if (!backingStore.Equals (newValue)) { backingStore = newValue; + LogSetProperty (propertyName, newValue); return true; } return false; diff --git a/Ooui/HtmlMapping.cs b/Ooui/HtmlMapping.cs new file mode 100644 index 0000000..c98fb03 --- /dev/null +++ b/Ooui/HtmlMapping.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +namespace Ooui +{ + public class HtmlMapping + { + readonly Type type; + public string TagName { get; private set; } + + public HtmlMapping (Type type) + { + this.type = type; + TagName = type.Name.ToLowerInvariant (); + } + + public string GetMemberPath (string propertyName) + { + return propertyName; + } + + static readonly Dictionary mappings = + new Dictionary (); + + public static HtmlMapping Get (Type type) + { + var key = type.FullName; + HtmlMapping m; + if (!mappings.TryGetValue (key, out m)) { + m = new HtmlMapping (type); + mappings[key] = m; + } + return m; + } + } +} diff --git a/Ooui/Message.cs b/Ooui/Message.cs new file mode 100644 index 0000000..fcde6c0 --- /dev/null +++ b/Ooui/Message.cs @@ -0,0 +1,49 @@ +using System; + +namespace Ooui +{ + public class Message + { + public DateTime CreatedTime = DateTime.UtcNow; + public MessageType MessageType = MessageType.Nop; + public string TargetId = ""; + public string Member = ""; + public string Value = ""; + + public void SetValue (object value) + { + switch (value) { + case null: + Value = "null"; + break; + case String s: + Value = EncodeString (s); + break; + default: + Value = String.Format (System.Globalization.CultureInfo.InvariantCulture, "{0}", value); + break; + } + } + + public static string EncodeString (string s) + { + return s; + } + public static string DecodeString (string s) + { + return s; + } + } + + public enum MessageType + { + Nop, + Create, + SetProperty, + } + + public enum ValueType + { + String + } +}