/// <summary> Creates a new FNode root. </summary> /// <param name="data"> Root data object to wrap. </param> /// <returns> FNode root object. </returns> public static FNode <V> NewRoot(V data) { var root = new FNode <V>(data); root.path = "/"; return(root); }
private static void DeserializeFill(FNode <V> parent, JsonObject obj) { if (obj.Has("children")) { JsonObject children = obj.Pull <JsonObject>("children"); JsonObject transitions = obj.Pull <JsonObject>("transitions"); foreach (var pair in children) { string name = pair.Key; JsonObject serializedChild = pair.Value as JsonObject; FNode <V> child = Deserialize(serializedChild, parent, name); } foreach (var pair in transitions) { string name = pair.Key; FNode <V> child = parent.GetChild(name); JsonObject links = pair.Value as JsonObject; foreach (var pair2 in links) { var transitionName = pair2.Key; var targetName = pair2.Value.stringVal; parent.Connect(transitionName, child, parent.GetChild(targetName)); } } } }
private static FNode <V> Deserialize(JsonObject obj, FNode <V> parent, string name) { V data = Json.GetValue <V>(obj["data"]); FNode <V> node = parent.AddChild(name, data); DeserializeFill(node, obj); return(node); }
public static FNode <V> Deserialize(JsonObject obj) { V data = Json.GetValue <V>(obj["data"]); FNode <V> node = NewRoot(data); DeserializeFill(node, obj); return(node); }
/// <summary> Creates a connection between this node and <paramref name="destination"/>. </summary> /// <param name="destination"> Destination of transition to create. </param> /// <returns> Result describing connection success or failure reason </returns> public ConnectResult Connect(string key, FNode <V> destination) { if (isRoot) { return(SourceIsRootNode); } return(parent.Connect(key, this, destination)); }
/// <summary> Get the name of a potential child. </summary> /// <param name="node"> Node to check name of </param> /// <returns> Name of node, if it is a child, or null if it is not. </returns> public string GetName(FNode <V> node) { if (_nodeToName.ContainsKey(node)) { return(_nodeToName[node]); } return(null); }
/// <summary> Convinience method to create root instances with types that have an empty parameter constructor. </summary> /// <returns> FNode root object. </returns> public static FNode <V> NewRoot() { V raw = Activator.CreateInstance <V>(); var root = new FNode <V>(raw); root.path = "/"; return(root); }
/// <summary> Disconnects <paramref name="source"/> from <paramref name="destination"/>, if possible. </summary> /// <param name="source"> Source of transition to remove. </param> /// <param name="destination"> Destination of transition to remove. </param> /// <returns> Result describing connection success or failure reason </returns> public ConnectResult Disconnect(string key, FNode <V> source) { if (!HasChild(source)) { return(NotSiblingNodes); } if (source[key] == null) { return(ConnectionNotPresent); } _children[source].Remove(key); return(ConnectionRemoved); }
/// <summary> Connects <paramref name="source"/> to <paramref name="destination"/>, /// with <paramref name="key"/> as description/key. </summary> /// <param name="key"> Description of connection </param> /// <param name="source"> Source of transition to create </param> /// <param name="destination"> Destination of transition to create. </param> /// <returns> Result describing connection success or failure reason </returns> public ConnectResult Connect(string key, FNode <V> source, FNode <V> destination) { if (!HasChild(source) || !HasChild(destination)) { return(NotSiblingNodes); } if (source[key] != null) { return(ConnectionAlreadyPresent); } _children[source][key] = destination; return(ConnectionCreated); }
public static JsonObject Serialize(FNode <V> node) { JsonObject serialized = new JsonObject(); JsonValue data = Json.Reflect(node.data); serialized["data"] = data; if (node._children != null) { JsonObject children = new JsonObject(); JsonObject transitions = new JsonObject(); serialized["children"] = children; serialized["transitions"] = transitions; foreach (var pair in node._nameToNode) { var name = pair.Key; var child = pair.Value; var links = node._children[child]; JsonObject serializedChild = Serialize(child); children[name] = serializedChild; if (links != null && links.Count > 0) { JsonObject childTransitions = new JsonObject(); transitions[name] = childTransitions; foreach (var pair2 in links) { string from = pair2.Key; string to = node._nodeToName[pair2.Value]; childTransitions[from] = to; } } } } return(serialized); }
/// <summary> Creates a child node to this FNode. </summary> /// <param name="data"> Data object to wrap. </param> /// <returns> Newly created FNode. </returns> public FNode <V> AddChild(string name, V data) { if (name.Contains("/")) { throw new InvalidOperationException("Names may not have '/' in them."); } var node = new FNode <V>(data); node.parent = this; node.path = isRoot ? path + name : path + "/" + name; if (_children == null) { _children = new Nodes(); _nameToNode = new NameToNode(); _nodeToName = new NodeToName(); } _children[node] = new Transitions(); _nameToNode[name] = node; _nodeToName[node] = name; return(node); }
/// <summary> Compare all elements within a FNode structure with another. </summary> /// <param name="other"> Other structure to compare to </param> /// <returns> True if the structures are entirely equal (data, children, names, transitions), otherwise false. </returns> public bool RecursiveEquals(FNode <V> other) { if (ReferenceEquals(this, other)) { return(true); } if (!other.data.Equals(data)) { return(false); } if ((_children != null) != (other._children != null)) { return(false); } if (_children != null && other._children != null) { if (_children.Count != other._children.Count) { return(false); } foreach (var pair in _nameToNode) { var name = pair.Key; var child = pair.Value; if (!other._nameToNode.ContainsKey(name)) { return(false); } if (!other._nameToNode[name].RecursiveEquals(child)) { return(false); } var transitions = _children[child]; var otherChild = other._nameToNode[pair.Key]; var otherTransitions = other._children[otherChild]; if (transitions.Count != otherTransitions.Count) { return(false); } foreach (var pair2 in transitions) { var transitionName = pair2.Key; var transitionTarget = pair2.Value; if (!otherTransitions.ContainsKey(transitionName)) { return(false); } var otherTransitionTarget = otherTransitions[transitionName]; var targetName = _nodeToName[transitionTarget]; var otherTargetName = other._nodeToName[otherTransitionTarget]; if (targetName != otherTargetName) { return(false); } } } } return(true); }
/// <summary> Query if the given <paramref name="node"/> is a direct child of this node. </summary> /// <param name="node"> Node to check child status of </param> /// <returns> true if <paramref name="node"/> is a child, otherwise false. </returns> public bool HasChild(FNode <V> node) { return(_children != null && _children.ContainsKey(node)); }