/// <summary>
        /// 获取子孙数据(深度优先,后序)
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="root">根</param>
        /// <param name="predicate">子孙筛选条件</param>
        /// <returns>筛选的子孙</returns>
        public static IEnumerable <IHierarchical <T> > GetDescendantsDfsLrd <T>(this IHierarchical <T> root,
                                                                                Func <IHierarchical <T>, bool> predicate = null)
        {
            var children = predicate == null ? root.Children : root.Children.Where(predicate);
            Stack <IHierarchical <T> > stack = new Stack <IHierarchical <T> >(children.Reverse());

            IHierarchical <T> lastAccessedNode = null;

            while (stack.Count > 0)
            {
                var node = stack.Peek();

                if (node.Children.Any() && node.Children.Last() != lastAccessedNode)
                {
                    children = predicate == null ? node.Children : node.Children.Where(predicate);
                    foreach (IHierarchical <T> child in children.Reverse())
                    {
                        stack.Push(child);
                    }
                }
                else
                {
                    yield return(node);

                    lastAccessedNode = node;
                    stack.Pop();
                }
            }
        }
Beispiel #2
0
        public static TAncestor GetAncestor <T, TAncestor>(this IHierarchical <T> source, bool includingItselt = false)
            where TAncestor : class
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (includingItselt)
            {
                var itself = source as TAncestor;
                if (itself != null)
                {
                    return(itself);
                }
            }
            var castedParent = source.Parent as TAncestor;

            if (castedParent != null)
            {
                return(castedParent);
            }
            var hierarhicalParent = source.Parent as IHierarchical <T>;

            if (hierarhicalParent == null)
            {
                return(null);
            }
            return(GetAncestor <T, TAncestor>(hierarhicalParent));
        }
Beispiel #3
0
        private void TraverseNodes <U>(U closureArg, IHierarchical item, Action <U, SkipTreeNode> traverseFn, bool includeDisabled)
        {
            SkipTreeNode node;

            if (nodeMap.TryGetValue(item.UniqueId, out node))
            {
                TraverseNodesStep(closureArg, node, traverseFn, includeDisabled);
                return;
            }

            SkipTreeNode parent = FindParent(item);

            parent = parent ?? root;
            SkipTreeNode ptr = parent.firstChild;

            while (ptr != null)
            {
                if (IsDescendantOf(ptr.item, item))
                {
                    TraverseNodesStep(closureArg, ptr, traverseFn, includeDisabled);
                }

                ptr = ptr.nextSibling;
            }
        }
        /// <summary>
        /// 转换为可枚举集合
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="root">根</param>
        /// <param name="childSelector">下层数据选择器</param>
        /// <param name="predicate">子孙筛选条件</param>
        /// <param name="enumerateType">枚举方式</param>
        /// <returns>已枚举的集合</returns>
        public static IEnumerable <IHierarchical <T> > AsEnumerable <T>(this IHierarchical <T> root,
                                                                        Func <IHierarchical <T>, IEnumerable <IHierarchical <T> > > childSelector, Func <IHierarchical <T>, bool> predicate,
                                                                        EnumerateType enumerateType = EnumerateType.DfsDlr)
        {
            yield return(root);

            switch (enumerateType)
            {
            case EnumerateType.DfsDlr:
                foreach (var descendant in GetDescendantDfsDlr(root, childSelector, predicate))
                {
                    yield return(descendant);
                }

                break;

            case EnumerateType.Bfs:
                foreach (var descendant in GetDescendantsBfs(root, childSelector, predicate))
                {
                    yield return(descendant);
                }

                break;
            }
        }
