Exemplo n.º 1
0
        public List <string> GetListOfAllBundles()
        {
            var cookingRulesMap = CookingRulesBuilder.Build(The.Workspace.AssetFiles, Target);
            var bundles         = new HashSet <string>();

            foreach (var dictionaryItem in cookingRulesMap)
            {
                foreach (var bundle in dictionaryItem.Value.Bundles)
                {
                    bundles.Add(bundle);
                }
            }
            return(bundles.ToList());
        }
Exemplo n.º 2
0
        private static HashSet <string> GetAllBundles()
        {
            var bundles = new HashSet <string>()
            {
                CookingRulesBuilder.MainBundleName
            };
            var cookingRulesMap = CookingRulesBuilder.Build(The.Workspace.AssetFiles, The.Workspace.ActiveTarget);

            foreach (var bundle in cookingRulesMap.SelectMany(i => i.Value.Bundles.Where(bundle => bundle != CookingRulesBuilder.MainBundleName)))
            {
                bundles.Add(bundle);
            }
            return(bundles);
        }
Exemplo n.º 3
0
        private static HashSet <string> GetAllBundles(Target target)
        {
            var bundles = new HashSet <string>()
            {
                CookingRulesBuilder.MainBundleName
            };
            var cookingRulesMap = CookingRulesBuilder.Build(Lime.AssetBundle.Current, target);

            foreach (var bundle in cookingRulesMap.SelectMany(i => i.Value.Bundles.Where(bundle => bundle != CookingRulesBuilder.MainBundleName)))
            {
                bundles.Add(bundle);
            }
            return(bundles);
        }
Exemplo n.º 4
0
        public void Cook(List <string> bundles)
        {
            AssetCache.Instance.Initialize();
            CookingRulesMap = CookingRulesBuilder.Build(InputBundle, Target);
            LogText         = "";
            var allTimer = StartBenchmark(
                $"Asset cooking. Asset cache mode: {AssetCache.Instance.Mode}. Active platform: {Target.Platform}" +
                System.Environment.NewLine +
                DateTime.Now +
                System.Environment.NewLine
                );

            PluginLoader.BeforeBundlesCooking();
            var requiredCookCode = !The.Workspace.ProjectJson.GetValue <bool>("SkipCodeCooking");
            var bundleBackups    = new List <string>();

            try {
                UserInterface.Instance.SetupProgressBar(CalculateOperationCount(bundles));
                BeginCookBundles?.Invoke();
                var assetsGroupedByBundles = GetAssetsGroupedByBundles(InputBundle.EnumerateFileInfos(), bundles);
                for (int i = 0; i < bundles.Count; i++)
                {
                    var extraTimer = StartBenchmark();
                    CookBundle(bundles[i], assetsGroupedByBundles[i], bundleBackups);
                    StopBenchmark(extraTimer, $"{bundles[i]} cooked: ");
                }
                var extraBundles = bundles.ToList();
                extraBundles.Remove(CookingRulesBuilder.MainBundleName);
                extraBundles.Reverse();
                PluginLoader.AfterBundlesCooked(extraBundles);
                if (requiredCookCode)
                {
                    CodeCooker.Cook(Target, CookingRulesMap, bundles.ToList());
                }
                StopBenchmark(allTimer, "All bundles cooked: ");
                PrintBenchmark();
            } catch (System.Exception e) {
                Console.WriteLine(e.Message);
                RestoreBackups(bundleBackups);
            } finally {
                cookCanceled = false;
                RemoveBackups(bundleBackups);
                EndCookBundles?.Invoke();
                UserInterface.Instance.StopProgressBar();
            }
        }
Exemplo n.º 5
0
        public void CookCustomAssets(List <string> assets)
        {
            CookingRulesMap = CookingRulesBuilder.Build(The.Workspace.AssetFiles, Target);

            var defaultAssetsEnumerator = The.Workspace.AssetFiles;
            var assetsFileInfo          = assets
                                          .Select(asset => new FileInfo {
                Path = asset, LastWriteTime = DateTime.Now
            })
                                          .ToList();

            The.Workspace.AssetFiles = new CustomFilesEnumerator(defaultAssetsEnumerator.Directory, assetsFileInfo);

            var defaultCookingProfile = AssetCooker.cookingProfile;

            AssetCooker.cookingProfile = CookingProfile.Partial;

            CookBundles(GetListOfAllBundles(), false);
            The.Workspace.AssetFiles   = defaultAssetsEnumerator;
            AssetCooker.cookingProfile = defaultCookingProfile;
        }
