/// <see cref="AbstractNode.Clone"/> public override AbstractNode Clone() { var node = new ObjectAbstractNode(Parent); node.File = File; node.Line = Line; node.Name = this.Name; node.Cls = this.Cls; node.Id = this.Id; node.IsAbstract = this.IsAbstract; foreach (var an in this.Children) { var newNode = (AbstractNode)(an.Clone()); newNode.Parent = node; node.Children.Add(newNode); } foreach (var an in this.Values) { var newNode = (AbstractNode)(an.Clone()); newNode.Parent = node; node.Values.Add(newNode); } node._environment = new Dictionary <string, string>(this._environment); return(node); }
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 ); } } } } }
private Pass _commonProgramChecks( ScriptCompiler compiler, ObjectAbstractNode node, out string createdProgramName ) { createdProgramName = string.Empty; if ( string.IsNullOrEmpty( node.Name ) ) { compiler.AddError( CompileErrorCode.ObjectNameExpected, node.File, node.Line ); return null; } ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent( ProcessResourceNameScriptCompilerEvent.ResourceType.GpuProgram, node.Name ); compiler._fireEvent( ref evt ); createdProgramName = ( (ProcessResourceNameScriptCompilerEvent)evt ).Name; if ( GpuProgramManager.Instance.GetByName( createdProgramName ) == null ) { compiler.AddError( CompileErrorCode.ReferenceToaNonExistingObject, node.File, node.Line ); return null; } Pass pass = (Pass)node.Parent.Context; return pass; }
protected void _translateShadowReceiverFragmentProgramRef( ScriptCompiler compiler, ObjectAbstractNode node ) { string createdProgramName; Pass pass = _commonProgramChecks( compiler, node, out createdProgramName ); if ( pass == null ) return; pass.SetShadowReceiverFragmentProgram( createdProgramName ); if ( GpuProgramManager.Instance.GetByName( createdProgramName ).IsSupported ) { #warning this need GpuProgramParametersShared implementation // GpuProgramParametersSharedPtr params = pass->getShadowReceiverFragmentProgramParameters(); // GpuProgramTranslator::translateProgramParameters(compiler, params, node); } }
protected void _translateGeometryProgramRef( ScriptCompiler compiler, ObjectAbstractNode node ) { string createdProgramName; Pass pass = _commonProgramChecks( compiler, node, out createdProgramName ); if ( pass == null ) return; pass.SetGeometryProgram( createdProgramName ); if ( pass.GeometryProgram.IsSupported ) { var parameters = pass.GeometryProgramParameters; GpuProgramTranslator.TranslateProgramParameters( compiler, parameters, node ); } }
protected void _translateGeometryProgramRef( ScriptCompiler compiler, ObjectAbstractNode node ) { string createdProgramName; Pass pass = _commonProgramChecks( compiler, node, out createdProgramName ); if ( pass == null ) return; pass.SetGeometryProgram( createdProgramName ); if ( pass.GeometryProgram.IsSupported ) { #warning this need GpuProgramParametersShared implementation //GpuProgramParametersShared parameters = pass.GeometryProgramParameters; //GpuProgramTranslator.TranslateProgramParameters( compiler, parameters, node ); } }
public static void TranslateProgramParameters( ScriptCompiler compiler, /*it should be GpuProgramParametersShared*/ GpuProgramParameters parameters, ObjectAbstractNode obj ) { int animParametricsCount = 0; foreach ( AbstractNode i in obj.Children ) { if ( i is PropertyAbstractNode ) { PropertyAbstractNode prop = (PropertyAbstractNode)i; LogManager.Instance.Write("TranslateProgramParameters {0}", (Keywords)prop.Id); switch ( (Keywords)prop.Id ) { #region ID_SHARED_PARAMS_REF case Keywords.ID_SHARED_PARAMS_REF: { if ( prop.Values.Count != 1 ) { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "shared_params_ref requires a single parameter" ); continue; } AbstractNode i0 = getNodeAt( prop.Values, 0 ); if ( !( i0 is AtomAbstractNode ) ) { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "shared parameter set name expected" ); continue; } AtomAbstractNode atom0 = (AtomAbstractNode)i0; throw new NotImplementedException(); #if UNREACHABLE_CODE try { //TODO //parameters->addSharedParameters(atom0->value); } catch ( AxiomException e ) { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, e.Message ); } } break; #else } #endif #endregion ID_SHARED_PARAMS_REF #region ID_PARAM_INDEXED || ID_PARAM_NAMED case Keywords.ID_PARAM_INDEXED: case Keywords.ID_PARAM_NAMED: { if ( prop.Values.Count >= 3 ) { bool named = ( prop.Id == (uint)Keywords.ID_PARAM_NAMED ); AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 ), k = getNodeAt( prop.Values, 2 ); if ( !(i0 is AtomAbstractNode) || !(i1 is AtomAbstractNode) ) { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "name or index and parameter type expected" ); return; } AtomAbstractNode atom0 = (AtomAbstractNode)i0, atom1 = (AtomAbstractNode)i1; if ( !named && !atom0.IsNumber ) { compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line, "parameter index expected" ); return; } string name = string.Empty; int index = 0; // Assign the name/index if ( named ) name = atom0.Value; else index = (int)atom0.Number; // Determine the type if ( atom1.Value == "matrix4x4" ) { Matrix4 m; if ( getMatrix4( prop.Values, 2, out m ) ) { try { if ( named ) parameters.SetNamedConstant( name, m ); else parameters.SetConstant( index, m ); } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting matrix4x4 parameter failed" ); } } else { compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line, "incorrect matrix4x4 declaration" ); } } else { // Find the number of parameters var isValid = true; GpuProgramParameters.ElementType type = GpuProgramParameters.ElementType.Real; int count = 0; if ( atom1.Value.Contains( "float" ) ) { type = GpuProgramParameters.ElementType.Real; if ( atom1.Value.Length >= 6 ) count = int.Parse( atom1.Value.Substring( 5 ) ); else { count = 1; } } else if ( atom1.Value.Contains( "int" ) ) { type = GpuProgramParameters.ElementType.Int; if ( atom1.Value.Length >= 4 ) count = int.Parse( atom1.Value.Substring( 3 ) ); else { count = 1; } } else { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "incorrect type specified; only variants of int and float allowed" ); isValid = false; } if ( isValid ) { // First, clear out any offending auto constants if ( named ) { parameters.ClearNamedAutoConstant(name); } else { parameters.ClearAutoConstant(index); } int roundedCount = count % 4 != 0 ? count + 4 - ( count % 4 ) : count; if ( type == GpuProgramParameters.ElementType.Int ) { int[] vals = new int[ roundedCount ]; if ( getInts( prop.Values, 2, out vals, roundedCount ) ) { try { if ( named ) { parameters.SetNamedConstant(name, vals, count, 1); } else { parameters.SetConstant(index , vals, roundedCount/4); } } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed" ); } } else { compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line, "incorrect integer constant declaration" ); } } else { float[] vals = new float[ roundedCount ]; if ( getFloats( prop.Values, 2, out vals, roundedCount ) ) { try { if ( named ) { parameters.SetNamedConstant(name, vals, count, 1); } else { parameters.SetConstant(index , vals, roundedCount/4); } } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed" ); } } else { compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line, "incorrect float constant declaration" ); } } } } } else { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "param_named and param_indexed properties requires at least 3 arguments" ); } } break; #endregion ID_PARAM_INDEXED || ID_PARAM_NAMED #region ID_PARAM_INDEXED_AUTO || ID_PARAM_NAMED_AUTO case Keywords.ID_PARAM_INDEXED_AUTO: case Keywords.ID_PARAM_NAMED_AUTO: { bool named = ( prop.Id == (uint)Keywords.ID_PARAM_NAMED_AUTO ); string name = string.Empty; int index = 0; if ( prop.Values.Count >= 2 ) { AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 ), i2 = getNodeAt( prop.Values, 2 ), i3 = getNodeAt( prop.Values, 3 ); if ( !(i0 is AtomAbstractNode) || !(i1 is AtomAbstractNode) ) { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "name or index and auto constant type expected" ); return; } AtomAbstractNode atom0 = (AtomAbstractNode)i0, atom1 = (AtomAbstractNode)i1; if ( !named && !atom0.IsNumber ) { compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line, "parameter index expected" ); return; } if ( named ) name = atom0.Value; else index = int.Parse( atom0.Value ); // Look up the auto constant atom1.Value = atom1.Value.ToLower(); GpuProgramParameters.AutoConstantDefinition def; bool defFound = GpuProgramParameters.GetAutoConstantDefinition( atom1.Value, out def ); if ( defFound ) { switch ( def.DataType ) { #region None case GpuProgramParameters.AutoConstantDataType.None: // Set the auto constant try { if ( named ) parameters.SetNamedAutoConstant( name, def.AutoConstantType ); else parameters.SetAutoConstant( index, def.AutoConstantType ); } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed" ); } break; #endregion None #region Int case GpuProgramParameters.AutoConstantDataType.Int: if ( def.AutoConstantType == GpuProgramParameters.AutoConstantType.AnimationParametric ) { try { if ( named ) parameters.SetNamedAutoConstant( name, def.AutoConstantType, animParametricsCount++ ); else parameters.SetAutoConstant( index, def.AutoConstantType, animParametricsCount++ ); } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed" ); } } else { // Only certain texture projection auto params will assume 0 // Otherwise we will expect that 3rd parameter if ( i2 == null ) { if ( def.AutoConstantType == GpuProgramParameters.AutoConstantType.TextureViewProjMatrix || def.AutoConstantType == GpuProgramParameters.AutoConstantType.TextureWorldViewProjMatrix || def.AutoConstantType == GpuProgramParameters.AutoConstantType.SpotLightViewProjMatrix || def.AutoConstantType == GpuProgramParameters.AutoConstantType.SpotLightWorldViewProjMatrix ) { try { if ( named ) parameters.SetNamedAutoConstant( name, def.AutoConstantType, 0 ); else parameters.SetAutoConstant( index, def.AutoConstantType, 0 ); } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed" ); } } else { compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line, "extra parameters required by constant definition " + atom1.Value ); } } else { bool success = false; int extraInfo = 0; if ( i3 == null ) { // Handle only one extra value if ( getInt( i2, out extraInfo ) ) { success = true; } } else { // Handle two extra values int extraInfo1 = 0, extraInfo2 = 0; if ( getInt( i2, out extraInfo1 ) && getInt( i3, out extraInfo2 ) ) { extraInfo = extraInfo1 | ( extraInfo2 << 16 ); success = true; } } if ( success ) { try { if ( named ) parameters.SetNamedAutoConstant( name, def.AutoConstantType, extraInfo ); else parameters.SetAutoConstant( index, def.AutoConstantType, extraInfo ); } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed" ); } } else { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "invalid auto constant extra info parameter" ); } } } break; #endregion Int #region Real case GpuProgramParameters.AutoConstantDataType.Real: if ( def.AutoConstantType == GpuProgramParameters.AutoConstantType.Time || def.AutoConstantType == GpuProgramParameters.AutoConstantType.FrameTime ) { Real f = 1.0f; if ( i2 != null ) getReal( i2, out f ); try { if ( named ) { parameters.SetNamedAutoConstantReal(name, def.AutoConstantType, f); } else parameters.SetAutoConstantReal( index, def.AutoConstantType, f ); } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed" ); } } else { if ( i2 != null ) { Real extraInfo = 0.0f; if ( getReal( i2, out extraInfo ) ) { try { if ( named ) { parameters.SetNamedAutoConstantReal(name, def.AutoConstantType, extraInfo); } else parameters.SetAutoConstantReal( index, def.AutoConstantType, extraInfo ); } catch { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed" ); } } else { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "incorrect float argument definition in extra parameters" ); } } else { compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line, "extra parameters required by constant definition " + atom1.Value ); } } break; #endregion Real } } else { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line ); } } else { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line ); } } break;
/// <see cref="AbstractNode.Clone"/> public override AbstractNode Clone() { var node = new ObjectAbstractNode( Parent ); node.File = File; node.Line = Line; node.Name = this.Name; node.Cls = this.Cls; node.Id = this.Id; node.IsAbstract = this.IsAbstract; foreach ( var an in this.Children ) { var newNode = (AbstractNode)( an.Clone() ); newNode.Parent = node; node.Children.Add( newNode ); } foreach ( var an in this.Values ) { var newNode = (AbstractNode)( an.Clone() ); newNode.Parent = node; node.Values.Add( newNode ); } node._environment = new Dictionary<string, string>( this._environment ); return node; }
protected void _translateShadowReceiverFragmentProgramRef( ScriptCompiler compiler, ObjectAbstractNode node ) { string createdProgramName; var pass = _commonProgramChecks( compiler, node, out createdProgramName ); if ( pass == null ) { return; } pass.SetShadowReceiverFragmentProgram( createdProgramName ); if ( GpuProgramManager.Instance.GetByName( createdProgramName ).IsSupported ) { var parameters = pass.ShadowReceiverFragmentProgramParameters; GpuProgramTranslator.TranslateProgramParameters( compiler, parameters, node ); } }
private void visit( ConcreteNode node ) { AbstractNode asn = null; // Import = "import" >> 2 children, _current == null if ( node.Type == ConcreteNodeType.Import && this._current == null ) { if ( node.Children.Count > 2 ) { this._compiler.AddError( CompileErrorCode.FewerParametersExpected, node.File, node.Line ); return; } if ( node.Children.Count < 2 ) { this._compiler.AddError( CompileErrorCode.StringExpected, node.File, node.Line ); return; } var impl = new ImportAbstractNode(); impl.Line = node.Line; impl.File = node.File; impl.Target = node.Children[ 0 ].Token; impl.Source = node.Children[ 1 ].Token; asn = impl; } // variable set = "set" >> 2 children, children[0] == variable else if ( node.Type == ConcreteNodeType.VariableAssignment ) { if ( node.Children.Count > 2 ) { this._compiler.AddError( CompileErrorCode.FewerParametersExpected, node.File, node.Line ); return; } if ( node.Children.Count < 2 ) { this._compiler.AddError( CompileErrorCode.StringExpected, node.File, node.Line ); return; } if ( node.Children[ 0 ].Type != ConcreteNodeType.Variable ) { this._compiler.AddError( CompileErrorCode.VariableExpected, node.Children[ 0 ].File, node.Children[ 0 ].Line ); return; } var name = node.Children[ 0 ].Token; var value = node.Children[ 1 ].Token; if ( this._current != null && this._current is ObjectAbstractNode ) { var ptr = (ObjectAbstractNode)this._current; ptr.SetVariable( name, value ); } else { this._compiler.Environment.Add( name, value ); } } // variable = $*, no children else if ( node.Type == ConcreteNodeType.Variable ) { if ( node.Children.Count != 0 ) { this._compiler.AddError( CompileErrorCode.FewerParametersExpected, node.File, node.Line ); return; } var impl = new VariableGetAbstractNode( this._current ); impl.Line = node.Line; impl.File = node.File; impl.Name = node.Token; asn = impl; } // Handle properties and objects here else if ( node.Children.Count != 0 ) { // Grab the last two nodes ConcreteNode temp1 = null, temp2 = null; if ( node.Children.Count >= 1 ) { temp1 = node.Children[ node.Children.Count - 1 ]; } if ( node.Children.Count >= 2 ) { temp2 = node.Children[ node.Children.Count - 2 ]; } // object = last 2 children == { and } if ( temp1 != null && temp2 != null && temp1.Type == ConcreteNodeType.RightBrace && temp2.Type == ConcreteNodeType.LeftBrace ) { if ( node.Children.Count < 2 ) { this._compiler.AddError( CompileErrorCode.StringExpected, node.File, node.Line ); return; } var impl = new ObjectAbstractNode( this._current ); impl.Line = node.Line; impl.File = node.File; impl.IsAbstract = false; // Create a temporary detail list var temp = new List<ConcreteNode>(); if ( node.Token == "abstract" ) { impl.IsAbstract = true; } else { temp.Add( node ); } temp.AddRange( node.Children ); // Get the type of object IEnumerator<ConcreteNode> iter = temp.GetEnumerator(); iter.MoveNext(); impl.Cls = iter.Current.Token; var validNode = iter.MoveNext(); // Get the name // Unless the type is in the exclusion list if ( validNode && ( iter.Current.Type == ConcreteNodeType.Word || iter.Current.Type == ConcreteNodeType.Quote ) && !this._compiler._isNameExcluded( impl.Cls, this._current ) ) { impl.Name = iter.Current.Token; validNode = iter.MoveNext(); } // Everything up until the colon is a "value" of this object while ( validNode && iter.Current.Type != ConcreteNodeType.Colon && iter.Current.Type != ConcreteNodeType.LeftBrace ) { if ( iter.Current.Type == ConcreteNodeType.Variable ) { var var = new VariableGetAbstractNode( impl ); var.File = iter.Current.File; var.Line = iter.Current.Line; var.Name = iter.Current.Token; impl.Values.Add( var ); } else { var atom = new AtomAbstractNode( impl ); atom.File = iter.Current.File; atom.Line = iter.Current.Line; atom.Value = iter.Current.Token; impl.Values.Add( atom ); } validNode = iter.MoveNext(); } // Find the base if ( validNode && iter.Current.Type == ConcreteNodeType.Colon ) { // Children of the ':' are bases foreach ( var j in iter.Current.Children ) { impl.Bases.Add( j.Token ); } validNode = iter.MoveNext(); } // Finally try to map the cls to an id if ( this._compiler.KeywordMap.ContainsKey( impl.Cls ) ) { impl.Id = this._compiler.KeywordMap[ impl.Cls ]; } asn = (AbstractNode)impl; this._current = impl; // Visit the children of the { AbstractTreeBuilder.Visit( this, temp2.Children ); // Go back up the stack this._current = impl.Parent; } // Otherwise, it is a property else { var impl = new PropertyAbstractNode( this._current ); impl.Line = node.Line; impl.File = node.File; impl.Name = node.Token; if ( this._compiler.KeywordMap.ContainsKey( impl.Name ) ) { impl.Id = this._compiler.KeywordMap[ impl.Name ]; } asn = (AbstractNode)impl; this._current = impl; // Visit the children of the { AbstractTreeBuilder.Visit( this, node.Children ); // Go back up the stack this._current = impl.Parent; } } // Otherwise, it is a standard atom else { var impl = new AtomAbstractNode( this._current ); impl.Line = node.Line; impl.File = node.File; impl.Value = node.Token; if ( this._compiler.KeywordMap.ContainsKey( impl.Value ) ) { impl.Id = this._compiler.KeywordMap[ impl.Value ]; } asn = impl; } if ( asn != null ) { if ( this._current != null ) { if ( this._current is PropertyAbstractNode ) { var impl = (PropertyAbstractNode)this._current; impl.Values.Add( asn ); } else { var impl = (ObjectAbstractNode)this._current; impl.Children.Add( asn ); } } else { this._nodes.Add( asn ); } } }
protected void _translateUnifiedGpuProgram( ScriptCompiler compiler, ObjectAbstractNode obj ) { var customParameters = new NameValuePairList(); AbstractNode parameters = null; foreach ( var i in obj.Children ) { if ( i is PropertyAbstractNode ) { var prop = (PropertyAbstractNode)i; if ( prop.Name == "delegate" ) { var value = string.Empty; if ( prop.Values.Count != 0 && prop.Values[ 0 ] is AtomAbstractNode ) { value = ( (AtomAbstractNode)prop.Values[ 0 ] ).Value; } ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent( ProcessResourceNameScriptCompilerEvent.ResourceType.GpuProgram, value ); compiler._fireEvent( ref evt ); customParameters[ "delegate" ] = ( (ProcessResourceNameScriptCompilerEvent)evt ).Name; } else { var name = prop.Name; var value = string.Empty; var first = true; foreach ( var it in prop.Values ) { if ( it is AtomAbstractNode ) { if ( !first ) { value += " "; } else { first = false; } value += ( (AtomAbstractNode)it ).Value; } } customParameters.Add( name, value ); } } else if ( i is ObjectAbstractNode ) { if ( ( (ObjectAbstractNode)i ).Id == (uint)Keywords.ID_DEFAULT_PARAMS ) { parameters = i; } else { processNode( compiler, i ); } } } // Allocate the program Object progObj; HighLevelGpuProgram prog = null; ScriptCompilerEvent evnt = new CreateHighLevelGpuProgramScriptCompilerEvent( obj.File, obj.Name, compiler.ResourceGroup, string.Empty, "unified", _translateIDToGpuProgramType( obj.Id ) ); var processed = compiler._fireEvent( ref evnt, out progObj ); if ( !processed ) { prog = (HighLevelGpuProgram) ( HighLevelGpuProgramManager.Instance.CreateProgram( obj.Name, compiler.ResourceGroup, "unified", _translateIDToGpuProgramType( obj.Id ) ) ); } else { prog = (HighLevelGpuProgram)progObj; } // Check that allocation worked if ( prog == null ) { compiler.AddError( CompileErrorCode.ObjectAllocationError, obj.File, obj.Line, "gpu program \"" + obj.Name + "\" could not be created" ); return; } obj.Context = prog; prog.IsMorphAnimationIncluded = false; prog.PoseAnimationCount = 0; prog.IsSkeletalAnimationIncluded = false; prog.IsVertexTextureFetchRequired = false; prog.Origin = obj.File; // Set the custom parameters prog.SetParameters( customParameters ); // Set up default parameters if ( prog.IsSupported && parameters != null ) { var ptr = prog.DefaultParameters; GpuProgramTranslator.TranslateProgramParameters( compiler, ptr, (ObjectAbstractNode)parameters ); } }
protected void _translateGpuProgram( ScriptCompiler compiler, ObjectAbstractNode obj ) { var customParameters = new NameValuePairList(); string syntax = string.Empty, source = string.Empty; AbstractNode parameters = null; foreach ( var i in obj.Children ) { if ( i is PropertyAbstractNode ) { var prop = (PropertyAbstractNode)i; if ( prop.Id == (uint)Keywords.ID_SOURCE ) { if ( prop.Values.Count != 0 ) { if ( prop.Values[ 0 ] is AtomAbstractNode ) { source = ( (AtomAbstractNode)prop.Values[ 0 ] ).Value; } else { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "source file expected" ); } } else { compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line, "source file expected" ); } } else if ( prop.Id == (uint)Keywords.ID_SYNTAX ) { if ( prop.Values.Count != 0 ) { if ( prop.Values[ 0 ] is AtomAbstractNode ) { syntax = ( (AtomAbstractNode)prop.Values[ 0 ] ).Value; } else { compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, "syntax string expected" ); } } else { compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line, "syntax string expected" ); } } else { string name = prop.Name, value = string.Empty; var first = true; foreach ( var it in prop.Values ) { if ( it is AtomAbstractNode ) { if ( !first ) { value += " "; } else { first = false; } value += ( (AtomAbstractNode)it ).Value; } } customParameters.Add( name, value ); } } else if ( i is ObjectAbstractNode ) { if ( ( (ObjectAbstractNode)i ).Id == (uint)Keywords.ID_DEFAULT_PARAMS ) { parameters = i; } else { processNode( compiler, i ); } } } if ( !GpuProgramManager.Instance.IsSyntaxSupported( syntax ) ) { compiler.AddError( CompileErrorCode.UnsupportedByRenderSystem, obj.File, obj.Line ); //Register the unsupported program so that materials that use it know that //it exists but is unsupported var unsupportedProg = GpuProgramManager.Instance.Create( obj.Name, compiler.ResourceGroup, _translateIDToGpuProgramType( obj.Id ), syntax ); return; } // Allocate the program object progObj; GpuProgram prog = null; ScriptCompilerEvent evt = new CreateGpuProgramScriptCompilerEvent( obj.File, obj.Name, compiler.ResourceGroup, source, syntax, _translateIDToGpuProgramType( obj.Id ) ); var processed = compiler._fireEvent( ref evt, out progObj ); if ( !processed ) { prog = (GpuProgram) GpuProgramManager.Instance.CreateProgram( obj.Name, compiler.ResourceGroup, source, _translateIDToGpuProgramType( obj.Id ), syntax ); } else { prog = (GpuProgram)progObj; } // Check that allocation worked if ( prog == null ) { compiler.AddError( CompileErrorCode.ObjectAllocationError, obj.File, obj.Line, "gpu program \"" + obj.Name + "\" could not be created" ); return; } obj.Context = prog; prog.IsMorphAnimationIncluded = false; prog.PoseAnimationCount = 0; prog.IsSkeletalAnimationIncluded = false; prog.IsVertexTextureFetchRequired = false; prog.Origin = obj.File; // Set the custom parameters prog.SetParameters( customParameters ); // Set up default parameters if ( prog.IsSupported && parameters != null ) { var ptr = prog.DefaultParameters; GpuProgramTranslator.TranslateProgramParameters( compiler, ptr, (ObjectAbstractNode)parameters ); } }