public static bool TryParse(string rawLog, out InkCompilerLog log)
        {
            var match = _errorRegex.Match(rawLog);

            if (match.Success)
            {
                Ink.ErrorType errorType = Ink.ErrorType.Author;
                string        filename  = null;
                int           lineNo    = -1;
                string        message   = null;

                var errorTypeCapture = match.Groups["errorType"];
                if (errorTypeCapture != null)
                {
                    var errorTypeStr = errorTypeCapture.Value;
                    if (errorTypeStr == "AUTHOR" || errorTypeStr == "TODO")
                    {
                        errorType = Ink.ErrorType.Author;
                    }
                    else if (errorTypeStr == "WARNING")
                    {
                        errorType = Ink.ErrorType.Warning;
                    }
                    else if (errorTypeStr == "ERROR")
                    {
                        errorType = Ink.ErrorType.Error;
                    }
                    else
                    {
                        Debug.LogWarning("Could not parse error type from " + errorTypeStr);
                    }
                }

                var filenameCapture = match.Groups["filename"];
                if (filenameCapture != null)
                {
                    filename = filenameCapture.Value;
                }

                var lineNoCapture = match.Groups["lineNo"];
                if (lineNoCapture != null)
                {
                    lineNo = int.Parse(lineNoCapture.Value);
                }

                var messageCapture = match.Groups["message"];
                if (messageCapture != null)
                {
                    message = messageCapture.Value.Trim();
                }
                log = new InkCompilerLog(errorType, message, filename, lineNo);
                return(true);
            }
            else
            {
                Debug.LogWarning("Could not parse InkFileLog from log: " + rawLog);
                log = null;
                return(false);
            }
        }
        private static void CompileInkThreaded(object itemObj)
        {
            CompilationStackItem item = (CompilationStackItem)itemObj;

            if (item.state == CompilationStackItem.State.Compiling)
            {
                Debug.LogWarning("CompileInkThreaded was called on a file that is already compiling! This is most likely a threading bug. Please report this!");
                return;
            }
            BeginCompilingFile(item);

            var inputString = File.ReadAllText(item.inkAbsoluteFilePath);
            var compiler    = new Compiler(inputString, new Compiler.Options
            {
                countAllVisits = true,
                fileHandler    = new UnityInkFileHandler(Path.GetDirectoryName(item.inkAbsoluteFilePath)),
                errorHandler   = (string message, ErrorType type) => {
                    InkCompilerLog log;
                    if (InkCompilerLog.TryParse(message, out log))
                    {
                        if (string.IsNullOrEmpty(log.fileName))
                        {
                            log.fileName = Path.GetFileName(item.inkAbsoluteFilePath);
                        }
                        item.logOutput.Add(log);
                    }
                    else
                    {
                        Debug.LogWarning("Couldn't parse log " + message);
                    }
                }
            });

            try
            {
                var compiledStory = compiler.Compile();
                if (compiledStory != null)
                {
                    item.compiledJson = compiledStory.ToJson();
                }
            }
            catch (SystemException e)
            {
                item.unhandledErrorOutput.Add(string.Format(
                                                  "Ink Compiler threw exception \nError: {0}\n---- Trace ----\n{1}\n--------\n", e.Message,
                                                  e.StackTrace));
            }

            CompleteCompilingFile(item);

            // This doesn't seem to execute when called in a thread, and I apparently don't have a bloody clue how threads work.
            // If someone can make this work, I'd rather that TryCompileNextFileInStack ran directly after CompileInkThreaded finishes.
            // I couldn't make it work, so I've put TryCompileNextFileInStack in Update instead. Bleh!
            // TryCompileNextFileInStack();
        }
        /// <summary>
        /// Opens an ink file in the associated editor at the correct line number.
        /// TODO - If the editor is inky, this code should load the master file, but immediately show the correct child file at the correct line.
        /// </summary>
        public static void OpenInEditor(InkFile inkFile, InkCompilerLog log)
        {
            var targetFilePath = log.GetAbsoluteFilePath(inkFile);

                        #if UNITY_2019_1_OR_NEWER
            // This function replaces OpenFileAtLineExternal, but I guess it's totally internal and can't be accessed.
            // CodeEditorUtility.Editor.Current.OpenProject(targetFilePath, lineNumber);
                        #pragma warning disable
            UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(targetFilePath, log.lineNumber);
                        #pragma warning restore
                        #else
            UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(targetFilePath, log.lineNumber);
                        #endif
        }
