Пример #1
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++;
				}
			}
		}
Пример #2
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="processor"></param>
		/// <param name="fileName"></param>
		void BuildAsset ( AssetProcessor processor, string[] args, AssetSource assetFile, ref BuildResult buildResult )
		{					
			try {
				
				//	Is up-to-date?
				if (!context.Options.ForceRebuild) {
					if (!Wildcard.Match(assetFile.KeyPath, context.Options.CleanPattern, true)) {
						if (assetFile.IsUpToDate) {
							buildResult.UpToDate ++;
							return;
						}
					}
				}


				var keyPath = assetFile.KeyPath;

				if (keyPath.Length > 40) {
					keyPath = "..." + keyPath.Substring( keyPath.Length - 40 + 3 );
				}

				Log.Message("{0,-40} {1,-5}   {3}", keyPath, Path.GetExtension(keyPath), string.Join(" ", args), assetFile.Hash );

				// Apply attribute :
				var parser =	new CommandLineParser( processor );
				parser.Configuration.OptionLeadingChar = '/';
				parser.Configuration.ThrowExceptionOnShowError = true;

				parser.ParseCommandLine( args );

				//
				//	Build :
				//
				processor.Process( assetFile, context );

				buildResult.Succeded ++;

			} catch ( Exception e ) {
				Log.Error( "{0} : {1}", assetFile.KeyPath, e.Message );
				buildResult.Failed ++;
			}
		}
Пример #3
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;
		}
Пример #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;
		}
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="processor"></param>
        /// <param name="fileName"></param>
        void BuildAsset(AssetProcessor processor, string[] args, AssetSource assetFile, ref BuildResult buildResult)
        {
            try {
                //	Is up-to-date?
                if (!context.Options.ForceRebuild)
                {
                    if (!Wildcard.Match(assetFile.KeyPath, context.Options.CleanPattern, true))
                    {
                        if (!context.Options.Files.Contains(assetFile.KeyPath))
                        {
                            if (assetFile.IsUpToDate)
                            {
                                buildResult.UpToDate++;
                                return;
                            }
                        }
                    }
                }


                var keyPath = assetFile.KeyPath;

                if (keyPath.Length > 40)
                {
                    keyPath = "..." + keyPath.Substring(keyPath.Length - 40 + 3);
                }

                Log.Message("{0,-40} {1,-5}   {3}", keyPath, Path.GetExtension(keyPath), string.Join(" ", args), assetFile.Hash);

                // Apply attribute :
                var parser = new CommandLineParser(processor.GetType());
                parser.OptionLeadingChar = '/';

                parser.ParseCommandLine(processor, args);

                //
                //	Build :
                //
                processor.Process(assetFile, context);

                buildResult.Succeded++;
            } catch (Exception e) {
                Log.Error("{0} : {1}", assetFile.KeyPath, e.Message);
                buildResult.Failed++;
            }
        }
Пример #6
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);
        }
Пример #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourceFolder"></param>
        /// <param name="targetFolder"></param>
        /// <param name="force"></param>
        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 = new List <AssetSource>();

            assetSources.AddRange(GatherRequiredShaders(context, result));
            assetSources.AddRange(GatherAssetFiles(ignorePatterns, iniData, context, ref result));
            Log.Message("");

            File.WriteAllLines(Path.Combine(options.FullOutputDirectory, "assetdb"), assetSources.Select(asset => asset.KeyPath).OrderBy(n => n));


            //
            //	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);
            }


            //
            //	Build megatexture
            //
            BuildMegatexture(ref result);


            return(result);
        }