Axiom.Scripting.Compiler.ScriptCompiler._overlayObject C# (CSharp) Метод

_overlayObject() приватный Метод

private _overlayObject ( AbstractNode source, Axiom.Scripting.Compiler.AST.ObjectAbstractNode dest ) : void
source Axiom.Scripting.Compiler.AST.AbstractNode
dest Axiom.Scripting.Compiler.AST.ObjectAbstractNode
Результат void
		private void _overlayObject( AbstractNode source, ObjectAbstractNode dest )
		{
			if ( source is ObjectAbstractNode )
			{
				ObjectAbstractNode src = (ObjectAbstractNode)source;

				// Overlay the environment of one on top the other first
				foreach ( KeyValuePair<string, string> i in src.Variables )
				{
					KeyValuePair<bool, string> var = dest.GetVariable( i.Key );
					if ( !var.Key )
						dest.SetVariable( i.Key, i.Value );
				}

				// Create a vector storing each pairing of override between source and destination
				List<KeyValuePair<AbstractNode, AbstractNode>> overrides = new List<KeyValuePair<AbstractNode, AbstractNode>>();
				// A list of indices for each destination node tracks the minimum
				// source node they can index-match against
				Dictionary<ObjectAbstractNode, int> indices = new Dictionary<ObjectAbstractNode, int>();
				// A map storing which nodes have overridden from the destination node
				Dictionary<ObjectAbstractNode, bool> overridden = new Dictionary<ObjectAbstractNode, bool>();

				// Fill the vector with objects from the source node (base)
				// And insert non-objects into the overrides list of the destination
				int insertPos = 0;

				foreach ( AbstractNode i in src.Children )
				{
					if ( i is ObjectAbstractNode )
					{
						overrides.Add( new KeyValuePair<AbstractNode, AbstractNode>( i, null ) );
					}
					else
					{
						AbstractNode newNode = i.Clone();
						newNode.Parent = dest;
						dest.Overrides.Add( newNode );
					}
				}

				// Track the running maximum override index in the name-matching phase
				int maxOverrideIndex = 0;

				// Loop through destination children searching for name-matching overrides
				for ( int i = 0; i < dest.Children.Count; i++ )
				{
					if ( dest.Children[ i ] is ObjectAbstractNode )
					{
						// Start tracking the override index position for this object
						int overrideIndex = 0;

						ObjectAbstractNode node = (ObjectAbstractNode)dest.Children[ i ];
						indices[ node ] = maxOverrideIndex;
						overridden[ node ] = false;

						// special treatment for materials with * in their name
						bool nodeHasWildcard = ( !string.IsNullOrEmpty( node.Name ) && node.Name.Contains( "*" ) );

						// Find the matching name node
						for ( int j = 0; j < overrides.Count; ++j )
						{
							ObjectAbstractNode temp = (ObjectAbstractNode)overrides[ j ].Key;
							// Consider a match a node that has a wildcard and matches an input name
							bool wildcardMatch = nodeHasWildcard &&
								( ( new Regex( node.Name ) ).IsMatch( temp.Name ) ||
									( node.Name.Length == 1 && string.IsNullOrEmpty( temp.Name ) ) );

							if ( temp.Cls == node.Cls && !string.IsNullOrEmpty( node.Name ) && ( temp.Name == node.Name || wildcardMatch ) )
							{
								// Pair these two together unless it's already paired
								if ( overrides[ j ].Value == null )
								{
									int currentIterator = i;
									ObjectAbstractNode currentNode = node;
									if ( wildcardMatch )
									{
										//If wildcard is matched, make a copy of current material and put it before the iterator, matching its name to the parent. Use same reinterpret cast as above when node is set
										AbstractNode newNode = dest.Children[ i ].Clone();
										dest.Children.Insert( currentIterator, newNode );
										currentNode = (ObjectAbstractNode)dest.Children[ currentIterator ];
										currentNode.Name = temp.Name;//make the regex match its matcher
									}
									overrides[ j ] = new KeyValuePair<AbstractNode, AbstractNode>( overrides[ j ].Key, dest.Children[ currentIterator ] );
									// Store the max override index for this matched pair
									overrideIndex = j;
									overrideIndex = maxOverrideIndex = System.Math.Max( overrideIndex, maxOverrideIndex );
									indices[ currentNode ] = overrideIndex;
									overridden[ currentNode ] = true;
								}
								else
								{
									AddError( CompileErrorCode.DuplicateOverride, node.File, node.Line );
								}

								if ( !wildcardMatch )
									break;
							}
						}

						if ( nodeHasWildcard )
						{
							//if the node has a wildcard it will be deleted since it was duplicated for every match
							dest.Children.RemoveAt( i );
							i--;
						}
					}
				}

				// Now make matches based on index
				// Loop through destination children searching for name-matching overrides
				foreach ( AbstractNode i in dest.Children )
				{
					if ( i is ObjectAbstractNode )
					{
						ObjectAbstractNode node = (ObjectAbstractNode)i;
						if ( !overridden[ node ] )
						{
							// Retrieve the minimum override index from the map
							int overrideIndex = indices[ node ];

							if ( overrideIndex < overrides.Count )
							{
								// Search for minimum matching override
								for ( int j = overrideIndex; j < overrides.Count; ++j )
								{
									ObjectAbstractNode temp = (ObjectAbstractNode)overrides[ j ].Key;
									if ( string.IsNullOrEmpty( temp.Name ) && temp.Cls == node.Cls && overrides[ j ].Value == null )
									{
										overrides[ j ] = new KeyValuePair<AbstractNode, AbstractNode>( overrides[ j ].Key, i );
										break;
									}
								}
							}
						}
					}
				}

				// Loop through overrides, either inserting source nodes or overriding
				for ( int i = 0; i < overrides.Count; ++i )
				{
					if ( overrides[ i ].Value != null )
					{
						// Override the destination with the source (base) object
						_overlayObject( overrides[ i ].Key, (ObjectAbstractNode)overrides[ i ].Value );
						insertPos = dest.Children.IndexOf( overrides[ i ].Value );
						insertPos++;
					}
					else
					{
						// No override was possible, so insert this node at the insert position
						// into the destination (child) object
						AbstractNode newNode = overrides[ i ].Key.Clone();
						newNode.Parent = dest;
						if ( insertPos != dest.Children.Count - 1 )
						{
							dest.Children.Insert( insertPos, newNode );
						}
						else
						{
							dest.Children.Add( newNode );
						}
					}
				}
			}
		}