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