Example #1
0
        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);
        }
Example #2
0
        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);
        }