| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962 | // Amplify Shader Editor - Visual Shader Editing Tool// Copyright (c) Amplify Creations, Lda <info@amplify.pt>using System;using System.IO;using System.Collections.Generic;using UnityEditor;using UnityEngine;using UnityEditorInternal;using System.Linq;namespace AmplifyShaderEditor{	public enum AdditionalLineType	{		Include,		Define,		Pragma,		Custom	}	public enum AdditionalContainerOrigin	{		Native,		ShaderFunction,		Custom	}	[Serializable]	public class AdditionalDirectiveContainerSaveItem	{		public AdditionalLineType LineType = AdditionalLineType.Include;		public string LineValue = string.Empty;		public bool GUIDToggle = false;		public string GUIDValue = string.Empty;		public bool ShowConditionals = false;		public int VersionMin = 0;		public int VersionMax = 0;		public string Passes = string.Empty;		public AdditionalContainerOrigin Origin = AdditionalContainerOrigin.Custom;		public AdditionalDirectiveContainerSaveItem( AdditionalDirectiveContainer container )		{			LineType = container.LineType;			LineValue = container.LineValue;			GUIDToggle = container.GUIDToggle;			GUIDValue = container.GUIDValue;			ShowConditionals = container.ShowConditionals;			VersionMin = container.VersionMin;			VersionMax = container.VersionMax;			Passes = container.Passes;			Origin = container.Origin;		}	}	[Serializable]	public class AdditionalDirectiveContainer : ScriptableObject	{		public AdditionalLineType LineType = AdditionalLineType.Include;		public string LineValue = string.Empty;		public bool GUIDToggle = false;		public string GUIDValue = string.Empty;		public bool ShowConditionals = false;		public int VersionMin = 0;		public int VersionMax = 0;		public string Passes = string.Empty;		public AdditionalContainerOrigin Origin = AdditionalContainerOrigin.Custom;		public TextAsset LibObject = null;		public string OwnerId = string.Empty;		public void Init( string ownerId, AdditionalDirectiveContainer item )		{			LineType = item.LineType;			LineValue = item.LineValue;			GUIDToggle = item.GUIDToggle;			GUIDValue = item.GUIDValue;			ShowConditionals = item.ShowConditionals;			VersionMin = item.VersionMin;			VersionMax = item.VersionMax;			Passes = item.Passes;			Origin = item.Origin;			LibObject = item.LibObject;			OwnerId = ownerId;		}		public void Init( AdditionalDirectiveContainerSaveItem item )		{			LineType = item.LineType;			LineValue = item.LineValue;			GUIDToggle = item.GUIDToggle;			GUIDValue = item.GUIDValue;			ShowConditionals = item.ShowConditionals;			VersionMin = item.VersionMin;			VersionMax = item.VersionMax;			Passes = item.Passes;			Origin = item.Origin;			if( GUIDToggle )			{				LibObject = AssetDatabase.LoadAssetAtPath<TextAsset>( AssetDatabase.GUIDToAssetPath( GUIDValue ) );			}		}		public void OnDestroy()		{			//Debug.Log( "Destoying directives" );			LibObject = null;		}		public string Value		{			get			{				switch( LineType )				{					case AdditionalLineType.Include:					{						if( GUIDToggle )						{							string shaderPath = AssetDatabase.GUIDToAssetPath( GUIDValue );							if( !string.IsNullOrEmpty( shaderPath ) )								return shaderPath;						}						return LineValue;					}					case AdditionalLineType.Define: return LineValue;					case AdditionalLineType.Pragma: return LineValue;				}				return LineValue;			}		}		public string FormattedValue		{			get			{				switch( LineType )				{					case AdditionalLineType.Include:					{						if( GUIDToggle )						{							string shaderPath = AssetDatabase.GUIDToAssetPath( GUIDValue );							if( !string.IsNullOrEmpty( shaderPath ) )								return string.Format( Constants.IncludeFormat, shaderPath );						}						return string.Format( Constants.IncludeFormat, LineValue );					}					case AdditionalLineType.Define:					return string.Format( Constants.DefineFormat, LineValue );					case AdditionalLineType.Pragma:					return string.Format( Constants.PragmaFormat, LineValue );				}				return LineValue;			}		}	}	public enum ReordableAction	{		None,		Add,		Remove	}	[Serializable]	public sealed class TemplateAdditionalDirectivesHelper : TemplateModuleParent	{		private string NativeFoldoutStr = "Native";		[SerializeField]		private List<AdditionalDirectiveContainer> m_additionalDirectives = new List<AdditionalDirectiveContainer>();		[SerializeField]		private List<AdditionalDirectiveContainer> m_shaderFunctionDirectives = new List<AdditionalDirectiveContainer>();		[SerializeField]		private List<string> m_nativeDirectives = new List<string>();		[SerializeField]		private int m_nativeDirectivesIndex = -1;		[SerializeField]		private bool m_nativeDirectivesFoldout = false;		//ONLY USED BY SHADER FUNCTIONS		// Since AdditionalDirectiveContainer must be a ScriptableObject because of serialization shenanigans it will not serialize the info correctly into the shader function when saving it into a file ( it only saves the id )		// For it to properly work, each AdditionalDirectiveContainer should be added to the SF asset, but that would make it to have children ( which are seen on the project inspector )		// Must revisit this later on and come up with a proper solution		[SerializeField]		private List<AdditionalDirectiveContainerSaveItem> m_directivesSaveItems = new List<AdditionalDirectiveContainerSaveItem>();		private ReordableAction m_actionType = ReordableAction.None;		private int m_actionIndex = 0;		private ReorderableList m_reordableList = null;		private GUIStyle m_propertyAdjustment;		private UndoParentNode m_currOwner;		private Rect m_nativeRect = Rect.zero;		public TemplateAdditionalDirectivesHelper( string moduleName ) : base( moduleName ) { }		//public void AddShaderFunctionItem( AdditionalLineType type, string item )		//{		//	UpdateShaderFunctionDictionary();		//	string id = type + item;		//	if( !m_shaderFunctionDictionary.ContainsKey( id ) )		//	{		//		AdditionalDirectiveContainer newItem = ScriptableObject.CreateInstance<AdditionalDirectiveContainer>();		//		newItem.LineType = type;		//		newItem.LineValue = item;		//		newItem.hideFlags = HideFlags.HideAndDontSave;		//		m_shaderFunctionDirectives.Add( newItem );		//		m_shaderFunctionDictionary.Add( id, newItem );		//	}		//}		public void AddShaderFunctionItems( string ownerOutputId, List<AdditionalDirectiveContainer> functionList )		{			RemoveShaderFunctionItems( ownerOutputId );			if( functionList.Count > 0 )			{				for( int i = 0; i < functionList.Count; i++ )				{					AdditionalDirectiveContainer item = ScriptableObject.CreateInstance<AdditionalDirectiveContainer>();					item.Init( ownerOutputId, functionList[ i ] );					item.hideFlags = HideFlags.HideAndDontSave;					m_shaderFunctionDirectives.Add( item );				}			}			//if( functionList.Count > 0 )			//{			//	m_shaderFunctionDirectives.AddRange( functionList );			//}		}		public void RemoveShaderFunctionItems( string ownerOutputId/*, List<AdditionalDirectiveContainer> functionList */)		{			List<AdditionalDirectiveContainer>  list = m_shaderFunctionDirectives.FindAll( ( x ) => x.OwnerId.Equals( ownerOutputId ));			for( int i = 0; i < list.Count; i++ )			{				m_shaderFunctionDirectives.Remove( list[ i ] );				ScriptableObject.DestroyImmediate( list[ i ] );			}			list.Clear();			list = null;			//for( int i = 0; i < functionList.Count; i++ )			//{			//	m_shaderFunctionDirectives.Remove( functionList[ i ] );			//}		}		//public void RemoveShaderFunctionItem( AdditionalLineType type, string item )		//{		//	m_shaderFunctionDirectives.RemoveAll( x => x.LineType == type && x.LineValue.Equals( item ) );		//}		public void AddItems( AdditionalLineType type, List<string> items )		{			int count = items.Count;			for( int i = 0; i < count; i++ )			{				AdditionalDirectiveContainer newItem = ScriptableObject.CreateInstance<AdditionalDirectiveContainer>();				newItem.LineType = type;				newItem.LineValue = items[ i ];				newItem.hideFlags = HideFlags.HideAndDontSave;				m_additionalDirectives.Add( newItem );			}			UpdateNativeIndex();		}		public void AddNativeContainer()		{			if( m_nativeDirectives.Count > 0 )			{				if( m_additionalDirectives.FindIndex( x => x.Origin.Equals( AdditionalContainerOrigin.Native ) ) == -1 )				{					AdditionalDirectiveContainer newItem = ScriptableObject.CreateInstance<AdditionalDirectiveContainer>();					newItem.Origin = AdditionalContainerOrigin.Native;					newItem.hideFlags = HideFlags.HideAndDontSave;					//m_additionalDirectives.Add( newItem );					//m_nativeDirectivesIndex = m_additionalDirectives.Count - 1;					m_additionalDirectives.Insert( 0, newItem );					m_nativeDirectivesIndex = 0;				}			}		}		public void FillNativeItems( List<string> nativeItems )		{			m_nativeDirectives.Clear();			m_nativeDirectives.AddRange( nativeItems );			AddNativeContainer();		}		void DrawNativeItems()		{			EditorGUILayout.Separator();			EditorGUI.indentLevel++;			int count = m_nativeDirectives.Count;			for( int i = 0; i < count; i++ )			{				EditorGUILayout.LabelField( m_nativeDirectives[ i ] );			}			EditorGUI.indentLevel--;			EditorGUILayout.Separator();		}		void DrawNativeItemsRect()		{			int count = m_nativeDirectives.Count;			m_nativeRect.y += EditorGUIUtility.singleLineHeight;			for( int i = 0; i < count; i++ )			{				EditorGUI.LabelField( m_nativeRect, m_nativeDirectives[ i ] );				m_nativeRect.y += EditorGUIUtility.singleLineHeight;			}		}		void DrawButtons()		{			EditorGUILayout.Separator();			// Add keyword			if( GUILayout.Button( string.Empty, UIUtils.PlusStyle, GUILayout.Width( Constants.PlusMinusButtonLayoutWidth ) ) )			{				AdditionalDirectiveContainer newItem = ScriptableObject.CreateInstance<AdditionalDirectiveContainer>();				newItem.hideFlags = HideFlags.HideAndDontSave;				m_additionalDirectives.Add( newItem );				UpdateNativeIndex();				EditorGUI.FocusTextInControl( null );				m_isDirty = true;			}			//Remove keyword			if( GUILayout.Button( string.Empty, UIUtils.MinusStyle, GUILayout.Width( Constants.PlusMinusButtonLayoutWidth ) ) )			{				if( m_additionalDirectives.Count > 0 )				{					AdditionalDirectiveContainer itemToDelete = m_additionalDirectives[ m_additionalDirectives.Count - 1 ];					m_additionalDirectives.RemoveAt( m_additionalDirectives.Count - 1 );					ScriptableObject.DestroyImmediate( itemToDelete );					EditorGUI.FocusTextInControl( null );				}				m_isDirty = true;			}		}		void DrawConditionals( Rect rect, AdditionalDirectiveContainer directive )		{			var tog = rect;			tog.width = 15;			tog.x += 5;			tog.y -= ( tog.height - ( EditorGUIUtility.singleLineHeight + 5 ) ) * 0.5f + 1;			tog.xMin += 2;			tog.yMin -= 2;			bool value = GUI.Toggle( tog, directive.ShowConditionals, "", UIUtils.MenuItemToggleStyle );			if ( Event.current.button == Constants.FoldoutMouseId )			{				directive.ShowConditionals = value;			}			if ( directive.ShowConditionals )			{				const int labelWidth = 70;				const int versionEditWidth = 55;				Rect condPos = rect;				condPos.height = EditorGUIUtility.singleLineHeight;				// List of passes to apply directive				directive.Passes = ( directive.Passes != null ) ? directive.Passes : string.Empty;				condPos.x = rect.x + 23;				condPos.y += EditorGUIUtility.singleLineHeight + 2;				condPos.width = labelWidth;				EditorGUI.LabelField( condPos, new GUIContent( "Passes", "Template pass names separated by semicolon (;). Empty means it will be included in all passes." ) );				condPos.x += labelWidth;				condPos.xMax = rect.xMax + 1;				directive.Passes = m_currOwner.EditorGUITextField( condPos, string.Empty, directive.Passes );				// Range of SRP versions to apply directive				condPos.x = rect.x + 23;				condPos.y += EditorGUIUtility.singleLineHeight + 2;				condPos.width = labelWidth;				EditorGUI.LabelField( condPos, new GUIContent( "SRPVersion", "Valid SRP version numbers must have 6 digits and be equal or higher than 100000, the lowest supported version." ) );				condPos.x += labelWidth;				condPos.width = versionEditWidth;				string minText = ( directive.VersionMin == 0 ) ? string.Empty : directive.VersionMin.ToString();				minText = m_currOwner.EditorGUITextField( condPos, string.Empty, minText );				directive.VersionMin = int.TryParse( minText, out int min ) ? min : 0;				condPos.x += versionEditWidth + 5;				EditorGUI.LabelField( condPos, "to" );				condPos.x += 20;				string maxText = ( directive.VersionMax == 0 ) ? string.Empty : directive.VersionMax.ToString();				maxText = m_currOwner.EditorGUITextField( condPos, string.Empty, maxText );				directive.VersionMax = int.TryParse( maxText, out int max ) ? max : 0;				condPos.x = rect.x + 40;			}		}		public override void Draw( UndoParentNode currOwner, bool style = true )		{			m_currOwner = currOwner;			if( m_reordableList == null )			{				m_reordableList = new ReorderableList( m_additionalDirectives, typeof( AdditionalDirectiveContainer ), true, false, false, false )				{					headerHeight = 0,					footerHeight = 0,					showDefaultBackground = false,					elementHeightCallback = ( index ) =>					{						if( m_additionalDirectives[ index ].Origin == AdditionalContainerOrigin.Native && m_nativeDirectivesFoldout )						{							return ( m_nativeDirectives.Count + 1 ) * ( EditorGUIUtility.singleLineHeight ) + 5;						}						int lineCount = ( m_additionalDirectives[ index ].ShowConditionals ) ? 3 : 1;						return EditorGUIUtility.singleLineHeight * lineCount + 5;					},					drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) =>					{						if( m_additionalDirectives[ index ].Origin == AdditionalContainerOrigin.Native && m_nativeDirectivesFoldout )						{							rect.height = ( m_nativeDirectives.Count + 1 ) * ( EditorGUIUtility.singleLineHeight ) + 5;						}						if( m_additionalDirectives[ index ] != null )						{							float labelWidthStyleAdjust = 0;							if ( m_additionalDirectives[ index ].Origin == AdditionalContainerOrigin.Native )							{								rect.xMin -= 5;								rect.xMax += 1;								m_nativeRect = rect;								m_nativeRect.y -= ( m_nativeRect.height - ( EditorGUIUtility.singleLineHeight + 5 ) ) * 0.5f;								m_nativeRect.xMin += 2;								m_nativeRect.xMax -= 2;								m_nativeRect.yMax -= 2;								NodeUtils.DrawNestedPropertyGroup( ref m_nativeDirectivesFoldout, rect, NativeFoldoutStr, DrawNativeItemsRect, 4 );								return;							}							else							{								rect.xMin -= 10;								labelWidthStyleAdjust = 15;								DrawConditionals( rect, m_additionalDirectives[ index ] );							}							const int conditionalsOffset = 20;							rect.x += conditionalsOffset;							float popUpWidth = 88;							float widthAdjust = m_additionalDirectives[ index ].LineType == AdditionalLineType.Include ? -14 : 0;							widthAdjust -= conditionalsOffset;							Rect popupPos = new Rect( rect.x, rect.y, popUpWidth, EditorGUIUtility.singleLineHeight );							Rect GUIDTogglePos = m_additionalDirectives[ index ].LineType == AdditionalLineType.Include ? new Rect( rect.x + rect.width - 3 * Constants.PlusMinusButtonLayoutWidth - conditionalsOffset + 3, rect.y, Constants.PlusMinusButtonLayoutWidth, Constants.PlusMinusButtonLayoutWidth ) : new Rect();							Rect buttonPlusPos = new Rect( rect.x + rect.width - 2 * Constants.PlusMinusButtonLayoutWidth - conditionalsOffset + 1, rect.y - 2, Constants.PlusMinusButtonLayoutWidth, Constants.PlusMinusButtonLayoutWidth );							Rect buttonMinusPos = new Rect( rect.x + rect.width - Constants.PlusMinusButtonLayoutWidth - conditionalsOffset + 1, rect.y - 2, Constants.PlusMinusButtonLayoutWidth, Constants.PlusMinusButtonLayoutWidth );							float labelWidthBuffer = EditorGUIUtility.labelWidth;							Rect labelPos = new Rect( rect.x + popupPos.width - labelWidthStyleAdjust, rect.y, labelWidthStyleAdjust + rect.width - popupPos.width - buttonPlusPos.width - buttonMinusPos.width + widthAdjust, EditorGUIUtility.singleLineHeight );							m_additionalDirectives[ index ].LineType = (AdditionalLineType)m_currOwner.EditorGUIEnumPopup( popupPos, m_additionalDirectives[ index ].LineType );							if( m_additionalDirectives[ index ].LineType == AdditionalLineType.Include )							{								if( m_additionalDirectives[ index ].GUIDToggle )								{									//if( m_additionalDirectives[ index ].LibObject == null && !string.IsNullOrEmpty( m_additionalDirectives[ index ].GUIDValue ) )									//{									//	m_additionalDirectives[ index ].LibObject = AssetDatabase.LoadAssetAtPath<TextAsset>( AssetDatabase.GUIDToAssetPath( m_additionalDirectives[ index ].GUIDValue ) );									//}									EditorGUI.BeginChangeCheck();									TextAsset obj = m_currOwner.EditorGUIObjectField( labelPos, m_additionalDirectives[ index ].LibObject, typeof( TextAsset ), false ) as TextAsset;									if( EditorGUI.EndChangeCheck() )									{										string pathName = AssetDatabase.GetAssetPath( obj );										string extension = Path.GetExtension( pathName );										extension = extension.ToLower();										if( extension.Equals( ".cginc" ) || extension.Equals( ".hlsl" ) )										{											m_additionalDirectives[ index ].LibObject = obj;											m_additionalDirectives[ index ].GUIDValue = AssetDatabase.AssetPathToGUID( pathName );										}									}								}								else								{									m_additionalDirectives[ index ].LineValue = m_currOwner.EditorGUITextField( labelPos, string.Empty, m_additionalDirectives[ index ].LineValue );								}								if( GUI.Button( GUIDTogglePos, m_additionalDirectives[ index ].GUIDToggle ? UIUtils.FloatIntIconOFF : UIUtils.FloatIntIconON, UIUtils.FloatIntPickerONOFF ) )									m_additionalDirectives[ index ].GUIDToggle = !m_additionalDirectives[ index ].GUIDToggle;							}							else							{								m_additionalDirectives[ index ].LineValue = m_currOwner.EditorGUITextField( labelPos, string.Empty, m_additionalDirectives[ index ].LineValue );							}							//NodeUtils.DrawNestedPropertyGroup( ref m_additionalDirectives[ index ].ShowConditionals, rect, "TEMP", DrawConditionals, 4 );							if ( GUI.Button( buttonPlusPos, string.Empty, UIUtils.PlusStyle ) )							{								m_actionType = ReordableAction.Add;								m_actionIndex = index;							}							if( GUI.Button( buttonMinusPos, string.Empty, UIUtils.MinusStyle ) )							{								m_actionType = ReordableAction.Remove;								m_actionIndex = index;							}						}					},					onReorderCallback = ( ReorderableList list ) =>					{						UpdateNativeIndex();					}				};			}			if( m_actionType != ReordableAction.None )			{				switch( m_actionType )				{					case ReordableAction.Add:					{						AdditionalDirectiveContainer newItem = ScriptableObject.CreateInstance<AdditionalDirectiveContainer>();						newItem.hideFlags = HideFlags.HideAndDontSave;						m_additionalDirectives.Insert( m_actionIndex + 1, newItem );					}					break;					case ReordableAction.Remove:					AdditionalDirectiveContainer itemToDelete = m_additionalDirectives[ m_actionIndex ];					m_additionalDirectives.RemoveAt( m_actionIndex );					ScriptableObject.DestroyImmediate( itemToDelete );					break;				}				m_isDirty = true;				m_actionType = ReordableAction.None;				EditorGUI.FocusTextInControl( null );			}			bool foldoutValue = currOwner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalDirectives;			if( style )			{				NodeUtils.DrawPropertyGroup( ref foldoutValue, m_moduleName, DrawReordableList, DrawButtons );			}			else			{				NodeUtils.DrawNestedPropertyGroup( ref foldoutValue, m_moduleName, DrawReordableList, DrawButtons );			}			currOwner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalDirectives = foldoutValue;		}		void DrawReordableList()		{			if( m_reordableList != null )			{				if( m_propertyAdjustment == null )				{					m_propertyAdjustment = new GUIStyle();					m_propertyAdjustment.padding.left = 17;				}				//EditorGUILayout.BeginVertical( m_propertyAdjustment );				EditorGUILayout.Space();				if( m_nativeDirectives.Count > 0 )				{					//NodeUtils.DrawNestedPropertyGroup( ref m_nativeDirectivesFoldout, NativeFoldoutStr, DrawNativeItems, 4 );				}				if( m_additionalDirectives.Count == 0 )				{					EditorGUILayout.HelpBox( "Your list is Empty!\nUse the plus button to add one.", MessageType.Info );				}				else				{					m_reordableList.DoLayoutList();				}				EditorGUILayout.Space();				//EditorGUILayout.EndVertical();			}		}		public void AddAllToDataCollector( ref MasterNodeDataCollector dataCollector, TemplatePass pass, TemplateIncludePragmaContainter nativesContainer )		{			//List<AdditionalDirectiveContainer> list = m_additionalDirectives;			//int count = list.FindIndex( x => x.Origin.Equals( AdditionalContainerOrigin.Native ) );			//for( int i = 0; i < count; i++ )			//{			//	switch( list[ i ].LineType )			//	{			//		case AdditionalLineType.Include:			//		{			//			string value = list[ i ].Value;			//			if( !string.IsNullOrEmpty( value ) &&			//			  !nativesContainer.HasInclude( value ) )			//			{			//				dataCollector.AddToMisc( list[ i ].FormattedValue );			//			}			//		}			//		break;			//		case AdditionalLineType.Define:			//		{			//			if( !string.IsNullOrEmpty( list[ i ].LineValue ) &&			//			  !nativesContainer.HasDefine( list[ i ].LineValue ) )			//			{			//				dataCollector.AddToMisc( list[ i ].FormattedValue );			//			}			//		}			//		break;			//		case AdditionalLineType.Pragma:			//		{			//			if( !string.IsNullOrEmpty( list[ i ].LineValue ) &&			//			  !nativesContainer.HasPragma( list[ i ].LineValue ) )			//			{			//				dataCollector.AddToMisc( list[ i ].FormattedValue );			//			}			//		}			//		break;			//		default:			//		case AdditionalLineType.Custom:			//		dataCollector.AddToMisc( list[ i ].LineValue );			//		break;			//	}			//}			AddToDataCollector( ref dataCollector, pass, nativesContainer, false );			AddToDataCollector( ref dataCollector, pass, nativesContainer, true );		}		public void AddAllToDataCollector( ref MasterNodeDataCollector dataCollector )		{			AddToDataCollector( ref dataCollector, null, false );			AddToDataCollector( ref dataCollector, null, true );		}		bool TestConditionals( TemplatePass pass, AdditionalDirectiveContainer directive )		{			bool isSRP = ASEPackageManagerHelper.CurrentSRPVersion > 0;			if ( isSRP && directive.VersionMin != 0 && ASEPackageManagerHelper.CurrentSRPVersion < directive.VersionMin )			{				return false;			}			if ( isSRP && directive.VersionMax != 0 && ASEPackageManagerHelper.CurrentSRPVersion > directive.VersionMax )			{				return false;			}			if ( pass != null && !string.IsNullOrEmpty( directive.Passes ) )			{				string[] passes = directive.Passes.Split( ';' );				if ( !passes.Contains( pass.PassNameContainer.Data ) )				{					return false;				}			}			return true;		}		void AddToDataCollector( ref MasterNodeDataCollector dataCollector, TemplatePass pass, TemplateIncludePragmaContainter nativesContainer, bool fromSF )		{			List<AdditionalDirectiveContainer> list = fromSF ? m_shaderFunctionDirectives : m_additionalDirectives;			int count = list.Count;			for( int i = 0; i < count; i++ )			{				AdditionalDirectiveContainer directive = list[ i ];				int orderIdx = fromSF ? 1 : ( i > m_nativeDirectivesIndex ? 1 : -1 );				if ( !TestConditionals( pass, directive ) )				{					continue;				}				switch( directive.LineType )				{					case AdditionalLineType.Include:					{						string value = directive.Value;						if( !string.IsNullOrEmpty( value ) &&						  !nativesContainer.HasInclude( value ) )						{							dataCollector.AddToDirectives( directive.FormattedValue, orderIdx );						}					}					break;					case AdditionalLineType.Define:					{						if( !string.IsNullOrEmpty( directive.LineValue ) &&						  !nativesContainer.HasDefine( directive.LineValue ) )						{							dataCollector.AddToDirectives( directive.FormattedValue, orderIdx );						}					}					break;					case AdditionalLineType.Pragma:					{						if( !string.IsNullOrEmpty( directive.LineValue ) &&						  !nativesContainer.HasPragma( directive.LineValue ) )						{							dataCollector.AddToDirectives( directive.FormattedValue, orderIdx );						}					}					break;					default:					case AdditionalLineType.Custom:					dataCollector.AddToDirectives( directive.LineValue, orderIdx );						break;				}			}		}		void AddToDataCollector( ref MasterNodeDataCollector dataCollector, TemplatePass pass, bool fromSF )		{			List<AdditionalDirectiveContainer> list = fromSF ? m_shaderFunctionDirectives : m_additionalDirectives;			int orderIdx = 1;			int count = list.Count;			for( int i = 0; i < count; i++ )			{				AdditionalDirectiveContainer directive = list[ i ];				if ( !TestConditionals( pass, directive ) )				{					continue;				}				switch ( directive.LineType )				{					case AdditionalLineType.Include:					{						string value = directive.FormattedValue;						if( !string.IsNullOrEmpty( value ) )						{							dataCollector.AddToDirectives( value, orderIdx );						}					}					break;					case AdditionalLineType.Define:					{						if( !string.IsNullOrEmpty( directive.LineValue ) )						{							dataCollector.AddToDirectives( directive.FormattedValue, orderIdx );						}					}					break;					case AdditionalLineType.Pragma:					{						if( !string.IsNullOrEmpty( directive.LineValue ) )						{							dataCollector.AddToDirectives( directive.FormattedValue, orderIdx );						}					}					break;					default:					case AdditionalLineType.Custom:					dataCollector.AddToDirectives( directive.LineValue, orderIdx );					break;				}			}		}		public override void ReadFromString( ref uint index, ref string[] nodeParams )		{			try			{				m_nativeDirectivesIndex = -1;				int count = Convert.ToInt32( nodeParams[ index++ ] );				m_additionalDirectives.Clear();				for( int i = 0; i < count; i++ )				{					AdditionalLineType lineType = (AdditionalLineType)Enum.Parse( typeof( AdditionalLineType ), nodeParams[ index++ ] );					string lineValue = nodeParams[ index++ ];					AdditionalDirectiveContainer newItem = ScriptableObject.CreateInstance<AdditionalDirectiveContainer>();					newItem.hideFlags = HideFlags.HideAndDontSave;					newItem.LineType = lineType;					newItem.LineValue = lineValue.Replace( Constants.SemiColonSeparator, ';' );					if( UIUtils.CurrentShaderVersion() > 15607 )					{						newItem.GUIDToggle = Convert.ToBoolean( nodeParams[ index++ ] );						newItem.GUIDValue = nodeParams[ index++ ];						if( newItem.GUIDToggle )						{							newItem.LibObject = AssetDatabase.LoadAssetAtPath<TextAsset>( AssetDatabase.GUIDToAssetPath( newItem.GUIDValue ) );							if( newItem.LibObject == null )							{								Debug.LogWarning( "Include file not found with GUID " + newItem.GUIDValue );							}						}					}					AdditionalContainerOrigin origin = AdditionalContainerOrigin.Custom;					if( UIUtils.CurrentShaderVersion() > 16902 )					{						origin = (AdditionalContainerOrigin)Enum.Parse( typeof( AdditionalContainerOrigin ), nodeParams[ index++ ] );						newItem.Origin = origin;					}					if ( UIUtils.CurrentShaderVersion() > 19103 )					{						newItem.ShowConditionals = Convert.ToBoolean( nodeParams[ index++ ] );						newItem.VersionMin = Convert.ToInt32( nodeParams[ index++ ] );						newItem.VersionMax = Convert.ToInt32( nodeParams[ index++ ] );						newItem.Passes = nodeParams[ index++ ];						newItem.Passes.Replace( Constants.SemiColonSeparator, ';' );					}					m_additionalDirectives.Add( newItem );					if( origin == AdditionalContainerOrigin.Native )					{						m_nativeDirectivesIndex = i;					}				}				AddNativeContainer();			}			catch( Exception e )			{				Debug.LogException( e );			}		}		public override void WriteToString( ref string nodeInfo )		{			if( m_additionalDirectives.Count == 1 && m_additionalDirectives[ 0 ].Origin == AdditionalContainerOrigin.Native )			{				IOUtils.AddFieldValueToString( ref nodeInfo, 0 );				return;			}			IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives.Count );			for( int i = 0; i < m_additionalDirectives.Count; i++ )			{				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].LineType );				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].LineValue.Replace( ';', Constants.SemiColonSeparator ) );				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].GUIDToggle );				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].GUIDValue );				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].Origin );				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].ShowConditionals );				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].VersionMin );				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].VersionMax );				IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDirectives[ i ].Passes.Replace( ';', Constants.SemiColonSeparator ) );			}		}		// read comment on m_directivesSaveItems declaration		public void UpdateSaveItemsFromDirectives()		{			bool foundNull = false;			m_directivesSaveItems.Clear();			for( int i = 0; i < m_additionalDirectives.Count; i++ )			{				if( m_additionalDirectives[ i ] != null )				{					m_directivesSaveItems.Add( new AdditionalDirectiveContainerSaveItem( m_additionalDirectives[ i ] ) );				}				else				{					foundNull = true;				}			}			if( foundNull )			{				m_additionalDirectives.RemoveAll( item => item == null );			}		}		public void CleanNullDirectives()		{			m_additionalDirectives.RemoveAll( item => item == null );		}		public void ResetDirectivesOrigin()		{			for( int i = 0; i < m_directivesSaveItems.Count; i++ )			{				m_directivesSaveItems[ i ].Origin = AdditionalContainerOrigin.Custom;			}		}		// read comment on m_directivesSaveItems declaration		public void UpdateDirectivesFromSaveItems()		{			if( m_directivesSaveItems.Count > 0 )			{				for( int i = 0; i < m_additionalDirectives.Count; i++ )				{					if( m_additionalDirectives[ i ] != null )						ScriptableObject.DestroyImmediate( m_additionalDirectives[ i ] );				}				m_additionalDirectives.Clear();				for( int i = 0; i < m_directivesSaveItems.Count; i++ )				{					AdditionalDirectiveContainer newItem = ScriptableObject.CreateInstance<AdditionalDirectiveContainer>();					newItem.hideFlags = HideFlags.HideAndDontSave;					newItem.Init( m_directivesSaveItems[ i ] );					m_additionalDirectives.Add( newItem );				}				UpdateNativeIndex();				//m_directivesSaveItems.Clear();			}		}		void UpdateNativeIndex()		{			m_nativeDirectivesIndex = -1;			int count = m_additionalDirectives.Count;			for( int i = 0; i < count; i++ )			{				if( m_additionalDirectives[ i ].Origin == AdditionalContainerOrigin.Native )				{					m_nativeDirectivesIndex = i;					break;				}			}		}		public override void Destroy()		{			base.Destroy();			m_nativeDirectives.Clear();			m_nativeDirectives = null;			for( int i = 0; i < m_additionalDirectives.Count; i++ )			{				ScriptableObject.DestroyImmediate( m_additionalDirectives[ i ] );			}			m_additionalDirectives.Clear();			m_additionalDirectives = null;			for( int i = 0; i < m_shaderFunctionDirectives.Count; i++ )			{				ScriptableObject.DestroyImmediate( m_shaderFunctionDirectives[ i ] );			}			m_shaderFunctionDirectives.Clear();			m_shaderFunctionDirectives = null;			m_propertyAdjustment = null;			m_reordableList = null;		}		public List<AdditionalDirectiveContainer> DirectivesList { get { return m_additionalDirectives; } }		public bool IsValid { get { return m_validData; } set { m_validData = value; } }	}}
 |