Exemplo n.º 6
0
        public static void CookCustomAssets(TargetPlatform platform, List <string> assets)
        {
            AssetCooker.Platform = platform;
            cookingRulesMap      = CookingRulesBuilder.Build(The.Workspace.AssetFiles, The.Workspace.ActiveTarget);

            var defaultAssetsEnumerator = The.Workspace.AssetFiles;
            var assetsFileInfo          = assets
                                          .Select(asset => new FileInfo {
                Path = asset, LastWriteTime = DateTime.Now
            })
                                          .ToList();

            The.Workspace.AssetFiles = new CustomFilesEnumerator(defaultAssetsEnumerator.Directory, assetsFileInfo);

            var defaultCookingProfile = AssetCooker.cookingProfile;

            AssetCooker.cookingProfile = CookingProfile.Partial;

            CookBundles(requiredCookCode: false);
            The.Workspace.AssetFiles   = defaultAssetsEnumerator;
            AssetCooker.cookingProfile = defaultCookingProfile;
        }
Exemplo n.º 7
0
        public static void Unpack(TargetPlatform platform)
        {
            var cookingRulesMap = CookingRulesBuilder.Build(The.Workspace.AssetFiles, The.Workspace.ActiveTarget);
            var bundles         = new HashSet <string>();

            foreach (var dictionaryItem in cookingRulesMap)
            {
                foreach (var bundle in dictionaryItem.Value.Bundles)
                {
                    bundles.Add(bundle);
                }
            }

            foreach (var bundleName in bundles)
            {
                string bundlePath = The.Workspace.GetBundlePath(bundleName, The.Workspace.ActivePlatform);
                var    dirInfo    = new System.IO.DirectoryInfo(Path.GetDirectoryName(bundlePath));
                foreach (var fileInfo in dirInfo.GetFiles('*' + Path.GetExtension(bundlePath), SearchOption.TopDirectoryOnly))
                {
                    UnpackBundle(fileInfo.FullName);
                }
            }
        }
Exemplo n.º 8
0
 public void Cook(IEnumerable <string> bundles)
 {
     AssetCache.Instance.Initialize();
     CookingRulesMap = CookingRulesBuilder.Build(The.Workspace.AssetFiles, Target);
     CookBundles(bundles);
 }
