From 8dcadfa28b643568a9571f5b5e07d9e7e7d25c84 Mon Sep 17 00:00:00 2001 From: Tim Nugent Date: Wed, 17 Jan 2024 14:08:38 +1100 Subject: [PATCH] Automatic linking codegen can now be controlled via the YS settings. Had to make a bunch of changes to a bunch of files and also add MiniJSON. This is because the codegen pipeline can't use the Unity side of things so the built in JSON stuff is out. Pretty much everything else is just some minor refactoring to make it less all jumbled together into a single file. --- .../ActionsGenerator.cs | 109 ++-- .../Generator.csproj | 3 + Editor/ILogger.cs | 65 ++ Editor/ILogger.cs.meta | 11 + Editor/MiniJSON.cs | 599 ++++++++++++++++++ Editor/MiniJSON.cs.meta | 11 + Editor/YarnSpinnerProjectSettings.cs | 126 ++-- Editor/YarnSpinnerProjectSettingsProvider.cs | 53 ++ ...YarnSpinnerProjectSettingsProvider.cs.meta | 11 + .../YarnSpinner.Unity.SourceCodeGenerator.dll | Bin 54272 -> 60928 bytes 10 files changed, 885 insertions(+), 103 deletions(-) create mode 100644 Editor/ILogger.cs create mode 100644 Editor/ILogger.cs.meta create mode 100644 Editor/MiniJSON.cs create mode 100644 Editor/MiniJSON.cs.meta create mode 100644 Editor/YarnSpinnerProjectSettingsProvider.cs create mode 100644 Editor/YarnSpinnerProjectSettingsProvider.cs.meta diff --git a/Editor/Analysis/ActionsRegistrationGenerator~/ActionsGenerator.cs b/Editor/Analysis/ActionsRegistrationGenerator~/ActionsGenerator.cs index 6587bcf3..9119a9d7 100644 --- a/Editor/Analysis/ActionsRegistrationGenerator~/ActionsGenerator.cs +++ b/Editor/Analysis/ActionsRegistrationGenerator~/ActionsGenerator.cs @@ -19,11 +19,56 @@ public class ActionRegistrationSourceGenerator : ISourceGenerator public void Execute(GeneratorExecutionContext context) { var output = GetOutput(context); + output.WriteLine(DateTime.Now); + + // we need to know if the settings are configured to not perform codegen to link attributed methods + // this is kinda annoying because the path root of the project settings and the root path of this process are *very* different + // so what we do is we use the included Compilation Assembly additional file that Unity gives us. + // This file if opened has the path of the Unity project, which we can then use to get the settings + // if any stage of this fails then we bail out and assume that codegen is desired + if (context.AdditionalFiles.Any()) + { + var relevants = context.AdditionalFiles.Where(i => i.Path.Contains($"{context.Compilation.AssemblyName}.AdditionalFile.txt")); + if (relevants.Any()) + { + var arsgacsaf = relevants.First(); + if (File.Exists(arsgacsaf.Path)) + { + try + { + var projectPath = File.ReadAllText(arsgacsaf.Path); + var fullPath = Path.Combine(projectPath, Yarn.Unity.Editor.YarnSpinnerProjectSettings.YarnSpinnerProjectSettingsPath); + output.WriteLine($"Attempting to read settings file at {fullPath}"); + + if (!Yarn.Unity.Editor.YarnSpinnerProjectSettings.GetOrCreateSettings(projectPath, output).automaticallyLinkAttributedYarnCommandsAndFunctions) + { + output.WriteLine("Skipping codegen due to settings."); + output.Dispose(); + return; + } + } + catch (Exception e) + { + output.WriteLine($"Unable to determine Yarn settings, settings values will be ignored and codegen will occur: {e.Message}"); + } + } + else + { + output.WriteLine($"The project settings path metadata file does not exist at: {arsgacsaf.Path}. Settings values will be ignored and codegen will occur"); + } + } + else + { + output.WriteLine("Unable to determine Yarn settings path, no file containing the project path metadata was included. Settings values will be ignored and codegen will occur."); + } + } + else + { + output.WriteLine("Unable to determine Yarn settings path as no additional files were included. Settings values will be ignored and codegen will occur."); + } try { - output.WriteLine(DateTime.Now); - output.WriteLine("Source code generation for assembly " + context.Compilation.AssemblyName); if (context.AdditionalFiles.Any()) { @@ -322,18 +367,21 @@ public void Initialize(GeneratorInitializationContext context) context.RegisterForSyntaxNotifications(() => new ClassDeclarationSyntaxReceiver()); } - public ILogger GetOutput(GeneratorExecutionContext context) + public Yarn.Unity.ILogger GetOutput(GeneratorExecutionContext context) { if (GetShouldLogToFile(context)) { var tempPath = System.IO.Path.GetTempPath(); + var path = System.IO.Path.Combine(tempPath, $"{nameof(ActionRegistrationSourceGenerator)}-{context.Compilation.AssemblyName}.txt"); var outFile = System.IO.File.Open(path, System.IO.FileMode.Create); - return new FileLogger(new System.IO.StreamWriter(outFile)); - } else { - return new NullLogger(); + return new Yarn.Unity.FileLogger(new System.IO.StreamWriter(outFile)); + } + else + { + return new Yarn.Unity.NullLogger(); } } @@ -365,52 +413,3 @@ public void OnVisitSyntaxNode(SyntaxNode syntaxNode) } } } - -public interface ILogger : IDisposable -{ - void Write(object obj); - void WriteLine(object obj); -} - -public class FileLogger : ILogger -{ - System.IO.TextWriter writer; - - public FileLogger(TextWriter writer) - { - this.writer = writer; - } - - public void Dispose() - { - writer.Dispose(); - } - - public void Write(object text) - { - writer.Write(text); - } - - public void WriteLine(object text) - { - writer.WriteLine(text); - } -} - -public class NullLogger : ILogger -{ - public void Dispose() - { - - } - - public void Write(object text) - { - - } - - public void WriteLine(object text) - { - - } -} diff --git a/Editor/Analysis/ActionsRegistrationGenerator~/Generator.csproj b/Editor/Analysis/ActionsRegistrationGenerator~/Generator.csproj index 1880a230..b46a49a8 100644 --- a/Editor/Analysis/ActionsRegistrationGenerator~/Generator.csproj +++ b/Editor/Analysis/ActionsRegistrationGenerator~/Generator.csproj @@ -15,6 +15,9 @@ + + + diff --git a/Editor/ILogger.cs b/Editor/ILogger.cs new file mode 100644 index 00000000..136ceac9 --- /dev/null +++ b/Editor/ILogger.cs @@ -0,0 +1,65 @@ +using System; +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; +#endif + +namespace Yarn.Unity +{ + public interface ILogger : IDisposable + { + void Write(object obj); + void WriteLine(object obj); + } + + public class FileLogger : ILogger + { + System.IO.TextWriter writer; + + public FileLogger(System.IO.TextWriter writer) + { + this.writer = writer; + } + + public void Dispose() + { + writer.Dispose(); + } + + public void Write(object text) + { + writer.Write(text); + } + + public void WriteLine(object text) + { + writer.WriteLine(text); + } + } + + public class UnityLogger : ILogger + { + public void Dispose() { } + + public void Write(object text) + { + WriteLine(text); + } + + public void WriteLine(object text) + { +#if UNITY_EDITOR + Debug.LogWarning(text.ToString()); +#endif + } + } + + public class NullLogger : ILogger + { + public void Dispose() { } + + public void Write(object text) { } + + public void WriteLine(object text) { } + } +} diff --git a/Editor/ILogger.cs.meta b/Editor/ILogger.cs.meta new file mode 100644 index 00000000..e6c1ea2b --- /dev/null +++ b/Editor/ILogger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45e3ce698d3364e5790443887a66daff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/MiniJSON.cs b/Editor/MiniJSON.cs new file mode 100644 index 00000000..6810cc0d --- /dev/null +++ b/Editor/MiniJSON.cs @@ -0,0 +1,599 @@ +/* + * Copyright (c) 2013 Calvin Rien + * + * Based on the JSON parser by Patrick van Bergen + * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html + * + * Simplified it so that it doesn't throw exceptions + * and can be used in Unity iPhone with maximum code stripping. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Yarn.Unity.Editor +{ + /// + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary. + /// All numbers are parsed to doubles. + /// + public static class Json + { + /// + /// Parses the string json into a value + /// + /// A JSON string. + /// An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false + public static object Deserialize(string json) + { + // save the string for debug information + if (json == null) + { + return null; + } + + return Parser.Parse(json); + } + + sealed class Parser : IDisposable + { + const string WORD_BREAK = "{}[],:\""; + + public static bool IsWordBreak(char c) + { + return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1; + } + + enum TOKEN + { + NONE, + CURLY_OPEN, + CURLY_CLOSE, + SQUARED_OPEN, + SQUARED_CLOSE, + COLON, + COMMA, + STRING, + NUMBER, + TRUE, + FALSE, + NULL + }; + + StringReader json; + + Parser(string jsonString) + { + json = new StringReader(jsonString); + } + + public static object Parse(string jsonString) + { + using (var instance = new Parser(jsonString)) + { + return instance.ParseValue(); + } + } + + public void Dispose() + { + json.Dispose(); + json = null; + } + + Dictionary ParseObject() + { + Dictionary table = new Dictionary(); + + // ditch opening brace + json.Read(); + + // { + while (true) + { + switch (NextToken) + { + case TOKEN.NONE: + return null; + case TOKEN.COMMA: + continue; + case TOKEN.CURLY_CLOSE: + return table; + default: + // name + string name = ParseString(); + if (name == null) + { + return null; + } + + // : + if (NextToken != TOKEN.COLON) + { + return null; + } + // ditch the colon + json.Read(); + + // value + table[name] = ParseValue(); + break; + } + } + } + + List ParseArray() + { + List array = new List(); + + // ditch opening bracket + json.Read(); + + // [ + var parsing = true; + while (parsing) + { + TOKEN nextToken = NextToken; + + switch (nextToken) + { + case TOKEN.NONE: + return null; + case TOKEN.COMMA: + continue; + case TOKEN.SQUARED_CLOSE: + parsing = false; + break; + default: + object value = ParseByToken(nextToken); + + array.Add(value); + break; + } + } + + return array; + } + + object ParseValue() + { + TOKEN nextToken = NextToken; + return ParseByToken(nextToken); + } + + object ParseByToken(TOKEN token) + { + switch (token) + { + case TOKEN.STRING: + return ParseString(); + case TOKEN.NUMBER: + return ParseNumber(); + case TOKEN.CURLY_OPEN: + return ParseObject(); + case TOKEN.SQUARED_OPEN: + return ParseArray(); + case TOKEN.TRUE: + return true; + case TOKEN.FALSE: + return false; + case TOKEN.NULL: + return null; + default: + return null; + } + } + + string ParseString() + { + StringBuilder s = new StringBuilder(); + char c; + + // ditch opening quote + json.Read(); + + bool parsing = true; + while (parsing) + { + + if (json.Peek() == -1) + { + parsing = false; + break; + } + + c = NextChar; + switch (c) + { + case '"': + parsing = false; + break; + case '\\': + if (json.Peek() == -1) + { + parsing = false; + break; + } + + c = NextChar; + switch (c) + { + case '"': + case '\\': + case '/': + s.Append(c); + break; + case 'b': + s.Append('\b'); + break; + case 'f': + s.Append('\f'); + break; + case 'n': + s.Append('\n'); + break; + case 'r': + s.Append('\r'); + break; + case 't': + s.Append('\t'); + break; + case 'u': + var hex = new char[4]; + + for (int i = 0; i < 4; i++) + { + hex[i] = NextChar; + } + + s.Append((char)Convert.ToInt32(new string(hex), 16)); + break; + } + break; + default: + s.Append(c); + break; + } + } + + return s.ToString(); + } + + object ParseNumber() + { + string number = NextWord; + + if (number.IndexOf('.') == -1) + { + long parsedInt; + Int64.TryParse(number, out parsedInt); + return parsedInt; + } + + double parsedDouble; + Double.TryParse(number, out parsedDouble); + return parsedDouble; + } + + void EatWhitespace() + { + while (Char.IsWhiteSpace(PeekChar)) + { + json.Read(); + + if (json.Peek() == -1) + { + break; + } + } + } + + char PeekChar + { + get + { + return Convert.ToChar(json.Peek()); + } + } + + char NextChar + { + get + { + return Convert.ToChar(json.Read()); + } + } + + string NextWord + { + get + { + StringBuilder word = new StringBuilder(); + + while (!IsWordBreak(PeekChar)) + { + word.Append(NextChar); + + if (json.Peek() == -1) + { + break; + } + } + + return word.ToString(); + } + } + + TOKEN NextToken + { + get + { + EatWhitespace(); + + if (json.Peek() == -1) + { + return TOKEN.NONE; + } + + switch (PeekChar) + { + case '{': + return TOKEN.CURLY_OPEN; + case '}': + json.Read(); + return TOKEN.CURLY_CLOSE; + case '[': + return TOKEN.SQUARED_OPEN; + case ']': + json.Read(); + return TOKEN.SQUARED_CLOSE; + case ',': + json.Read(); + return TOKEN.COMMA; + case '"': + return TOKEN.STRING; + case ':': + return TOKEN.COLON; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return TOKEN.NUMBER; + } + + switch (NextWord) + { + case "false": + return TOKEN.FALSE; + case "true": + return TOKEN.TRUE; + case "null": + return TOKEN.NULL; + } + + return TOKEN.NONE; + } + } + } + + /// + /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string + /// + /// A Dictionary<string, object> / List<object> + /// A JSON encoded string, or null if object 'json' is not serializable + public static string Serialize(object obj) + { + return Serializer.Serialize(obj); + } + + sealed class Serializer + { + StringBuilder builder; + + Serializer() + { + builder = new StringBuilder(); + } + + public static string Serialize(object obj) + { + var instance = new Serializer(); + + instance.SerializeValue(obj); + + return instance.builder.ToString(); + } + + void SerializeValue(object value) + { + IList asList; + IDictionary asDict; + string asStr; + + if (value == null) + { + builder.Append("null"); + } + else if ((asStr = value as string) != null) + { + SerializeString(asStr); + } + else if (value is bool) + { + builder.Append((bool)value ? "true" : "false"); + } + else if ((asList = value as IList) != null) + { + SerializeArray(asList); + } + else if ((asDict = value as IDictionary) != null) + { + SerializeObject(asDict); + } + else if (value is char) + { + SerializeString(new string((char)value, 1)); + } + else + { + SerializeOther(value); + } + } + + void SerializeObject(IDictionary obj) + { + bool first = true; + + builder.Append('{'); + + foreach (object e in obj.Keys) + { + if (!first) + { + builder.Append(','); + } + + SerializeString(e.ToString()); + builder.Append(':'); + + SerializeValue(obj[e]); + + first = false; + } + + builder.Append('}'); + } + + void SerializeArray(IList anArray) + { + builder.Append('['); + + bool first = true; + + foreach (object obj in anArray) + { + if (!first) + { + builder.Append(','); + } + + SerializeValue(obj); + + first = false; + } + + builder.Append(']'); + } + + void SerializeString(string str) + { + builder.Append('\"'); + + char[] charArray = str.ToCharArray(); + foreach (var c in charArray) + { + switch (c) + { + case '"': + builder.Append("\\\""); + break; + case '\\': + builder.Append("\\\\"); + break; + case '\b': + builder.Append("\\b"); + break; + case '\f': + builder.Append("\\f"); + break; + case '\n': + builder.Append("\\n"); + break; + case '\r': + builder.Append("\\r"); + break; + case '\t': + builder.Append("\\t"); + break; + default: + int codepoint = Convert.ToInt32(c); + if ((codepoint >= 32) && (codepoint <= 126)) + { + builder.Append(c); + } + else + { + builder.Append("\\u"); + builder.Append(codepoint.ToString("x4")); + } + break; + } + } + + builder.Append('\"'); + } + + void SerializeOther(object value) + { + // NOTE: decimals lose precision during serialization. + // They always have, I'm just letting you know. + // Previously floats and doubles lost precision too. + if (value is float) + { + builder.Append(((float)value).ToString("R")); + } + else if (value is int + || value is uint + || value is long + || value is sbyte + || value is byte + || value is short + || value is ushort + || value is ulong) + { + builder.Append(value); + } + else if (value is double + || value is decimal) + { + builder.Append(Convert.ToDouble(value).ToString("R")); + } + else + { + SerializeString(value.ToString()); + } + } + } + } +} \ No newline at end of file diff --git a/Editor/MiniJSON.cs.meta b/Editor/MiniJSON.cs.meta new file mode 100644 index 00000000..fcc696c0 --- /dev/null +++ b/Editor/MiniJSON.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b4adfe2cc33c4714a7fad372d96d61e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/YarnSpinnerProjectSettings.cs b/Editor/YarnSpinnerProjectSettings.cs index 35195fac..5931d082 100644 --- a/Editor/YarnSpinnerProjectSettings.cs +++ b/Editor/YarnSpinnerProjectSettings.cs @@ -1,12 +1,10 @@ namespace Yarn.Unity.Editor { - using System.Collections.Generic; using System.IO; - using System.Linq; +#if UNITY_EDITOR using UnityEditor; using UnityEngine; - using UnityEngine.UIElements; - using UnityEditor.UIElements; +#endif /// /// Basic data class of unity settings that impact Yarn Spinner. @@ -18,91 +16,123 @@ class YarnSpinnerProjectSettings { public static string YarnSpinnerProjectSettingsPath => Path.Combine("ProjectSettings", "Packages", "dev.yarnspinner", "YarnSpinnerProjectSettings.json"); - [SerializeField] internal bool autoRefreshLocalisedAssets = true; + public bool autoRefreshLocalisedAssets = true; + public bool automaticallyLinkAttributedYarnCommandsAndFunctions = true; - internal static YarnSpinnerProjectSettings GetOrCreateSettings() + // need to make it os the output can be passed in also so it can log + internal static YarnSpinnerProjectSettings GetOrCreateSettings(string path = null, Yarn.Unity.ILogger iLogger = null) { + var settingsPath = YarnSpinnerProjectSettingsPath; + if (path != null) + { + settingsPath = Path.Combine(path, YarnSpinnerProjectSettingsPath); + } + var logger = ValidLogger(iLogger); + YarnSpinnerProjectSettings settings = new YarnSpinnerProjectSettings(); - if (File.Exists(YarnSpinnerProjectSettingsPath)) + if (File.Exists(settingsPath)) { try { - var settingsData = File.ReadAllText(YarnSpinnerProjectSettingsPath); - EditorJsonUtility.FromJsonOverwrite(settingsData, settings); + var settingsData = File.ReadAllText(settingsPath); + settings = YarnSpinnerProjectSettings.FromJson(settingsData, logger); return settings; } catch (System.Exception e) { - Debug.LogWarning($"Failed to load Yarn Spinner project settings at {YarnSpinnerProjectSettingsPath}: {e.Message}"); + logger.WriteLine($"Failed to load Yarn Spinner project settings at {settingsPath}: {e.Message}"); } } + else + { + logger.WriteLine($"No settings file exists at {settingsPath}, will fallback to default settings"); + } settings.autoRefreshLocalisedAssets = true; - settings.WriteSettings(); + settings.automaticallyLinkAttributedYarnCommandsAndFunctions = true; + settings.WriteSettings(path, logger); return settings; } - internal void WriteSettings() + private static YarnSpinnerProjectSettings FromJson(string jsonString, Yarn.Unity.ILogger iLogger = null) { - var jsonValue = EditorJsonUtility.ToJson(this); - - var folder = Path.GetDirectoryName(YarnSpinnerProjectSettingsPath); - if (!Directory.Exists(folder)) + var logger = ValidLogger(iLogger); + + YarnSpinnerProjectSettings settings = new YarnSpinnerProjectSettings(); + var jsonDict = Json.Deserialize(jsonString) as System.Collections.Generic.Dictionary; + if (jsonDict == null) { - Directory.CreateDirectory(folder); + logger.WriteLine($"Failed to parse Yarn Spinner project settings JSON"); + return settings; } + bool automaticallyLinkAttributedYarnCommandsAndFunctions = true; + bool autoRefreshLocalisedAssets = true; try { - File.WriteAllText(YarnSpinnerProjectSettingsPath, jsonValue); + automaticallyLinkAttributedYarnCommandsAndFunctions = (bool)jsonDict["automaticallyLinkAttributedYarnCommandsAndFunctions"]; + autoRefreshLocalisedAssets = (bool)jsonDict["autoRefreshLocalisedAssets"]; } catch (System.Exception e) { - Debug.LogError($"Failed to save Yarn Spinner project settings to {YarnSpinnerProjectSettingsPath}: {e.Message}"); + logger.WriteLine($"Failed to parse Yarn Spinner project settings: {e.Message}"); } - } - } - - class YarnSpinnerProjectSettingsProvider : SettingsProvider - { - private YarnSpinnerProjectSettings baseSettings; - public YarnSpinnerProjectSettingsProvider(string path, SettingsScope scope = SettingsScope.Project) : base(path, scope) { } + settings.automaticallyLinkAttributedYarnCommandsAndFunctions = automaticallyLinkAttributedYarnCommandsAndFunctions; + settings.autoRefreshLocalisedAssets = autoRefreshLocalisedAssets; - public override void OnActivate(string searchContext, VisualElement rootElement) - { - // This function is called when the user clicks on the MyCustom element in the Settings window. - baseSettings = YarnSpinnerProjectSettings.GetOrCreateSettings(); + return settings; } - public override void OnGUI(string searchContext) + internal void WriteSettings(string path = null, Yarn.Unity.ILogger iLogger = null) { - // Use IMGUI to display UI: - EditorGUILayout.LabelField("Automatically update localised assets with Yarn Projects"); + var logger = ValidLogger(iLogger); - using (var changeCheck = new EditorGUI.ChangeCheckScope()) + var settingsPath = YarnSpinnerProjectSettingsPath; + if (path != null) { - var result = EditorGUILayout.Toggle(baseSettings.autoRefreshLocalisedAssets); + settingsPath = Path.Combine(path, settingsPath); + } - if (changeCheck.changed) - { - baseSettings.autoRefreshLocalisedAssets = result; - baseSettings.WriteSettings(); - } + // var jsonValue = EditorJsonUtility.ToJson(this); + var dictForm = new System.Collections.Generic.Dictionary(); + dictForm["automaticallyLinkAttributedYarnCommandsAndFunctions"] = this.automaticallyLinkAttributedYarnCommandsAndFunctions; + dictForm["autoRefreshLocalisedAssets"] = this.autoRefreshLocalisedAssets; + + var jsonValue = Json.Serialize(dictForm); + + var folder = Path.GetDirectoryName(YarnSpinnerProjectSettingsPath); + if (!Directory.Exists(folder)) + { + Directory.CreateDirectory(folder); + } + + try + { + File.WriteAllText(YarnSpinnerProjectSettingsPath, jsonValue); + } + catch (System.Exception e) + { + logger.WriteLine($"Failed to save Yarn Spinner project settings to {YarnSpinnerProjectSettingsPath}: {e.Message}"); } } - // Register the SettingsProvider - [SettingsProvider] - public static SettingsProvider CreateYarnSpinnerProjectSettingsProvider() + // if the provided logger is valid just return it + // otherwise return the default logger + private static Yarn.Unity.ILogger ValidLogger(Yarn.Unity.ILogger iLogger) { - var provider = new YarnSpinnerProjectSettingsProvider("Project/Yarn Spinner", SettingsScope.Project); - - var keywords = new List() { "yarn", "spinner", "localisation" }; - provider.keywords = keywords; - return provider; + var logger = iLogger; + if (logger == null) + { +#if UNITY_EDITOR + logger = new UnityLogger(); +#else + logger = new NullLogger(); +#endif + } + return logger; } } } diff --git a/Editor/YarnSpinnerProjectSettingsProvider.cs b/Editor/YarnSpinnerProjectSettingsProvider.cs new file mode 100644 index 00000000..98442bbc --- /dev/null +++ b/Editor/YarnSpinnerProjectSettingsProvider.cs @@ -0,0 +1,53 @@ +namespace Yarn.Unity.Editor +{ + using System.Collections.Generic; + using System.IO; + using System.Linq; + using UnityEditor; + using UnityEngine; + using UnityEngine.UIElements; + using UnityEditor.UIElements; + + class YarnSpinnerProjectSettingsProvider : SettingsProvider + { + private YarnSpinnerProjectSettings baseSettings; + + public YarnSpinnerProjectSettingsProvider(string path, SettingsScope scope = SettingsScope.Project) : base(path, scope) { } + + public override void OnActivate(string searchContext, VisualElement rootElement) + { + // This function is called when the user clicks on the MyCustom element in the Settings window. + baseSettings = YarnSpinnerProjectSettings.GetOrCreateSettings(); + } + + public override void OnGUI(string searchContext) + { + using (var changeCheck = new EditorGUI.ChangeCheckScope()) + { + EditorGUILayout.LabelField("Automatically update localised assets with Yarn Projects"); + var localisedAssetUpdate = EditorGUILayout.Toggle(baseSettings.autoRefreshLocalisedAssets); + + EditorGUILayout.LabelField("do codegen"); + var linkingAttributedFuncs = EditorGUILayout.Toggle(baseSettings.automaticallyLinkAttributedYarnCommandsAndFunctions); + + if (changeCheck.changed) + { + baseSettings.autoRefreshLocalisedAssets = localisedAssetUpdate; + baseSettings.automaticallyLinkAttributedYarnCommandsAndFunctions = linkingAttributedFuncs; + baseSettings.WriteSettings(); + } + } + } + + // Register the SettingsProvider + [SettingsProvider] + public static SettingsProvider CreateYarnSpinnerProjectSettingsProvider() + { + var provider = new YarnSpinnerProjectSettingsProvider("Project/Yarn Spinner", SettingsScope.Project); + + var keywords = new List() { "yarn", "spinner", "localisation", "codegen", "attribute" }; + provider.keywords = keywords; + return provider; + } + } +} diff --git a/Editor/YarnSpinnerProjectSettingsProvider.cs.meta b/Editor/YarnSpinnerProjectSettingsProvider.cs.meta new file mode 100644 index 00000000..644dcd5f --- /dev/null +++ b/Editor/YarnSpinnerProjectSettingsProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ba3b32b8f5dd4ee0abbb05c8eef314a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SourceGenerator/YarnSpinner.Unity.SourceCodeGenerator.dll b/SourceGenerator/YarnSpinner.Unity.SourceCodeGenerator.dll index b90682abb2a183760803c5a157b02bf12866abe8..e9bc1720014836359a73d7a9c0ff363a76b9e428 100644 GIT binary patch literal 60928 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 ULIDaz#{NIAWdFZJ|91)eFWXYHasU7T literal 54272 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 A+W-In