Ejemplo n.º 1
0
        public async Task Run(OperationArguments args)
        {
            var platformTasks = args.Platforms.Select(platform => Task.Run(async() =>
            {
                Console.WriteLine("Starting compilation for " + platform + "...");

                var targetPlatform = (TargetPlatform)Enum.Parse(typeof(TargetPlatform), platform);

                var targetOutputPath = Path.Combine(new DirectoryInfo(args.OutputPath).FullName, platform);
                Directory.CreateDirectory(targetOutputPath);

                var kernel = new StandardKernel();
                kernel.Load <ProtogameAssetModule>();
                var sourceLayer = kernel.Get <LocalFilesystemAssetFsLayer>(new NamedConstructorArgument("basePath", Environment.CurrentDirectory));
                kernel.Unbind <IAssetFsLayer>();
                kernel.Bind <IAssetFsLayer>().ToMethod(ctx => sourceLayer);
                kernel.Bind <IAssetFsLayer>().ToMethod(ctx => ctx.Kernel.Get <LocalFilesystemAssetFsLayer>(new NamedConstructorArgument("basePath", targetOutputPath)));
                kernel.Unbind <ICompiledAssetFs>();
                kernel.Rebind <ICompiledAssetFs>().ToMethod(ctx => ctx.Kernel.Get <HostCompiledAssetFs>(new NamedConstructorArgument("targetPlatform", targetPlatform)));
                kernel.Rebind <IRenderBatcher>().To <NullRenderBatcher>();
                kernel.Unbind <IAssetCompiler>();
                (new ProtogameAssetModule()).LoadRawAssetStrategies(kernel);
                LoadAndBindTypes(kernel, args.Assemblies);

                var compiledAssetFs = kernel.Get <ICompiledAssetFs>();
                var assetFs         = kernel.Get <IAssetFs>();

                Console.WriteLine("Scanning for content...");
                var compilationTasks = await compiledAssetFs.ListTasks().ConfigureAwait(false);
                var saveTasks        = new List <Task>();
                var expectedPaths    = new ConcurrentBag <string>();
                foreach (var compilationTask in compilationTasks)
                {
                    saveTasks.Add(compilationTask.ContinueWith(async compiledAssetTask =>
                    {
                        var compiledAsset = await compiledAssetTask.ConfigureAwait(false);
                        var originalAsset = await assetFs.Get(compiledAsset.Name).ConfigureAwait(false);
                        var targetPath    = Path.Combine(targetOutputPath, compiledAsset.Name.Replace('.', Path.DirectorySeparatorChar)) + ".bin";
                        // Check that the source file exists on disk in order to add it to the expected paths.
                        if (await sourceLayer.Get(compiledAsset.Name).ConfigureAwait(false) != null)
                        {
                            expectedPaths.Add(targetPath);
                        }
                        if (originalAsset.ModificationTimeUtcTimestamp < compiledAsset.ModificationTimeUtcTimestamp)
                        {
                            Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                            using (var writer = new FileStream(targetPath, FileMode.Create, FileAccess.Write, FileShare.None))
                            {
                                Console.WriteLine("Saving " + compiledAsset.Name + " to disk for " + platform + "...");
                                using (var stream = await compiledAsset.GetContentStream().ConfigureAwait(false))
                                {
                                    await stream.CopyToAsync(writer).ConfigureAwait(false);
                                }
                            }
                        }
                    }));
                }

                await Task.WhenAll(saveTasks).ConfigureAwait(false);

                Console.WriteLine("Deleting compiled assets that have no source asset...");

                var allActualCompiledAssets   = FindAllCompiledAssets(targetOutputPath).Select(x => Path.Combine(targetOutputPath, x.Replace('.', Path.DirectorySeparatorChar) + ".bin").ToLowerInvariant()).ToArray();
                var allExpectedCompiledAssets = expectedPaths.Select(x => x.ToLowerInvariant()).ToArray();
                var hashsetWorking            = new HashSet <string>(allActualCompiledAssets);
                var hashsetExpected           = new HashSet <string>(allExpectedCompiledAssets);
                hashsetWorking.ExceptWith(hashsetExpected);
                foreach (var compiledAssetOnDisk in hashsetWorking)
                {
                    Console.WriteLine("Deleting " + compiledAssetOnDisk + "...");
                    File.Delete(compiledAssetOnDisk);
                }
            })).ToArray();

            await Task.WhenAll(platformTasks);
        }
Ejemplo n.º 2
0
        public static void Main(string[] args)
        {
            var    assemblies           = new List <string>();
            var    platforms            = new List <string>();
            var    output               = string.Empty;
            var    operation            = string.Empty;
            string androidPlatformTools = null;

            var options = new OptionSet
            {
                { "a|assembly=", "Load an assembly.", v => assemblies.Add(v) },
                { "p|platform=", "Specify one or more platforms to target.", v => platforms.Add(v) },
                { "o|output=", "Specify the output folder for the compiled assets.", v => output = v },
                { "m|operation=", "Specify the mode of operation (either 'compile', 'server' or 'builtin', default is 'compile').", v => operation = v },
                { "android-platform-tools=", "Specifies the path to ADB (used for connecting to a game running on an Android device)", v => androidPlatformTools = v },
            };

            try
            {
                options.Parse(args);
            }
            catch (OptionException ex)
            {
                Console.Write("ProtogameAssetTool.exe: ");
                Console.WriteLine(ex.Message);
                Console.WriteLine("Try `ProtogameAssetTool.exe --help` for more information.");
                Environment.Exit(1);
                return;
            }

            var operationArguments = new OperationArguments
            {
                Assemblies           = assemblies.ToArray(),
                Platforms            = platforms.ToArray(),
                AndroidPlatformTools = androidPlatformTools,
                OutputPath           = output
            };

            IOperation operationInst;

            switch (operation)
            {
            case "remote":
                throw new NotSupportedException();

            case "server":
                operationInst = new ServerOperation();
                break;

            case "builtin":
                operationInst = new BuiltinOperation();
                break;

            case "compile":
            default:
                operationInst = new CompileOperation();
                break;
            }

            var task = Task.Run(async() => await operationInst.Run(operationArguments).ConfigureAwait(false));

            task.Wait();
        }