Beispiel #4
0
        private static void CompileInkThreaded(object itemObj)
        {
            CompilationStackItem item = (CompilationStackItem)itemObj;

            // This should be called before this point, but just in case.
            BeginCompilingFile(item);

            var inputString = File.ReadAllText(item.inkAbsoluteFilePath);
            var compiler    = new Compiler(inputString, new Compiler.Options
            {
                countAllVisits = true,
                fileHandler    = new UnityInkFileHandler(Path.GetDirectoryName(item.inkAbsoluteFilePath)),
                errorHandler   = (string message, ErrorType type) => {
                    InkCompilerLog log;
                    if (InkCompilerLog.TryParse(message, out log))
                    {
                        if (string.IsNullOrEmpty(log.fileName))
                        {
                            log.fileName = Path.GetFileName(item.inkAbsoluteFilePath);
                        }
                        item.logOutput.Add(log);
                    }
                    else
                    {
                        Debug.LogWarning("Couldn't parse log " + message);
                    }
                }
            });

            try
            {
                var compiledStory = compiler.Compile();
                if (compiledStory != null)
                {
                    item.compiledJson = compiledStory.ToJson();
                }
            }
            catch (SystemException e)
            {
                item.unhandledErrorOutput.Add(string.Format(
                                                  "Ink Compiler threw exception \nError: {0}\n---- Trace ----\n{1}\n--------\n", e.Message,
                                                  e.StackTrace));
            }


            CompleteCompilingFile(item);
            TryCompileNextFileInStack();
        }
 void CreateTodoList()
 {
     todosList = new ReorderableList(inkFile.metaInfo.todos, typeof(string), false, false, false, false);
     todosList.elementHeight      = 18;
     todosList.drawHeaderCallback = (Rect rect) => {
         EditorGUI.LabelField(rect, "To do");
     };
     todosList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
         Rect           labelRect  = new Rect(rect.x, rect.y, rect.width - 80, rect.height);
         Rect           buttonRect = new Rect(labelRect.xMax, rect.y, 80, rect.height - 2);
         InkCompilerLog log        = ((List <InkCompilerLog>)todosList.list)[index];
         string         label      = log.content;
         GUI.Label(labelRect, label);
         string openLabel = "Open" + (log.lineNumber == -1 ? "" : " (" + log.lineNumber + ")");
         if (GUI.Button(buttonRect, openLabel))
         {
             OpenInEditor(inkFile.filePath, log.lineNumber);
         }
     };
 }
Beispiel #6
0
 void CreateWarningList()
 {
     warningList = new ReorderableList(inkFile.warnings, typeof(string), false, true, false, false);
     warningList.elementHeight      = 18;
     warningList.drawHeaderCallback = (Rect rect) => {
         EditorGUI.LabelField(rect, new GUIContent(InkBrowserIcons.warningIcon), new GUIContent("Warnings"));
     };
     warningList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
         Rect           labelRect  = new Rect(rect.x, rect.y, rect.width - 80, rect.height);
         Rect           buttonRect = new Rect(labelRect.xMax, rect.y, 80, rect.height - 2);
         InkCompilerLog log        = ((List <InkCompilerLog>)warningList.list)[index];
         string         label      = log.content;
         GUI.Label(labelRect, label);
         string openLabel = "Open" + (log.lineNumber == -1 ? "" : " (" + log.lineNumber + ")");
         if (GUI.Button(buttonRect, openLabel))
         {
             InkEditorUtils.OpenInEditor(inkFile, log);
         }
     };
 }