4 using System.Collections;
5 using System.Collections.Concurrent;
6 using System.Collections.Generic;
7 using System.Linq.Expressions;
8 using System.Reflection;
12 namespace SiliconStudio.Shaders.Ast
19 private static readonly ConcurrentDictionary<Type, NodeProcessor> RegisteredProcessors =
new ConcurrentDictionary<Type, NodeProcessor>();
30 if (node == null)
return null;
32 var type = node.GetType();
33 var process = RegisteredProcessors.GetOrAdd(type, BuildChildrensIterator);
34 if (listProcessor == null)
35 listProcessor = DefaultListProcessor;
37 return process(node, ref context);
50 for (
int i = 0; i < list.Count;)
52 var previousValue = (
Node)list[i];
53 var temp = nodeProcessor(previousValue, ref nodeProcessorContext);
56 for (i = 0; i < list.Count; i++)
58 if (ReferenceEquals(previousValue, list[i]))
68 if (!ReferenceEquals(previousValue, temp))
79 return (FieldInfo)((MemberExpression)access.Body).Member;
82 private static FieldInfo nodeProcessorProperty = FieldReflector<NodeProcessorContext>(obj =>
obj.NodeProcessor);
83 private static FieldInfo nodeListProcessorProperty = FieldReflector<NodeProcessorContext>(obj => obj.ListProcessor);
92 private static NodeProcessor BuildChildrensIterator(Type rootType)
94 var sourceParameter = LinqExpression.Parameter(typeof(Node),
"source");
95 var explorerParameter = LinqExpression.Parameter(typeof(NodeProcessorContext).MakeByRefType(),
"nodeProcessorContext");
96 var variableNodeProcessor = LinqExpression.Variable(typeof(
NodeProcessor),
"nodeProcessor");
97 var variableNodeListProcessor = LinqExpression.Variable(typeof(
NodeListProcessor),
"listProcessor");
98 var statements =
new List<LinqExpression>();
101 var castVar = LinqExpression.Variable(rootType,
"cast");
102 var variables =
new List<ParameterExpression> { castVar, variableNodeProcessor, variableNodeListProcessor };
104 statements.Add(LinqExpression.Assign(castVar, LinqExpression.Convert(sourceParameter, rootType)));
106 statements.Add(LinqExpression.Assign(variableNodeProcessor, LinqExpression.Field(explorerParameter, nodeProcessorProperty)));
107 statements.Add(LinqExpression.Assign(variableNodeListProcessor, LinqExpression.Field(explorerParameter, nodeListProcessorProperty)));
111 for (var type = rootType; type != null; type = type.BaseType)
116 foreach (var type
in types)
119 foreach (var sourceField
in type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic))
123 if (sourceField.GetCustomAttributes(typeof(VisitorIgnoreAttribute),
true).Length != 0)
128 var propertyType = sourceField.FieldType;
130 var interfaces = propertyType.GetInterfaces();
133 if (!typeof(StatementList).IsAssignableFrom(propertyType))
135 foreach (var interfaceBase
in interfaces)
137 if (interfaceBase.IsGenericType && interfaceBase.GetGenericTypeDefinition() == typeof(IList<>))
139 var parameterType = interfaceBase.GetGenericArguments()[0];
140 if (typeof(Node).IsAssignableFrom(parameterType))
142 LinqExpression.Invoke(variableNodeListProcessor, LinqExpression.Field(castVar, sourceField), explorerParameter));
148 if (typeof(Node).IsAssignableFrom(propertyType))
151 LinqExpression.Assign(
152 LinqExpression.Field(castVar, sourceField),
159 statements.Add(sourceParameter);
162 var block = LinqExpression.Block(variables, statements);
165 var lambda = LinqExpression.Lambda<
NodeProcessor>(block, sourceParameter, explorerParameter);
166 return lambda.Compile();
delegate Node NodeProcessor(Node node, ref NodeProcessorContext nodeProcessorContext)
Processor for a single node.
static Node Childrens(this Node node, NodeProcessor nodeProcessor, NodeListProcessor listProcessor=null)
Iterate on childrens and apply the specified transform function.
delegate void NodeListProcessor(IList list, ref NodeProcessorContext nodeProcessorContext)
Processor for a list of node.
System.Linq.Expressions.Expression LinqExpression
static void DefaultListProcessor(IList list, ref NodeProcessorContext nodeProcessorContext)
Default NodeListProcessor implementation used by Childrens iterator.
Shader childrens iterator.