예제 #1
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="keyPath">Key path</param>
		/// <param name="baseDir">Base directory</param>
		/// <param name="buildParameters"></param>
		/// <param name="context"></param>
		public AssetSource ( string keyPath, string baseDir, Type assetProcessorType, string[] buildArgs, BuildContext context )
		{
			this.assetProcessorType	=	assetProcessorType;
			this.outputDir			=	context.Options.FullOutputDirectory;
			this.fullPath			=	Path.Combine( baseDir, keyPath );
			this.baseDir			=	baseDir;
			this.keyPath			=	keyPath;
			this.BuildArguments		=	buildArgs;
			this.context			=	context;
		}
예제 #2
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="sourceFolder"></param>
		/// <returns></returns>
		List<AssetSource> GatherAssetFiles ( string[] ignorePatterns, IniData iniData, BuildContext context, ref BuildResult result )
		{
			var assetSources = new List<AssetSource>();

			//	key contain key path
			//	value containt full path
			var files	=	new List<LocalFile>();

			//	gather files from all directories 
			//	and then distinct them by key path.
			foreach ( var contentDir in context.ContentDirectories ) {

				var localFiles	=	Directory.EnumerateFiles( contentDir, "*", SearchOption.AllDirectories )
								.Where( f1 => Path.GetFileName(f1).ToLowerInvariant() != ".content" );
							
				files.AddRange( localFiles.Select( fullpath => new LocalFile( contentDir, fullpath ) ) );
			}

			files			=	files.DistinctBy( file => file.KeyPath ).ToList();
			result.Total	=	files.Count;


			//	ignore files by ignore pattern
			//	and count ignored files :
			result.Ignored = files.RemoveAll( file => {
				foreach ( var pattern in ignorePatterns ) {
					if (Wildcard.Match( file.KeyPath, pattern )) {
						return true;
					}
				}
				return false;
			});



			foreach ( var section in iniData.Sections ) {

				//	'Ingore' is a special section.
				if (section.SectionName=="Ignore") { continue; }
				if (section.SectionName=="ContentDirectories") { continue; }
				if (section.SectionName=="BinaryDirectories") { continue; }
				if (section.SectionName=="Download") { continue; }

				//	get processor :
				if (!processors.ContainsKey(section.SectionName)) {
					Log.Warning("Asset processor '{0}' not found. Files will be skipped.", section.SectionName );
					Log.Message("");
					continue;
				}
				
				var procBind = processors[section.SectionName];

				//	get mask and arguments :
				var maskArgs = section.Keys
					.Reverse()
					.Select( key => new {
						Mask = key.KeyName.Split(' ', '\t').FirstOrDefault(), 
						Args = CommandLineParser.SplitCommandLine( key.KeyName ).Skip(1).ToArray()
					 })
					.ToList();
					

				foreach ( var file in files ) {

					if (file.Handled) {
						continue;
					}

					foreach ( var maskArg in maskArgs ) {
						if ( Wildcard.Match( file.KeyPath, maskArg.Mask, true ) ) {
							file.Handled = true;
							assetSources.Add( new AssetSource( file.KeyPath, file.BaseDir, procBind.Type, maskArg.Args, context ) ); 
							break;
						}
					}
				}

				//	count unhandled files :
				result.Skipped = files.Count( f => !f.Handled );
			}


			return assetSources;
		}
예제 #3
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="section"></param>
		void Download ( BuildContext context, KeyDataCollection section, BuildResult result )
		{
			Log.Message("Downloading...");

			foreach ( var keyValue in section ) {

				if (Path.IsPathRooted(keyValue.KeyName)) {
					throw new BuildException(string.Format("Rooted paths are not allowed: {0}", keyValue.KeyName));
				}
				
				var fullPath	=	Path.Combine( context.Options.FullInputDirectory, keyValue.KeyName );
				var urlName		=	keyValue.Value;

				Log.Message("  {0} -> {1}", urlName, keyValue.KeyName);

				try {
					
					DownloadIfModified( urlName, fullPath);
					 
				} catch ( WebException wex ) {
					Log.Error("{0} : {1}", keyValue.KeyName, wex.Message );
					result.Failed++;
				}
			}
		}
예제 #4
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="sourceFolder"></param>
		/// <param name="targetFolder"></param>
		/// <param name="force"></param>
		public BuildResult Build ( BuildOptions options, IniData iniData )
		{
			BuildResult result	=	new BuildResult();
	
			context				=	new BuildContext( options, iniData );
			var ignorePatterns	=	new string[0];

			if ( iniData.Sections.ContainsSection("Ignore") ) {
				ignorePatterns	=	iniData.Sections["Ignore"]
									.Select( element => element.KeyName )
									.Select( key => ContentUtils.BackslashesToSlashes( key ) )
									.ToArray();
			}


			if ( iniData.Sections.ContainsSection("Download") ) {
				Download( context, iniData.Sections["Download"], result );
			}


			//
			//	gather files on source folder ignoring 
			//	files that match ignore pattern :
			//
			Log.Message("Gathering files...");
			var assetSources =	GatherAssetFiles( ignorePatterns, iniData, context, ref result );
			Log.Message("");


			//
			//	Check hash collisions :
			//
			var collisions	=	assetSources
								.GroupBy( file0 => file0.TargetName )
								.Where( fileGroup1 => fileGroup1.Count() > 1 )
								.Distinct()
								.ToArray();

			if (collisions.Any()) {
				Log.Error("Hash collisions detected:");
				int collisionCount = 0;
				foreach ( var collision in collisions ) {
					Log.Error("  [{0}] {1}", collisionCount++, collision.Key);
					foreach ( var collisionEntry in collision ) {
						Log.Error( "    {0}",  collisionEntry.FullSourcePath );
					}
				}
				throw new BuildException("Hash collisions detected");
			}


			//
			//	remove stale built content :
			//
			Log.Message("Cleaning stale content up...");
			CleanStaleContent( options.FullOutputDirectory, assetSources );			
			Log.Message("");


			//
			//	Build everything :
			//
			foreach ( var assetSource in assetSources ) {
				
				var proc = assetSource.CreateProcessor();
				BuildAsset( proc, assetSource.BuildArguments, assetSource, ref result );

			}

			return result;
		}