Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
DataVisitNodeExtensions.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.IO;
6 using System.Linq;
7 
8 namespace SiliconStudio.Assets.Visitors
9 {
10  /// <summary>
11  /// Extensions for <see cref="IDataVisitNode{T}"/>
12  /// </summary>
13  public static class DataVisitNodeExtensions
14  {
15  /// <summary>
16  /// Counts recursively the number of nodes, including the specified node.
17  /// </summary>
18  /// <typeparam name="T">Type of the node</typeparam>
19  /// <param name="node">The node.</param>
20  /// <returns>The number of nodes.</returns>
21  public static int CountChildren<T>(this T node) where T : class, IDataVisitNode<T>
22  {
23  return node.Children(item => true).Count();
24  }
25 
26  /// <summary>
27  /// Iterate on a <see cref="IDataVisitNode{T}" /> recursively.
28  /// </summary>
29  /// <typeparam name="T">Type of the node</typeparam>
30  /// <param name="node">The node.</param>
31  /// <param name="acceptNode">A visitor to accept the node or not in the returning iteration.</param>
32  /// <param name="shouldVisitChildren">A visitor to indicate wether or not to visit children (members and items).</param>
33  /// <returns>An enumeration on nodes.</returns>
34  /// <exception cref="System.ArgumentNullException">acceptNode</exception>
35  public static IEnumerable<T> Children<T>(this T node, Func<T, bool> acceptNode, Func<T, bool> shouldVisitChildren = null) where T : class, IDataVisitNode<T>
36  {
37  if (acceptNode == null) throw new ArgumentNullException("acceptNode");
38 
39  if (node == null)
40  {
41  yield break;
42  }
43 
44  if (shouldVisitChildren != null && !shouldVisitChildren(node))
45  {
46  yield break;
47  }
48 
49  if (acceptNode(node))
50  {
51  yield return node;
52  }
53 
54  if (node.HasMembers)
55  {
56  foreach (var diffMember in node.Members)
57  {
58  foreach (var sub in diffMember.Children(acceptNode, shouldVisitChildren))
59  {
60  yield return sub;
61  }
62  }
63  }
64 
65  if (node.HasItems)
66  {
67  foreach (var diffItem in node.Items)
68  {
69  foreach (var sub in diffItem.Children(acceptNode, shouldVisitChildren))
70  {
71  yield return sub;
72  }
73  }
74  }
75  }
76 
77  /// <summary>
78  /// Dumps a <see cref="IDataVisitNode{T}"/> recursively to a writer, used for debug purposes.
79  /// </summary>
80  /// <param name="node">The node.</param>
81  /// <param name="writer">The writer.</param>
82  /// <param name="level">The initial level of indent. Default to 0</param>
83  /// <exception cref="System.ArgumentNullException">writer</exception>
84  public static void Dump<T>(this T node, TextWriter writer, int level = 0) where T : class, IDataVisitNode<T>
85  {
86  if (writer == null) throw new ArgumentNullException("writer");
87  writer.WriteLine("{0}- {1}", string.Concat(Enumerable.Repeat(" ", level)), node);
88  level++;
89  if (node.HasMembers)
90  {
91  foreach (var diffMember in node.Members)
92  {
93  diffMember.Dump(writer, level);
94  }
95  }
96  if (node.HasMembers && node.HasItems)
97  writer.WriteLine("{0}- Items:", string.Concat(Enumerable.Repeat(" ", level)));
98 
99  if (node.HasItems)
100  {
101  foreach (var diffItem in node.Items)
102  {
103  diffItem.Dump(writer, level);
104  }
105  }
106  }
107  }
108 }
Interface providing a generic access to hierarchical data that contains members (property/fields) and...