Beispiel #5
0
        public void TraversePreOrder <U>(IHierarchical item, U closureArg, Action <U, T> traverseFn, bool includeDisabled = false)
        {
            SkipTreeNode node;

            if (nodeMap.TryGetValue(item.UniqueId, out node))
            {
                TraversePreOrderCallbackStep(node, closureArg, traverseFn, includeDisabled);
                return;
            }

            SkipTreeNode parent = FindParent(item);

            parent = parent ?? root;
            SkipTreeNode ptr = parent.firstChild;

            while (ptr != null)
            {
                if (IsDescendantOf(ptr.item, item))
                {
                    TraversePreOrderCallbackStep(ptr, closureArg, traverseFn, includeDisabled);
                }

                ptr = ptr.nextSibling;
            }
        }
        /// <summary>
        /// 获取子孙数据(深度优先,先序)
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="root">根</param>
        /// <param name="predicate">子孙筛选条件</param>
        /// <returns>筛选的子孙</returns>
        public static IEnumerable <IHierarchical <T> > GetDescendantsDfsDlr <T>(this IHierarchical <T> root,
                                                                                Func <IHierarchical <T>, bool> predicate = null)
        {
            var children = predicate == null ? root.Children : root.Children.Where(predicate);
            Stack <IHierarchical <T> > stack = new Stack <IHierarchical <T> >(children.Reverse());

            while (stack.Count > 0)
            {
                IHierarchical <T> node = stack.Pop();
                yield return(node);

                children = predicate == null ? node.Children : node.Children.Where(predicate);
                foreach (IHierarchical <T> child in children.Reverse())
                {
                    stack.Push(child);
                }
            }

            #region 递归方式

            //foreach (T t in childSelector(root))
            //{
            //    if (predicate(t))
            //        yield return t;
            //    foreach (T child in GetDescendantDfsDlr(t, childSelector, predicate))
            //        yield return child;
            //}

            #endregion 递归方式
        }
Beispiel #7
0
        public void ConditionalTraversePreOrder <U>(IHierarchical start, U closureArg, Func <T, U, bool> traverseFn)
        {
            if (start == null)
            {
                ConditionalTraversePreOrderStep(root, closureArg, traverseFn);
                return;
            }

            SkipTreeNode node;

            if (nodeMap.TryGetValue(start.UniqueId, out node))
            {
                ConditionalTraversePreOrderStep(node, closureArg, traverseFn);
                return;
            }

            SkipTreeNode parent = FindParent(start);

            parent = parent ?? root;
            SkipTreeNode ptr = parent.firstChild;

            while (ptr != null)
            {
                if (IsDescendantOf(ptr.item, start))
                {
                    if (traverseFn(ptr.item, closureArg))
                    {
                        ConditionalTraversePreOrderStep(ptr, closureArg, traverseFn);
                    }
                }

                ptr = ptr.nextSibling;
            }
        }
        /// <summary>
        /// 设置节点的双亲和子节点引用
        /// </summary>
        /// <typeparam name="T">节点类型</typeparam>
        /// <param name="root">根节点</param>
        /// <param name="childrenSelector">子节点选择器</param>
        /// <param name="clearChildrenBeforeSet">是否在设置子节点前清空子节点集合</param>
        /// <param name="parentSetter">双亲节点设置器,第一个参数为待设置引用的节点,第二个参数为第一个参数的双亲节点</param>
        /// <returns>原始根节点</returns>
        public static T SetParentChildren <T>(this IHierarchical <T> root,
                                              Func <T, ICollection <T> > childrenSelector, bool clearChildrenBeforeSet = false, Action <T, T> parentSetter = null)
        {
            if (childrenSelector == null)
            {
                throw new ArgumentNullException(nameof(childrenSelector));
            }

            foreach (var node in root.AsEnumerable())
            {
                parentSetter?.Invoke(node.Current, node.Parent != null ? node.Parent.Current : default(T));

                var children = childrenSelector.Invoke(node.Current);
                if (children == null)
                {
                    throw new InvalidOperationException("子节点集合为 null");
                }

                if (clearChildrenBeforeSet)
                {
                    children.Clear();
                }

                foreach (var child in node.Children)
                {
                    children.Add(child.Current);
                }
            }

            return(root.Current);
        }