Exemplo n.º 9
0
        public static void AnalyzeResourcesAction()
        {
            var target = The.UI.GetActiveTarget();

            requestedPaths = new List <PathRequestRecord>();
            var crossRefReport           = new List <Tuple <string, List <string> > >();
            var missingResourcesReport   = new List <string>();
            var suspiciousTexturesReport = new List <string>();
            var bundles         = new HashSet <string>();
            var cookingRulesMap = CookingRulesBuilder.Build(AssetBundle.Current, target);

            AssetBundle.Current = new PackedAssetBundle(The.Workspace.GetBundlePath(target.Platform, CookingRulesBuilder.MainBundleName));
            foreach (var i in cookingRulesMap)
            {
                if (i.Key.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
                {
                    if (i.Value.TextureAtlas == null && i.Value.PVRFormat != PVRFormat.PVRTC4 && i.Value.PVRFormat != PVRFormat.PVRTC4_Forced)
                    {
                        suspiciousTexturesReport.Add(string.Format("{0}: {1}, atlas: none",
                                                                   i.Key, i.Value.PVRFormat));
                    }
                    if (i.Value.PVRFormat != PVRFormat.PVRTC4 && i.Value.PVRFormat != PVRFormat.PVRTC4_Forced && i.Value.PVRFormat != PVRFormat.PVRTC2)
                    {
                        int  w;
                        int  h;
                        bool hasAlpha;
                        TextureConverterUtils.GetPngFileInfo(AssetBundle.Current, i.Key, out w, out h, out hasAlpha);
                        if (w >= 1024 || h >= 1024)
                        {
                            suspiciousTexturesReport.Add(string.Format("{3}: {0}, {1}, {2}, {4}, atlas: {5}",
                                                                       w, h, hasAlpha, i.Key, i.Value.PVRFormat, i.Value.TextureAtlas));
                        }
                    }
                }
                foreach (var bundle in i.Value.Bundles)
                {
                    if (bundle != CookingRulesBuilder.MainBundleName)
                    {
                        bundles.Add(bundle);
                    }
                }
            }
            var savedAssetBundle = AssetBundle.Current;

            try {
                var aggregateBundle =
                    new AggregateAssetBundle(
                        bundles.Select(
                            i => new PackedAssetBundle(The.Workspace.GetBundlePath(target.Platform, i))).ToArray());
                AssetBundle.Current = new CustomSetAssetBundle(aggregateBundle,
                                                               aggregateBundle.EnumerateFileInfos().Where(i => {
                    if (cookingRulesMap.TryGetValue(i.Path, out CookingRules rules))
                    {
                        if (rules.Ignore)
                        {
                            return(false);
                        }
                    }
                    return(true);
                }));
                var usedImages = new HashSet <string>();
                var usedSounds = new HashSet <string>();
                foreach (var srcPath in AssetBundle.Current.EnumerateFiles(null, ".tan"))
                {
                    using (var scene = (Frame)Node.CreateFromAssetBundle(srcPath)) {
                        foreach (var j in scene.Descendants)
                        {
                            var checkTexture = new Action <SerializableTexture>((Lime.SerializableTexture t) => {
                                if (t == null)
                                {
                                    return;
                                }
                                string texPath;
                                try {
                                    texPath = t.SerializationPath;
                                } catch {
                                    return;
                                }
                                if (string.IsNullOrEmpty(texPath))
                                {
                                    return;
                                }
                                if (texPath.Length == 2 && texPath[0] == '#')
                                {
                                    switch (texPath[1])
                                    {
                                    case 'a':
                                    case 'b':
                                    case 'c':
                                    case 'd':
                                    case 'e':
                                    case 'f':
                                    case 'g':
                                        return;

                                    default:
                                        suspiciousTexturesReport.Add(string.Format("wrong render target: {0}, {1}", texPath, j.ToString()));
                                        return;
                                    }
                                }
                                string[] possiblePaths = new string[]
                                {
                                    texPath + ".atlasPart",
                                    texPath + ".pvr",
                                    texPath + ".jpg",
                                    texPath + ".png",
                                    texPath + ".dds",
                                    texPath + ".jpg",
                                    texPath + ".png",
                                };
                                foreach (var tpp in possiblePaths)
                                {
                                    if (Lime.AssetBundle.Current.FileExists(tpp))
                                    {
                                        Lime.AssetBundle.Current.OpenFile(tpp);
                                        usedImages.Add(texPath.Replace('\\', '/'));
                                        return;
                                    }
                                }
                                missingResourcesReport.Add(string.Format("texture missing:\n\ttexture path: {0}\n\tscene path: {1}\n",
                                                                         t.SerializationPath, j.ToString()));
                            });
                            var checkAnimators = new Action <Node>((Node n) => {
                                if (n.Animators.TryFind <SerializableTexture>("Texture", out var ta))
                                {
                                    foreach (var key in ta.ReadonlyKeys)
                                    {
                                        checkTexture(key.Value);
                                    }
                                }
                            });
                            if (j is Widget)
                            {
                                var w = j as Lime.Widget;
                                var serializableTexture = w.Texture as SerializableTexture;
                                if (serializableTexture != null)
                                {
                                    checkTexture(serializableTexture);
                                }
                                checkAnimators(w);
                            }
                            else if (j is ParticleModifier)
                            {
                                var pm = j as Lime.ParticleModifier;
                                var serializableTexture = pm.Texture as SerializableTexture;
                                if (serializableTexture != null)
                                {
                                    checkTexture(serializableTexture);
                                }
                                checkAnimators(pm);
                            }
                            else if (j is Lime.Audio)
                            {
                                var au   = j as Lime.Audio;
                                var path = au.Sample.SerializationPath + ".sound";
                                usedSounds.Add(au.Sample.SerializationPath.Replace('\\', '/'));
                                if (!Lime.AssetBundle.Current.FileExists(path))
                                {
                                    missingResourcesReport.Add(string.Format("audio missing:\n\taudio path: {0}\n\tscene path: {1}\n",
                                                                             path, j.ToString()));
                                }
                                else
                                {
                                    using (var tempStream = Lime.AssetBundle.Current.OpenFile(path)) {
                                    }
                                }
                                // FIXME: should we check for audio:Sample animators too?
                            }
                        }
                    }
                    var reportList = new List <string>();
                    foreach (var rpr in requestedPaths)
                    {
                        string pattern = String.Format(@".*[/\\](.*)\.{0}", target.Platform.ToString());
                        string bundle  = "";
                        foreach (Match m in Regex.Matches(rpr.bundle, pattern, RegexOptions.IgnoreCase))
                        {
                            bundle = m.Groups[1].Value;
                        }
                        int index = Array.IndexOf(cookingRulesMap[srcPath].Bundles, bundle);
                        if (index == -1)
                        {
                            reportList.Add(string.Format("\t[{0}]=>[{2}]: {1}",
                                                         string.Join(", ", cookingRulesMap[srcPath].Bundles), rpr.path, bundle));
                        }
                    }
                    requestedPaths.Clear();
                    if (reportList.Count > 0)
                    {
                        crossRefReport.Add(new Tuple <string, List <string> >(srcPath, reportList));
                    }
                    Lime.Application.FreeScheduledActions();
                }

                var allImages = new Dictionary <string, bool>();
                foreach (var img in AssetBundle.Current.EnumerateFiles(null, ".png"))
                {
                    var key = Path.Combine(Path.GetDirectoryName(img), Path.GetFileNameWithoutExtension(img)).Replace('\\', '/');
                    if (!key.StartsWith("Fonts"))
                    {
                        allImages[key] = false;
                    }
                }
                foreach (var img in usedImages)
                {
                    allImages[img] = true;
                }
                var unusedImages = allImages.Where(kv => !kv.Value).Select(kv => kv.Key).ToList();

                var allSounds = new Dictionary <string, bool>();
                foreach (var sound in AssetBundle.Current.EnumerateFiles(null, ".ogg"))
                {
                    var key = Path.Combine(Path.GetDirectoryName(sound), Path.GetFileNameWithoutExtension(sound))
                              .Replace('\\', '/');
                    allSounds[key] = false;
                }
                foreach (var sound in usedSounds)
                {
                    allSounds[sound] = true;
                }
                var unusedSounds = allSounds.Where(kv => !kv.Value).Select(kv => kv.Key).ToList();

                Action <string> writeHeader = (s) => {
                    int n0 = (80 - s.Length) / 2;
                    int n1 = (80 - s.Length) % 2 == 0 ? n0 : n0 - 1;
                    Console.WriteLine("\n" + new String('=', n0) + " " + s + " " + new String('=', n1));
                };
                writeHeader("Cross Bundle Dependencies");
                foreach (var scenePath in crossRefReport)
                {
                    Console.WriteLine("\n" + scenePath.Item1);
                    foreach (var refStr in scenePath.Item2)
                    {
                        Console.WriteLine(refStr);
                    }
                }
                writeHeader("Missing Resources");
                foreach (var s in missingResourcesReport)
                {
                    Console.WriteLine(s);
                }
                writeHeader("Unused Images");
                foreach (var s in unusedImages)
                {
                    Console.WriteLine(s);
                }
                writeHeader("Unused Sounds");
                foreach (var s in unusedSounds)
                {
                    Console.WriteLine(s);
                }
                writeHeader("Suspicious Textures");
                foreach (var s in suspiciousTexturesReport)
                {
                    Console.WriteLine(s);
                }
            } finally {
                AssetBundle.Current = savedAssetBundle;
            }
        }
Exemplo n.º 10
0
 public static void Cook(TargetPlatform platform)
 {
     AssetCooker.Platform = platform;
     cookingRulesMap      = CookingRulesBuilder.Build(The.Workspace.AssetFiles, The.Workspace.ActiveTarget);
     CookBundles();
 }