예제 #1
0
        /// <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);
        }
예제 #2
0
        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));
                    }
                }
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        public static FNode <V> Deserialize(JsonObject obj)
        {
            V         data = Json.GetValue <V>(obj["data"]);
            FNode <V> node = NewRoot(data);

            DeserializeFill(node, obj);
            return(node);
        }
예제 #5
0
 /// <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));
 }
예제 #6
0
 /// <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);
 }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
 /// <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));
 }