Beispiel #9
0
        public void UpdateItemParent(IHierarchical element)
        {
            T item = GetItem(element);

            if (item != null)
            {
                SkipTreeNode node     = nodeMap[item.UniqueId];
                SkipTreeNode parent   = node.parent;
                SkipTreeNode nodeNext = node.nextSibling;
                SkipTreeNode nodePrev = FindPreviousSibling(node);

                if (nodePrev != null)
                {
                    nodePrev.nextSibling = nodeNext;
                }
                else
                {
                    parent.firstChild = nodeNext;
                }

                parent.childCount--;

                node.parent = null;
                parent      = FindParent(element);
                Insert(parent ?? root, node);
            }
        }
Beispiel #10
0
        //递归父节点跟随其全选或全不选
        private static void FooParent(IHierarchical root)
        {
            if (root.Parent == null)
            {
                return;
            }
            //遍历该节点的兄弟节点
            var brotherNodeCheckedCount = root.Parent.Children.Count(node => ((ISelectable)node).IsSelected == true);

            //兄弟节点全没选
            if (brotherNodeCheckedCount == 0)
            {
                var parentNode = root.Parent;
                ((ISelectable)parentNode).IsSelected = false;
                //其父节点也不选
                FooParent(parentNode);
            }
            //兄弟节点中只要有一个被选
            if (brotherNodeCheckedCount == 1)
            {
                var parentNode = root.Parent;
                ((ISelectable)parentNode).IsSelected = true;
                //其父节点也被选
                FooParent(parentNode);
            }
        }
Beispiel #11
0
        private void Insert(SkipTreeNode parent, SkipTreeNode inserted)
        {
            SkipTreeNode  ptr     = parent.firstChild;
            IHierarchical element = inserted.item;

            // set parent
            // walk through current parent's children
            // if any of those are descendants of inserted
            // remove from parent
            // attach as first sibling to inserted

            SkipTreeNode insertedLastChild   = null;
            SkipTreeNode parentPreviousChild = null;

            while (ptr != null)
            {
                IHierarchical currentElement = ptr.item;
                if (IsDescendantOf(currentElement, element))
                {
                    SkipTreeNode next = ptr.nextSibling;

                    if (ptr == parent.firstChild)
                    {
                        parent.firstChild = next;
                    }
                    else if (parentPreviousChild != null)
                    {
                        parentPreviousChild.nextSibling = next;
                    }

                    if (insertedLastChild != null)
                    {
                        insertedLastChild.nextSibling = ptr;
                    }
                    else
                    {
                        inserted.firstChild = ptr;
                    }

                    ptr.parent.childCount--;
                    ptr.parent = inserted;
                    inserted.childCount++;
                    ptr.nextSibling   = null;
                    insertedLastChild = ptr;
                    ptr = next;
                }
                else
                {
                    parentPreviousChild = ptr;
                    ptr = ptr.nextSibling;
                }
            }

            parent.childCount++;
            inserted.parent      = parent;
            inserted.isDisabled  = parent.isDisabled;
            inserted.nextSibling = parent.firstChild;
            parent.firstChild    = inserted;
        }
