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