Exemplo n.º 1
0
        public static void Cook(Target target, Dictionary <string, CookingRules> assetToCookingRules, List <string> cookingBundles)
        {
            var cache            = LoadCodeCookerCache();
            var scenesToCook     = new List <string>();
            var visitedScenes    = new HashSet <string>();
            var usedBundles      = new HashSet <string>();
            var sceneToBundleMap = new Dictionary <string, string>();
            var allScenes        = new List <string>();
            var modifiedScenes   = new List <string>();

            using (var dc = new DirectoryChanger(The.Workspace.AssetsDirectory)) {
                foreach (var kv in assetToCookingRules)
                {
                    var  scenePath = kv.Key;
                    bool presentInCookingBundles = false;
                    foreach (var bundle in kv.Value.Bundles)
                    {
                        if (cookingBundles.Contains(bundle))
                        {
                            presentInCookingBundles = true;
                            break;
                        }
                    }
                    if (
                        (
                            scenePath.EndsWith(".tan", StringComparison.OrdinalIgnoreCase) ||
                            scenePath.EndsWith(".model", StringComparison.OrdinalIgnoreCase)
                        ) &&
                        !kv.Value.Ignore &&
                        presentInCookingBundles
                        )
                    {
                        allScenes.Add(scenePath);
                        sceneToBundleMap.Add(scenePath, kv.Value.Bundles.First());
                        var dateModified = File.GetLastWriteTime(scenePath).ToUniversalTime();
                        if (!cache.SceneFiles.ContainsKey(scenePath))
                        {
                            modifiedScenes.Add(scenePath);
                            scenesToCook.Add(scenePath);
                            var bundles = assetToCookingRules[scenePath].Bundles;
                            foreach (var bundle in bundles)
                            {
                                usedBundles.Add(bundle);
                            }
                            cache.SceneFiles.Add(scenePath, new SceneRecord {
                                Bundle       = bundles.First(),
                                DateModified = dateModified
                            });
                        }
                        else
                        {
                            var cacheRecord = cache.SceneFiles[kv.Key];
                            if (dateModified > cacheRecord.DateModified)
                            {
                                var queue = new Queue <string>();
                                if (!visitedScenes.Contains(scenePath))
                                {
                                    queue.Enqueue(scenePath);
                                    visitedScenes.Add(scenePath);
                                }
                                while (queue.Count != 0)
                                {
                                    var scene = queue.Dequeue();
                                    scenesToCook.Add(scene);
                                    var bundles = assetToCookingRules[scene].Bundles;
                                    foreach (var bundle in bundles)
                                    {
                                        usedBundles.Add(bundle);
                                    }
                                    foreach (var referringScene in cache.SceneFiles[scene].ReferringScenes)
                                    {
                                        if (!visitedScenes.Contains(referringScene))
                                        {
                                            visitedScenes.Add(referringScene);
                                            queue.Enqueue(referringScene);
                                        }
                                    }
                                }
                                cache.SceneFiles[scenePath].DateModified = dateModified;
                                modifiedScenes.Add(scenePath);
                            }
                        }
                    }
                }
            }
            try {
                // Don't return early even if there's nothing modified since there may be stuff to delete
                // Also, don't bother with loading ony usedBundles for now, just load all of them
                AssetBundle.SetCurrent(new AggregateAssetBundle(cookingBundles.Select(bundleName => new PackedAssetBundle(The.Workspace.GetBundlePath(target.Platform, bundleName))).ToArray()), false);
                new ScenesCodeCooker(
                    The.Workspace.ProjectDirectory,
                    The.Workspace.GeneratedScenesPath,
                    The.Workspace.ProjectName,
                    CookingRulesBuilder.MainBundleName,
                    sceneToBundleMap,
                    scenesToCook,
                    allScenes,
                    modifiedScenes,
                    cache
                    ).Start();
                SaveCodeCookerCache(cache);
            } finally {
                AssetBundle.Current.Dispose();
                AssetBundle.SetCurrent(null, false);
            }
        }
Exemplo n.º 2
0
        public static void NewProjectAction(Func <string, bool> projectOpened)
        {
            Application.InvokeOnMainThread(() => {
                var citrusPath = Toolbox.FindCitrusDirectory();
                var dlg        = new FileDialog {
                    AllowedFileTypes = new string[] { "" },
                    Mode             = FileDialogMode.SelectFolder
                };
                if (dlg.RunModal())
                {
                    targetDirectory    = dlg.FileName;
                    newCitrusDirectory = Path.Combine(dlg.FileName, "Citrus");
                    var projectName    = Path.GetFileName(dlg.FileName);
                    if (char.IsDigit(projectName[0]))
                    {
                        throw new System.Exception($"Project name '{projectName}' cannot start with a digit");
                    }
                    foreach (char c in projectName)
                    {
                        if (!ValidChars.Contains(c))
                        {
                            throw new System.Exception($"Project name '{projectName}' must contain only latin letters and digits");
                        }
                    }
                    var newProjectApplicationName = String.Join(" ", Regex.Split(projectName, @"(?<!^)(?=[A-Z])"));
                    Console.WriteLine($"New project name is \"{projectName}\"");
                    HashSet <string> textfileExtensions = new HashSet <string> {
                        ".cs", ".xml", ".csproj", ".sln", ".citproj", ".projitems", ".shproj", ".txt", ".plist", ".strings", ".gitignore",
                    };
                    using (var dc = new DirectoryChanger($"{citrusPath}/Samples/EmptyProject/")) {
                        var fe = new FileEnumerator(".");
                        foreach (var f in fe.Enumerate())
                        {
                            var targetPath = Path.Combine(dlg.FileName, f.Path.Replace("EmptyProject", projectName));
                            Console.WriteLine($"Copying: {f.Path} => {targetPath}");
                            Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                            System.IO.File.Copy(f.Path, targetPath);
                            if (textfileExtensions.Contains(Path.GetExtension(targetPath).ToLower(CultureInfo.InvariantCulture)))
                            {
                                string text     = File.ReadAllText(targetPath);
                                text            = text.Replace("EmptyProject", projectName);
                                text            = text.Replace("Empty Project", newProjectApplicationName);
                                text            = text.Replace("emptyproject", projectName.ToLower());
                                var citrusUri   = new Uri(newCitrusDirectory);
                                var fileUri     = new Uri(targetPath);
                                var relativeUri = fileUri.MakeRelativeUri(citrusUri);
                                // TODO: apply only to .sln and .csproj file
                                text = text.Replace("..\\..\\..", relativeUri.ToString());
                                if (targetPath.EndsWith(".citproj", StringComparison.OrdinalIgnoreCase))
                                {
                                    text = text.Replace("\"CitrusDirectory\": \"../../\",", $"\"CitrusDirectory\": \"{relativeUri}\",");
                                    newProjectCitprojPath = targetPath;
                                }
                                File.WriteAllText(targetPath, text);
                            }
                        }
                    }
#if WIN
// TODO: fix unresponsiveness on mac
                    Git.Exec(targetDirectory, "init");
                    Git.Exec(targetDirectory, "add -A");
                    Git.Exec(targetDirectory, "submodule add https://gitlab.game-forest.com:8888/Common/Citrus.git Citrus");
                    Git.Exec(targetDirectory, "submodule update --init --recursive");
                    Git.Exec(targetDirectory, "commit -m\"Initial commit.\"");
#endif // WIN
                }
            });
            if (projectOpened != null)
            {
                projectOpened?.Invoke(newProjectCitprojPath);
            }
        }