Beispiel #12
0
        public static IEnumerable <TAncestor> GetDescendants <T, TAncestor>(this IHierarchical <T> source, bool includingItselt = true)
            where TAncestor : class
        {
            var result = new Collection <TAncestor>();

            CollectDescendants(source, includingItselt, result);
            return(result);
        }
        /// <summary>
        /// 判断节点是否是指定节点的祖先节点
        /// </summary>
        /// <typeparam name="T">节点数据类型</typeparam>
        /// <param name="node">待判断的节点</param>
        /// <param name="target">目标节点</param>
        /// <returns>判断结果</returns>
        public static bool IsAncestorOf <T>(this IHierarchical <T> node, IHierarchical <T> target)
        {
            if (node.Root != target.Root)
            {
                throw new InvalidOperationException($"{nameof(node)} and {nameof(target)} are not at same tree.");
            }

            return(target.Ancestors.SingleOrDefault(n => n == node) != null);
        }
        /// <summary>
        /// 判断节点是否是指定节点的后代节点
        /// </summary>
        /// <typeparam name="T">节点数据类型</typeparam>
        /// <param name="node">待判断的节点</param>
        /// <param name="target">目标节点</param>
        /// <returns>判断结果</returns>
        public static bool IsDescendantOf <T>(this IHierarchical <T> node, IHierarchical <T> target)
        {
            if (node.Root != target.Root)
            {
                throw new InvalidOperationException($"{nameof(node)} and {nameof(target)} are not at same tree.");
            }

            return(target.IsAncestorOf(node));
        }
        /// <summary>
        /// 获取从当前节点到指定节点的路径
        /// </summary>
        /// <typeparam name="T">节点数据类型</typeparam>
        /// <param name="node">当前节点(起点)</param>
        /// <param name="to">目标节点(终点)</param>
        /// <returns>按从当前节点到目标节点顺序经过的节点集合</returns>
        public static IEnumerable <IHierarchical <T> > GetPathToNode <T>(this IHierarchical <T> node, IHierarchical <T> to)
        {
            if (node.Root != to.Root)
            {
                throw new InvalidOperationException($"{nameof(node)} and {nameof(to)} are not at same tree.");
            }

            return(to.GetPathFromNode(node));
        }
Beispiel #16
0
 public IContainer Add(IHierarchical child)
 {
     if (child != null)
     {
         children.Add(child);
         child.Parent = this;
     }
     return(this);
 }
Beispiel #17
0
        public int GetChildCount(IHierarchical item)
        {
            SkipTreeNode node;

            if (!nodeMap.TryGetValue(item.UniqueId, out node))
            {
                return(0);
            }

            return(node.childCount);
        }
