private static void ProcessError(Process process, string error) { string inkFilePath = process.StartInfo.EnvironmentVariables["inkAbsoluteFilePath"]; CompilationStackItem compilingFile = InkLibrary.GetCompilationStackItem(inkFilePath); compilingFile.errorOutput = error; }
private static void ProcessError(Process process, string message) { if (message != null) { message = message.Trim(); } else { Debug.LogWarning("[Ink compiler process] Got spurious null error message, ignoring"); return; } // Byte-order mark seems to confuse the living hell out of the library if (message == "" || message[0] == (char)65279) { Debug.LogWarning("[Ink compiler process] Got empty error message, ignoring"); return; } if (InkEditorUtils.IsNullOrWhiteSpace(message) || message == "???") { return; } Debug.Log(message[0]); Debug.Log(char.IsWhiteSpace(message[0])); Debug.Log((int)(message[0])); CompilationStackItem compilingFile = InkLibrary.GetCompilationStackItem(process); compilingFile.errorOutput.Add(message); }
static void OnCompileProcessComplete(object sender, EventArgs e) { Process process = (Process)sender; CompilationStackItem pendingFile = InkLibrary.GetCompilationStackItem(process); pendingFile.state = CompilationStackItem.State.Importing; }
private static void CompileInkThreaded(object itemObj) { CompilationStackItem item = (CompilationStackItem)itemObj; var inputString = File.ReadAllText(item.inkAbsoluteFilePath); var compiler = new Compiler(inputString, new Compiler.Options { countAllVisits = true, fileHandler = new UnityInkFileHandler(Path.GetDirectoryName(item.inkAbsoluteFilePath)) }); 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)); } item.output.AddRange(compiler.errors); item.output.AddRange(compiler.warnings); item.state = CompilationStackItem.State.Complete; }
private static void SetOutputLog(CompilationStackItem pendingFile) { pendingFile.inkFile.metaInfo.errors.Clear(); pendingFile.inkFile.metaInfo.warnings.Clear(); pendingFile.inkFile.metaInfo.todos.Clear(); foreach (var childInkFile in pendingFile.inkFile.metaInfo.inkFilesInIncludeHierarchy) { childInkFile.metaInfo.unhandledCompileErrors.Clear(); childInkFile.metaInfo.errors.Clear(); childInkFile.metaInfo.warnings.Clear(); childInkFile.metaInfo.todos.Clear(); } foreach (var output in pendingFile.logOutput) { if (output.type == ErrorType.Error) { pendingFile.inkFile.metaInfo.errors.Add(output); Debug.LogError("Ink " + output.type + ": " + output.content + " (at " + output.fileName + ":" + output.lineNumber + ")", pendingFile.inkFile.inkAsset); } else if (output.type == ErrorType.Warning) { pendingFile.inkFile.metaInfo.warnings.Add(output); Debug.LogWarning("Ink " + output.type + ": " + output.content + " (at " + output.fileName + " " + output.lineNumber + ")", pendingFile.inkFile.inkAsset); } else if (output.type == ErrorType.Author) { pendingFile.inkFile.metaInfo.todos.Add(output); Debug.Log("Ink Log: " + output.content + " (at " + output.fileName + " " + output.lineNumber + ")", pendingFile.inkFile.inkAsset); } } }
private static void BeginCompilingFile(CompilationStackItem item) { if (item.state != CompilationStackItem.State.Queued) { return; } item.state = CompilationStackItem.State.Compiling; item.startTime = DateTime.Now; }
private static void ProcessError(Process process, string message) { if (message == null || message.Length == 0 || message == "???") { return; } CompilationStackItem compilingFile = InkLibrary.GetCompilationStackItem(process); compilingFile.errorOutput.Add(message); }
public static void CompileInk(InkFile inkFile) { if (inkFile == null) { Debug.LogError("Tried to compile ink file " + inkFile.filePath + ", but input was null."); return; } if (!inkFile.isMaster) { Debug.LogWarning("Compiling InkFile which is an include. Any file created is likely to be invalid. Did you mean to call CompileInk on inkFile.master?"); } if (InkLibrary.GetCompilationStackItem(inkFile) != null) { UnityEngine.Debug.LogWarning("Tried compiling ink file, but file is already compiling. " + inkFile.filePath); return; } string inklecatePath = InkEditorUtils.GetInklecateFilePath(); if (inklecatePath == null) { UnityEngine.Debug.LogWarning("Inklecate (the ink compiler) not found in assets. This will prevent automatic building of JSON TextAsset files from ink story files."); return; } if (Application.platform == RuntimePlatform.OSXEditor) { SetInklecateFilePermissions(inklecatePath); } string inputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileName(inkFile.filePath)); string outputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileNameWithoutExtension(Path.GetFileName(inkFile.filePath))) + ".json"; string inkArguments = "-c -o " + "\"" + outputPath + "\" \"" + inputPath + "\""; CompilationStackItem pendingFile = new CompilationStackItem(); pendingFile.inkFile = InkLibrary.GetInkFileWithAbsolutePath(inputPath); pendingFile.inkAbsoluteFilePath = inputPath; pendingFile.jsonAbsoluteFilePath = outputPath; pendingFile.state = CompilationStackItem.State.Compiling; InkLibrary.Instance.compilationStack.Add(pendingFile); Process process = new Process(); process.StartInfo.WorkingDirectory = inkFile.absoluteFolderPath; process.StartInfo.FileName = inklecatePath; process.StartInfo.Arguments = inkArguments; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.EnableRaisingEvents = true; process.StartInfo.EnvironmentVariables["inkAbsoluteFilePath"] = inputPath; process.ErrorDataReceived += OnProcessError; process.Exited += OnCompileProcessComplete; process.Start(); }
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> /// Starts a System.Process that compiles a master ink file, creating a playable JSON file that can be parsed by the Ink.Story class /// </summary> /// <param name="inkFile">Ink file.</param> private static void CompileInkInternal(InkFile inkFile, bool immediate) { // If we've not yet locked C# compilation do so now if (!hasLockedUnityCompilation) { hasLockedUnityCompilation = true; EditorApplication.LockReloadAssemblies(); } RemoveFromPendingCompilationStack(inkFile); if (inkFile == null) { Debug.LogError("Tried to compile ink file but input was null."); return; } if (!inkFile.metaInfo.isMaster) { Debug.LogWarning("Compiling InkFile which is an include. Any file created is likely to be invalid. Did you mean to call CompileInk on inkFile.master?"); } if (InkLibrary.GetCompilationStackItem(inkFile) != null) { UnityEngine.Debug.LogWarning("Tried compiling ink file, but file is already compiling. " + inkFile.filePath); return; } string inputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileName(inkFile.filePath)); Debug.Assert(inkFile.absoluteFilePath == inputPath); CompilationStackItem pendingFile = new CompilationStackItem { inkFile = InkLibrary.GetInkFileWithAbsolutePath(inputPath), inkAbsoluteFilePath = inputPath, jsonAbsoluteFilePath = inkFile.jsonPath, state = CompilationStackItem.State.Compiling }; InkLibrary.Instance.compilationStack.Add(pendingFile); //InkLibrary.Save(); if (immediate) { CompileInkThreaded(pendingFile); Update(); } else { if (EditorApplication.isCompiling) { Debug.LogWarning("Was compiling scripts when ink compilation started! This seems to cause the thread to cancel and complete, but the work isn't done. It may cause a timeout."); } ThreadPool.QueueUserWorkItem(CompileInkThreaded, pendingFile); } }
static void OnProcessError(object sender, DataReceivedEventArgs e) { Process process = (Process)sender; Debug.LogError("Fatal Error compiling Ink! Ink failed to process. Please report this as a bug."); InkFile inkFile = InkLibrary.GetInkFileWithAbsolutePath(process.StartInfo.EnvironmentVariables["inkAbsoluteFilePath"]); Debug.LogError(inkFile); CompilationStackItem compilingFile = InkLibrary.GetCompilationStackItem(inkFile); InkLibrary.Instance.compilationStack.Remove(compilingFile); }
static void OnCompileProcessComplete(object sender, System.EventArgs e) { Process process = (Process)sender; CompilationStackItem pendingFile = InkLibrary.GetCompilationStackItem(process); pendingFile.state = CompilationStackItem.State.Importing; if (InkLibrary.FilesInCompilingStackInState(CompilationStackItem.State.Compiling).Count == 0) { // This event runs in another thread, preventing us from calling some UnityEditor functions directly. Instead, we delay till the next inspector update. EditorApplication.delayCall += Delay; } }
private static void CompleteCompilingFile(CompilationStackItem item) { if (item.state != CompilationStackItem.State.Compiling) { return; } item.state = CompilationStackItem.State.Complete; item.endTime = DateTime.Now; if (item.timeTaken > InkSettings.Instance.compileTimeout * 0.6f) { Debug.LogWarning("Compilation for " + Path.GetFileName(item.inkFile.filePath) + " took over 60% of the time required to timeout the compiler. Consider increasing the compile timeout on the InkSettings file."); } }
private static void ProcessError(Process process, string message) { message = message.Trim(); if (InkEditorUtils.IsNullOrWhiteSpace(message) || message == "???") { return; } Debug.Log(message[0]); Debug.Log(char.IsWhiteSpace(message[0])); Debug.Log((int)(message[0])); CompilationStackItem compilingFile = InkLibrary.GetCompilationStackItem(process); compilingFile.errorOutput.Add(message); }
static void OnCompileProcessComplete(object sender, System.EventArgs e) { Process process = (Process)sender; CompilationStackItem pendingFile = InkLibrary.GetCompilationStackItem(process.StartInfo.EnvironmentVariables["inkAbsoluteFilePath"]); pendingFile.state = CompilationStackItem.State.Importing; pendingFile.output = process.StandardOutput.ReadToEnd(); if (InkLibrary.FilesInCompilingStackInState(CompilationStackItem.State.Compiling).Count == 0) { // This event runs in another thread, preventing us from calling some UnityEditor functions directly. Instead, we delay till the next inspector update. EditorApplication.delayCall += Delay; } }
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(); }
private static void ProcessError(Process process, string message) { if (message == null) { return; } message = message.Trim(new char[] { '\uFEFF', '\u200B' }); if (IsNullOrWhiteSpace(message) || message == "???") { return; } Debug.Log(message[0]); Debug.Log(char.IsWhiteSpace(message[0])); Debug.Log((int)(message[0])); CompilationStackItem compilingFile = InkLibrary.GetCompilationStackItem(process); compilingFile.errorOutput.Add(message); }
/// <summary> /// Starts a System.Process that compiles a master ink file, creating a playable JSON file that can be parsed by the Ink.Story class /// </summary> /// <param name="inkFile">Ink file.</param> private static void CompileInkInternal(InkFile inkFile, bool immediate) { if (inkFile == null) { Debug.LogError("Tried to compile ink file but input was null."); return; } if (!inkFile.metaInfo.isMaster) { Debug.LogWarning("Compiling InkFile which is an include. Any file created is likely to be invalid. Did you mean to call CompileInk on inkFile.master?"); } // If we've not yet locked C# compilation do so now if (!hasLockedUnityCompilation) { hasLockedUnityCompilation = true; EditorApplication.LockReloadAssemblies(); } RemoveFromPendingCompilationStack(inkFile); if (InkLibrary.GetCompilationStackItem(inkFile) != null) { UnityEngine.Debug.LogWarning("Tried compiling ink file, but file is already compiling. " + inkFile.filePath); return; } string inputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileName(inkFile.filePath)); Debug.Assert(inkFile.absoluteFilePath == inputPath); CompilationStackItem pendingFile = new CompilationStackItem { inkFile = InkLibrary.GetInkFileWithAbsolutePath(inputPath), inkAbsoluteFilePath = inputPath, jsonAbsoluteFilePath = inkFile.absoluteJSONPath, state = CompilationStackItem.State.Queued, immediate = immediate }; InkLibrary.Instance.compilationStack.Add(pendingFile); InkLibrary.SaveToFile(); TryCompileNextFileInStack(); }
private static void SetOutputLog(CompilationStackItem pendingFile) { pendingFile.inkFile.metaInfo.errors.Clear(); pendingFile.inkFile.metaInfo.warnings.Clear(); pendingFile.inkFile.metaInfo.todos.Clear(); foreach (var childInkFile in pendingFile.inkFile.metaInfo.inkFilesInIncludeHierarchy) { childInkFile.metaInfo.compileErrors.Clear(); childInkFile.metaInfo.errors.Clear(); childInkFile.metaInfo.warnings.Clear(); childInkFile.metaInfo.todos.Clear(); } foreach (string output in pendingFile.output) { var match = _errorRegex.Match(output); if (match.Success) { string errorType = null; string filename = null; int lineNo = -1; string message = null; var errorTypeCapture = match.Groups["errorType"]; if (errorTypeCapture != null) { errorType = errorTypeCapture.Value; } 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(); } string logFilePath = InkEditorUtils.CombinePaths(Path.GetDirectoryName(pendingFile.inkFile.filePath), filename); InkFile inkFile = InkLibrary.GetInkFileWithPath(logFilePath); if (inkFile == null) { inkFile = pendingFile.inkFile; } string pathAndLineNumberString = "\n" + inkFile.filePath + ":" + lineNo; if (errorType == "ERROR") { inkFile.metaInfo.errors.Add(new InkMetaFile.InkFileLog(message, lineNo)); Debug.LogError("INK " + errorType + ": " + message + pathAndLineNumberString); } else if (errorType == "WARNING") { inkFile.metaInfo.warnings.Add(new InkMetaFile.InkFileLog(message, lineNo)); Debug.LogWarning("INK " + errorType + ": " + message + pathAndLineNumberString); } else if (errorType == "TODO") { inkFile.metaInfo.todos.Add(new InkMetaFile.InkFileLog(message, lineNo)); Debug.Log("INK " + errorType + ": " + message + pathAndLineNumberString); } } } }
private static void SetOutputLog(CompilationStackItem pendingFile) { pendingFile.inkFile.errors.Clear(); pendingFile.inkFile.warnings.Clear(); pendingFile.inkFile.todos.Clear(); foreach (var child in pendingFile.inkFile.includes) { if (child == null) { Debug.LogError("Error compiling ink: Ink file include in " + pendingFile.inkFile.filePath + " is null."); continue; } InkFile childInkFile = InkLibrary.GetInkFileWithFile((DefaultAsset)child); childInkFile.errors.Clear(); childInkFile.warnings.Clear(); childInkFile.todos.Clear(); } string[] splitOutput = pendingFile.output.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string output in splitOutput) { var match = _errorRegex.Match(output); if (match.Success) { string errorType = null; string filename = null; int lineNo = -1; string message = null; var errorTypeCapture = match.Groups["errorType"]; if (errorTypeCapture != null) { errorType = errorTypeCapture.Value; } 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(); } string logFilePath = Path.Combine(Path.GetDirectoryName(pendingFile.inkFile.filePath), filename); logFilePath = logFilePath.Replace('\\', '/'); InkFile inkFile = InkLibrary.GetInkFileWithPath(logFilePath); if (inkFile == null) { inkFile = pendingFile.inkFile; } string pathAndLineNumberString = "\n" + inkFile.filePath + "(" + lineNo + ")"; if (errorType == "ERROR") { inkFile.errors.Add(new InkFile.InkFileLog(message, lineNo)); Debug.LogError("INK " + errorType + ": " + message + pathAndLineNumberString); } else if (errorType == "WARNING") { inkFile.warnings.Add(new InkFile.InkFileLog(message, lineNo)); Debug.LogWarning("INK " + errorType + ": " + message + pathAndLineNumberString); } else if (errorType == "TODO") { inkFile.todos.Add(new InkFile.InkFileLog(message, lineNo)); Debug.Log("INK " + errorType + ": " + message + pathAndLineNumberString); } } } }
private static void SetOutputLog(CompilationStackItem pendingFile) { pendingFile.inkFile.errors.Clear(); pendingFile.inkFile.warnings.Clear(); pendingFile.inkFile.todos.Clear(); foreach(var child in pendingFile.inkFile.includes) { if(child == null) { Debug.LogError("Error compiling ink: Ink file include in "+pendingFile.inkFile.filePath+" is null."); continue; } InkFile childInkFile = InkLibrary.GetInkFileWithFile((DefaultAsset)child); childInkFile.errors.Clear(); childInkFile.warnings.Clear(); childInkFile.todos.Clear(); } string[] splitOutput = pendingFile.output.Split(new string[]{"\n"}, StringSplitOptions.RemoveEmptyEntries); foreach(string output in splitOutput) { var match = _errorRegex.Match(output); if (match.Success) { string errorType = null; string filename = null; int lineNo = -1; string message = null; var errorTypeCapture = match.Groups["errorType"]; if( errorTypeCapture != null ) { errorType = errorTypeCapture.Value; } 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(); string logFilePath = Path.Combine(Path.GetDirectoryName(pendingFile.inkFile.filePath), filename); logFilePath = logFilePath.Replace ('\\', '/'); InkFile inkFile = InkLibrary.GetInkFileWithPath(logFilePath); if(inkFile == null) inkFile = pendingFile.inkFile; string pathAndLineNumberString = "\n"+inkFile.filePath+"("+lineNo+")"; if(errorType == "ERROR") { inkFile.errors.Add(new InkFile.InkFileLog(message, lineNo)); Debug.LogError("INK "+errorType+": "+message + pathAndLineNumberString); } else if (errorType == "WARNING") { inkFile.warnings.Add(new InkFile.InkFileLog(message, lineNo)); Debug.LogWarning("INK "+errorType+": "+message + pathAndLineNumberString); } else if (errorType == "TODO") { inkFile.todos.Add(new InkFile.InkFileLog(message, lineNo)); Debug.Log("INK "+errorType+": "+message + pathAndLineNumberString); } } } }
/// <summary> /// Starts a System.Process that compiles a master ink file, creating a playable JSON file that can be parsed by the Ink.Story class /// </summary> /// <param name="inkFile">Ink file.</param> public static void CompileInk(InkFile inkFile) { if (inkFile == null) { Debug.LogError("Tried to compile ink file " + inkFile.filePath + ", but input was null."); return; } if (!inkFile.metaInfo.isMaster) { Debug.LogWarning("Compiling InkFile which is an include. Any file created is likely to be invalid. Did you mean to call CompileInk on inkFile.master?"); } if (InkLibrary.GetCompilationStackItem(inkFile) != null) { UnityEngine.Debug.LogWarning("Tried compiling ink file, but file is already compiling. " + inkFile.filePath); return; } string inklecatePath = InkEditorUtils.GetInklecateFilePath(); if (inklecatePath == null) { UnityEngine.Debug.LogWarning("Inklecate (the ink compiler) not found in assets. This will prevent automatic building of JSON TextAsset files from ink story files."); return; } if (Application.platform == RuntimePlatform.OSXEditor) { SetInklecateFilePermissions(inklecatePath); } if (inklecatePath.Contains("'")) { Debug.LogError("Due to a Unity bug, Inklecate path cannot contain an apostrophe. Ink will not compile until this is resolved. Path is '" + inklecatePath + "'"); return; } // This hasn't been affecting us lately. Left it in so we can easily restore it in case of future bugs. /* else if(inklecatePath.Contains(" ")){ * Debug.LogWarning("Inklecate path should not contain a space. This might lead to compilation failing. Path is '"+inklecatePath+"'. If you don't see any compilation errors, you can ignore this warning."); * }*/ string inputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileName(inkFile.filePath)); string outputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileNameWithoutExtension(Path.GetFileName(inkFile.filePath))) + ".json"; string inkArguments = InkSettings.Instance.customInklecateOptions.additionalCompilerOptions + " -c -o " + "\"" + outputPath + "\" \"" + inputPath + "\""; CompilationStackItem pendingFile = new CompilationStackItem(); pendingFile.inkFile = InkLibrary.GetInkFileWithAbsolutePath(inputPath); pendingFile.inkAbsoluteFilePath = inputPath; pendingFile.jsonAbsoluteFilePath = outputPath; pendingFile.state = CompilationStackItem.State.Compiling; InkLibrary.Instance.compilationStack.Add(pendingFile); InkLibrary.Save(); Process process = new Process(); if (InkSettings.Instance.customInklecateOptions.runInklecateWithMono && Application.platform != RuntimePlatform.WindowsEditor) { if (File.Exists(_libraryMono)) { process.StartInfo.FileName = _libraryMono; } else if (File.Exists(_usrMono)) { process.StartInfo.FileName = _usrMono; } else { Debug.LogError("Mono was not found on machine"); return; } process.StartInfo.Arguments = inklecatePath + " " + inkArguments; } else { process.StartInfo.FileName = inklecatePath; process.StartInfo.Arguments = inkArguments; } process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.EnableRaisingEvents = true; process.OutputDataReceived += OnProcessOutput; // For some reason having this line enabled spams the output and error streams with null and "???" (only on OSX?) // Rather than removing unhandled error detection I thought it'd be best to just catch those messages and ignore them instead. process.ErrorDataReceived += OnProcessError; process.Exited += OnCompileProcessComplete; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); pendingFile.process = process; // If you'd like to run this command outside of unity, you could instead run process.StartInfo.Arguments in the command line. }
public static void CompileInk(InkFile inkFile) { if(inkFile == null) { Debug.LogError("Tried to compile ink file "+inkFile.filePath+", but input was null."); return; } if(!inkFile.isMaster) Debug.LogWarning("Compiling InkFile which is an include. Any file created is likely to be invalid. Did you mean to call CompileInk on inkFile.master?"); if(InkLibrary.GetCompilationStackItem(inkFile) != null) { UnityEngine.Debug.LogWarning("Tried compiling ink file, but file is already compiling. "+inkFile.filePath); return; } string inklecatePath = InkEditorUtils.GetInklecateFilePath(); if(inklecatePath == null) { UnityEngine.Debug.LogWarning("Inklecate (the ink compiler) not found in assets. This will prevent automatic building of JSON TextAsset files from ink story files."); return; } string inputPath = Path.Combine(inkFile.absoluteFolderPath, Path.GetFileName(inkFile.filePath)); inputPath = inputPath.Replace ('\\', '/'); string outputPath = Path.Combine(inkFile.absoluteFolderPath, Path.GetFileNameWithoutExtension(Path.GetFileName(inkFile.filePath)))+".json"; outputPath = outputPath.Replace ('\\', '/'); string inkArguments = "-c -o "+"\""+outputPath +"\" \""+inputPath+"\""; CompilationStackItem pendingFile = new CompilationStackItem(); pendingFile.inkFile = InkLibrary.GetInkFileWithAbsolutePath(inputPath); pendingFile.inkAbsoluteFilePath = inputPath; pendingFile.jsonAbsoluteFilePath = outputPath; pendingFile.state = CompilationStackItem.State.Compiling; InkLibrary.Instance.compilationStack.Add(pendingFile); Process process = new Process(); process.StartInfo.WorkingDirectory = inkFile.absoluteFolderPath; process.StartInfo.FileName = inklecatePath; process.StartInfo.Arguments = inkArguments; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.EnableRaisingEvents = true; process.StartInfo.EnvironmentVariables["inkAbsoluteFilePath"] = inputPath; process.Exited += OnCompileProcessComplete; process.ErrorDataReceived += OnProcessError; process.Start(); }
public static void CompileInk(InkFile inkFile) { if (inkFile == null) { Debug.LogError("Tried to compile ink file " + inkFile.filePath + ", but input was null."); return; } if (!inkFile.isMaster) { Debug.LogWarning("Compiling InkFile which is an include. Any file created is likely to be invalid. Did you mean to call CompileInk on inkFile.master?"); } if (InkLibrary.GetCompilationStackItem(inkFile) != null) { UnityEngine.Debug.LogWarning("Tried compiling ink file, but file is already compiling. " + inkFile.filePath); return; } string inklecatePath = InkEditorUtils.GetInklecateFilePath(); if (inklecatePath == null) { UnityEngine.Debug.LogWarning("Inklecate (the ink compiler) not found in assets. This will prevent automatic building of JSON TextAsset files from ink story files."); return; } if (Application.platform == RuntimePlatform.OSXEditor) { SetInklecateFilePermissions(inklecatePath); } if (inklecatePath.Contains("'")) { Debug.LogError("Due to a Unity bug, Inklecate path cannot contain an apostrophe. Ink will not compile until this is resolved. Path is '" + inklecatePath + "'"); return; } else if (inklecatePath.Contains(" ")) { Debug.LogWarning("Inklecate path should not contain a space. This might lead to compilation failing. Path is '" + inklecatePath + "'. If you don't see any compilation errors, you can ignore this warning."); } string inputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileName(inkFile.filePath)); string outputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileNameWithoutExtension(Path.GetFileName(inkFile.filePath))) + ".json"; string inkArguments = InkLibrary.Instance.additionalCompilerOptions + " -c -o " + "\"" + outputPath + "\" \"" + inputPath + "\""; CompilationStackItem pendingFile = new CompilationStackItem(); pendingFile.inkFile = InkLibrary.GetInkFileWithAbsolutePath(inputPath); pendingFile.inkAbsoluteFilePath = inputPath; pendingFile.jsonAbsoluteFilePath = outputPath; pendingFile.state = CompilationStackItem.State.Compiling; InkLibrary.Instance.compilationStack.Add(pendingFile); Process process = new Process(); if (InkLibrary.Instance.runInklecateWithMono) { process.StartInfo.FileName = "/usr/local/bin/mono"; process.StartInfo.Arguments = inklecatePath + " " + inkArguments; } else { process.StartInfo.FileName = inklecatePath; process.StartInfo.Arguments = inkArguments; } process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.EnableRaisingEvents = true; process.StartInfo.EnvironmentVariables["inkAbsoluteFilePath"] = inputPath; process.ErrorDataReceived += OnProcessError; process.Exited += OnCompileProcessComplete; process.Start(); }