public static IEnumerable GenerateCodeAndAssetsAsync(string path = null, Action<string, float> progressCallback = null) { switch (ToolsRunner.CheckCharon()) { case CharonCheckResult.MissingRuntime: yield return UpdateRuntimeWindow.ShowAsync(); break; case CharonCheckResult.MissingExecutable: yield return ToolsRunner.UpdateCharonExecutable(progressCallback); break; case CharonCheckResult.Ok: break; default: throw new InvalidOperationException("Unknown Tools check result."); } var paths = !string.IsNullOrEmpty(path) ? new string[] { path } : Settings.Current.GameDataPaths.ToArray(); var total = paths.Length; var forceReImportList = new List<string>(); for (var i = 0; i < paths.Length; i++) { var gameDataPath = paths[i]; if (File.Exists(gameDataPath) == false) continue; if (progressCallback != null) progressCallback(string.Format(Resources.UI_UNITYPLUGIN_PROGRESSCURRENTTARGETIS, gameDataPath), (float)i / total); var gameDataObj = AssetDatabase.LoadAssetAtPath(gameDataPath, typeof(UnityEngine.Object)); var assetImport = AssetImporter.GetAtPath(gameDataPath); if (assetImport == null) continue; var gameDataSettings = GameDataSettings.Load(gameDataObj); var codeGenerationPath = FileUtils.MakeProjectRelative(gameDataSettings.CodeGenerationPath); if (gameDataSettings.Generator == (int)GameDataSettings.CodeGenerator.None) continue; var generationOptions = gameDataSettings.Options; // trying to touch gamedata file var touchGamedata = new Coroutine<FileStream>(TouchGameDataFile(gameDataPath)); yield return touchGamedata; using (touchGamedata.GetResult()) { var generator = (GameDataSettings.CodeGenerator)gameDataSettings.Generator; switch (generator) { case GameDataSettings.CodeGenerator.CSharpCodeAndAsset: if (!string.IsNullOrEmpty(gameDataSettings.AssetGenerationPath)) { AssetGenerator.AddPath(gameDataPath); generationOptions &= ~(int)GameDataSettings.CodeGenerationOptions.SuppressJsonSerialization; } goto generateCSharpCode; case GameDataSettings.CodeGenerator.CSharp: generateCSharpCode: if (Settings.Current.Verbose) Debug.Log(string.Format("Generating C# code for '{0}'...", gameDataPath)); if (progressCallback != null) progressCallback(string.Format(Resources.UI_UNITYPLUGIN_GENERATECODEFOR, gameDataPath), (float)i / total); var generateProcess = ToolsRunner.RunCharonAsTool( "DATA", generator == GameDataSettings.CodeGenerator.CSharp ? "GENERATECSHARPCODE" : "GENERATEUNITYCSHARPCODE", Path.GetFullPath(gameDataPath), "--namespace", gameDataSettings.Namespace, "--gameDataClassName", gameDataSettings.GameDataClassName, "--documentClassName", gameDataSettings.DocumentClassName, "--options", generationOptions.ToString(), "--output", Path.GetFullPath(codeGenerationPath), Settings.Current.Verbose ? "--verbose" : "" ); yield return generateProcess; if (Settings.Current.Verbose) Debug.Log(string.Format("Generation complete, exit code: '{0}'", generateProcess.GetResult().ExitCode)); using (var generateResult = generateProcess.GetResult()) { if (generateResult.ExitCode != 0) { Debug.LogWarning(string.Format(Resources.UI_UNITYPLUGIN_GENERATEFAILEDDUEERRORS, gameDataPath, generateResult.GetErrorData())); } else { if (Settings.Current.Verbose) Debug.Log(string.Format("Code generation for '{0}' is complete.", gameDataPath)); forceReImportList.Add(codeGenerationPath); if (gameDataSettings.LineEnding != 0 || gameDataSettings.Indentation != 0) { if (progressCallback != null) progressCallback(string.Format(Resources.UI_UNITYPLUGIN_GENERATEREFORMATCODE, gameDataPath), (float)i / total); var code = new StringBuilder(File.ReadAllText(codeGenerationPath)); switch ((GameDataSettings.LineEndings)gameDataSettings.LineEnding) { case GameDataSettings.LineEndings.Windows: // already windows break; case GameDataSettings.LineEndings.Unix: code.Replace("\r\n", "\n"); break; default: throw new InvalidOperationException(string.Format("Unknown LineEnding value '{0}' is set for {1}", gameDataSettings.LineEnding, gameDataPath)); } switch ((GameDataSettings.Indentations)gameDataSettings.Indentation) { case GameDataSettings.Indentations.Tab: // already tabs break; case GameDataSettings.Indentations.FourSpaces: code.Replace("\t", " "); break; case GameDataSettings.Indentations.TwoSpaces: code.Replace("\t", " "); break; default: throw new InvalidOperationException(string.Format("Unknown indentation value '{0}' is set for {1}", gameDataSettings.Indentation, gameDataPath)); } File.WriteAllText(codeGenerationPath, code.ToString()); } } } break; default: Debug.LogError("Unknown code/asset generator type " + (GameDataSettings.CodeGenerator)gameDataSettings.Generator + "."); break; } } } if (progressCallback != null) progressCallback(Resources.UI_UNITYPLUGIN_GENERATEREFRESHINGASSETS, 0.99f); foreach (var forceReImportPath in forceReImportList) AssetDatabase.ImportAsset(forceReImportPath, ImportAssetOptions.ForceUpdate); if (progressCallback != null) progressCallback(Resources.UI_UNITYPLUGIN_PROGRESSDONE, 1); }
public static IEnumerable GenerateAssetsAsync(string[] paths, Action<string, float> progressCallback = null) { var total = paths.Length; for (var i = 0; i < paths.Length; i++) { var gameDataPath = paths[i]; if (File.Exists(gameDataPath) == false) continue; if (progressCallback != null) progressCallback(string.Format(Resources.UI_UNITYPLUGIN_PROGRESSCURRENTTARGETIS, gameDataPath), (float)i / total); var gameDataObj = AssetDatabase.LoadAssetAtPath(gameDataPath, typeof(UnityEngine.Object)); var assetImport = AssetImporter.GetAtPath(gameDataPath); if (assetImport == null) continue; var gameDataSettings = GameDataSettings.Load(gameDataObj); var assetGenerationPath = FileUtils.MakeProjectRelative(gameDataSettings.AssetGenerationPath); if (string.IsNullOrEmpty(assetGenerationPath)) continue; // trying to touch gamedata file var touchGamedata = new Coroutine<FileStream>(TouchGameDataFile(gameDataPath)); yield return touchGamedata; using (touchGamedata.GetResult()) using (var gameDataTextReader = new StreamReader(gameDataPath, Encoding.UTF8)) { var gameDataType = Type.GetType(gameDataSettings.Namespace + "." + gameDataSettings.GameDataClassName + ", Assembly-CSharp", throwOnError: false) ?? Type.GetType(gameDataSettings.Namespace + "." + gameDataSettings.GameDataClassName + ", Assembly-CSharp-firstpass", throwOnError: false) ?? Type.GetType(gameDataSettings.Namespace + "." + gameDataSettings.GameDataClassName + ", Assembly-CSharp-Editor", throwOnError: false); if (gameDataType == null) { Debug.LogError(Resources.UI_UNITYPLUGIN_GENERATEASSETCANTFINDGAMEDATACLASS); continue; } var gameDataJson = gameDataTextReader.ReadToEnd(); var gameDataAsset = (ScriptableObject)ScriptableObject.CreateInstance(gameDataType); gameDataAsset.SetFieldValue("jsonText", gameDataJson); AssetDatabase.CreateAsset(gameDataAsset, assetGenerationPath); AssetDatabase.SaveAssets(); } } if (progressCallback != null) progressCallback(Resources.UI_UNITYPLUGIN_GENERATEREFRESHINGASSETS, 0.99f); AssetDatabase.Refresh(ImportAssetOptions.Default); if (progressCallback != null) progressCallback(Resources.UI_UNITYPLUGIN_PROGRESSDONE, 1); }