Beispiel #18
0
 public static IHierarchical FindRootOrganization(this IHierarchical org)
 {
     if (org.Parent == null)
     {
         return(org);
     }
     else
     {
         return(FindRootOrganization(org.Parent));
     }
 }
        /// <summary>
        /// 获取从指定节点到当前节点的路径
        /// </summary>
        /// <typeparam name="T">节点数据类型</typeparam>
        /// <param name="node">当前节点(终点)</param>
        /// <param name="from">目标节点(起点)</param>
        /// <returns>按从目标节点到当前节点顺序经过的节点集合</returns>
        public static IEnumerable <IHierarchical <T> > GetPathFromNode <T>(this IHierarchical <T> node,
                                                                           IHierarchical <T> from)
        {
            if (node.Root != from.Root)
            {
                throw new InvalidOperationException($"{nameof(node)} and {nameof(from)} are not at same tree.");
            }

            yield return(from); //起点必然是需要的

            if (node == from)
            {
                yield break;               //如果终点就是起点,那么可以直接结束路径查找了
            }
            //只有终点和起点不存在双亲孩子关系时才需要执行内部代码,否则直接返回终点即可
            if (!(node.Parent == from || node.Children.Any(n => n == from)))
            {
                var nearestCommonAncestor = node.GetNearestCommonAncestor(from);

                //如果起点不是终点的祖先,需要先返回从起点的双亲到最近公共祖先
                //(不包括最近公共祖先。最近公共祖先可能就是终点,返回的话会导致终点被返回两次。终点会在方法末尾统一返回)的路径
                if (!from.IsAncestorOf(node))
                {
                    foreach (var ancestor in from.Ancestors)
                    {
                        if (ancestor != nearestCommonAncestor)
                        {
                            yield return(ancestor);
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                //如果最近公共祖先不是终点,返回从最近公共祖先到终点(不包括终点,原因不再赘述)的路径
                if (nearestCommonAncestor != node)
                {
                    var ancestorsOfNode = node.Ancestors.ToArray();
                    for (int i = Array.IndexOf(ancestorsOfNode, nearestCommonAncestor); i >= 0; i--)
                    {
                        yield return(ancestorsOfNode[i]);
                    }
                }
            }

            yield return(node); //最后返回终点
        }
Beispiel #20
0
        private static bool IsDescendantOf(IHierarchical child, IHierarchical parent)
        {
            IHierarchical ptr = child;

            while (ptr != null)
            {
                if (ptr == parent.Element)
                {
                    return(true);
                }

                ptr = ptr.Parent;
            }

            return(false);
        }
Beispiel #21
0
        private SkipTreeNode FindParent(IHierarchical element)
        {
            IHierarchical ptr = element.Parent;

            while (ptr != null)
            {
                SkipTreeNode node;
                if (nodeMap.TryGetValue(ptr.UniqueId, out node))
                {
                    return(node);
                }

                ptr = ptr.Parent;
            }

            return(null);
        }
        /// <summary>
        /// 获取子孙数据(广度优先)
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="root">根</param>
        /// <param name="predicate">子孙筛选条件</param>
        /// <returns>筛选的子孙</returns>
        public static IEnumerable <IHierarchical <T> > GetDescendantsBfs <T>(this IHierarchical <T> root,
                                                                             Func <IHierarchical <T>, bool> predicate = null)
        {
            predicate = predicate ?? (t => true);
            Queue <IHierarchical <T> > queue = new Queue <IHierarchical <T> >(root.Children.Where(predicate));

            while (queue.Count > 0)
            {
                IHierarchical <T> node = queue.Dequeue();
                yield return(node);

                foreach (IHierarchical <T> child in node.Children.Where(predicate))
                {
                    queue.Enqueue(child);
                }
            }
        }
Beispiel #23
0
        public void RemoveItem(IHierarchical item)
        {
            SkipTreeNode  node;
            IHierarchical element = item.Element;

            if (!nodeMap.TryGetValue(element.UniqueId, out node))
            {
                return;
            }

            SkipTreeNode parent    = node.parent;
            SkipTreeNode ptr       = node.firstChild;
            SkipTreeNode nodeNext  = node.nextSibling;
            SkipTreeNode nodePrev  = FindPreviousSibling(node);
            SkipTreeNode lastChild = null;

            parent.childCount--;

            while (ptr != null)
            {
                ptr.parent = node.parent;
                node.parent.childCount++;
                lastChild = ptr;
                ptr       = ptr.nextSibling;
            }

            if (parent.firstChild == node)
            {
                parent.firstChild = node.firstChild;
            }
            else
            {
                nodePrev.nextSibling = node.firstChild;
                if (lastChild != null)
                {
                    lastChild.nextSibling = nodeNext;
                }
            }

            node.parent      = null;
            node.item        = default(T);
            node.nextSibling = null;
            node.firstChild  = null;
            nodeMap.Remove(element.UniqueId);
            onTreeChanged?.Invoke(TreeChangeType.ItemRemoved);
        }
Beispiel #24
0
        public void AddItem(T item)
        {
            SkipTreeNode  node;
            IHierarchical element = item.Element;

            if (nodeMap.TryGetValue(element.UniqueId, out node))
            {
                return;
            }

            node = new SkipTreeNode(item);
            nodeMap[element.UniqueId] = node;
            SkipTreeNode parent = FindParent(element);

            Insert(parent ?? root, node);
            onTreeChanged?.Invoke(TreeChangeType.ItemAdded);
        }
        /// <summary>
        /// 获取节点与指定节点的最近公共祖先节点
        /// </summary>
        /// <typeparam name="T">节点数据类型</typeparam>
        /// <param name="node">待查找的节点</param>
        /// <param name="target">目标节点</param>
        /// <returns>最近的公共祖先节点</returns>
        public static IHierarchical <T> GetNearestCommonAncestor <T>(this IHierarchical <T> node, IHierarchical <T> target)
        {
            if (node.Root != target.Root)
            {
                throw new InvalidOperationException($"{nameof(node)} and {nameof(target)} are not at same tree.");
            }

            if (node.IsAncestorOf(target))
            {
                return(node);
            }
            if (target.IsAncestorOf(node))
            {
                return(target);
            }

            return(node.Ancestors.Intersect(target.Ancestors).OrderByDescending(no => no.Level).First());
        }
Beispiel #26
0
        public bool CanInsert(object parent, object child)
        {
            IHierarchical hierarchical = parent.As <IHierarchical>();

            if (hierarchical == null)
            {
                return(false);
            }
            ILockable lockable = parent.As <ILockable>();

            if (lockable != null && lockable.IsLocked)
            {
                return(false);
            }

            DomNode parentNode = parent.As <DomNode>();

            IEnumerable <object> items = Util.ConvertData(child, false);
            bool canInsert             = false;

            foreach (object item in items)
            {
                DomNode childNode = item as DomNode;
                if (parentNode != null && childNode != null)
                {
                    if ((parentNode.IsDescendantOf(childNode) ||
                         parentNode == childNode ||
                         parentNode == childNode.Parent))
                    {
                        return(false);
                    }
                }
                IResource   res = item as IResource;
                IGameObject gob = m_resourceConverterService.Convert(res);
                if (!hierarchical.CanAddChild(item) &&
                    !hierarchical.CanAddChild(gob))
                {
                    return(false);
                }

                canInsert = true;
            }
            return(canInsert);
        }
Beispiel #27
0
        public Router FindRouterInHierarchy(UIElement element)
        {
            IHierarchical ptr = element;

            while (ptr != null)
            {
                for (int i = 0; i < m_Routers.Count; i++)
                {
                    if (m_Routers[i].hostId == ptr.UniqueId)
                    {
                        return(m_Routers[i]);
                    }
                }

                ptr = ptr.Parent;
            }

            return(null);
        }
Beispiel #28
0
        public int GetActiveChildCount(IHierarchical element)
        {
            SkipTreeNode node;

            if (!nodeMap.TryGetValue(element.UniqueId, out node))
            {
                return(0);
            }

            SkipTreeNode ptr   = node.parent.firstChild;
            int          count = 0;

            while (ptr != null)
            {
                count += !ptr.isDisabled ? 1 : 0;
                ptr    = ptr.nextSibling;
            }

            return(count);
        }
Beispiel #29
0
        public void TraverseAncestors <U>(IHierarchical start, U closureArg, Action <T, U> traverseFn)
        {
            SkipTreeNode node;
            SkipTreeNode ptr;

            if (nodeMap.TryGetValue(start.UniqueId, out node))
            {
                ptr = node.parent;
            }
            else
            {
                ptr = FindParent(start);
            }

            while (ptr != null)
            {
                traverseFn(ptr.item, closureArg);
                ptr = ptr.parent;
            }
        }
Beispiel #30
0
        public TreeNode GetTraversableTree(T item, bool includeDisabled = false)
        {
            SkipTreeNode  node;
            IHierarchical element = item.Element;

            if (!nodeMap.TryGetValue(element.UniqueId, out node))
            {
                SkipTreeNode parent = FindParent(item);
                parent = parent ?? root;
                SkipTreeNode ptr = parent.firstChild;

                while (ptr != null)
                {
                    if (!includeDisabled && ptr.isDisabled)
                    {
                        ptr = ptr.nextSibling;
                        continue;
                    }

                    if (IsDescendantOf(ptr.item, item))
                    {
                        scratchNodeList.Add(ptr);
                    }

                    ptr = ptr.nextSibling;
                }

                TreeNode[] children = scratchNodeList.Count == 0
                    ? TreeNode.EmptyArray
                    : new TreeNode[scratchNodeList.Count];

                for (int i = 0; i < children.Length; i++)
                {
                    children[i] = GetChildTree(scratchNodeList[i], includeDisabled);
                }

                return(new TreeNode(item, false, children));
            }

            return(GetChildTree(node, includeDisabled));
        }
 private bool FindServiceOnSpecOrSpecSuperclass(IHierarchical spec) {
     if (spec == null) {
         return false;
     }
     if (spec == OnType) {
         return true;
     }
     return FindServiceOnSpecOrSpecSuperclass(spec.Superclass);
 }